MalwareAnalysisReports/XWormShellcode/Packer Shellcode Delivering XWorm.md at main ยท VenzoV/MalwareAnalysisReports By VenzoV Archived: 2026-04-06 01:17:11 UTC Sample Information Parent Hash: SHA256 51109A3D4CFEE3DAB4465677957F991C0E5EAC17637BB6C989373118F81948A3 Shellcode: SHA256 2FA571755AE79D22878273A487A326A4FA87FD77CF88AC98D4AE740FE38A1250 Final payload SHA256 B1F73B1AC29A3FE85E8AF634DF42BE1EF7E293624EAF9F3267B6AC0BED8091CB Sample is shellcode used by XWorm binary to load final stage payload. It originates from and AutoIT script which essentially is used to just run this intermediate stage. Analysis Resolving API Since we are dealing with shellcode, there isn't much information to go on. No exports no imports, so also looking at the code statically doesn't yield much information. The first step will be to understand which API the shellcode will use and how are they resolved. From the main entry point of the code we can reach the function responsible. The API are resolved by fetching necessary DLLs from the PEB and looping through export list to find the ones needed. Keep in mind that the API are hashed, so they will first go through a resolving function. https://github.com/VenzoV/MalwareAnalysisReports/blob/main/XWormShellcode/Packer%20Shellcode%20Delivering%20XWorm.md Page 1 of 10 Walks the PEB modules until it reaches the target DLL it needs Returns a pointer to the base address of the DLL needed Loops 37 times, calling another function which is used to get the address of the API based on hash. The hashes are resolvable by plugins such as HashDB, telling us they are crc32 values. So once it gets the address of the API from the DLL it is saved into an array. In total it resolved functions from 5 DLLS (NTDLL is actually used later) https://github.com/VenzoV/MalwareAnalysisReports/blob/main/XWormShellcode/Packer%20Shellcode%20Delivering%20XWorm.md Page 2 of 10 Helper Strucuture Considering the API are saved an array, we will build a structure to hold the correct values. This will reflect on other code blocks and make our life easier. The API index needs to be taken into account and struct needs to be built accordingly. We will order them based on the index inside the square brackets. Structure: https://github.com/VenzoV/MalwareAnalysisReports/blob/main/XWormShellcode/Packer%20Shellcode%20Delivering%20XWorm.md Page 3 of 10 struct _FUNC_TABLE { void* CreateProcessW; void* GetCursorPos; void* Sleep; void* GetTickCount; void* GetThreadContext; void* SetThreadContext; void* VirtualAlloc; void* PathCombineW; void* GetTempPathW; void* lstrcpyW; void* lstrcatW; void* CreateDirectoryW; void* WriteFile; void* SHGetFolderPathW; void* HeapAlloc; void* CommandLineToArgvW; void* GetProcessHeap; void* ExitThread; void* HeapFree; void* GetFileAttributesW; void* GetFileSizeEx; void* QueryPerformanceCounter; void* IsDebuggerPresent; void* GetCurrentThread; void* CreateThread; void* WaitForSingleObject; void* TerminateProcess; void* ExitProcess; void* ReadProcessMemory; void* GetModuleFileNameW; void* GetCommandLineW; void* GetProcAddress; void* CloseHandle; void* IsWow64Process; void* CreateFileW; void* ReadFile; void* GetFileSize; void* VirtualFree; void* LoadLibraryA; void* LoadLibraryW; void* CryptAcquireContextW; void* CryptGenRandom; void* CryptReleaseContext; https://github.com/VenzoV/MalwareAnalysisReports/blob/main/XWormShellcode/Packer%20Shellcode%20Delivering%20XWorm.md Page 4 of 10 void* GetModuleHandleW; }; Entry point This code block is the start of the shellcode. It initially runs the function described above to have a table of addresses that it will use to call the API. If the structure we made is applied correctly, this will clean the code and it is easy to see what is going on. Before: After: https://github.com/VenzoV/MalwareAnalysisReports/blob/main/XWormShellcode/Packer%20Shellcode%20Delivering%20XWorm.md Page 5 of 10 This part of the code will essentially do the following: Sets key in var L12L3V8NVXKURK7Y9XADR58 Opens the file in the TMP path, disimmure. Allocate memory based on size of contents Copy the contents of the file to memory section Pass the memory section, size, key and modulus operand to decryption function. The decryption routine is nothing special and is just basically a simple XOR (see Functions below) https://github.com/VenzoV/MalwareAnalysisReports/blob/main/XWormShellcode/Packer%20Shellcode%20Delivering%20XWorm.md Page 6 of 10 The result is that there is now a decryption payload in memory. Injection The final phase is to inject the payload. It chooses between three possible processes: C:\Windows\System32\svchost.exe C:\Windows\Microsoft.NET\Framework\v2.0.50727\RegSvcs.exe C:\Windows\Microsoft.NET\Framework\v4.0.30319\RegSvcs.exe Once a target has been picked, it will proceed to create the process and manipulate the memory to inject the malicious payload. This injection is done using syscalls. The API involved in injecting and running the payload are: NtCreateSection NtMapViewOfSection https://github.com/VenzoV/MalwareAnalysisReports/blob/main/XWormShellcode/Packer%20Shellcode%20Delivering%20XWorm.md Page 7 of 10 NtWriteVirtualMemory NtResumeThread Syscalls hook check The malware also checks for hooks on the Nt functions. It checks for jmp operands and skips them if found. 0xe9 & 0xea are the JMP & JMP FAR opcodes. Once checked it will enter the syscall: https://github.com/VenzoV/MalwareAnalysisReports/blob/main/XWormShellcode/Packer%20Shellcode%20Delivering%20XWorm.md Page 8 of 10 Functions mw_w_PEBWalking() mw_ResolveHashExports https://github.com/VenzoV/MalwareAnalysisReports/blob/main/XWormShellcode/Packer%20Shellcode%20Delivering%20XWorm.md Page 9 of 10 mw_XorDecrypt Source: https://github.com/VenzoV/MalwareAnalysisReports/blob/main/XWormShellcode/Packer%20Shellcode%20Delivering%20XWorm.m d https://github.com/VenzoV/MalwareAnalysisReports/blob/main/XWormShellcode/Packer%20Shellcode%20Delivering%20XWorm.md Page 10 of 10