通过VirtualAllocEx在目标进程内存空间申请所需要的空间,然后通过WriteProcessMemory将指令代码直接写进去,就可以实现对目标进程的控制或修改.此方法比dll注入更需要汇编能力.具体例子代码如下(实现的功能很简单,就是显示Hello):
#include <windows.h>
#include <stdio.h>

BYTE InsNew[5] = { 0xE9, 0x00, 0x00, 0x00, 0x00 }; //(5) jmp 0; -- Offset is NULL now.
BYTE InsOld[5] = { 0xB9, 0x08, 0x00, 0x00, 0x00 }; //(5) mov ecx, 0x08;
BYTE Ins[] = {
0x60, //(1) pushad;

0x6A, 0x40, //(2) push 0x40;
0xE8, 0x05, 0x00, 0x00, 0x00, //(5) call offset 0x05; == push offset "Test";
0x54, 0x65, 0x73, 0x74, 0x00, //(5) db "Test", 0;
0xE8, 0x06, 0x00, 0x00, 0x00, //(5) call offset 0x06; == push offset "Hello";
0x48, 0x65, 0x6C, 0x6C, 0x6F, 0x00, //(6) db "Hello", 0;
0x6A, 0x00, //(2) push 0;
0xE8, 0x00, 0x00, 0x00, 0x00, //(5) call offset 0x0; -- Offset is NULL now.

0x61, //(1) popad;
0xB9, 0x08, 0x00, 0x00, 0x00 //(5) mov ecx, 0x08;
};

VOID * buf = NULL;

LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
PAINTSTRUCT ps;
RECT rect;

switch(message)
{
case WM_CREATE:
//PlaySound("online.wav", NULL, SND_FILENAME|SND_ASYNC); //WINMM.LIB
break;

case WM_PAINT:
BeginPaint(hwnd, &ps);
GetClientRect(hwnd, &rect);
DrawText(ps.hdc, TEXT("Hello, Windows XP!"), -1, &rect, DT_SINGLELINE|DT_CENTER|DT_VCENTER);
EndPaint(hwnd, &ps);
break;

case WM_DESTROY:
PostQuitMessage(0);
break;
}

return DefWindowProc(hwnd, message, wParam, lParam);
}

int APIENTRY WinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPSTR lpCmdLine,
int nCmdShow)
{
static TCHAR szClassName[] = "ProcMemAlteration";
HWND hWnd;
MSG msg;
WNDCLASS wndclass;

wndclass.style = CS_HREDRAW|CS_VREDRAW;
wndclass.lpfnWndProc = WndProc;
wndclass.cbClsExtra = 0;
wndclass.cbWndExtra = 0;
wndclass.hInstance = hInstance;
wndclass.hIcon = LoadIcon(NULL, IDI_ASTERISK);
wndclass.hCursor = LoadCursor(NULL, IDC_ARROW);
wndclass.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
wndclass.lpszMenuName = NULL;
wndclass.lpszClassName = szClassName;

ATOM atom = RegisterClass(&wndclass);
if(!atom)
{
MessageBox(NULL, "This program requires Windows NT!", "Error", MB_ICONERROR);
return 1;
}

hWnd = CreateWindow(szClassName, // window class name
"Process Memory Alteration", // window caption
WS_OVERLAPPEDWINDOW, // window style
CW_USEDEFAULT, // initial x position
CW_USEDEFAULT, // initial y position
CW_USEDEFAULT, // initial x size
CW_USEDEFAULT, // initial y size
NULL, // parent window handle
NULL, // window menu handle
hInstance, // program instance handle
NULL); // creation parameters

ShowWindow(hWnd, nCmdShow);
UpdateWindow(hWnd);

//Alter instruction
//--------------------------------------------------
HWND hObjWnd = NULL;
DWORD dwObjProcessId = 0;
HANDLE hObjProcess = 0;

hObjWnd = ::FindWindow("Thunder", "Thunder");
if(hObjWnd)
{
GetWindowThreadProcessId(hObjWnd, &dwObjProcessId);
hObjProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, dwObjProcessId);
if(hObjProcess)
{
FARPROC pMessageBoxA = GetProcAddress(GetModuleHandle("user32.dll"), "MessageBoxA");
if(pMessageBoxA)
{
buf = VirtualAllocEx(hObjProcess, NULL, sizeof(Ins)+sizeof(InsNew), MEM_COMMIT, PAGE_READWRITE);
if(buf)
{
long Offset = (DWORD)pMessageBoxA-(DWORD)buf-31;
memcpy(Ins+27, &Offset, 4);

SIZE_T nSize = 0;
WriteProcessMemory(hObjProcess, (void *)buf, Ins, sizeof(Ins), &nSize);
Offset = -(long)((DWORD)buf+sizeof(Ins)+sizeof(InsNew)-0x466E90);
memcpy(InsNew+1, &Offset, 4);
WriteProcessMemory(hObjProcess, (void *)((DWORD)buf+sizeof(Ins)), InsNew, sizeof(InsNew), &nSize);
Offset = (DWORD)buf-0x466E8B-sizeof(InsNew);
memcpy(InsNew+1, &Offset, 4);
BYTE InsBuf[5] = {0};
ReadProcessMemory(hObjProcess, (void *)0x466E8B, InsBuf, sizeof(InsBuf), &nSize);
if(memcmp(InsBuf, InsOld, 5)==0)
WriteProcessMemory(hObjProcess, (void *)0x466E8B, InsNew, sizeof(InsNew), &nSize);
}
}

CloseHandle(hObjProcess);
}
}
//--------------------------------------------------

while(GetMessage(&msg, NULL, 0, 0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}

//Restore instruction
//--------------------------------------------------
if(hObjWnd)
{
GetWindowThreadProcessId(hObjWnd, &dwObjProcessId);
hObjProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, dwObjProcessId);
if(hObjProcess)
{
SIZE_T nSize = 0;
BYTE InsBuf[5] = {0};
ReadProcessMemory(hObjProcess, (void *)0x466E8B, InsBuf, sizeof(InsBuf), &nSize);

if(memcmp(InsBuf, InsNew, 5)==0)
WriteProcessMemory(hObjProcess, (void *)0x466E8B, InsOld, sizeof(InsOld), &nSize);

if(buf)
VirtualFreeEx(hObjProcess, buf, 0, MEM_DECOMMIT);

CloseHandle(hObjProcess);
}
}
//--------------------------------------------------

return 0;
}
具体过程看源代码:/Files/God4/ProcMem.rar
#include <windows.h>
#include <stdio.h>
BYTE InsNew[5] = { 0xE9, 0x00, 0x00, 0x00, 0x00 }; //(5) jmp 0; -- Offset is NULL now.
BYTE InsOld[5] = { 0xB9, 0x08, 0x00, 0x00, 0x00 }; //(5) mov ecx, 0x08;
BYTE Ins[] = {
0x60, //(1) pushad;
0x6A, 0x40, //(2) push 0x40;
0xE8, 0x05, 0x00, 0x00, 0x00, //(5) call offset 0x05; == push offset "Test";
0x54, 0x65, 0x73, 0x74, 0x00, //(5) db "Test", 0;
0xE8, 0x06, 0x00, 0x00, 0x00, //(5) call offset 0x06; == push offset "Hello";
0x48, 0x65, 0x6C, 0x6C, 0x6F, 0x00, //(6) db "Hello", 0;
0x6A, 0x00, //(2) push 0;
0xE8, 0x00, 0x00, 0x00, 0x00, //(5) call offset 0x0; -- Offset is NULL now.
0x61, //(1) popad;
0xB9, 0x08, 0x00, 0x00, 0x00 //(5) mov ecx, 0x08;
};
VOID * buf = NULL;
LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
PAINTSTRUCT ps;
RECT rect;
switch(message)
{
case WM_CREATE:
//PlaySound("online.wav", NULL, SND_FILENAME|SND_ASYNC); //WINMM.LIB
break;
case WM_PAINT:
BeginPaint(hwnd, &ps);
GetClientRect(hwnd, &rect);
DrawText(ps.hdc, TEXT("Hello, Windows XP!"), -1, &rect, DT_SINGLELINE|DT_CENTER|DT_VCENTER);
EndPaint(hwnd, &ps);
break;
case WM_DESTROY:
PostQuitMessage(0);
break;
}
return DefWindowProc(hwnd, message, wParam, lParam);
}
int APIENTRY WinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPSTR lpCmdLine,
int nCmdShow)
{
static TCHAR szClassName[] = "ProcMemAlteration";
HWND hWnd;
MSG msg;
WNDCLASS wndclass;
wndclass.style = CS_HREDRAW|CS_VREDRAW;
wndclass.lpfnWndProc = WndProc;
wndclass.cbClsExtra = 0;
wndclass.cbWndExtra = 0;
wndclass.hInstance = hInstance;
wndclass.hIcon = LoadIcon(NULL, IDI_ASTERISK);
wndclass.hCursor = LoadCursor(NULL, IDC_ARROW);
wndclass.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
wndclass.lpszMenuName = NULL;
wndclass.lpszClassName = szClassName;
ATOM atom = RegisterClass(&wndclass);
if(!atom)
{
MessageBox(NULL, "This program requires Windows NT!", "Error", MB_ICONERROR);
return 1;
}
hWnd = CreateWindow(szClassName, // window class name
"Process Memory Alteration", // window caption
WS_OVERLAPPEDWINDOW, // window style
CW_USEDEFAULT, // initial x position
CW_USEDEFAULT, // initial y position
CW_USEDEFAULT, // initial x size
CW_USEDEFAULT, // initial y size
NULL, // parent window handle
NULL, // window menu handle
hInstance, // program instance handle
NULL); // creation parameters
ShowWindow(hWnd, nCmdShow);
UpdateWindow(hWnd);
//Alter instruction
//--------------------------------------------------
HWND hObjWnd = NULL;
DWORD dwObjProcessId = 0;
HANDLE hObjProcess = 0;
hObjWnd = ::FindWindow("Thunder", "Thunder");
if(hObjWnd)
{
GetWindowThreadProcessId(hObjWnd, &dwObjProcessId);
hObjProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, dwObjProcessId);
if(hObjProcess)
{
FARPROC pMessageBoxA = GetProcAddress(GetModuleHandle("user32.dll"), "MessageBoxA");
if(pMessageBoxA)
{
buf = VirtualAllocEx(hObjProcess, NULL, sizeof(Ins)+sizeof(InsNew), MEM_COMMIT, PAGE_READWRITE);
if(buf)
{
long Offset = (DWORD)pMessageBoxA-(DWORD)buf-31;
memcpy(Ins+27, &Offset, 4);
SIZE_T nSize = 0;
WriteProcessMemory(hObjProcess, (void *)buf, Ins, sizeof(Ins), &nSize);
Offset = -(long)((DWORD)buf+sizeof(Ins)+sizeof(InsNew)-0x466E90);
memcpy(InsNew+1, &Offset, 4);
WriteProcessMemory(hObjProcess, (void *)((DWORD)buf+sizeof(Ins)), InsNew, sizeof(InsNew), &nSize);
Offset = (DWORD)buf-0x466E8B-sizeof(InsNew);
memcpy(InsNew+1, &Offset, 4);
BYTE InsBuf[5] = {0};
ReadProcessMemory(hObjProcess, (void *)0x466E8B, InsBuf, sizeof(InsBuf), &nSize);
if(memcmp(InsBuf, InsOld, 5)==0)
WriteProcessMemory(hObjProcess, (void *)0x466E8B, InsNew, sizeof(InsNew), &nSize);
}
}
CloseHandle(hObjProcess);
}
}
//--------------------------------------------------
while(GetMessage(&msg, NULL, 0, 0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
//Restore instruction
//--------------------------------------------------
if(hObjWnd)
{
GetWindowThreadProcessId(hObjWnd, &dwObjProcessId);
hObjProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, dwObjProcessId);
if(hObjProcess)
{
SIZE_T nSize = 0;
BYTE InsBuf[5] = {0};
ReadProcessMemory(hObjProcess, (void *)0x466E8B, InsBuf, sizeof(InsBuf), &nSize);
if(memcmp(InsBuf, InsNew, 5)==0)
WriteProcessMemory(hObjProcess, (void *)0x466E8B, InsOld, sizeof(InsOld), &nSize);
if(buf)
VirtualFreeEx(hObjProcess, buf, 0, MEM_DECOMMIT);
CloseHandle(hObjProcess);
}
}
//--------------------------------------------------
return 0;
}
具体过程看源代码:/Files/God4/ProcMem.rar
一天一点进步

BYTE InsNew[
浙公网安备 33010602011771号