Running the Program
The program itself looks like a harmless tool that lists a bunch of information about all running processes and the dll’s they load. Since this binary is in a chapter about static analysis, it makes sense that most of the work here will be done in IDA.
Modifying return address
Initially, the program looks to be a non-malicious binary that does exactly what we observed by running it. If we look towards the beginning of the
_main function, we can see that IDA has highlighted part of the
mov [ebp+4], eax instruction. This is highlighted because IDA does not expect a function to modify a value outside its own stack frame.
call instruction places the address of the next instruction on the stack so when the called function returns, execution can continue in the caller. The
retn function will pop the value of the return address off the stack and move pc to that address. This piece of malware exploits this mechanic by overwriting the return address at
ebp+4 to some malicious code hidden in the binary. After main is finished, the malicious payload beginning at address
0x40148C will execute.
Jumping Under Constant Condition
When we disassemble the code near
0x40148C, we quickly find that IDA generates some weird disassembly. IDA tells us that this disassembly is suspicious by highlighting the address of the
jmp instruction at
0x401496. Looking up at the previous two instructions, we see a sequence that always results in a jump to
0x401497. IDA has already disassembled the byte at that address as part of a bad jump instruction.
We can fix this by patching the
0xE9 byte to a
nop so IDA can correctly disassemble the rest of the function.
The next chunk of code disassembled looks like something that prints a message to the user. When we ran this binary we never saw this message. This code is a distraction to hide the interesting functionality of this software.
The three instructions starting at
0x401487 sets up an exception handler. Windows uses the fs segment to store information about the current thread. The first piece of data in this segment is a pointer to a linked list of exception handlers. When an exception occurs, the CPU will try to execute the first handler in the list. If that handler cannot recover from the exception, it will pass to the next handler. These three instructions create a handler with code at
0x4014C0 on the stack. It then stores the address of this handler at
The next two instructions cause an exception to occur. The
ecx register is set to zero used to divide. Once this exception occurs, control will go to the exception handler made previously. Since the following instructions never execute, we can simplify the code to an unconditional jump to
0x4014C0 so that stack analysis goes smoothly in the future. To continue with analysis, we need to examine
IDA did not disassemble the data at
0x4014C0. This is fine because we can press
c while highlighted over the raw bytes. IDA will disassemble from this address and we can make more sense of the is happening.
The disassembly produced by IDA reveals some code that cleans up after the weird exception handling stuff. Following that is an interesting
jmp instruction. This instruction will jump to the second byte of the
jmp instruction. Reusing bytes in instructions confuses IDA because it does not have a good way to display that there are more than one instructions at the same address. The disassembler continues but cannot disassemble the next byte because
0xC0 is not a valid opcode. We can fix this by turning the first byte of the
jmp into a
nop. It is important to note that this only helps us understand the functionality since we are creating functionally equivalent code. It may be confusing if we debugged this program because the
jmp instruction actually does execute.
Jumps with the same target
The code revealed after patching the
jmp decodes two strings from memory uses them to download a file from a remote server. After the download, we see a combination of a
jz and a
jnz that both go one byte into a call instruction. Functionally, this is the same thing as an unconditional jump to the fixed instruction. The benefit of this technique is that IDA will disassemble the code as if the branch was not taken first. When it tries to disassemble the code as if the branch was taken, it sees that that address is already part of an instruction so no further processing is needed.
We can just treat this as a jump under a constant condition and
nop out the byte not executed. Once this patch is complete, we can define go to
0x4014c0 and press
p. IDA will define the this malicious portion of the code as a function and we can easily read it in graph mode or decompile it with Hexrays.