上帝保佑 - God4

God Bless

  :: 首页 :: 新随笔 :: 联系 :: 订阅 :: 管理 ::

上一篇写的是通过钩子将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, 
00);

    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= 0xE90x000x000x000x00 };
BYTE InsOld[
5= 0xB90x080x000x000x00 };

InsOld是修改前的指令,InsNew是修改后的指令.0xE9是跳转,修改前将后面的4个0x00修改为要跳转的偏移,也就是我们自己代码的位置。

修改成功后,当目标进程运行到0x466E8B地址时,会执行注入代码,显示对话框“This is my code!”。

具体过程看源代码:
/Files/God4/Remote.rar
posted on 2007-11-17 21:44  God4  阅读(799)  评论(0)    收藏  举报