Windows核心编程Dll注入之远程线程
2014-06-02 22:54
357 查看
为了让某个进程运行我们的Dll,可以使用远程线程来达到目的。
为了达到这个目的,我们必须让该进程调用我们的Dll。怎样才能让目标进程来调用我们的DLL呢?首先不可能是隐式的,因为隐式调用Dll的名字必须要在进程的导入表中出现,修改程序的导入表将非常麻烦(有空偶再研究一下)。最直接的方式就是显式的调用LoadLibrary函数来调用我们的Dll。好主意!但是我们怎么样才能让目标进程去执行该动作呢,也就是去调用LoadLibrary函数呢?我们不可能去修改源代码来增加一个线程来执行吧。幸好,windows提供了一个API——CreateRemoteThread,他可以让目标进程创建一个线程!太神奇了!也就是说只要获取到了目标进程的进程句柄(这个容易实现)就可以给他创建一个线程。Good!然后在线程函数中执行调用我们Dll的代码,像这样
CreateRemoteThread(hRemoteProcess, NULL, 0, LoadLibraryW, "C:\\MyDll.dll", 0, NULL) ;慢着,有两个小问题。首先,目标进程真的会执行LoadLibraryW吗?不会!!!在编译和链接一个程序的时候,生成的二进制文件中会包含一个导入段,这个导入段由一些列转换函数(thunk)构成,这些转换函数用来跳转到导入的函数。因此,在代码调用诸如LoadLibraryW之类的函数时,链接器会生成一个调用,来调用我们模块中导入段中的一个转换函数,这个转换函数然后会跳到实际的函数,所以调用CreateRemoteThread时线程函数的地址是我们模块导入段的LoadLibraryW转换函数的地址,我们必须通过下面的方式来得到LoadLibraryW的地址。
GetProcAddress(GetModuleHandle(_T("Kernel32")), "LoadLibraryW")。
因为每个程序到需要调用Kernel32.dll,所以这个方法是可以的。还一个问题是你给线程函数的参数传入"C:\\MyDll.dll"就行啦?当然不行!"C:\\MyDll.dll"是这个进程中的字符串地址,而不是目标进程中的地址!我们必须传递目标进程中该字符串的地址。这两个函数VirtualAllocEx,WriteProcessMemory可以解决问题,一个用来在目标进程中分配地址,一个用来给地址赋值,正好,呵呵。然后调用CreateRemoteThread就OK了,下面给出完整代码:
为了达到这个目的,我们必须让该进程调用我们的Dll。怎样才能让目标进程来调用我们的DLL呢?首先不可能是隐式的,因为隐式调用Dll的名字必须要在进程的导入表中出现,修改程序的导入表将非常麻烦(有空偶再研究一下)。最直接的方式就是显式的调用LoadLibrary函数来调用我们的Dll。好主意!但是我们怎么样才能让目标进程去执行该动作呢,也就是去调用LoadLibrary函数呢?我们不可能去修改源代码来增加一个线程来执行吧。幸好,windows提供了一个API——CreateRemoteThread,他可以让目标进程创建一个线程!太神奇了!也就是说只要获取到了目标进程的进程句柄(这个容易实现)就可以给他创建一个线程。Good!然后在线程函数中执行调用我们Dll的代码,像这样
CreateRemoteThread(hRemoteProcess, NULL, 0, LoadLibraryW, "C:\\MyDll.dll", 0, NULL) ;慢着,有两个小问题。首先,目标进程真的会执行LoadLibraryW吗?不会!!!在编译和链接一个程序的时候,生成的二进制文件中会包含一个导入段,这个导入段由一些列转换函数(thunk)构成,这些转换函数用来跳转到导入的函数。因此,在代码调用诸如LoadLibraryW之类的函数时,链接器会生成一个调用,来调用我们模块中导入段中的一个转换函数,这个转换函数然后会跳到实际的函数,所以调用CreateRemoteThread时线程函数的地址是我们模块导入段的LoadLibraryW转换函数的地址,我们必须通过下面的方式来得到LoadLibraryW的地址。
GetProcAddress(GetModuleHandle(_T("Kernel32")), "LoadLibraryW")。
因为每个程序到需要调用Kernel32.dll,所以这个方法是可以的。还一个问题是你给线程函数的参数传入"C:\\MyDll.dll"就行啦?当然不行!"C:\\MyDll.dll"是这个进程中的字符串地址,而不是目标进程中的地址!我们必须传递目标进程中该字符串的地址。这两个函数VirtualAllocEx,WriteProcessMemory可以解决问题,一个用来在目标进程中分配地址,一个用来给地址赋值,正好,呵呵。然后调用CreateRemoteThread就OK了,下面给出完整代码:
#include "stdafx.h" #include <Windows.h> int _tmain(int argc, _TCHAR* argv[]) { HWND hwndTarget = FindWindow(NULL, _T("TestDllInj")) ; if(hwndTarget == NULL){ printf("could not find the window!!!\n") ; return 1 ; } DWORD dwTargetProId ; GetWindowThreadProcessId(hwndTarget, &dwTargetProId) ; HANDLE hRemoteProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, dwTargetProId) ; PVOID pMemRomote = VirtualAllocEx(hRemoteProcess, 0, 1024, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE) ; if(WriteProcessMemory(hRemoteProcess, pMemRomote, _T("C:\\MyDll.dll"), 1024, NULL) == NULL){ printf("can not write to mem of the remote process!!!\n") ; return 3; } PTHREAD_START_ROUTINE pfnAddr = (PTHREAD_START_ROUTINE)GetProcAddress(GetModuleHandle(_T("Kernel32")), "LoadLibraryW") ; HANDLE thrd = CreateRemoteThread(hRemoteProcess, NULL, 0, pfnAddr, pMemRomote, 0, NULL) ; if(thrd == NULL){ printf("create remote thread failed!!!\n") ; } else{ printf("Inject dll sucessed!!!\n") ; } return 0; }
相关文章推荐
- 【windows核心编程】远程线程DLL注入
- 远程线程模板(DLL注入)
- 远程线程dll注入
- delphi远程线程插入(DLL注入)
- 拦截API-通过远程线程dll注入目标进程
- 远程线程插入(DLL注入)
- Dll注入:X86/X64 远程线程CreateRemoteThread 注入
- 创建远程线程实现DLL注入
- 实战DELPHI:远程线程插入(DLL注入)
- Dll注入技术之远程线程注入
- 远程线程DLL注入
- 实战DELPHI:远程线程插入(DLL注入)
- PowerShell 2.0远程管理之交互式远程线程
- 最简单的远程线程
- 使用远程线程制作不死进程
- 进程注入DLL实现(APC和远程线程创建)
- 利用远程线程实现dll的注入
- WinAPI【远程注入】 远线程直接代码注入 Delphi实例
- 远程线程嵌入技术
- 利用远程线程将代码注入到目标进程中执行