“Unaligned Function Calls” to Windows API

A malware evasion technique

Sachiel
5 min readMay 4, 2024

Background

This is one of the evasion techniques used by malware. This is believed to be primarily used to evade dynamic analysis by EDRs and sandboxes. This technique was found in malware that appears to be xworm. I conducted research on this technique but could not find similar ones, so I will write notes for cybersecurity engineers to gain knowledge and investigation techniques.

postscript:

After asking many people what the name of this technique is, I learned the name “Unaligned Function Calls”. For this reason, I am correcting the title and some parts of the article.

Abstract

Normally, Windows APIs are called by their function’s entry address. However, the technique discovered was to offset and call the address of the API by adding 5 bytes. Therefore, the caller must execute the skipped 5-byte instruction itself before calling the API. This is believed to be primarily used to evade dynamic analysis by EDRs and sandboxes. In this article, I will explain:

  • Show evidence and explanation
  • Researching similar techniques
  • Consideration about this technique and its countermeasures

Show evidence and explanation

Figure 1 API caller within malware
Figure 2 Called API

Figure 1 shows the code inside the malware. it will call the address of edx by “call edx”. But the EDX value (0x77BCFA95) is strange (red line). It looks like that’s not the correct address for “NtProtectVirtualMemory” API in ntdll.dll. Figure 2 shows the code for this address (red line). If 0x77BCFA95 is called by “call edx” in Figure 1, “mov eax, 50h” (blue line) in Figure 2 will not be executed. It is expected that this API will not work correctly unless eax is set to the correct value (0x50). If we check Figure 1, we can confirm that eax is set 0x50 when calling the API. We can see that EAX is set to 0x50 before “call edx” is executed (blue line). This means that the caller is executing the operation that was not performed due to calling the API with a 5-byte offset. As a result, the API will work correctly even if you call the API address with a 5-byte offset. Figure 3 and Figure 4 are case where LdrLoadDLL is called. The caller executes will be skipped instructions (“push ebp” and “mov ebp, esp”) and then calls offset address.

Figure 3 API caller within malware
Figure 4 Called API

Researching similar techniques

Why would a malware author implement such an unusual API call? I found an interesting research article on a similar technique.

Agent Tesla: Evading EDR by Removing API Hooks

The sections “HOOKING API” and “MALWARE UNHOOKING API HOOKS” are very interesting. This article also happens to be about “NtProtectVirtualMemory”. This means that cybersecurity products are closely monitoring this API and malware authors are wary of detection.

The case in this article shows that some anti-malware security products rewrite the first 5 bytes of the API for API hooks. And it notes that the malware patches the code to return to the original in order to evade that API hook. As a result, anti-malware security products will not be able to monitor this API.

The technique found this time is also expected to serve the same purpose. The only difference is whether it patches or skips the 5 bytes of code in the API.

Consideration about this technique and its countermeasures

I expect the purpose of this technique to be:

  • Skipping API hooks
  • API address-based monitoring fails
  • Makes trace-based analysis difficult

I think skipping API hooks is an evolution of the article “Agent Tesla: Evading EDR by Removing API Hooks”. In the article, the malware uses NtProtectVirtualMemory to modify code, which is also monitored by security products. The technique introduced here allows malware to bypass API hooks without any code changes.

This technique may add two additional values. This technique does not call the API entry address. If a security product is monitoring the API being called, the offset call address will not match the API address. In this case, 0x77BCFA95 is not recognized as an “NtProtectVirtualMemory” address. As a result, it is expected that it will not be possible to detect that “NtProtectVirtualMemory” has been called. The same goes for analysis using traces. The called address will not be hit even if you create the API address map accurately. This will cause an overlook.

Do you think it is enough to know the API address of the address 5 bytes ago? Unfortunately, this is not such a simple problem. Please see Figure 5 as an example. NtProtectVirtualMemory and NtQuerySection are very similar code. The only difference is the value of eax. How would this work if the malware set eax to 0x50 and called the NtQuerySection at address 0x77BCFAA5, a 5-byte offset? NtProtectVirtualMemory will be executed. If the analyzer determines that the API was simply called 5 bytes earlier, it will cause an analysis error. Security engineers need to consider countermeasures that take into account such predictions.

Figure 5 APIs around NtProtectVirtualMemory in ntdll.dll

Automatic detection of this technique may be surprisingly easy. If software calls a DLL’s API and specifies an address other than the function’s entry address, they can all be determined to be malicious. This is because all legitimate applications would never make such a call. Basically, only malware can use such techniques.

Another option could be to change the way security products are monitored. It is necessary to monitor at the core of the OS. For example, monitoring syscalls.

Unfortunately, analysts need more care to make correct analyses. When finding an API offset call, the analyst should check the skipped steps and see how the caller set them. Understanding the content of this article is the first step for analysts.

Hashes:

Binary: D7566ACBE6FDBF191E074DBE9B6D2382A22F47842AC624DE7E20D2C9778B5308

Binary dropper(.vbs): 99e707a6b2b285cbd383e61ce00a20c0d5784a84997468c89f27195c71e36a79

--

--

Sachiel

Security Analyst in Japan. GIAC GREM (Gold) #165237