int
, and the next two parameters at ❷ and ❸ are 64-bit values representing pointers.To determine the string that the malware is searching, we can use dynamic analysis to obtain the encoded value that the executable should be named. To do so, we use WinDbg (again, because OllyDbg does not support 64-bit executables). We open the program in WinDbg and set a breakpoint on the call to strncmp
, as shown in .
WinDbg output can sometimes be a bit verbose, so we’ll focus on the commands issued. We can’t set a breakpoint using bp strncmp
because WinDbg doesn’t know the location of strncmp
. However, IDA Pro uses signatures to find strncmp
, and from , we know that the call to strncmp
is at 0000000140001205. As shown in , at ❶, we use the u
instruction to verify the instructions at 0000000140001205, and then set a breakpoint on .
Example C-230. A 64-bit call to CreateProcessA
0000000140001025 mov [rsp+0E8h+hHandle], rax 000000014000102A mov [rsp+0E8h+var_90], rax 000000014000102F mov [rsp+0E8h+var_88], rax 0000000140001034 lea rax, [rsp+0E8h+hHandle] 0000000140001039 xor r9d, r9d ; lpThreadAttributes 000000014000103C xor r8d, r8d ; lpProcessAttributes 000000014000103F mov [rsp+0E8h+var_A0], rax 0000000140001044 lea rax, [rsp+0E8h+var_78] 0000000140001049 xor ecx, ecx ; lpApplicationName 000000014000104B mov [rsp+0E8h+var_A8], rax ❶ 0000000140001050 xor eax, eax 0000000140001052 mov [rsp+0E8h+var_78], 68h 000000014000105A mov [rsp+0E8h+var_B0], rax 000000014000105F mov [rsp+0E8h+var_B8], rax 0000000140001064 mov [rsp+0E8h+var_C0], eax 0000000140001068 mov [rsp+0E8h+var_C8], 1 0000000140001070 mov [rsp+0E8h+var_3C], 100h 000000014000107B mov [rsp+0E8h+var_28], rbx ❷ 0000000140001083 mov [rsp+0E8h+var_18], rbx ❸ 000000014000108B mov [rsp+0E8h+var_20], rbx ❹ 0000000140001093 call cs:CreateProcessA
The socket is stored at RBX in code not shown in the listing. All the parameters are moved onto the stack instead of pushed onto the stack, which makes the function call considerably more complicated than the 32-bit version.
Most of the moves onto the stack represent parameters to CreateProcessA
, but some do not. For example, the move at ❶ is LPSTARTUPINFO
being passed as a parameter to CreateProcessA
. However, the STARTUPINFO
structure itself is stored on the stack, starting at var_78
. The mov
instructions seen at ❷, ❸, and ❹ are values being moved into the STARTUPINFO
structure, which happens to be stored on the stack, and not individual parameters for CreateProcessA
.
Because of all the intermingling of function parameters and other stack activity, it’s difficult to tell how many parameters are passed to a function just by looking at the function call. However, because CreateProcessA
is documented, we know that it takes exactly 10 parameters.
At this point, we’ve reached the end of the code. We’ve learned that the malware checks to see if the program is jzm.exe, and if so, it creates a reverse shell to a remote computer to enable remote access on the machine.