Blog de Zscaler
Reciba en su bandeja de entrada las últimas actualizaciones del blog de Zscaler
Technical Analysis of GuLoader Obfuscation Techniques
Introduction
GuLoader (also known as CloudEye) is a highly obfuscated malware family that was first observed in December 2019. It serves primarily as a downloader for Remote Access Trojans (RATs) and information stealers, which are delivered to compromised systems. The threat actors that distribute GuLoader often host malware on legitimate platforms including Google Drive and OneDrive to evade reputation-based detection.
In this blog post, Zscaler ThreatLabz explores the anti-analysis techniques that GuLoader employs including polymorphic code to dynamically construct constant and string values, as well as complex exception-based control flow obfuscation.
Key Takeaways
- GuLoader is a highly obfuscated malware downloader that originated at the end of 2019.
- The malware primarily acts as a delivery mechanism for secondary payloads like information stealers, RATs, and other malicious software.
- GuLoader employs polymorphic code and exception-based control flow obfuscation to conceal its functionality and evade detection.
- Over time, GuLoader has introduced increasingly complex exception-handling mechanisms to complicate analysis.
- GuLoader attempts to bypass reputation-based rules by hosting payloads on trusted cloud services such as Google Drive and OneDrive.
Technical Analysis
This section covers the obfuscation techniques that GuLoader leverages to hinder analysis and evade detection.
Dynamic constant construction
GuLoader employs polymorphic code to dynamically construct constants during execution. Instead of embedding these values statically, GuLoader uses a combination of assembly operations such as mov, xor, add, and sub to build the constants as needed, as shown in the figure below.

Figure 1: Shows an example of the operations that GuLoader uses to dynamically construct constant values during execution.
The main purpose of obfuscating these constant values is to increase the difficulty of interpreting the underlying code. The polymorphic operations also impede static-based signatures that can be used for detection.
Exception-based code redirection
GuLoader utilizes a control flow obfuscation technique that replaces standard code jump (jmp) instructions with deliberate CPU exceptions.
- Exception handling: GuLoader sets up a custom exception handler designed to intercept and process designated exceptions.
- Intentional exception: Rather than using a standard jump instruction, GuLoader executes carefully crafted instructions intended to deliberately trigger specific exceptions.
- Code redirection: Upon activation, the exception handler calculates the correct destination address and modifies the instruction pointer to continue execution at the intended location.
This technique makes the malware's execution flow extremely difficult for automated analysis tools to trace. The table below outlines the exception types that GuLoader actively handles across different versions.
Exception Code | Exception Type | 2022 | 2023 | 2024-2025 |
|---|---|---|---|---|
0x80000003 | STATUS_BREAKPOINT | X | X | X |
0x80000004 | STATUS_SINGLE_STEP | X | X | |
0xC0000005 | STATUS_ACCESS_VIOLATION | X | X | |
0xC000001D | STATUS_ILLEGAL_INSTRUCTION | X | ||
0xC0000096 | STATUS_PRIVILEGED_INSTRUCTION | X |
Table 1: Exception types handled by GuLoader across different versions.
Software breakpoint exceptions
Early versions of GuLoader implemented a simplified approach to exception-based control flow obfuscation. The malware would trigger a software breakpoint interrupt by executing an int 3 instruction, as shown in the figure below.

Figure 2: Demonstrates version 2022 of GuLoader’s use of an int 3 instruction to trigger a software interrupt.
GuLoader’s custom exception handler would then take control after the int 3 command was triggered. The handler analyzed the byte of data located immediately after the interrupt instruction, performed a simple calculation (an XOR operation, where the XOR key remains the same across all operations), and derived the actual destination address for the jump. Once calculated, the handler redirected the program’s execution, resuming it at the intended location, as shown in the figure below.

Figure 3: Example of GuLoader’s exception handler observed in samples from 2022.
In early initial versions of GuLoader, the exception handler included an additional anti-debugging mechanism that verified the presence of software breakpoints at the address of the jump destination. This extra step added another layer of complexity and made analysis even more complex. However, this feature was removed in later versions of GuLoader. The figure below depicts GuLoader 2022’s mechanism for scanning software breakpoints that check for the value 0xCC (i.e., int 3).

