{
	"id": "53853046-fbfc-4f8b-8707-a0b0ed08a525",
	"created_at": "2026-04-06T00:09:17.82893Z",
	"updated_at": "2026-04-10T03:21:52.019316Z",
	"deleted_at": null,
	"sha1_hash": "d4f5018549bad1e03d18b4e22332b6c255ffe386",
	"title": "GuLoader: Peering Into a Shellcode-based Downloader | CrowdStrike",
	"llm_title": "",
	"authors": "",
	"file_creation_date": "0001-01-01T00:00:00Z",
	"file_modification_date": "0001-01-01T00:00:00Z",
	"file_size": 1245219,
	"plain_text": "GuLoader: Peering Into a Shellcode-based Downloader |\r\nCrowdStrike\r\nBy Umesh Wanve\r\nArchived: 2026-04-05 20:25:00 UTC\r\nGuLoader, a malware family that emerged in the wild late last year, is written in Visual Basic 6 (VB6), which is\r\njust a wrapper for a core payload that is implemented as a shellcode. It is distributed via spam email campaigns\r\nwith archived attachments that contain the malware. The majority of malware downloaded by GuLoader is\r\ncommodity malware, with AgentTesla, FormBook and NanoCore being the most predominant.\r\nThis downloader typically stores its encrypted payloads on Google Drive. CrowdStrike has observed that\r\nGuLoader downloads its payloads from Microsoft OneDrive and also from compromised or attacker-controlled\r\nwebsites. By utilizing legitimate file-sharing websites, GuLoader can evade network-based detection, as these\r\nservices are not generally filtered or inspected in corporate environments. In addition, the downloaded payloads\r\nare encrypted with a hard-coded XOR key embedded in the malware, making it difficult for file-sharing service\r\nproviders to identify the payload as malicious. GuLoader is an advanced downloader that uses shellcode wrapped\r\nin a VB6 executable that changes in each campaign to evade antivirus (AV) detections. The shellcode itself is\r\nencrypted and later heavily obfuscated, making static analysis difficult. In this blog, we cover GuLoader’s internal\r\ndetails, including its main shellcode, anti-analysis techniques and final payload delivery mechanism.\r\nAnalysis\r\nGuLoader is often distributed through spam campaigns that contain the malware embedded in archived\r\nattachments. An example of GuLoader spam email is shown in Figure 1.\r\nhttps://www.crowdstrike.com/blog/guloader-malware-analysis/\r\nPage 1 of 15\n\nFigure 1: Sample spam email with RAR attachment (click image to enlarge)\r\nThe attachment contains a malicious executable file named transfer request form.exe . The sample is a PE32\r\nfile written in Microsoft Visual Basic (just a wrapper for a shellcode that implements the main functionality), as\r\nshown in Figure 2. Strings present inside the sample don’t reveal much as the binary is packed. The sample\r\ncontains numerous calls to meaningless VB functions that can slow down the analysis. By stepping through the\r\nassembly code, we will land into some block of code that is eventually used to decrypt the main shellcode, as\r\nshown in Figure 2.\r\nhttps://www.crowdstrike.com/blog/guloader-malware-analysis/\r\nPage 2 of 15\n\nFigure 2: Block of code used to decrypt main shellcode (click image to enlarge)\r\nThe snippet above contains junk code inserted within legitimate instructions to thwart analysis. After analyzing\r\nand understanding this code further, we see that this code is responsible for decrypting the main shellcode in\r\nmemory. It uses a 4-byte XOR key to decrypt the packed code to extract the final shellcode. The sample takes the\r\nfirst 4 bytes of encrypted data, XORs it with the ESI register and compares it with the value 0x200EC81 , as\r\nshown in Figure 3.\r\nhttps://www.crowdstrike.com/blog/guloader-malware-analysis/\r\nPage 3 of 15\n\nFigure 3: XOR key operation routine (click to enlarge image)\r\nIf it does not match, it keeps incrementing ESI and performs an XOR operation until the result matches the\r\nexpected value. The value 0x200EC81 , read as little-endian, translates into the instruction sub esp, 0x200 ,\r\nwhich is the actual start of the final shellcode.\r\n(First 4 bytes of encrypted data in little endian\r\nXOR 0x200EC81) = XOR Key which for this sample becomes: (0x4DB824FD XOR 0x200EC81) = 0x4FB8C87C After\r\nthis, the decryption routine will call VirtualAlloc() to allocate memory and start decrypting the final shellcode\r\ninto the newly allocated memory by XORing encrypted data with key 0x4FB8C87C , as shown in Figure 4.\r\nhttps://www.crowdstrike.com/blog/guloader-malware-analysis/\r\nPage 4 of 15\n\nFigure 4: Decrypted data in memory (click image to enlarge)\r\nOnce the shellcode is decrypted, the code will jump into that new shellcode for further execution. Since the\r\ndecryption routine has decrypted our shellcode, a memory dump of that newly allocated region gives us lots of\r\ninteresting strings, including API names and the final encrypted payload hosted on Google Drive, as shown below.\r\nASCII Strings\r\n00001A7F\r\nhxxps\u003c:\u003e//drive.google.com/uc?export=download\u0026id=1THD-itP7iOm05w_6SQSb-C3tgd3cLMzO 00001ADE\r\nMozilla/5.0 (Windows NT 6.1; WOW64; Trident/7.0; rv:11.0) like Gecko 0001B28 wininet.dll 00001B3B\r\nInternetOpenA 00001B4E InternetSetOptionA 00001B68 InternetOpenUrlA 00001B7E InternetReadFile 00001B94\r\nInternetCloseHandle 00001BCB ntdll 00001BD6 NtCreateSection 00001BEB NtMapViewOfSection 00001C03\r\nNtClose 00001C10 NtGetContextThread 00001C29 NtSetContextThread 00001C43 NtProtectVirtualMemory\r\n00001C5F NtAllocateVirtualMemory 00001C7C NtWriteVirtualMemory 00001C98 NtOpenFile 00001CA9\r\nNtResumeThread 00001CBD DbgBreakPoint 00001CD0 DbgUiRemoteBreakin 00001CE8 NtSetInformationThread\r\n00001D05 kernel32 00001D13 WaitForSingleObject 00001D2D LoadLibraryA 00001D40 CreateProcessInternalW\r\n00001D5C GetLongPathNameW 00001D73 TerminateProcess 00001D8A CreateThread 00001D9C\r\nAddVectoredExceptionHandler 00001DBD TerminateThread 00001DD2 CreateFileW 00001DE5 WriteFile 00001DF5\r\nhttps://www.crowdstrike.com/blog/guloader-malware-analysis/\r\nPage 5 of 15\n\nGetFileSize 00001E07 ReadFile 00001E15 CloseHandle 00001E26 Sleep 00001E31 advapi32 00001E3F\r\nRegCreateKeyExA 00001E54 RegSetValueExA 00001E68 user32 00001E74 EnumWindows 0000210F Startup key\r\n00002120 Software\\Microsoft\\Windows\\CurrentVersion\\RunOnce 000021A0 shell32 000021AD\r\nSHCreateDirectoryExW 000021C8 ShellExecuteW\r\nAnalyzing Shellcode\r\nFigure 5:\r\nEntry point of the main shellcode (click image to enlarge)\r\nThis entire shellcode is heavily obfuscated, contains lots of junk code and also contains anti-analysis and anti-debugging tricks to make shellcode analysis more difficult. The shellcode starts with a few lines that prepare the\r\nstack and registers for use within the function before an interesting call 362BA9 instruction, as shown in Figure\r\n6.\r\nFigure 6: Heaven’s Gate technique (click to enlarge image)\r\nThe code in Figure 6 applies the Heaven's Gate technique, the technique for executing code from x86 to x64 with\r\nthe far JMP command. The code checks the FS:\u003c0xC0\u003e register value to see whether the system is x64 or not. If\r\nit is x64, the shellcode uses the Heaven's Gate call technique.\r\nAccessing Kernel Imports via PEB\r\nWhen a malware injects a payload into memory, it needs to determine which API calls to use; this is done by using\r\nthe Process Environment Block (PEB), which is always located at offset 0x30 within the Threat Information\r\nBlock (TIB), which in turn is referenced by the segment register FS:\u003c0x00\u003e . For example, a common method is\r\nhttps://www.crowdstrike.com/blog/guloader-malware-analysis/\r\nPage 6 of 15\n\nto find the kernel32.dll address from the loaded modules and enumerate the export table of kernel32.dll to\r\nfind GetProcAddress() and start loading the API addresses required for its operation. Figure 7 shows the code\r\nthat does this after the Heaven’s Gate function call.\r\nFigure 7: Accessing kernel imports via PEB (click image to enlarge)\r\nDJB2 Hashes for Windows API Resolution\r\nWhen GuLoader needs to call a Windows API function, it must first resolve the function’s address, as it does not\r\nhave an Import Address Table (IAT). The code shown in Figure 7 iterates through export functions of\r\nkernel32.dll one by one, calculates the DJB2 hashes for each export API and compares those with the\r\nhardcoded hash value CF31BB1F (DJB2 hash of GetProcAddress API).\r\nPython Snippet for DJB2 Hash Calculation\r\n1. val = 0x1505\r\n2. inString = \"GetProcAddress\"\r\n3. for ch in inString:\r\n4. val += (val \u003c\u003c 5)\r\n5. val \u0026= 0xFFFFFFFF\r\n6. val += ord(ch)\r\n7. val \u0026= 0xFFFFFFFF\r\n8. print(hex(val).upper().lstrip(\"0X\").rstrip(\"L\"))\r\nOnce the shellcode matches the hash for the string name GetProcAddress , it will calculate its API address from\r\nkernel32.dll . Then it will start resolving the required APIs shown in the appendix at the end of this blog.\r\nhttps://www.crowdstrike.com/blog/guloader-malware-analysis/\r\nPage 7 of 15\n\nAnti-Sandbox/Anti-Emulation\r\nGuLoader also checks the number of application windows to detect an analysis environment. This check uses the\r\nfunction EnumWindows to enumerate and count all top-level windows on the screen. If the number of windows is\r\nless than 12, the malware calls TerminateProcess with its own process handle as the parameter to terminate.\r\nThis might have been done to evade sandboxes or emulator environments.\r\nAnti-Attach: Patching DbgBreakPoint and DbgUIRemoteBreakin\r\nThe Windows API functions DbgBreakPoint and DbgUiRemoteBreakin are called when a debugger attaches to a\r\nrunning process. The shellcode patches these two APIs by replacing the INT3 opcode of DbgBreakPoint with\r\nopcode 90 (NOP, or “no-operation,”\r\nto do nothing), and replacing the first few bytes of DbgUIRemoteBreakin with a dummy call (to cause a crash).\r\nThis is done to prevent a debugger from attaching to the process, as shown in Figure 8.\r\nFigure 8: Patching DbgBreakPoint and DbgUIRemoteBreakin (click image to enlarge)\r\nUnhooking API Hooks\r\nThe shellcode performs some pattern matching in the NTDLL API’s code functions — for example, searching for\r\nthe byte pattern “\\xb8\\x00.{3}\\xb9,” which represents NTDLL calls to system calls. Many security products like\r\nAV, endpoint detection and response (EDR) and sandbox software put their hooks here, so they can detour the\r\nexecution flow into their engines to monitor and intercept API calls and block anything suspicious. Basic user-mode API hooks by AV/EDR are often created by modifying the first 5 bytes of the API call with a jump ( JMP )\r\ninstruction to another memory address pointing to the security software. Considering this hooking mechanism, the\r\nshellcode scans for all such system calls and then restores its first 5 bytes to the original bytes in NTDLL , as\r\nshown in Figure 9.\r\nhttps://www.crowdstrike.com/blog/guloader-malware-analysis/\r\nPage 8 of 15\n\nFigure 9: Unhooking API hooks code (click image to enlarge)\r\nAs a result, GuLoader bypasses any hooks installed by anti-malware software. Lastly, it resets the NTDLL ’s\r\nmemory permissions back to PAGE_EXECUTE_READ only.\r\nAnti-debug (NtSetInformationThread)\r\nNext, the shellcode calls the NtSetInformationThread function with ThreadHideFromDebugger ( 0x11 ) as the\r\nsecond parameter for hiding the thread from a debugger, as shown in Figure 10.\r\nFigure 10: NtSetInformation thread function with ThreadHideFromDebugger parameter (click image to enlarge)\r\nThis causes a crash in the debugged application when a breakpoint is hit in the hidden thread or when the\r\ndebugger steps through the instructions.\r\nAnti-Analysis/Debug Techniques\r\nThe shellcode uses several anti-debugging techniques. The shellcode detects if hardware breakpoints or software\r\nbreakpoints have been set, each time it calls several key API functions, as shown in Figure 11.\r\nhttps://www.crowdstrike.com/blog/guloader-malware-analysis/\r\nPage 9 of 15\n\nFigure 11: Software and hardware breakpoint checks (click image to enlarge)\r\nDuring their malware analysis, analysts often use hardware or software breakpoints at the beginning of suspicious\r\nAPI calls — for example, by patching the first byte of CreateProcessInternalW with 0xCC .\r\nBy calling the NtGetContextThread function, debug registers ( DR0 through DR7 ) can be used to detect\r\nhardware breakpoints, while 0xCC , 0X3CD and 0xB0F opcodes are used to detect software breakpoints (if\r\npresent) at the beginning of the API calls.\r\nProcess Hollowing Injection\r\nProcess hollowing is a code injection technique used by malware in which the executable code of a legitimate\r\nprocess in memory is replaced with malicious code. By executing within the context of legitimate processes, the\r\nmalware can bypass security solutions. The shellcode similarly uses process hollowing techniques in order to\r\ninject its code into the legitimate process (here RegAsm.exe or MSBuild.exe or RegSvcs.exe ) with a slight\r\nvariation. Here, shellcode doesn’t unmap memory code of legitimate processes; instead it uses the\r\nNtCreateSection API section object to inject its malicious code. The process is as follows: 1) Calls\r\nkernel32.CreateProcessInternalW to create the Windows legitimate process\r\n\"C:\\Windows\\Microsoft.NET\\Framework\\v2.0.50727\\RegAsm.exe\" with CREATE_SUSPENDED(0x00000004) flags.\r\nIf it doesn’t find RegAsm.exe , it will try to find MSBuild.exe or RegSvcs.exe in the same directory path and\r\nloop until it finds one of them. 2) Opens a file handle to the hard-coded file path\r\n\"C:\\Windows\\syswow64\\mstsc.exe\" using ZwOpenFile\r\n3) Calls ntdll.NtCreateSection on the file handle for mstsc.exe . The ZwCreateSection function creates a\r\nsection object that represents a section of memory that can be shared. This file handle is used to create a new\r\nsection object with the DesiredAccess parameter. 4) The section is then mapped in the targeted process\r\n( RegAsm.exe ) using the function ntdll.NtMapViewOfSection with the BaseAddress parameter set to\r\n0x400000 . This maps the section in the base address 0x400000 , which is typically the address used to map the\r\nexecutable file image of the process.\r\nhttps://www.crowdstrike.com/blog/guloader-malware-analysis/\r\nPage 10 of 15\n\n5) Calls ntdll.NtWriteVirtualMemory in order to write the shellcode in the newly allocated memory of the\r\ntargeted process. 6) Calls ntdll.NtGetContextThread to obtain information about the main thread within the\r\nsuspended subprocess. 7) After the shellcode has been written to the memory of the targeted process, the\r\nexecution needs to be redirected to it. To achieve this, GuLoader makes use of the function\r\nntdll.NtSetContextThread to change the context of the only thread running in the targeted process (still in a\r\nsuspended state). This context change sets the EIP register to the address that points to the beginning of the\r\nshellcode, which makes the execution start there. 8) Calls ntdll.NtResumeThread to resume the new thread in\r\nRegAsm.exe to execute the malicious shellcode.\r\nFinal Payload\r\nAfter GuLoader has successfully injected into the RegAsm.exe\r\nprocess, its shellcode will download the final payload from the Google Drive link in memory in an encrypted\r\nform, as shown in Figure 12.\r\nFigure 12:\r\nEncrypted final payload downloaded in the memory (click image to enlarge)\r\nhttps://www.crowdstrike.com/blog/guloader-malware-analysis/\r\nPage 11 of 15\n\nThe real encrypted payload is appended after the first 64 bytes of random data. The GuLoader shellcode uses a\r\nhardcoded XOR key with a length of 517 bytes for this sample (as shown in Figure 13) to decrypt the final\r\npayload.\r\nFigure 13:\r\nEmbedded XOR key (null terminated) for decrypting final payload (click image to enlarge)\r\nThe following piece of code from the shellcode decrypts its encrypted payload back into its original one, as shown\r\nin Figure 14.\r\nhttps://www.crowdstrike.com/blog/guloader-malware-analysis/\r\nPage 12 of 15\n\nFigure 14: Decryption routine and decrypted final payload (click image to enlarge)\r\nHow the CrowdStrike Falcon® Platform Protects Against GuLoader\r\nThe CrowdStrike Falcon®® platform has the ability to detect and prevent GuLoader by taking advantage of the\r\nbehavioral patterns indicated by the malware. By turning on suspicious process blocking, Falcon ensures that\r\nGuLoader is killed in the very early stages of execution.\r\nIn addition, the CrowdStrike® machine learning (ML) algorithm provides additional coverage against this\r\nmalware family, as illustrated in Figure 16.\r\nhttps://www.crowdstrike.com/blog/guloader-malware-analysis/\r\nPage 13 of 15\n\nFigure 16: GuLoader process blocked by ML algorithm (click image to enlarge)\r\nConclusion\r\nGuLoader has been very active in 2020 and is frequently used by criminals to distribute their malware like\r\nAgentTesla, FormBook and NanoCore. The use of process hollowing and hosting encrypted payloads on Google\r\nDrive is designed to bypass many security solutions — but it doesn’t bypass CrowdStrike Falcon®.\r\nAppendix: APIs Resolved by GuLoader\r\nLoadLibraryA\r\nTerminateProcess\r\nEnumWindows\r\nZwProtectVirtualMemory\r\nDbgBreakPoint\r\nDbgUIRemoteBreakin\r\nNtGetContextThread\r\nNtSetContextThread\r\nNtWriteVirtualMemory\r\nNtCreateSection\r\nNtMapViewOfSection\r\nNtOpenFile\r\nNtClose\r\nNtResumeThread\r\nCreateProcessInternalW\r\nGetLongPathNameW\r\nSleep\r\nCreateThread\r\nWaitForSingleObject\r\nTerminateThread\r\nAddVectoredExceptionHandler\r\nhttps://www.crowdstrike.com/blog/guloader-malware-analysis/\r\nPage 14 of 15\n\nCreateFileW\r\nWriteFile\r\nCloseHandle\r\nGetFileSize\r\nReadFile\r\nShellExecuteW\r\nSHCreateDirectoryExW\r\nRegCreateKeyExA\r\nRegSetValueExA\r\nIndicators of Compromise (IOCs)\r\nAdditional Resources\r\nLearn more about the CrowdStrike Falcon® platform by visiting the product webpage.\r\nLearn more about CrowdStrike endpoint detection and response by visiting the Falcon Insight™ webpage.\r\nTest CrowdStrike next-gen AV for yourself. Start your free trial of Falcon Prevent™ today.\r\nSource: https://www.crowdstrike.com/blog/guloader-malware-analysis/\r\nhttps://www.crowdstrike.com/blog/guloader-malware-analysis/\r\nPage 15 of 15",
	"extraction_quality": 1,
	"language": "EN",
	"sources": [
		"Malpedia"
	],
	"references": [
		"https://www.crowdstrike.com/blog/guloader-malware-analysis/"
	],
	"report_names": [
		"guloader-malware-analysis"
	],
	"threat_actors": [],
	"ts_created_at": 1775434157,
	"ts_updated_at": 1775791312,
	"ts_creation_date": 0,
	"ts_modification_date": 0,
	"files": {
		"pdf": "https://archive.orkl.eu/d4f5018549bad1e03d18b4e22332b6c255ffe386.pdf",
		"text": "https://archive.orkl.eu/d4f5018549bad1e03d18b4e22332b6c255ffe386.txt",
		"img": "https://archive.orkl.eu/d4f5018549bad1e03d18b4e22332b6c255ffe386.jpg"
	}
}