Common DLLs


DLLDescription
Kernel32.dllThis is a very common DLL that contains core functionality, such as access and manipulation of memory, files, and hardware.
Advapi32.dllThis DLL provides access to advanced core Windows components such as the Service Manager and Registry.
User32.dllThis DLL contains all the user-interface components, such as buttons, scroll bars, and components for controlling and responding to user actions.
Gdi32.dllThis DLL contains functions for displaying and manipulating graphics.

Ntdll.dll
This DLL is the interface to the Windows kernel. Executables generally do not import this file directly, although it is always imported indirectly by Kernel32.dll. If an executable imports this file, it means that the author intended to use functionality not normally available to Windows programs. Some tasks, such as hiding functionality or manipulating processes, will use this interface.
WSock32.dll and Ws2_32.dllThese are networking DLLs. A program that accesses either of these most likely connects to a network or performs network-related tasks.
Wininet.dllThis DLL contains higher-level networking functions that implement protocols such as FTP, HTTP, and NTP.
Shell32.dllThis DLL can launch other programs.
Advapi32.dllProvides security calls and functions for manipulating the Windows Registry.
msvcrt.dllThe C standard library for the Visual C++ (MSVC) compiler from version 4.2 to 6.0. It provides programs compiled by these versions of MSVC with most of the standard C library functions. These include string manipulation, memory allocation, C-style input/output calls, and others
rpcrt4.dllThis is a crucial Windows file associated with the Remote Procedure Call (RPC) API, used by applications for network and internet communication

Headers


