Let’s proceed to investigate the newly decrypted function. It starts with two
calls to the traditional NtDelayExecution. Then the function proceeds to
call what appears to be NtOpenFilethrough the obfuscated interface, with
the string “\??\C:”hard-coded right there in the middle of the code. After
NtOpenFilethe function calls NtQueryVolumeInformationFilewith
the FileFsVolumeInformationinformation level flag. It then reads offset
+8 from the returned data structure and stores it in the local variable
[406020]. Offset +8 in data structure FILE_FS_VOLUME_INFORMATIONis
VolumeSerialNumber (this information was also obtained at http://
undocumented.ntinternals.net).
This is a fairly typical copy protection sequence, in a slightly different flavor.
The primary partition’s volume serial number is a good way to create com-
puter-specific dependencies. It is a 32-bit number that’s randomly assigned to a
partition when it’s being formatted. The value is retained until the partition is
formatted. Utilizing this value in a serial-number-based copy protection means
that serial numbers cannot be shared between users on different computers—
each computer has a different serial number. One slightly unusual thing about
this is that Defender is obtaining this value directly using the native API. This
is typically done using the GetVolumeInformationWin32 API.
You’ve pretty much reached the end of the current function. Before return-
ing it makes yet another call to NtDelayExecution, invokes RDTSC, loads
the low-order word into EAXas the return value (to make for a garbage return
value), and goes back to the beginning to reencrypt itself.
Parsing the Program Parameters
Back at the main entry point function, you find another call to NtDelay
Executionwhich is followed by a call into what appears to be the final func-
tion call (other than that apparently useless call to IsDebuggerPresent) in
the program entry point, 402082.
Naturally, 402082 is also encrypted, so you will set a breakpoint on 402198 ,
which is right after the decryption code is done decrypting. You immediately
start seeing familiar bits of code (if Olly is still showing you junk instead of
code at this point, you can either try stepping into that code and see if auto-
matically fixes itself or you can specifically tell Olly to treat these bytes as code
by right-clicking the first line and selecting Analysis. During next analysis,
treat selection as➪Command). You will see a call to NtDelayExecution,
followed by a sequence that loads a new DLL: SHELL32.DLL. The loading is
followed by the creation of the obfuscated module interface: allocating mem-
ory at a random address, creating checksums for each of the exported
SHELL32.DLLnames, and copying the entire code section into the newly allo-
cated memory block. After all of this the program calls a KERNEL32.DLLthat
404 Chapter 11