Figure 4: Example of GuLoader manipulating control flow via software breakpoints.
In 2023, GuLoader's exception handler was updated to support two additional exceptions: 0x80000004 (STATUS_SINGLE_STEP) and 0xC0000005 (STATUS_ACCESS_VIOLATION). For these two exceptions, the exception handler follows an approach similar to software breakpoint exceptions. However, in this case, the (encrypted) jump offset is located two bytes past the exception address.

Figure 5: Example of GuLoader’s exception handler observed in samples from 2023.
Single step exceptions
GuLoader purposefully triggers a single step exception (0x80000004) by manipulating the EFLAGS register by using the PUSHF instruction to copy the current EFLAGS onto the stack. GuLoader enables the Trap Flag (TF) by setting bit 8 of the EFLAGS value by adding the EFLAGS value on the stack with 0x100. The result (with the TF flag set) is then written to the EFLAGS register by executing a POPF instruction. When the very next instruction is executed by the CPU, the single step exception will be triggered and processed by GuLoader’s exception handler. The example below shows how GuLoader triggers a single step exception and how the exception handler (shown in the previous figure) redirects the control flow to the next valid instruction.

Figure 6: Example of GuLoader code leveraging single-step exceptions to manipulate control flow.
Access violation exceptions
GuLoader intentionally attempts to access (e.g., write to) a memory address below 0x10000, triggering an access violation. The custom exception handler intercepts this error and redirects the instruction pointer to the intended destination, as shown in the figure below.

Figure 7: Example of GuLoader code leveraging access violation exceptions to manipulate control flow.
In 2024, GuLoader introduced support for two new additional exceptions: 0xC000001D (STATUS_ILLEGAL_INSTRUCTION) and 0xC0000096 (STATUS_PRIVILEGED_INSTRUCTION). These changes both led to a more intricate method for calculating the jump address. Since the instructions that trigger these exceptions can vary in length, placing the jump offset directly after the instruction is unreliable. To solve this, GuLoader's developers implemented a fixed, hardcoded offset within the exception handler. This offset consistently locates the encrypted jump address, regardless of the preceding instruction’s size. Rather than relying on a single obfuscated byte, the updated handler now includes a hardcoded offset that points to a secondary byte. This secondary byte contains the encrypted offset to the address of the jump target. To decrypt the encrypted offset, the handler uses a dynamically generated XOR key that ultimately reveals the final jump destination. This multi-step approach significantly increases the complexity of the technique, making the jumps even harder to trace. For example, in the figure below, the hardcoded offset is 0x23, and the XOR key used to decrypt this offset is 0x85. This dynamically generated XOR key is created within the same subfunction of the exception handler that also verifies hardware breakpoints, as shown in the figure below.

Figure 8: Example of GuLoader 2024 leveraging the five different exception types progressively added across versions to manipulate control flow.
Dynamic hashing
Similar to many malware families, GuLoader uses the DJB2 hashing algorithm to identify API functions, modules, and process names. The GuLoader versions released after 2022 combine the DJB2 hash value with a bitwise XOR operation and a hardcoded 32-bit value (DWORD). The result is then compared against a pre-calculated list of expected hash values. This post-hash step is also common in malware families to prevent static values that can be used to create static detections.
Encrypted strings
GuLoader hides its command-and-control (C2) domains, file paths, and other critical information by encrypting strings with a simple XOR algorithm. Although the encryption mechanism itself is basic, the real challenge complexity lies in GuLoader’s polymorphic code, which makes the strings difficult to locate and decrypt.
Static encrypted strings
In version 2022, GuLoader stored encrypted strings statically within shellcode, along with the corresponding string decryption key, as shown in the figure below.

Figure 9: Version 2022 of GuLoader’s string decryption.
GuLoader used a clever technique to handle encrypted strings. A CALL instruction was placed immediately before the string’s XOR key to push the key's memory address onto the stack. The XOR key size is then dynamically calculated and written to the stack. In the example above, the size value is calculated using the formula ((0x34BB49B7 - 0x6774883) ^ 0x34EC7B91) - 0x1AA87A69 = 0x3C. Similarly, another CALL instruction was used to push the memory address of the encrypted string onto the stack, as shown in the figure below.