HeaderDescription
[[Headers, DLLs and Functions#<stdio.h>|stdio.h]]It is a Header file basic I/O like printf(), etc.
[[Headers, DLLs and Functions#netinet/ip.h|netinet/ip.h]]Provides definitions for IP (Internet Protocol) related structures and constants, specifically for IPv4 networking
[[Headers, DLLs and Functions#arpa/inet.h| arpa/inet.h]]Provides functions for manipulating IP addresses, especially for converting between text (string) and binary formats used in network programming.
[[Headers, DLLs and Functions#sys/socket.h|sys/socket.h]]Provides the definitions and functions for using sockets which are used for network communication.
unistd.hIt is a POSIX (Unix standard) header file that gives you access to low-level OS functions, mainly related to I/O, processes, and file descriptors.
[[Headers, DLLs and Functions#windows.h|windows.h]]<windows.h> is the main Windows API header file used for developing applications on Windows OS. It includes declarations for all core Windows functionality.
[[Headers, DLLs and Functions#stdlib.h|stdlib.h]]<stdlib.h> is a standard C header that provides general-purpose utility functions, including memory management, random numbers, conversions, and process control.
[[Headers, DLLs and Functions#string.h|string.h]]<string.h> is the standard C header that provides functions for handling strings and memory blocks.

stdio.h

  • It is a Header file basic I/O like printf(), etc.

Functions

printf

printf is a C standard library function used to print formatted text to the console (stdout).

Signature:

int printf(const char *format, ...);

Parameters:

  • format: A format string (e.g., "Value: %d\n")
  • ...: Variable arguments to insert into the format string

Returns:

  • Number of characters printed, or a negative value on error.

Example:

printf("Hello %s, number = %d\n", "world", 42);

Output: Hello world, number = 42

sys/socket.h


  • It is a header file that provides the definitions and functions for using sockets which are used for network communication.

Functions


socket()

The socket() function is the starting point for network programming in C/C++. It’s how you create a communication endpoint.

Signature :

int socket(int domain, int type, int protocol);
ParameterDescription
domainSpecifies the protocol family (e.g. AF_INET for IPv4, AF_INET6 for IPv6)
typeSpecifies the type of socket (e.g. SOCK_STREAM for TCP, SOCK_DGRAM for UDP)
protocolUsually 0 (default) which means “Let’s the OS choose the appropriate protocol for the type you chose”.

Example:

int sockfd = socket(AF_INET, SOCK_STREAM, 0);
  • AF_INET → IPv4
  • SOCK_STREAM → TCP
  • 0 → Automatically picks TCP for this combo

Return Value:

  • Success: returns a file descriptor (non-negative int)
  • Failure: returns -1
connect()
  • The connect() function is used in socket programming to initiate a connection from a client to a server.
  • It says: “Hey server, I want to talk to you at this IP and port.” If the server is listening and accepts your connection, you’re now ready to send and receive data.

Signature

int connect(int sockfd, const struct sockaddr *addr, socklen_t addrlen);
ParameterDescription
sockfdThe socket file descriptor returned by [[Headers, DLLs and Functions#socket()|socket]] function.
addrPointer to a sockaddr structure containing the server’s IP and port
addrlenSize of the sockaddr structure (usually sizeof(struct sockaddr_in) for IPv4)
Return Value:
  • 0 on success
  • -1 on failure → you should check errno or use perror() for details
    connect() is what a client uses to “call” the server.

Structures


sockaddr

The sockaddr structure is a generic socket address used by socket functions like connect(), bind(), accept(), etc. It acts as a placeholder that can represent any address type (IPv4, IPv6, etc.).

Structure Signature:

struct sockaddr {
    sa_family_t sa_family;     // Address family (e.g., AF_INET)
    char        sa_data[14];   // Protocol-specific address information
};
  • It’s a generic container, so it’s not used directly for setting IP addresses or ports.
  • Instead, you use a more specific structure (like sockaddr_in(for IPv4),sockaddr_in6(for IPv6) ), then cast its pointer to sockaddr* when passing it to socket functions.

Example :

struct sockaddr_in addr;
addr.sin_family = AF_INET;
addr.sin_port = htons(8080);
inet_pton(AF_INET, "127.0.0.1", &addr.sin_addr);
 
// Pass to connect(), cast to (struct sockaddr*)
connect(sockfd, (struct sockaddr*)&addr, sizeof(addr));

netinet/ip.h


  • It is a C header file that provides definitions for IP (Internet Protocol) related structures and constants, specifically for IPv4 networking.

Structures


sockaddr_in
  • This structure specifies a transport address and port for the IPv4.

Structure Signature:

struct sockaddr_in {
    sa_family_t    sin_family;  // Address family (AF_INET for IPv4)
    in_port_t      sin_port;    // Port number (in network byte order)
    struct in_addr sin_addr;    // IP address (in network byte order)
    // Padding to make struct size same as struct sockaddr
    unsigned char  sin_zero[8];
};
 
FieldDescription
sin_familyAlways set to AF_INET for IPv4.
sin_portThe port number, which must be in network byte order (use [[Headers, DLLs and Functions#htons()– Host to Network Short|htons()]] to convert in network byte).
sin_addrA structure of type in_addr that holds the IPv4 address.
sin_zeroPadding field to make sockaddr_in the same size as sockaddr. Not used in practice; just set to zero.
sockaddr_in6

This structure represents a socket address for IPv6.

Signature :

struct sockaddr_in6 {
    sa_family_t     sin6_family;   // Address family (AF_INET6)
    in_port_t       sin6_port;     // Port number (network byte order)
    uint32_t        sin6_flowinfo; // Flow information (usually 0)
    struct in6_addr sin6_addr;     // IPv6 address
    uint32_t        sin6_scope_id; // Scope ID (for link-local addresses)
};
FieldDescription
sin6_familyAlways set to AF_INET6 for IPv6.
sin6_portPort number (use [[Headers, DLLs and Functions#htons()– Host to Network Short|htons()]] to convert to network byte order).
sin6_flowinfoOptional. Used for IPv6 flow labels (usually 0).
sin6_addrAn in6_addr struct that holds the IPv6 address.
sin6_scope_idUsed to specify interface for link-local addresses (e.g., fe80::...). Set to 0 otherwise.
in_addr

The in_addr structure represents a single IPv4 address. It is used within sockaddr_in and other network functions that deal specifically with IP addresses.

Structure Signature:

struct in_addr {
    in_addr_t s_addr; // 32-bit IPv4 address (in network byte order)
};
  • s_addr is usually an unsigned long or uint32_t, depending on the platform.
  • It holds the IP address in network byte order (big-endian).
  • To convert a human-readable IP string (e.g., "192.168.1.1") to this format, you use functions like:
in6_addr

Used inside sockaddr_in6 to hold the 128-bit IPv6 address.

Signature :

struct in6_addr {
    unsigned char s6_addr[16]; // 128-bit IPv6 address (in network byte order)
};
  • s6_addr is an array of 16 bytes = 128 bits (standard IPv6 address size).
  • It holds the IP address in network byte order (big-endian).
  • Use inet_pton() function to convert from string to binary format.

arpa/inet.h


  • It is a C header file that provides functions for manipulating IP addresses, especially for converting between text (string) and binary formats used in network programming.

Functions


inet_aton()
  • Converts an IPv4 address string (e.g., "192.168.1.1") to binary format and stores it in a struct in_addr.
  • Used only for IPv4.
  • Returns non-zero on success, 0 on failure.
  • Non-standard on Windows (not portable across platforms).
int inet_aton(const char *cp, struct in_addr *inp);

Parameters:

ParameterTypeDescription
cpconst char*The IPv4 address in string format, e.g. "192.168.1.1"
inpstruct in_addr*Pointer to a struct in_addr where the binary address will be stored

Example:

#include <arpa/inet.h>
#include <stdio.h>
int main() {
    const char* ip = "192.168.1.1";
    struct in_addr addr;
    
    if (inet_aton(ip, &addr)) {
        printf("IP address converted: 0x%x\n", addr.s_addr);
    } else {
        printf("Invalid IP address\n");
    }
    return 0;
}
inet_pton()
  • General-purpose: works for both IPv4 (AF_INET) and IPv6 (AF_INET6).
  • Safer and more modern.
  • Portable and POSIX-compliant.
  • Returns 1 on success, 0 if the address is invalid, -1 on error.

Signature:

int inet_pton(int af, const char *src, void *dst);

Parameters:

ParameterTypeDescription
afintAddress family: AF_INET (IPv4) or AF_INET6 (IPv6)
srcconst char*IP address string (e.g., "192.168.1.1" or "::1")
dstvoid*Pointer to a buffer to store the binary IP (typically &in_addr or &in6_addr)

Example for IPv4:

#include <arpa/inet.h>
#include <stdio.h>
#include <string.h>
int main() {
    const char* ip = "192.168.1.1";
    struct in_addr addr;
    
    if (inet_pton(AF_INET, ip, &addr) == 1) {
        printf("IPv4 address converted successfully.\n");
    } else {
        printf("Invalid IPv4 address.\n");
    }
    return 0;
}

Example for IPv6:

#include <arpa/inet.h>
#include <stdio.h>
#include <string.h>
int main() {
    const char* ip = "::1";
    struct in6_addr addr6;
	
    if (inet_pton(AF_INET6, ip, &addr6) == 1) {
        printf("IPv6 address converted successfully.\n");
    } else {
        printf("Invalid IPv6 address.\n");
    }
    return 0;
}
hton

hton = “Host TO Network”

These functions convert values from the host’s byte order (which might be little-endian) to network byte order (which is always big-endian).

Different computers use different endianness:

  • Little-endian (e.g., x86/x64 CPUs): least significant byte comes first
  • Big-endian: most significant byte comes first

But network protocols (like TCP/IP) always use big-endian format, so if your CPU is little-endian (which most are), you need to convert numbers before sending them.

Common hton and ntoh Functions

FunctionUse CaseInput TypeConverts From → To
htonsPort numbersuint16_tHost → Network (16-bit)
htonlIP addressesuint32_tHost → Network (32-bit)
ntohsReceived port numbersuint16_tNetwork → Host (16-bit)
ntohlReceived IP addressesuint32_tNetwork → Host (32-bit)
htons()– Host to Network Short
uint16_t htons(uint16_t hostshort);
  • Converts a 16-bit integer (e.g., a port number) from host byte order to network byte order.
htonl()– Host to Network Long
uint32_t htonl(uint32_t hostlong);
  • Converts a 32-bit integer (e.g., an IPv4 address) from host byte order to network byte order.
ntohs()– Network to Host Short
uint16_t htons(uint16_t hostshort);
  • Converts a 16-bit integer (e.g., a port number) from Network byte order to Host byte order.
ntohl()– Network to Host Long
uint32_t htonl(uint32_t hostlong);
  • Converts a 32-bit integer (e.g., an IPv4 address) from Network byte order to Host byte order.

unistd.h


It is a POSIX (Unix standard) header file that gives you access to low-level OS functions, mainly related to I/O, processes, and file descriptors.

Functions


dup2()

dup2() is a system call that duplicates one file descriptor to another.

Signature:

int dup2(int oldfd, int newfd);
ParameterDescription
oldfdThe original file descriptor you want to duplicate (e.g., a socket, file, etc.)
newfdThe file descriptor you want to overwrite or redirect to point to oldfd
  • Makes newfd refer to the same open file (or socket) as oldfd.
  • If newfd is already open, it will be closed first automatically.
  • oldfd and newfd will both now refer to the same underlying resource, but are still separate file descriptors.

Return Value:

  • Returns newfd on success
  • Returns -1 on error (check errno)

Example:

dup2(sockfd, 0); // stdin
dup2(sockfd, 1); // stdout
dup2(sockfd, 2); // stderr
  • 0, 1 & 2 in file descriptor refer to stdin, stdout & stderr respectively.
  • So we are copying this file descriptor to sockfd.
execve()

execve() is a system call used to replace the current running process with a new program.

Signature:

int execve(const char *pathname, char *const argv[], char *const envp[]);
ParameterDescription
pathnameFull path to the executable file (e.g., /bin/sh)
argv[]Array of arguments passed to the program (like argv in main())
envp[]Array of environment variables (can pass environ or NULL)
  • Does not return on success (the current process is replaced)
  • Returns -1 on failure (and sets errno)

Example:

char *argv[] = {"/bin/sh", NULL};
execve("/bin/sh", argv, NULL);

windows.h


<windows.h> is the main Windows API header file used for developing applications on Windows OS. It includes declarations for all core Windows functionality.

Functions

VirtualAlloc

VirtualAlloc is a Windows API function used to allocate memory pages directly from the system’s virtual memory.

Signature:

LPVOID VirtualAlloc(
  LPVOID lpAddress,
  SIZE_T dwSize,
  DWORD  flAllocationType,
  DWORD  flProtect
);
ParameterDescription
lpAddressPreferred memory address (or NULL to let Windows decide)
dwSizeSize (in bytes) of memory to allocate
flAllocationTypeMemory allocation type commonly MEM_COMMIT or MEM_RESERVE
flProtectMemory protection — commonly PAGE_READWRITE, PAGE_EXECUTE_READWRITE, etc.
Common Constants:
ConstantMeaning
MEM_COMMITAllocates physical memory
MEM_RESERVEReserves a range of virtual addresses
PAGE_READWRITERead and write access
PAGE_EXECUTE_READWRITERead, write, and execute access (used for shellcode)

Example:

#include <windows.h>
 
int main() {
    void *mem = VirtualAlloc(
        NULL,                   // Let system choose address
        1024,                   // Allocate 1024 bytes
        MEM_COMMIT | MEM_RESERVE, // Commit and reserve pages
        PAGE_EXECUTE_READWRITE    // Allow code execution (for shellcode)
    );
	
    if (mem != NULL) {
        // Use the memory...
    }
	
    return 0;
}
RtlMoveMemory

RtlMoveMemory is a Windows API function used to copy memory blocks in same process.

Signature:

VOID RtlMoveMemory(
  VOID UNALIGNED *Destination,
  const VOID UNALIGNED *Source,
  SIZE_T Length
);
ParameterMeaning
VOID UNALIGNED *DestinationA pointer to the destination memory buffer where data will be copied.
const VOID UNALIGNED *SourceA pointer to the source memory buffer to copy data from. It’s const, so the function does not modify it.
SIZE_T LengthNumber of bytes to copy from source to destination. SIZE_T is typically an unsigned integer type.

Example:

#include <windows.h>
 
int main() {
    char src[] = "Hello, Windows!";
    char dest[20];
 
    RtlMoveMemory(dest, src, sizeof(src));
 
    MessageBoxA(NULL, dest, "Copied Message", MB_OK);
    return 0;
}
VirtualProtect

VirtualProtect is a Windows API function used to change the protection (read, write, execute permissions) of a region of memory that your program owns.

Signature:

BOOL VirtualProtect(
  LPVOID lpAddress,
  SIZE_T dwSize,
  DWORD  flNewProtect,
  PDWORD lpflOldProtect
);
ParameterTypeDescription
lpAddressLPVOIDPointer to the starting address of the memory region
dwSizeSIZE_TNumber of bytes to change protection for
flNewProtectDWORDNew protection flags (e.g., PAGE_EXECUTE_READWRITE)
lpflOldProtectPDWORDPointer to a variable that receives the previous protection value
Common Protection Flags :
FlagMeaning
PAGE_READONLYRead-only
PAGE_READWRITERead and write
PAGE_EXECUTEExecute only
PAGE_EXECUTE_READExecute and read
PAGE_EXECUTE_READWRITEExecute, read, and write (used for shellcode)
PAGE_NOACCESSCannot access at all

Example:

#include <windows.h>
#include <stdio.h>
 
int main() {
    unsigned char code[] = { 0x90, 0x90, 0xC3 }; // NOP, NOP, RET (safe test shellcode)
 
    DWORD oldProtect;
    BOOL result = VirtualProtect(
        code,                        // memory address
        sizeof(code),                // size
        PAGE_EXECUTE_READWRITE,      // new protection
        &oldProtect                  // save old protection
    );
 
    if (result) {
        printf("Memory protection changed.\n");
        ((void(*)())code)(); // Call the shellcode
    } else {
        printf("VirtualProtect failed: %lu\n", GetLastError());
    }
 
    return 0;
}
CreateThread

CreateThread is a Windows API function used to create a new thread in your process. It’s one of the most direct ways to launch concurrent execution in Windows.

Signature :

HANDLE CreateThread(
  LPSECURITY_ATTRIBUTES   lpThreadAttributes,
  SIZE_T                  dwStackSize,
  LPTHREAD_START_ROUTINE  lpStartAddress,
  LPVOID                  lpParameter,
  DWORD                   dwCreationFlags,
  LPDWORD                 lpThreadId
);
ParameterTypeDescription
lpThreadAttributesLPSECURITY_ATTRIBUTESCan be NULL (default security)
dwStackSizeSIZE_TInitial stack size in bytes (use 0 for default)
lpStartAddressLPTHREAD_START_ROUTINEFunction pointer to the thread’s entry function
lpParameterLPVOIDPointer to data passed to the thread function
dwCreationFlagsDWORD0 to run immediately, or CREATE_SUSPENDED
lpThreadIdLPDWORDPointer to receive the thread ID (can be NULL)
Return Value :
  • On success: Returns a HANDLE to the new thread.
  • On failure: Returns NULL. Call GetLastError() for details.

Example :

#include <windows.h>
#include <stdio.h>
 
DWORD WINAPI MyThreadFunction(LPVOID lpParam) {
    printf("Hello from thread! Param: %s\n", (char *)lpParam);
    return 0;
}
 
int main() {
    HANDLE hThread;
    DWORD threadId;
 
    hThread = CreateThread(
        NULL,              // Default security
        0,                 // Default stack size
        MyThreadFunction,  // Function to run
        "Thread Param",    // Parameter to pass
        0,                 // Run immediately
        &threadId          // Thread ID
    );
 
    if (hThread == NULL) {
        printf("CreateThread failed! Error: %lu\n", GetLastError());
        return 1;
    }
 
    // Wait for thread to finish
    WaitForSingleObject(hThread, INFINITE);
    CloseHandle(hThread);
 
    return 0;
}
WaitForSingleObject

WaitForSingleObject is a Windows API function that pauses the calling thread until the specified object is signaled or a timeout occurs.

Signature :

DWORD WaitForSingleObject(
  HANDLE hHandle,
  DWORD  dwMilliseconds
);
ParameterTypeDescription
hHandleHANDLEA handle to a thread, process, mutex, event, etc.
dwMillisecondsDWORDTime to wait (in milliseconds) or special constants like INFINITE
Common Constants:
  • INFINITE → Wait forever until the object is signaled.
  • 0 → Do not wait; return immediately (polling).

Return Values :

Return CodeMeaning
WAIT_OBJECT_0The object is signaled — success
WAIT_TIMEOUTThe timeout interval elapsed
WAIT_FAILEDThe function failed

Example :

HANDLE hThread = CreateThread(...);
WaitForSingleObject(hThread, INFINITE);
CloseHandle(hThread);

This waits for the thread to finish before continuing, ensuring synchronization.

OpenProcess

OpenProcess is a Windows API function that opens a handle to a running process using its process ID (PID) for further operations like reading memory or injecting code.

Signature:

HANDLE OpenProcess(
  DWORD dwDesiredAccess,
  BOOL  bInheritHandle,
  DWORD dwProcessId
);

Parameters:

ParameterDescription
dwDesiredAccessWhat access you want (e.g., PROCESS_ALL_ACCESS)
bInheritHandleTRUE if child processes should inherit the handle
dwProcessIdThe ID of the target process (usually from argv, GetCurrentProcessId, etc.)
Return Value:
  • On success: Returns a HANDLE to the process.
  • On failure: Returns NULL (use GetLastError() to debug).

Common constants for dwDesiredAccess parameter.

Access RightDescription
PROCESS_VM_READRead memory in the target process
PROCESS_VM_WRITEWrite to memory in the target process
PROCESS_VM_OPERATIONPerform memory operations (e.g., allocate)
PROCESS_CREATE_THREADCreate a thread in the target process
PROCESS_QUERY_INFORMATIONQuery info like priority, handle count
PROCESS_QUERY_LIMITED_INFORMATIONSafer, limited query access
PROCESS_TERMINATETerminate the process
PROCESS_SUSPEND_RESUMESuspend/resume the process (Win 7+)
PROCESS_ALL_ACCESSRequests all possible permissions on the target process

Example:

HANDLE hProc = OpenProcess(PROCESS_ALL_ACCESS, FALSE, pid);
VirtualAllocEx

VirtualAllocEx is a Windows API function used to allocate memory in the address space of another process.

Signature:

LPVOID VirtualAllocEx(
  HANDLE hProcess,
  LPVOID lpAddress,
  SIZE_T dwSize,
  DWORD  flAllocationType,
  DWORD  flProtect
);
ParameterTypeDescription
hProcessHANDLEHandle to the target process (must have PROCESS_VM_OPERATION access)
lpAddressLPVOIDDesired starting address (usually NULL for automatic selection)
dwSizeSIZE_TSize of memory to allocate (in bytes)
flAllocationTypeDWORDType of memory allocation (e.g., MEM_COMMIT, MEM_RESERVE)
flProtectDWORDMemory protection (e.g., PAGE_EXECUTE_READWRITE)
Return:
  • On success: Returns a pointer (LPVOID) to the base address of allocated memory in the target process.
  • On failure: Returns NULL. Use GetLastError() for more info.

Example:

HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, pid);
LPVOID remoteMem = VirtualAllocEx(
    hProcess, 
    NULL, 
    4096, 
    MEM_COMMIT | MEM_RESERVE, 
    PAGE_EXECUTE_READWRITE
);

This allocates 1 memory page (4096 bytes) with read/write/execute permissions in another process’s memory.

WriteProcessMemory

WriteProcessMemory is a Windows API function that writes data into the memory of another process.

Signature:

BOOL WriteProcessMemory(
  HANDLE  hProcess,
  LPVOID  lpBaseAddress,
  LPCVOID lpBuffer,
  SIZE_T  nSize,
  SIZE_T  *lpNumberOfBytesWritten
);
ParameterTypeDescription
hProcessHANDLEHandle to the target process (must have PROCESS_VM_WRITE and PROCESS_VM_OPERATION access)
lpBaseAddressLPVOIDAddress in the target process where data will be written (from VirtualAllocEx)
lpBufferLPCVOIDPointer to the buffer containing the data to write
nSizeSIZE_TNumber of bytes to write
lpNumberOfBytesWrittenSIZE_T*Pointer to receive the actual number of bytes written (can be NULL)
Return
  • Returns TRUE on success.
  • Returns FALSE on failure — call GetLastError() for details.

Example:

char shellcode[] = "...";  // your shellcode
LPVOID remoteAddr = VirtualAllocEx(hProcess, NULL, sizeof(shellcode), MEM_COMMIT, PAGE_EXECUTE_READWRITE);
 
WriteProcessMemory(
    hProcess,
    remoteAddr,
    shellcode,
    sizeof(shellcode),
    NULL
);

This writes your shellcode into another process’s memory.

CreateRemoteThread

CreateRemoteThread is a powerful Windows API function that lets you create a new thread inside another process.

Signature:

HANDLE CreateRemoteThread(
  HANDLE                 hProcess,
  LPSECURITY_ATTRIBUTES  lpThreadAttributes,
  SIZE_T                 dwStackSize,
  LPTHREAD_START_ROUTINE lpStartAddress,
  LPVOID                 lpParameter,
  DWORD                  dwCreationFlags,
  LPDWORD                lpThreadId
);
ParameterTypeDescription
hProcessHANDLEHandle to the target process (must have PROCESS_CREATE_THREAD and PROCESS_VM_OPERATION access)
lpThreadAttributesLPSECURITY_ATTRIBUTESUsually NULL (default security)
dwStackSizeSIZE_TStack size for the thread (0 = default)
lpStartAddressLPTHREAD_START_ROUTINEAddress of the function to execute (e.g. start of shellcode or LoadLibraryA)
lpParameterLPVOIDOptional parameter passed to the thread
dwCreationFlagsDWORD0 to run immediately, or CREATE_SUSPENDED
lpThreadIdLPDWORDPointer to receive the thread ID (can be NULL)
Return:
  • Returns a HANDLE to the created thread if successful.
  • Returns NULL if it fails — use GetLastError() to diagnose.

Example: - DLL Injection:

HANDLE hProcess = OpenProcess(...);
LPVOID remoteMem = VirtualAllocEx(hProcess, NULL, len, MEM_COMMIT, PAGE_READWRITE);
WriteProcessMemory(hProcess, remoteMem, dllPath, len, NULL);
HANDLE hThread = CreateRemoteThread(hProcess, NULL, 0, 
    (LPTHREAD_START_ROUTINE)LoadLibraryA, remoteMem, 0, NULL);

This injects a DLL by remotely calling LoadLibraryA(dllPath) inside the target process.

CloseHandle

CloseHandle is a Windows API function used to release system resources associated with handles (like processes, threads, files, etc.).

Signature:

BOOL CloseHandle(HANDLE hObject);
ParameterTypeDescription
hObjectHANDLEA valid handle to a system object (e.g., process, thread, file, event)
Return:
  • Returns TRUE on success.
  • Returns FALSE on failure — use GetLastError() for more info.

When to Use CloseHandle:

Handle TypeUse Case Example
HANDLE to a processAfter OpenProcess() or CreateProcess()
HANDLE to a threadAfter CreateThread() or CreateRemoteThread()
HANDLE to a fileAfter CreateFile()

Example:

HANDLE hThread = CreateRemoteThread(...);
 
// Wait for thread to finish
WaitForSingleObject(hThread, INFINITE);
 
// Clean up
CloseHandle(hThread);
CreateToolhelp32Snapshot

CreateToolhelp32Snapshot is a function in the Windows API used to take a snapshot of system resources, such as:

  • All running processes
  • Threads in a process
  • Modules (DLLs) loaded in a process
  • Heaps in a process

Implemented in Kernel32.dll.

Signature:

HANDLE CreateToolhelp32Snapshot(
  DWORD dwFlags,
  DWORD th32ProcessID
);

Parameters:

ParameterDescription
dwFlagsWhat to include in the snapshot. E.g., TH32CS_SNAPPROCESS, TH32CS_SNAPTHREAD, etc.
th32ProcessIDUsed when capturing threads, modules, or heaps in a specific process. Set to 0 when capturing system-wide process list.

Common Flags:

FlagDescription
TH32CS_SNAPPROCESSAll running processes
TH32CS_SNAPTHREADAll threads in the system
TH32CS_SNAPMODULEModules (DLLs/EXEs) of a specific process
TH32CS_SNAPHEAPLISTHeap info of a process
TH32CS_SNAPALLCombination of the above
Returns:
  • Valid HANDLE if successful.
  • INVALID_HANDLE_VALUE ((HANDLE)(LONG_PTR)-1) on failure — check with GetLastError().

Example: List Running Processes

#include <windows.h>
#include <tlhelp32.h>
#include <iostream>
 
int main() {
    HANDLE hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
    if (hSnapshot == INVALID_HANDLE_VALUE) {
        std::cout << "Snapshot failed. Error: " << GetLastError() << "\n";
        return 1;
    }
 
    PROCESSENTRY32 pe;
    pe.dwSize = sizeof(PROCESSENTRY32);
 
    if (Process32First(hSnapshot, &pe)) {
        do {
            std::wcout << L"Process: " << pe.szExeFile << L" | PID: " << pe.th32ProcessID << L"\n";
        } while (Process32Next(hSnapshot, &pe));
    } else {
        std::cout << "Failed to retrieve process info.\n";
    }
 
    CloseHandle(hSnapshot);
    return 0;
}
Process32First

Process32First is a Windows API function used to retrieve information about the first process in a snapshot created by CreateToolhelp32Snapshot().

Signature:

BOOL Process32First(
  HANDLE hSnapshot,
  LPPROCESSENTRY32 lppe
);
ParameterDescription
hSnapshotA handle to a snapshot returned from [[Headers, DLLs and Functions#CreateToolhelp32Snapshot|CreateToolhelp32Snapshot]] with TH32CS_SNAPPROCESS.
lppePointer to a [[Headers, DLLs and Functions#PROCESSENTRY32|PROCESSENTRY32]] structure that will receive information about the first process.
Return:
  • Returns non-zero (TRUE) if successful (i.e., the first process entry was retrieved).
  • Returns 0 (FALSE) if it fails (e.g., invalid handle or empty list).
  • Call GetLastError() for extended error info if it fails.

Note

  • You must call Process32First before calling Process32Next.

  • It fills the PROCESSENTRY32 struct with information about the first process (like its name, PID, parent PID, etc.).

  • Before calling Process32First, you must initialize the dwSize member of PROCESSENTRY32:

PROCESSENTRY32 pe;
pe.dwSize = sizeof(PROCESSENTRY32); // mandatory

Example :

HANDLE snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
PROCESSENTRY32 pe;
pe.dwSize = sizeof(PROCESSENTRY32);
 
if (Process32First(snapshot, &pe)) {
    do {
        printf("Process: %s, PID: %lu\n", pe.szExeFile, pe.th32ProcessID);
    } while (Process32Next(snapshot, &pe));
}
Process32Next

Process32Next is a Windows API function that retrieves information about the next process in a system snapshot - after Process32First has been called.

Signature:

BOOL Process32Next(
  HANDLE hSnapshot,
  LPPROCESSENTRY32 lppe
);
ParameterDescription
hSnapshotA handle to the snapshot returned by [[Headers, DLLs and Functions#CreateToolhelp32Snapshot|CreateToolhelp32Snapshot()]].
lppeA pointer to a PROCESSENTRY32 structure that will receive information about the next process.
Return :
  • Returns non-zero (TRUE) if the next process entry was successfully retrieved.
  • Returns 0 (FALSE) when there are no more processes to enumerate.
  • Use GetLastError() for error details if needed.

After you call Process32First, you use Process32Next in a loop to:

  • Move to the next process in the snapshot.
  • Collect its details (name, PID, etc.) into the PROCESSENTRY32 structure.

Example :

You must call Process32First() once before using Process32Next.

HANDLE snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
PROCESSENTRY32 pe;
pe.dwSize = sizeof(PROCESSENTRY32);
 
if (Process32First(snapshot, &pe)) {
    do {
        printf("Process Name: %s, PID: %lu\n", pe.szExeFile, pe.th32ProcessID);
    } while (Process32Next(snapshot, &pe)); // keep iterating
}
CloseHandle(snapshot);

stdlib.h


<stdlib.h> is a standard C header that provides general-purpose utility functions, including memory management, random numbers, conversions, and process control.

Functions

atoi

atoi (ASCII to Integer) is a C standard library function that converts a string to an int.

Signature :

int atoi(const char *str);

Parameters:

  • str: A C-style string (null-terminated) representing a number (e.g., "42")

Returns:

  • The converted int value of the string.
  • If the string is invalid or doesn’t start with a number, it returns 0 (no error indication!).

Example:

int num = atoi("123");  // num = 123

string.h


<string.h> is the standard C header that provides functions for handling strings and memory blocks.

tlhelp32.h


<tlhelp32.h> is a Windows header file that provides declarations for Tool Help Library functions, used to take snapshots of the system’s process, thread, module, and heap states.

  • Link against Kernel32.lib.

Functions

Structures

PROCESSENTRY32

The PROCESSENTRY32 structure is a Windows API data structure used with functions like Process32First() and Process32Next() to describe a process entry retrieved from a system snapshot.

Signature:

typedef struct tagPROCESSENTRY32 {
  DWORD   dwSize;
  DWORD   cntUsage;
  DWORD   th32ProcessID;
  ULONG_PTR th32DefaultHeapID;
  DWORD   th32ModuleID;
  DWORD   cntThreads;
  DWORD   th32ParentProcessID;
  LONG    pcPriClassBase;
  DWORD   dwFlags;
  CHAR    szExeFile[MAX_PATH];
} PROCESSENTRY32;
FieldTypeDescription
dwSizeDWORDMust be set to sizeof(PROCESSENTRY32) before calling [[Headers, DLLs and Functions#Process32First|Process32First]].
cntUsageDWORDObsolete (always 0); historical ref count.
th32ProcessIDDWORDProcess ID (PID) of the process.
th32DefaultHeapIDULONG_PTRObsolete; handle to the process’s default heap (ignore).
th32ModuleIDDWORDObsolete (always 0); kept for compatibility.
cntThreadsDWORDNumber of execution threads in the process.
th32ParentProcessIDDWORDPID of the parent process (the one that created it).
pcPriClassBaseLONGBase priority of threads in the process.
dwFlagsDWORDReserved; not used (always 0).
szExeFileCHAR[260]Null-terminated string containing the name of the executable file.

Example:

PROCESSENTRY32 pe;
pe.dwSize = sizeof(PROCESSENTRY32);
 
if (Process32First(snapshot, &pe)) {
    do {
        printf("Process Name: %s\n", pe.szExeFile);
        printf("PID: %lu\n", pe.th32ProcessID);
        printf("Threads: %lu\n", pe.cntThreads);
        printf("Parent PID: %lu\n", pe.th32ParentProcessID);
        printf("Priority Base: %ld\n\n", pe.pcPriClassBase);
    } while (Process32Next(snapshot, &pe));
}

Common Functions


FunctionAccess byDescription
FindFirstFile and FindNextFileKernel32.dllUsed to search through directories.
RegisterClassEx, SetWindowText, and ShowWindowUser32.dllThis are GUI manipulation functions.
SetWindowsHookExUser32.dllSetWindowsHookEx is commonly used in spyware and is the most popular way that keyloggers receive keyboard inputs.
RegisterHotKeyUser32.dllIt registers a hotkey (such as CTRL-SHIFT-P) so that whenever the user presses that hotkey combination, the application is notified.
DLLMainSpecial reserved name. Windows expects this function inside a DLL. Refer, DLL Injection Into The Process
[[Headers, DLLs and Functions#sizeof()|sizeof()]]It calculates the total size (in bytes).
[[Headers, DLLs and Functions#main()|main()]]The special function where the program starts running.
[[Headers, DLLs and Functions#OpenProcess|OpenProcess()]][[Headers, DLLs and Functions#windows.h|windows.h]]A Windows API function → It opens an existing process and gives you a handle to it.
[[Headers, DLLs and Functions#VirtualAlloc|VirtualAlloc]] and [[Headers, DLLs and Functions#VirtualAllocEx|VirtualAllocEx]][[Headers, DLLs and Functions#windows.h|windows.h]] , kernel32.lib, kernel32.dll- [[Headers, DLLs and Functions#VirtualAlloc|VirtualAlloc]] Allocates memory inside the process that’s running the code (yourself).
- [[Headers, DLLs and Functions#VirtualAllocEx|VirtualAllocEx]] allocates memory inside another process.
[[Headers, DLLs and Functions#CreateThread|CreateThread()]] and [[Headers, DLLs and Functions#CreateRemoteThread|CreateRemoteThread()]][[Headers, DLLs and Functions#windows.h|windows.h]]- [[Headers, DLLs and Functions#CreateThread|CreateThread()]] creates a thread in your own process.
- [[Headers, DLLs and Functions#CreateRemoteThread|CreateRemoteThread()]] creates a thread in a different(remote) process.
CreateToolhelp32Snapshotthelp32.hCaptures a snapshot of the system’s processes, threads, modules, or heaps at a particular point in time.
Process32Firstand Process32Nextthelp32.hUsed to iterate through the list of processes in the snapshot.
Thread32Firstand Thread32Nextthelp32.hUsed to enumerate threads in a snapshot.
Module32First and Module32Nextthelp32.hUsed to enumerate the modules (DLLs or EXEs) loaded by a process.
GetModuleHandleUsed to get the handle of loaded module(DLL) inside the current process.
GetProcAddressUsed to find the memory address of function
[[Headers, DLLs and Functions#socket()|socket()]][[Headers, DLLs and Functions#sys/socket.h|sys/socket.h]]It is the starting point for network programming in C/C++. It’s how you create a communication endpoint.
[[Headers, DLLs and Functions#connect()|connect()]][[Headers, DLLs and Functions#sys/socket.h|sys/socket.h]]The connect() function is used in socket programming to initiate a connection from a client to a server.
[[Headers, DLLs and Functions#inet_aton()|inet_aton()]][[Headers, DLLs and Functions#arpa/inet.h|arpa/inet.h]]Converts an IPv4 address string (e.g., "192.168.1.1") to binary format and stores it in a struct in_addr
[[Headers, DLLs and Functions#inet_pton()|inet_pton()]][[Headers, DLLs and Functions#arpa/inet.h|arpa/inet.h]]Converts both IPv4 or IPv6 address string to binary format and stores it in a in_addr or in6_addr structure respectively.
[[Headers, DLLs and Functions#htonl()– Host to Network Long|htons()]][[Headers, DLLs and Functions#arpa/inet.h|arpa/inet.h]]Converts a 16-bit integer (e.g., a port number) from host byte order to network byte order.
[[Headers, DLLs and Functions#htonl()– Host to Network Long|htonl()]][[Headers, DLLs and Functions#arpa/inet.h|arpa/inet.h]]Converts a 32-bit integer (e.g., an IPv4 address) from host byte order to network byte order.
[[Headers, DLLs and Functions#ntohs()– Network to Host Short|ntohs()]][[Headers, DLLs and Functions#arpa/inet.h|arpa/inet.h]]Converts a 16-bit integer (e.g., a port number) from Network byte order to Host byte order.
[[Headers, DLLs and Functions#ntohl()– Network to Host Long|ntohl()]][[Headers, DLLs and Functions#arpa/inet.h|arpa/inet.h]]Converts a 32-bit integer (e.g., an IPv4 address) from Network byte order to Host byte order.
[[Headers, DLLs and Functions#dup2()|dup2()]][[Headers, DLLs and Functions#unistd.h|uniistd.h]]Duplicates one file descriptor to another.
[[Headers, DLLs and Functions#execve()|execve()]][[Headers, DLLs and Functions#unistd.h|uniistd.h]]Used to replace the current running process with a new program.
[[Headers, DLLs and Functions#RtlMoveMemory|RtlMoveMemory()]][[Headers, DLLs and Functions#windows.h|windows.h]]Used to copy memory blocks in same process.
[[Headers, DLLs and Functions#WriteProcessMemory|WriteMemoryProcess()]][[Headers, DLLs and Functions#windows.h|windows.h]]Used to copy memory blocks in remote process using PID.
[[Headers, DLLs and Functions#VirtualProtect|VirtualProtect()]][[Headers, DLLs and Functions#windows.h|windows.h]]Used to change the protection (read, write, execute permissions) of a region of memory that your program owns.
[[Headers, DLLs and Functions#WaitForSingleObject|WaitForSingleObject()]][[Headers, DLLs and Functions#windows.h|windows.h]]Function that pauses the calling thread until the specified object is signaled or a timeout occurs.
[[Headers, DLLs and Functions#CloseHandle|CloseHandle()]][[Headers, DLLs and Functions#windows.h|windows.h]]Used to release system resources associated with handles (like processes, threads, files, etc.)
[[Headers, DLLs and Functions#atoi|atoi()]][[Headers, DLLs and Functions#stdlib.h|stdlib.h]]Converts a string to an int.

Functions which doesn’t required Header.

main()

In C, main() is the entry point of any program.

When you run a compiled C program, the operating system calls the main() function always first. It’s where your program starts executing.

sizeof()

sizeof is a compile-time operator in C/C++ that returns the size (in bytes) of a data type or variable.

Signature:

sizeof(type)
sizeof(variable)

Returns:

  • The number of bytes required to store the data type or variable.
  • The result is of type size_t (an unsigned integer).

Note

  • sizeof is evaluated at compile time, not runtime.
  • For dynamically allocated memory (malloc), sizeof is not useful on the pointer.
strcmp

strcmp stands for string compare, and it’s a function from the C standard library used to compare two C-style strings (null-terminated char arrays).

Signature:

int strcmp(const char *str1, const char *str2);

Return :

Return ValueMeaning
0The strings are equal.
< 0str1 is less than str2.
> 0str1 is greater than str2.
  • Compares each character of str1 and str2 1lexicographically (ASCII value).
  • Stops when:
    • Characters differ, or
    • A null character \0 is encountered (end of string).

Example:

CharacterASCII Value
'A'65
'B'66
'a'97
'b'98
strcmp("apple", "banana");
  • Compare 'a' vs 'b''a' < 'b'"apple" is less than "banana".
strcmp("cat", "car");
  • 'c' = 'c'
  • 'a' = 'a'
  • 't' > 'r'"cat" is greater than "car"
strcmp("Apple", "apple"); // Returns < 0
  • Because 'A' (65) < 'a' (97), even though they’re the same letter.

NOTE

  • It is case-sensitive.
    • strcmp("abc", "ABC")0
  • If you want case-insensitive comparison, use:
    • stricmp() on Windows (_stricmp)
    • strcasecmp() on POSIX
THREADENTRY32

The THREADENTRY32 structure in Windows is used with the Tool Help Library to retrieve information about threads running in the system. It is primarily used with functions like Thread32First and Thread32Next when you’re taking a snapshot of the system’s threads (using CreateToolhelp32Snapshot with TH32CS_SNAPTHREAD).

Signature :

typedef struct tagTHREADENTRY32 {
  DWORD   dwSize;
  DWORD   cntUsage;
  DWORD   th32ThreadID;
  DWORD   th32OwnerProcessID;
  LONG    tpBasePri;
  LONG    tpDeltaPri;
  DWORD   dwFlags;
} THREADENTRY32;
MemberDescription
dwSizeSize of the structure in bytes. Must be set before calling [[Headers, DLLs and Functions#Thread32First|Thread32First]].
cntUsageReserved. Not used in Windows; ignore.
th32ThreadIDUnique thread ID.
th32OwnerProcessIDProcess ID of the process that owns this thread.
tpBasePriBase priority of the thread.
tpDeltaPriPriority delta from the base.
dwFlagsReserved. Not used in Windows; ignore.

Example :

THREADENTRY32 te;
te.dwSize = sizeof(THREADENTRY32);
 
HANDLE hThreadSnap = CreateToolhelp32Snapshot(TH32CS_SNAPTHREAD, 0);
 
if (Thread32First(hThreadSnap, &te)) {
    do {
        if (te.th32OwnerProcessID == targetPID) {
            printf("Found thread ID: %lu\n", te.th32ThreadID);
        }
    } while (Thread32Next(hThreadSnap, &te));
}
Thread32First

Thread32First is a Windows API function used to retrieve information about the first thread in a system snapshot created with CreateToolhelp32Snapshot(). It works hand-in-hand with Thread32Next to loop through all threads currently running on the system.

Signature :

BOOL Thread32First(
  HANDLE hSnapshot,
  LPTHREADENTRY32 lpte
);
ParameterDescription
hSnapshotHandle to a snapshot of the system (created using [[Headers, DLLs and Functions#CreateToolhelp32Snapshot|CreateToolhelp32Snapshot()]] with TH32CS_SNAPTHREAD).
lptePointer to a [[Headers, DLLs and Functions#THREADENTRY32|THREADENTRY32]] structure. You must initialize lpte.dwSize to sizeof(THREADENTRY32) before calling.
Return :
  • Returns nonzero (TRUE) if successful (i.e., a thread entry is found).
  • Returns 0 (FALSE) if the function fails or no threads are found. Use GetLastError() to get more info on failure.

Example :

THREADENTRY32 te;
te.dwSize = sizeof(THREADENTRY32);
 
HANDLE hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPTHREAD, 0);
if (hSnapshot == INVALID_HANDLE_VALUE) {
    // handle error
}
 
if (Thread32First(hSnapshot, &te)) {
    do {
        printf("Thread ID: %lu, Owner PID: %lu\n", te.th32ThreadID, te.th32OwnerProcessID);
    } while (Thread32Next(hSnapshot, &te));
}
CloseHandle(hSnapshot);
CONTEXT

The CONTEXT structure is defined in the Windows API and is used to represent the complete CPU state of a thread. You use it with GetThreadContext() and to inspect or modify a thread’s execution.

Signature :

typedef struct _CONTEXT {
  DWORD64 P1Home;
  DWORD64 P2Home;
  DWORD64 P3Home;
  DWORD64 P4Home;
  DWORD64 P5Home;
  DWORD64 P6Home;
 
  DWORD ContextFlags; // Must be set before using GetThreadContext or SetThreadContext
 
  DWORD MxCsr;
  WORD  SegCs;
  WORD  SegDs;
  WORD  SegEs;
  WORD  SegFs;
  WORD  SegGs;
  WORD  SegSs;
  DWORD EFlags;
 
  // General Purpose Registers
  DWORD64 Rax;
  DWORD64 Rcx;
  DWORD64 Rdx;
  DWORD64 Rbx;
  DWORD64 Rsp;
  DWORD64 Rbp;
  DWORD64 Rsi;
  DWORD64 Rdi;
  DWORD64 R8;
  DWORD64 R9;
  DWORD64 R10;
  DWORD64 R11;
  DWORD64 R12;
  DWORD64 R13;
  DWORD64 R14;
  DWORD64 R15;
 
  // Control Registers
  DWORD64 Rip;
 
  // Floating Point / Debug / Vector registers (omitted here for brevity)
 
  // ... (there’s more: XMM registers, debug registers, etc.)
} CONTEXT, *PCONTEXT;
MemberDescription
ContextFlagsDetermines which parts are valid/readable
RipInstruction pointer (where code will execute)
RspStack pointer
RbpBase pointer
Rax to R15General-purpose registers (arguments, temps)
EFlagsCPU flags (like zero, carry, overflow, etc.)
FlagIncludes
CONTEXT_CONTROLRIP, RSP, CS, SS, EFlags
CONTEXT_INTEGERGeneral-purpose registers (RAX, RBX, etc.)
CONTEXT_FULLCombines CONTROL and INTEGER
CONTEXT_ALLEvery possible register (including FP/XMM)

Example :

CONTEXT ctx;
ctx.ContextFlags = CONTEXT_FULL;
 
HANDLE thread = OpenThread(THREAD_ALL_ACCESS, FALSE, threadId);
SuspendThread(thread);
GetThreadContext(thread, &ctx);     // retrieve thread registers
ctx.Rip = (DWORD_PTR)remoteBuffer;  // change next instruction to shellcode
SetThreadContext(thread, &ctx);     // apply changes
ResumeThread(thread);
GetThreadContext

The GetThreadContext() function retrieves the context (CPU register values) of a specific thread. It’s essential when you want to inspect or modify where a thread is or what it’s doing, especially useful in process/thread injection, debugging, and hooking.

Signature :

BOOL GetThreadContext(
  HANDLE    hThread,        // handle to the target thread
  LPCONTEXT lpContext        // pointer to CONTEXT structure
);
ParameterDescription
hThreadHandle to the thread (opened with THREAD_GET_CONTEXT or THREAD_ALL_ACCESS)
lpContextPointer to a [[Headers, DLLs and Functions#CONTEXT|CONTEXT]] structure. You must set ContextFlags before the call to indicate what parts of the context you’re interested in.
Return :
  • Returns TRUE on success
  • Returns FALSE on failure — use GetLastError() to get details

NOTE

Before calling GetThreadContext, you must set:

ctx.ContextFlags = CONTEXT_FULL; // or another appropriate flag

If you don’t set ContextFlags, the function may fail or return incomplete data.

Example:

CONTEXT ctx;
ctx.ContextFlags = CONTEXT_FULL;
 
SuspendThread(hThread);              // pause the thread
if (GetThreadContext(hThread, &ctx)) {
    printf("Current RIP: %llx\n", ctx.Rip); // print instruction pointer
    ctx.Rip = (DWORD_PTR)remoteShellcode;   // redirect to our shellcode
    SetThreadContext(hThread, &ctx);        // update registers
}
ResumeThread(hThread);               // resume thread execution
SetThreadContext

SetThreadContext() modifies the register values (context) of a specified thread. It’s commonly used in process/thread injection, especially to redirect execution flow (e.g., to shellcode).

Signature :

BOOL SetThreadContext(
  HANDLE       hThread,
  const CONTEXT *lpContext
);
ParameterDescription
hThreadHandle to the thread (must be suspended first!)
lpContextPointer to a CONTEXT structure containing the new register values. You must set the ContextFlags field to indicate which parts you’re modifying.

Example :

CONTEXT ctx;
ctx.ContextFlags = CONTEXT_FULL;
 
SuspendThread(hThread);               // pause the thread
GetThreadContext(hThread, &ctx);      // get current register state
 
ctx.Rip = (DWORD_PTR)remoteShellcode; // set new instruction pointer (x64)
SetThreadContext(hThread, &ctx);      // update thread to start executing shellcode
 
ResumeThread(hThread);                // resume the hijacked thread

Requirements

RequirementValue
Thread must beSuspended
Access rights neededTHREAD_SET_CONTEXT or THREAD_ALL_ACCESS
ContextFlagsMust be set before the call (CONTEXT_FULL, etc.)
OpenThread

The OpenThread function allows you to obtain a handle to an existing thread, given its Thread ID and desired access rights.

Signature

HANDLE OpenThread(
  DWORD dwDesiredAccess,
  BOOL bInheritHandle,
  DWORD dwThreadId
);
ParameterTypeDescription
dwDesiredAccessDWORDSpecifies the access rights (e.g., THREAD_ALL_ACCESS, THREAD_SUSPEND_RESUME, etc.)
bInheritHandleBOOLWhether the handle can be inherited by child processes (TRUE or FALSE)
dwThreadIdDWORDThe thread ID (not the handle) of the thread you want to open
Return
  • Returns a HANDLE to the thread if successful.
  • Returns NULL on failure – use GetLastError() for more info.

Example

DWORD tid = 1234; // existing thread ID
HANDLE hThread = OpenThread(THREAD_SUSPEND_RESUME, FALSE, tid);
 
if (hThread != NULL) {
    SuspendThread(hThread);
    CloseHandle(hThread);
}
Thread32Next

Thread32Next is used to enumerate threads in a system snapshot, usually after calling Thread32First. It’s often used to iterate through all threads in the system or in a specific process.


🔹 Function Signature

BOOL Thread32Next(
  HANDLE hSnapshot,
  LPTHREADENTRY32 lpte
);

🔸 Parameters

ParameterTypeDescription
hSnapshotHANDLEHandle to a snapshot created by CreateToolhelp32Snapshot, with TH32CS_SNAPTHREAD flag.
lpteLPTHREADENTRY32Pointer to a THREADENTRY32 structure that receives info about the next thread.

🔹 Return Value

  • Returns TRUE if successful (i.e., more threads exist).

  • Returns FALSE when there are no more threads or an error occurs. Use GetLastError() to check.


🔸 Usage Pattern

You typically use it like this:

THREADENTRY32 te32;
te32.dwSize = sizeof(THREADENTRY32);
 
HANDLE hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPTHREAD, 0);
 
if (Thread32First(hSnapshot, &te32)) {
    do {
        printf("Thread ID: %u in process %u\n", te32.th32ThreadID, te32.th32OwnerProcessID);
    } while (Thread32Next(hSnapshot, &te32));
}
 
CloseHandle(hSnapshot);

📌 Required Header

#include <tlhelp32.h>
#include <windows.h>

📦 Required Library

Linked automatically with Kernel32.lib.


🧠 One-Line Summary

Thread32Next continues enumerating threads from a system snapshot, helping you loop through all active threads on the system or in a specific process.

Let me know if you also want to filter threads by process or use it for process injection scenarios.

Footnotes

  1. Lexicographically means dictionary order, just like how words are sorted in a dictionary.
    In computer terms, it means comparing strings character by character using their ASCII (or Unicode) values.