Hi Malware Analyst
Reading some fantastic report from many other security researcher is very fun. The techniques of the adversaries is always growing and their crieativities has no limit which makes me always curious to learn and understand more things.
I am gonna share a technique which is called windows API detouring. This technique is tightly related to windows API hooking where the objective is to do a manipulation on how an application interact with the operating system. This can be used for many purpose which to bypass AV detection or to change the legitimate application behaviour to become malicious
Windows API Detour Library
Microsoft provides a library (https://github.com/microsoft/Detours) to do the process. You can detour any windows API
Detours is a library for intercepting arbitrary Win32 binary functions on x86 machines. Interception code is applied dynamically at runtime. Detours replaces the first few instructions of the target function with an unconditional jump to the user-provided detour function. Instructions from the target function are placed in a trampoline. The address of the trampoline is placed in a target pointer. The detour function can either replace the target function, or extend its semantics by invoking the target function as a subroutine through the target pointer to the trampoline.

There are many source code samples available on the net that you can use. I will provide an easy sample which will give you an idea on how to detour a windows API
Detour MessageBoxA
So, The idea of this sample is to allow us to overwrite a legitimate windows API call from an application to become malcious by injecting a dll into the process
First, I will create a simple C++ code that will execute MessageBoxA to pop up a message like below

#include <iostream>
#include <windows.h>
#include <filesystem>
using namespace std;
int main()
{
while (true) {
int i;
cout << "Press anu numeric key : ";
cin >> i;
MessageBoxA(NULL, "Pop up from legitimate application", "Error!", MB_ICONEXCLAMATION | MB_OK);
}
}
We will tamper the MessageBoxA API call to be rerouted to our application function that we define in our DLL so that we can execute our malicious code when the legit application try to call MessageBoxA
To develop the full code, You need to be able to compile a dll. I use visual studio to manage the project.
Because we would like to overwrite the existing windows API call with our malcious MessageBoxA function then we should follow the original MessageBoxA function parameter. https://learn.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-messageboxa
int MessageBoxA(HWND hWnd, LPCSTR lpText, LPCSTR lpCaption, UINT uType);
As you can see that the function will receive 4 parameters. So we need to declare the same function with the below code
Code Declaration
typedef int (WINAPI* LPFN_MBA)(HWND, LPCSTR, LPCSTR, UINT);
LPFN_MBA originalMessageBoxA = NULL;
int WINAPI MyMessageBox(HWND hWnd, LPCSTR lpText, LPCSTR lpCaption, UINT uType)
{
cout << "Some Malicious Action here ..." << endl;
return originalMessageBoxA(hWnd, "Original MessageBoxA has been Overwritten.", lpCaption, uType);
}
In the above code, We need to declare the function parameter and declare the a variable to host the original pointer to the legit API. Also we need to define our own function definition, here we can do whatever we want the application to behave
Patch the function
Below is the code sequence to patch the API so that everytime MessageBoxA is called then our function will be executed
void patchMessageBox() {
HMODULE user32 = GetModuleHandle(TEXT("user32.dll"));
if (user32 != NULL)
{
originalMessageBoxA = (LPFN_MBA)GetProcAddress(user32, "MessageBoxA");
if (originalMessageBoxA != NULL)
{
DetourTransactionBegin();
DetourUpdateThread(GetCurrentThread());
DetourAttach((PVOID*)&originalMessageBoxA, MyMessageBox);
DetourTransactionCommit();
}
}
}
UnPatch the function
Below is the code sequence to unpatch the API to bring the original API of MessageBoxA to the the process.
void detachMessageBox() {
if (originalMessageBoxA != NULL)
{
DetourTransactionBegin();
DetourUpdateThread(GetCurrentThread());
DetourDetach((PVOID*)&originalMessageBoxA, MyMessageBox);
DetourTransactionCommit();
}
}
Patching the Process
Original application running wihtout any malicious code was injected

The process has been injected with the new malicious dll


We can see and make sure that our DLL has been loaded into the memory by checking on the module tab of the process by using process hacker

So, When we run the next call to the MessageBoxA then we can see the original code has been overwritten with our definition where malicious code is executed.

Unloading the DLL to unpatch the function so that the application will return back to normal

We can see the application is now back to normal

Below is the full code
#include <stdio.h>
#include <windows.h>
#include <shlwapi.h>
#include <winternl.h>
#include "detours.h"
#include "nt.h"
#include <iostream>
using namespace std;
typedef int (WINAPI* LPFN_MBA)(HWND, LPCSTR, LPCSTR, UINT);
LPFN_MBA originalMessageBoxA = NULL;
int WINAPI MyMessageBox(HWND hWnd, LPCSTR lpText, LPCSTR lpCaption, UINT uType)
{
cout << "Some Malicious Action here ..." << endl;
return originalMessageBoxA(hWnd, "Original MessageBoxA has been Overwritten.", lpCaption, uType);
}
void patchMessageBox() {
HMODULE user32 = GetModuleHandle(TEXT("user32.dll"));
if (user32 != NULL)
{
originalMessageBoxA = (LPFN_MBA)GetProcAddress(user32, "MessageBoxA");
if (originalMessageBoxA != NULL)
{
DetourTransactionBegin();
DetourUpdateThread(GetCurrentThread());
DetourAttach((PVOID*)&originalMessageBoxA, MyMessageBox);
DetourTransactionCommit();
}
}
}
void detachMessageBox() {
if (originalMessageBoxA != NULL)
{
DetourTransactionBegin();
DetourUpdateThread(GetCurrentThread());
DetourDetach((PVOID*)&originalMessageBoxA, MyMessageBox);
DetourTransactionCommit();
}
}
BOOL APIENTRY DllMain( HMODULE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved
)
{
switch (ul_reason_for_call)
{
case DLL_PROCESS_ATTACH:
DisableThreadLibraryCalls(hModule);
patchMessageBox();
break;
case DLL_THREAD_ATTACH:
case DLL_THREAD_DETACH:
case DLL_PROCESS_DETACH:
detachMessageBox();
break;
}
return TRUE;
}
You need to have the detour.lib to be linked during the compilation. You can download the library https://github.com/rioasmara/Windows-Detrour-Lib
Blue Team Perspective
So, from the perspective of the blue team what we need to do is more to the behaviour analysis of the process because when the adversaries has enough privilege on the host then they can freely inject malicious DLL and change the behaviour of application with less noticeable. If the blue team only rely on the static code analysis then it is going to be quite challenging because the API call can be changed dynamically at anytime.
The blueteam need to keep their eye on the dll load and unload for a process during its lifetime which is very noisy. The adversaies can change the behaviour of the legitimate application in ad-hoc by loading and unload the DLL. From the perspective of the application it would not know when the API has been detoured to something else because the application still calling the same API