Deep Analysis of SmokeLoader By Abdallah Elshinbary Published: 2020-06-21 · Archived: 2026-04-05 16:33:08 UTC SmokeLoader is a well known bot that is been around since 2011. It’s mainly used to drop other malware families. SmokeLoader has been under development and is constantly changing with multiple novel features added throughout the years. Sample SHA256: fc20b03299b8ae91e72e104ee4f18e40125b2b061f1509d1c5b3f9fac3104934 Stage 1Permalink This stage starts off by allocating memory for shellcode using LocalAlloc() (not VirtualAlloc), then it fills this memory with the shellcode (86 KB). Next, it changes the protection of the allocated memory region to PAGE_EXECUTE_READWRITE using VirtualProtect() , then it writes the shellcode and executes it. https://n1ght-w0lf.github.io/malware%20analysis/smokeloader/ Page 1 of 18 ShellcodePermalink The shellcode starts by getting the addresses of LoadLibraryA and GetProcAddress to resolve APIs dynamically, but first let’s see how it does that. First it passes some hash values to a sub-routine that returns the address of the requested function. After some digging, I found out that the algorithm for calculating the hashes is pretty simple. int calc_hash(char* name) { int x, hash = 0; for(int i=0; i.tmp" then loads it using LdrLoadDll() and resolves its imports from it. https://n1ght-w0lf.github.io/malware%20analysis/smokeloader/ Page 8 of 18 Custom ImportsPermalink SmokeLoader stores a hash table of its imports, it uses the same PEB traversal technique explained earlier to walk through the DLLs’ export table and compare the hash of each API name with the stored hashes. The hashing function is an implementation of djb2 hashing algorithms: int calc_hash(char *api_name) { int hash=0x1505; for(int i=0; i<=strlen(api_name); i++) // null byte included hash = ((hash << 5) + hash) + api_name[i]; return hash; } Here is a list of imported functions and their corresponding hashes: Expand to see more   ntdll.dll       LdrLoadDll (0x64033f83)       NtClose (0xfd507add)       NtTerminateProcess (0xf779110f)       RtlInitUnicodeString (0x60a350a9)       RtlMoveMemory (0x845136e7)       RtlZeroMemory (0x8a3d4cb0)   kernel32.dll       CopyFileW (0x306cceb7)       CreateEventW (0xfd4027f2) And here is the list of the imported functions from the copied ntdll (for anti-hooking): Expand to see more   4DD3.tmp       NtAllocateVirtualMemory (0x5a0c2ccc)       NtCreateSection (0xd5f23ad0)       NtEnumerateKey (0xb6306996)       NtFreeVirtualMemory (0x2a6fa509)       NtMapViewOfSection (0x870246aa)       NtOpenKey (0xc29efe42)       NtOpenProcess (0x507bcb58)       NtQueryInformationProcess (0xd6d488a2)       NtQueryKey (0xa9475346) https://n1ght-w0lf.github.io/malware%20analysis/smokeloader/ Page 9 of 18 Anti VMPermalink SmokeLoader enumerates all the subkeys of these keys: System\CurrentControlSet\Enum\IDE System\CurrentControlSet\Enum\SCSI Then it transforms them into lowercase and searches for these strings in the enumerated keys names: qemu virtio vmware vbox xen If one of them is found, the binary exits. Process InjectionPermalink SmokeLoader uses PROPagate injection method to inject the next stage into explorer.exe . First it decompresses the next stage using RtlDecompressBuffer() . Then there is a call to NtOpenProcess() to open explorer.exe for the injection. The injection process starts by creating two shared sections between the current process and explorer process (one section for the modified property and the other for the next stage’s code), then SmokeLoader maps the created https://n1ght-w0lf.github.io/malware%20analysis/smokeloader/ Page 10 of 18 sections to the current process and explorer process memory space (so any changes in the sections will be reflected in explorer process). Note that both sections have "RWX" protection which might raise some red flags by security solutions. We can see that explorer got a handle to these two sections (this is similar to classic code injection but with much more stealth). SmokeLoader then writes the next stage to one of the sections and the modified property (which will call the next stage’s code) to the other section. Finally, it sets the modified property using SetPropA() and sends a message to explorer window using SendNotifyMessageA() , this will result in the injected code being executed in the context of explorer.exe . Stage 3Permalink This is the final stage of SmokeLoader, it starts by doing some anti-analysis checks. Checking Running ProcessesPermalink https://n1ght-w0lf.github.io/malware%20analysis/smokeloader/ Page 11 of 18 This stage loops through the running process, it calculates each process name’s hash and compares it against some hardcoded hashes. Here is the algorithm for calculating the hash of a process name: uint ROL(uint x, uint bits) { return x<>(32-bits); } int calc_hash(char *proc_name) { int hash = 0; for(int i=0; i