Blog Post

The Human Connection Blog
2 MIN READ

Reverse Engineering SmokeLoader: An In-Depth Analysis (Stage 2)

BenMcCarthy's avatar
BenMcCarthy
Icon for Immerser rankImmerser
18 days ago

This is the second part of a series of blog posts analyzing the SmokeLoader malware. It goes into detail on how we reverse-engineered it to identify its objectives and actions. 

The first part of this blog series looked at the malware’s contextual information and some of our initial analysis considerations.

In this second part, we’ll continue where we left off by going deeper into the debugging and decompiling process to identify more shellcode and obfuscation techniques.

As a reminder, we left off the previous post by identifying the first shellcode in memory, which was located at memory address 0x008A300.

EAX pointed to this memory address, where deobfuscated instructions were provided. The execution was now at this location, meaning we had to dump the memory and load it into Ghidra for some static analysis.

We dumped the whole heap allocation from here instead of starting at 0x2310. When we started analyzing it in Ghidra, we had to start at location 0x2310.

The first thing that occurred was a CALL instruction.

The second stage of this malware runs similarly to the first stage but employs some API hashing to obfuscate the API function calls that the malware makes. The malware ultimately allocates memory on the heap, places obfuscated data there, deobfuscates it, and then calls it.

The starting function of the shellcode resembles a similar structure to the main() of the parent stage malware.

We’ve changed some of the names of the functions and variables to help you understand these screenshots. The first function did the API hashing and called a nested function for the process of LoadLibraryA and GetProcAddress.

Inside the function called FUN_00002448, you are presented with the following:

The image above shows a function that performs the LoadLibraryA and GetProcAddress processes commonly used by malware. This is done for the following APIs:

  • LoadLibraryA(“Kerne32.dll”)
  • GetProcAddress(“GlobalAlloc”)
  • GetProcAddress(“Sleep”)
  • GetProcAddress(“VirtualAlloc”)
  • GetProcAddress(“CreateTool32Snapshot”)
  • GetProcAddress(“Module32First”)
  • GetProcAddress(“CloseHandle”)

These APIs indicate some of the malware’s behavior. But the most important here is VirtualAlloc. The size of the allocated location on the heap is important to note for later dumping of the third-stage shellcode. 

The second important function is the allocation on the heap and the deobfuscation.

In the debugger, we set a breakpoint at the line (*local_8)(), which is the location of the return value from VirtualAlloc. This process is the same as the previous stage; we simply had to dump the memory from that location then load it into Ghidra for the next stage!

This image shows the jump to the new shellcode location 0x02420000!

Conclusion

The second part of our SmokeLoader analysis identified another location in memory where shellcode is being allocated and stored. We also identified some obfuscation and XOR decryption being used throughout. 

Stay tuned for the next blog entry, where we’ll delve even deeper into this sample to identify some of the key API functions the malware employs to allocate memory, store shellcode, and deceive analysts.

Updated 18 days ago
Version 1.0
No CommentsBe the first to comment