Figure 10: Shows version 2022 of GuLoader’s string decryption process.
Additionally, a value is dynamically calculated and pushed onto the stack after the address of the encrypted string, indicating whether the string is ASCII (value 0) or wide (value 1). In the example above, the value is 0 to denote that the string is ASCII. Finally, the malware invoked the decryption function simple_xor_bufs (found inside the function decrypt_str), which retrieved both the encrypted string address and decryption key address from the stack to perform the XOR operation to obtain the final string.
The first four bytes (DWORD) of each encrypted string encoded the string’s length. The size is decrypted using a separate 4-byte XOR key.
ThreatLabz developed IDA scripts, available in the ThreatLabz GitHub repository, to decrypt the static encrypted strings found in GuLoader samples from 2022.
Stack-based string encryption
Starting in 2023, GuLoader updated their string encryption algorithms to use more convoluted polymorphic code that dynamically constructs the decrypted string with a combination of mov, xor, add, and sub operations on hardcoded constants, as shown in the figure below.

Figure 11: Example of a GuLoader function utilizing polymorphic code to dynamically decrypt a string on the stack.
Once the individual components of the encrypted string and the encryption key are constructed, GuLoader uses simple XOR operations to decrypt the string. This modification to the string algorithm was further designed to complicate analysis and detection efforts, making emulation one of the best approaches to obtain the decrypted string.
Payload decryption
One of GuLoader's encrypted strings is binary data, often exceeding 0x300 bytes in length. This binary buffer functions as an XOR key, which is used to decrypt a malware payload that is downloaded from a hardcoded URL. The payload’s URL, which is itself an encrypted string, often points to a shared file hosted on legitimate cloud services like Google Drive or OneDrive.
IDA scripts
To effectively deobfuscate GuLoader's constants, strings, and control flow, ThreatLabz created IDA scripts that are available in the ThreatLabz GitHub repository. These scripts dynamically calculate constants and string values, as well as remove the exception-based control flow obfuscation to streamline code analysis.
Conclusion
GuLoader is a malware downloader that has been active since at least December 2019. The malware has continuously been updated since its inception to include a variety of anti-analysis techniques with methods to mask constants and string values in addition to exception-based control flow obfuscation. Given the consistent development over time, GuLoader is likely to remain a significant threat for the foreseeable future.
Zscaler Coverage
Zscaler’s multilayered cloud security platform detects indicators related to GuLoader at various levels. The figure below depicts the Zscaler Cloud Sandbox, showing detection details for GuLoader.

Figure 12: Zscaler Cloud Sandbox report for GuLoader.
In addition to sandbox detections, Zscaler’s multilayered cloud security platform detects indicators related to GuLoader at various levels with the following threat names:
Indicators Of Compromise (IOCs)
Hash | Version |
|---|---|
90de01c5ff417f23d7327aed517ff7f285e02dfe5dad475d7f13aced410f1b95 | 2022 |
274329db2d871d43eed704af632101c6939227d36f4a04229e14603f72be9303 | 2022 |
4be24d314fc9b2c9f8dbae1c185e2214db0522dcc480ba140657b635745e997b | 2023 |
0bcc5819a83a3ad0257a4fe232e7727d2f3d04e6f74c6d0b9e4dfe387af58067 | 2023 |
7fccb9545a51bb6d40e9c78bf9bc51dc2d2a78a27b81bf1c077eaf405cbba6e9 | 2024 |
53bad49e755725c8d041dfaa326e705a221cd9ac3ec99292e441decd719b501d | 2024 |
¿Este post ha sido útil?
Descargo de responsabilidad: Esta entrada de blog ha sido creada por Zscaler con fines únicamente informativos y se proporciona "tal cual" sin ninguna garantía de exactitud, integridad o fiabilidad. Zscaler no asume ninguna responsabilidad por cualquier error u omisión o por cualquier acción tomada en base a la información proporcionada. Cualquier sitio web de terceros o recursos vinculados en esta entrada del blog se proporcionan solo por conveniencia, y Zscaler no es responsable de su contenido o prácticas. Todo el contenido está sujeto a cambios sin previo aviso. Al acceder a este blog, usted acepta estos términos y reconoce su exclusiva responsabilidad de verificar y utilizar la información según convenga a sus necesidades.
Reciba en su bandeja de entrada las últimas actualizaciones del blog de Zscaler
Al enviar el formulario, acepta nuestra política de privacidad.


