Please read the disclaimer

In this quick blog post, we take a look specifically at the Anti reverse engineer techniques used by a recent GuLoader sample. This blog post can be used a reference for other researchers to understand the techniques used by GuLoader.

Code obfuscation through jumps

We can see the malware obfuscate the assembly code by using unconditional jumps to mess up the disassembly.

alt text

Opaque predicate in conditional jumps

In other word, it will always evaluate to either a false or a true statement, this is used to fool the disassembler that there is 2 paths but in reality it is just one single path.

alt text

Obfuscation of functions parameters through arithmetic calculation

In this example we see the parameter of get_func_address is xored multiple time.

alt text

Dynamic retrieval of WinAPI function addresses

It first parse the PEB_LDR_DATA of PEB structure of the process, locates kernel32, then looks for LoadLibraryA function. Then the malware parse the library, hash function names with DJB2 hashing algorithm and compare with the hash given as parameter to the function.

alt text

Xoring dexoring the .text instructions to break the disassembly view

Before calling a WINAPI, the malware xors the whole shellcode, then dexor it after calling the WINAPI function. The purpose of this technique is to break the dissasembly view (functions recognized by the disassembler, the graph view etc…)

Check for hardware and software breakpoints

The malware uses ZwGetThreadContext WINAPI to check if hardware breakpoints are set by checking DR0-7 registers.

It also check for software breakpoints before calling a WINAPI function by comparing it’s first bytes to 0xCC 0X3CD 0xB0F, if breakpoints are set the malware will crash itself.

alt text

Detect virtual machine through CPUID

Calling CPUID with eax set to 1 can be used to detect if the malicious code is running inside a virtual machine, a quick fix for this is to change the .vmx config file for vmware to always return 0 in the 31st bit. Example: cpuid.1.ecx="0---:----:----:----:----:----:----:----" to be added to the .vmx

alt text

Check if it is running in a 64bit machine

The shellcode checks if the machine is a 64 bit machine, if yes it will switch to 64bit mode.

alt text

Patching DbgBreakPoint && DbgUIRemoteBreakin

The malware patchs both DbgBreakPoint DbgUIRemoteBreakin to prevent debuggers from attaching to the process.

Count the number of application windows using EnumWindows

EnumWindows WINAPI is used to enumerate and count the open windows, this technique is used to detect sandboxes.

alt text

Check for QEMU

Guloader tries to open the following two files C:\Program Files\Qemu-ga\qemu-ga.exe C:\Program Files\qga\qga.exe, this files are related to Qemu emulator. It is used as sandbox detection

anti debugging NtSetInformationThread

NtSetInformationThread API with ThreadHideFromDebugger as parameter is used to hide the thread from a debugger, if a debugger is already present it will result in a crash.

alt text

Enumerate windows devices

The malware uses EnumDeviceDrivers and GetDeviceDriverBaseName to enumerate windows drivers, their names are hashed and compared to pre-hashed values.

alt text

Enumerate installed softwares

It uses MsiEnumProductsA MsiGetProductInfoA WINAPI to enumerate installed softwares, the names are hashed then compared to pre-hashed values.

alt text

Enumerate Services

The malware uses OpenSCManagerA and EnumServicesStatusA winAPI to enumerate services on the machine, the names are hashed then compared to pre-hashed values.

alt text

Retrieve the port number of the debugger for the process using the NtQueryInformationProcess

Guloader retrieve the port number of the debugger for the process using NtQueryInformationProcess API.

alt text

Injecting shellcode through process hollowing

The malware uses process hollowing injection technique to inject a similar shellcode with different capabilities, the following outlines the execution flow of the malware:

  • It create a suspended process RegAsm.exe or MSBuild.exe with CreateProcessInternalW API.

alt text

  • It opens a handle to C:\Windows\syswow64\msvbvm60.dll with ZwOpenFile WINAPI.

alt text

  • It creates a new section with ZwCreateSection WINAPI.
  • It maps the section in the created process using NtMapViewOfSection WINAPI.
  • It writes the shellcode to the memory with NtWriteVirtualMemory WINAPI.
  • It change the Instruction pointer of the process to the start of the injected shellcode with NtSetContextThread WINAPI.
  • Finally, it resume the thead with NtResumeThread WINAPI.

After bypassing all the anti reverse engineering mechanism, we can dump the second shellcode just before it calls for NtWriteVirtualMemory, another solution is to change the first bytes of the new shellcode to jmp 0x00, then we can attach to it with a debugger and restore the original bytes.

The second shellcode is a copy of the first shellcode so all the anti reverse engineering mechanism enumerated above applies to it. The second shellcode downloads a payload from a google drive link and execute it.

Some hashes for reference:

  • getcontextthread FAD4F3C4
  • queryvirtualmemory 0F9CE5538
  • kernel32 48522397
  • LoadLibraryA 645AAB39
  • NtAllocateVirtualMemory 4E829A87
  • MSVBVM60 82AAF280
  • ZwProtectVirtualMemory 85E648F6
  • DbgBreakPoint 676E43AA
  • DbgUiRemoteBreakin 0A3B0C16C
  • TerminateProcess 9E059483
  • EnumWindows BB301E26
  • ExitProcess 98EC4D6B
  • CreateFileA 97F9AE3
  • NtSetInformationThread 0E9BE1A6F
  • EnumDeviceDrivers 96ABEF9C
  • vmmouse.sys 0D46C4133
  • vm3dmp_loader.sys DC8850D2
  • vm3dmp.sys 2B5C7A6B
  • vmusbmouse.sys 5440D1F6
  • MsiEnumProductsA 0E3F98748
  • MsiGetProductInfoA 568AB98E
  • ShellExecuteW 2A433AAE