设为首页 加入收藏

TOP

《windows核心编程系列》谈谈使用远程线程来注入DLL(一)
2014-11-24 00:12:01 来源: 作者: 【 】 浏览:51
Tags:windows 核心 编程 系列 谈谈 使用 远程 线程 注入 DLL

windows内的各个进程有各自的地址空间。它们相互独立互不干扰保证了系统的安全性。但是windows也为调试器或是其他工具设计了一些函数,这些函数可以让一个进程对另一个进程进行操作。虽然他们是为调试器设计的,但是任何应用程序都可以调用它们 。接下来我们来谈谈使用远程线程来注入DLL。

从根本上说,DLL注入就是将某一DLL注入到某一进程的地址空间。该进程中的一个线程调用LoadLibrary来载入想要注入的DLL。由于我们不能直接控制其他进程内的线程,因此我们必须在其他进程内创建一个我们自己的线程。我们可以对新创建的线程加以控制,让他调用LoadLibrary来载入DLL。windows提供了一个函数,可以让我们在其他进程内创建一个线程:

在其他进程内创建的线程被称为:远程线程,该进程被称为远程进程。

HANDLE WINAPI CreateRemoteThread(

__in HANDLE hProcess,

__in LPSECURITY_ATTRIBUTES lpThreadAttributes,

__in SIZE_T dwStackSize,

__in LPTHREAD_START_ROUTINE lpStartAddress,

__in LPVOID lpParameter,

__in DWORD dwCreationFlags,

__out LPDWORD lpThreadId

);

很容易吧。该函数除了第一个参数hProcess,标识要创建的线程所属的进程外,其他参数与CreateThread的参数完全相同。

参数lpstartAddress是线程函数的地址。由于是在远程进程创建的,所以该函数一定必须在远程进程的地址空间内。

现在知道了如何在另一个进程创建一个线程,那么我们如何让该线程载入我们的DLL呢?

先别急着让线程调用LoadLibrary载入DLL,现在要考虑的是如何让线程运行起来,即为线程选择线程函数。因为线程是在其他进程内运行的,所以该线程函数必须符合以下条件:

1:该函数符合线程函数的原型,

2:存在于远程线程地址空间内。

仔细分析下,远程线程的任务只有一个。就是调用LoadLibray加载DLL。

既然如此可不可以让LoadLibrary直接作为线程函数呢?

先看第一个条件:函数签名是否相同。你还别说,除了参数类型有点不一样外,其他一摸一样的。由于参数类型可以通过强转实现,所以第一个条件是满足的。

再看第二个条件:该函数是否在远程进程地址空间内。用屁股想一下我们都知道肯定在。另外他们都有相同的函数调用约定,也就是说他们的参数传递是从右到左压栈的,有子程序平衡堆栈。OK,太棒了。使用LoadLibrary作为线程函数真的是太方便了 。

难道是微软故意为我们这样设计的?无从知晓。但在这里要谢谢发现这一技巧的牛人。

查看MSDN可以发现LoadLibrary并不是一个API,它其实是一个宏。

在WinBase.h可以发现这样一句话:

#ifdef UNICODE

#define LoadLibrary LoadLibraryW

#else

#define LoadLibrary LoadLibraryA

#endif

明白了吗?实际上有两个Load*函数,他们的唯一区别就是参数类型不同。如果DLL文件名是以ANSI形式保存的,我们就必须调用LoadLibraryA,如果是UNICODE形式保存的我们就必须调用LoadLibraryW。

接下来我们要做的事情就简单了,只需要调用CreateThread函数,传给标识线程函数的参数LoadLibraryA或是LoadLibraryW。然后将我们要远程进程加载的DLL的路径名的地址作为参数传给它。哈哈,很兴奋吧!一切都是那么的顺!

不要高兴的太早。你就没发现哪有不对的地方吗?传给线程函数的参数是DLL路径名的地址。但是该地址是在我们进城内的。如果远程进程引用此地址的数据,很可能会导致访问违规,远程进程被终止。怎么样很严重吧。但这也给我们一个破坏其他进程的思路。哈哈。自己发挥吧!

为了解决这个问题,我们应该将该字符串放到远程地址的地址空间去。有没有相应的函数呢?当然有!

首先应该在远程进程的地址空间分配一块儿内存。如何做呢!或许你很熟悉VirtualAlloc,但是他没有这个功能。他兄弟VirtualAllocEx可以解决这个问题。看原型:

LPVOID WINAPI VirtualAllocEx(

__in HANDLE hProcess,

__in_opt LPVOID lpAddress,

__in SIZE_T dwSize,

__in DWORD flAllocationType,

__in DWORD flProtect

);

hProcess应该知道是干嘛的吧。他就是标识你要想在那个进程的地址空间申请内存的进程句柄。其他参数跟VirtualAlloc完全相同。此处不再介绍。

当然知道如何申请还有知道如何释放!看他搭档:VirtualFreeEx

BOOL WINAPI VirtualFreeEx(

__in HANDLE hProcess,

__in LPVOID lpAddress,

__in SIZE_T dwSize,

__in DWORD dwFreeType

);

与VirtualFree的区别这只是多一个进程句柄。

现在申请空间的任务完成了,要怎么样将本进程的数据复制到另外一个进程呢?可以使用ReadProcessMemory和WriteProcessMemory

BOOL WINAPI ReadProcessMemory(

__in HANDLE hProcess,

__in LPCVOID lpBaseAddress,

__out LPVOID lpBuffer,

__in SIZE_T nSize,

__out SIZE_T *lpNumberOfBytesRead

);

BOOL WINAPI WriteProcessMemory(

__in HANDLE hProcess,

__in LPVOID lpBaseAddress,

__in LPCVOID lpBuffer,

首页 上一页 1 2 下一页 尾页 1/2/2
】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
分享到: 
上一篇《windows核心编程系列》谈谈wind.. 下一篇《Windows核心编程系列》谈谈DLL..

评论

帐  号: 密码: (新用户注册)
验 证 码:
表  情:
内  容: