上一篇写的是通过钩子将DLL注入到别的进程空间,并截获鼠标消息的例子.这一篇是通过远程线程注入,即利用CreateRemoteThread函数使目标线程加载DLL,并通过WriteProcessMemory修改目标进程指令代码,以控制目标进程执行过程,运行我们自己的代码.
首先是我们自己的DLL代码,里面有我们自己的函数:
__declspec(naked) Proc(void)
{
DWORD RetAddr;
_asm
{
pushad;
}
//MessageBox(NULL, "This is my code!", "Hello", MB_OK);
if(IsWindow(hWnd))
SendMessage(hWnd, UWM_INJECTANTMSG, 0, 0);
RetAddr = 0x466E90;
_asm
{
popad;
mov ecx, 8;
jmp [RetAddr];
}
}注意该函数的定义是__declspec(naked),以使得编译的时候不会产生压栈出栈的指令,而由我们自己来写,这样,可以避免修改目标进程代码后,跳转到次处运行并返回时产生错误.
然后说的是EXE代码.第一步,在目标进程中申请内存空间存放DLL路径,然后调用CreateRemoteThread使目标进程加载DLL:
//申请空间
void * buf = VirtualAllocEx(hObjProcess, NULL,
sizeof(DllPath), MEM_COMMIT, PAGE_READWRITE);
if(buf)
{
SIZE_T nSize;
WriteProcessMemory(hObjProcess, (void *)buf,
DllPath, sizeof(DllPath), &nSize);
FARPROC pLoadLibraryA = GetProcAddress(
GetModuleHandle("kernel32.dll"), "LoadLibraryA");
if(pLoadLibraryA)
{
HANDLE hThread = CreateRemoteThread(hObjProcess, NULL, 0,
(LPTHREAD_START_ROUTINE)pLoadLibraryA, buf, 0, NULL);
if(hThread)
WaitForSingleObject(hThread, INFINITE);
}
VirtualFreeEx(hObjProcess, buf, 0, MEM_DECOMMIT);
}
CloseHandle(hObjProcess);第二步,通过WriteProcessMemory修改目标进程指令代码,使其在运行到目的地址时来执行我们自己的代码:
//Alter instruction
//----------------------------------
DWORD * pProcAddr = (DWORD *)GetProcAddress(Remote_Dll, "ProcAddr");
long Offset = *pProcAddr-0x466E8B-5;
memcpy(InsNew+1, &Offset, 5-1);
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);
//----------------------------------需要说明的是,这里的修改必须与目标进程配套,先是要反汇编目标程序,找到要修改的地址才能修改正确,否则会发生错误.其中:
BYTE InsNew[5] = { 0xE9, 0x00, 0x00, 0x00, 0x00 };
BYTE InsOld[5] = { 0xB9, 0x08, 0x00, 0x00, 0x00 };InsOld是修改前的指令,InsNew是修改后的指令.0xE9是跳转,修改前将后面的4个0x00修改为要跳转的偏移,也就是我们自己代码的位置。
修改成功后,当目标进程运行到0x466E8B地址时,会执行注入代码,显示对话框“This is my code!”。
具体过程看源代码:/Files/God4/Remote.rar
一天一点进步



浙公网安备 33010602011771号