两种DLL注入方式

转自:http://www.cnblogs.com/cfas/p/5121452.html(侵删)

后卫大师教你进程注入
首先提一下,由于文章完全是我手写,所以打不了太多,请包含,由于我已经提供了源代码,所以我在这里详细讲一下理论,至于想看代码的下载代码就可以了。代码中关于注入的部分做了详细的注释。MFC界面部分的注释没有写,(毕竟太肤浅了。)
     好,言归正传。
     所谓DLL注入,既把一个DLL文件放到目标进程中。
     下面介绍2种注入方式:
     1.远程线程注入。
     2.利用hook注入。(可以过卡巴斯基)
由于本文篇幅限制,不写如何编写DLL。
一.首先讲一下远程线程注入的方法:
1.假设我们已经写好了一个DLL文件。
2.设置本进程权限为debug权限,既调试权限,可以打开其他进程。代码如下:


BOOL SetToken(void)
{
 HANDLE hToken;
 TOKEN_PRIVILEGES Privileges;
 LUID luid;
 OpenProcessToken(GetCurrentProcess(),TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY | TOKEN_READ,&hToken);
 Privileges.PrivilegeCount=1;
 LookupPrivilegeValue(NULL,SE_DEBUG_NAME,&luid);
 Privileges.Privileges[0].Luid=luid;
 Privileges.Privileges[0].Attributes=SE_PRIVILEGE_ENABLED;
 if(!AdjustTokenPrivileges(hToken,FALSE,&Privileges,NULL,NULL,NULL)!=0)
  return FALSE;
 CloseHandle(hToken);
 return (GetLastError() == ERROR_SUCCESS);
}
3.获得目标进程的句柄。
OpenProcess(权限类型,是否可被继承,进程ID)功能:返回目标进程句柄.
4.在远程进程中分配内存,用来存储,我们要注入的dll的路径
VirtualAllocEx(hProcess, NULL, cb, MEM_COMMIT, PAGE_READWRITE);


//VirtualAllocEx()函数功能:为制定的进程分配虚拟地址
//参1:要分配的进程句柄
//参2:要分配的虚拟地址的位置,0表示,自动分配位置
//参3:分配的大小
//参4:MEM_COMMIT表示,分配物理内存或者页面内存,并且初始化内存为0
//参5:存储选项:PAGE_READWRITE表示可以在页面内存中 “读写”
//返回值:如果分配内存成功,则返回分配内存的地址,如果分配失败则返回NULL,调用GetLastError()查看错误原因


5.在远程进程中刚才分配的内存处,写入目标DLL路径:
WriteProcessMemory(hProcess, pszLibFileRemote,PVOID) pszLibFile, cb, NULL)
//WriteProcessMemory()函数功能:在制定进程中写入内存
//参1:写入进程的句柄
//参2:写入内存的起始地址,必须是已经创建的地址,比如上面用VirtualAllocEx()在进程中创建的内存地址
//参3:写入内存中的数据内容的缓存
//参4:写入数据大小
//参5:一个选项,0表示忽视
//返回值: 非0值表示成功, 返回0则表示写入错误。调用GetLastError()查看错误原因


6.获取LoadLibrary()函数地址,因为要用他来动态加载DLL,该函数在kernel32.dll文件中
PROC AdrMyDllDir=(PROC)::GetProcAddress(::GetModuleHandle(TEXT("kernel32.dll")),"LoadLibraryW");//W代表UNICODE版本,说实话,A代表多字节字符集,本人喜欢UNICODE版本


GetProcAddress()
FARPROC GetProcAddress(HMODULE hModule,LPCWSTR lpProcName); 
//功能:返回指定的DLL输出函数的函数地址
//参数1:DLL模块句柄
//参数2:DLL输出函数的函数名
这个函数的返回值,就是LoadLibraryW的地址了


7.创建远程线程,既在目标进程中创建一个线程,这里的线程跟普通的线程不同,普通线程有线程处理函数ProcThread()
CreateRemoteThread()
HANDLE CreateRemoteThread(
  HANDLE hProcess,
  LPSECURITY_ATTRIBUTES lpThreadAttributes,
  SIZE_T dwStackSize,
  LPTHREAD_START_ROUTINE lpStartAddress,
  LPVOID lpParameter,
  DWORD dwCreationFlags,
  LPDWORD lpThreadId
);
//函数功能:在制定进程中的虚拟地址中创建一个线程
//参数1:进程句柄,线程被创建在这个进程中
//参数2:安全等级,0表示默认安全等级
//参数3:创建线程的大小,0表示系统自动分配线程实际需要的大小
//参数4:线程起始地址,使用LPTHREAD_START_ROUTINE 定义的线程,并且线程是在远程进程中已经存在。
//参数5: 给线程函数传递的参数
//参数6:创建标志,如果参数是0,则线程创建后立即运行
//参数7:线程ID,如果 ID给0 ,则不返回创建线程的ID


::CreateRemoteThread(hProcess,0,0,(LPTHREAD_START_ROUTINE)AdrMyDllDir,bufRemote,0,0);
这里的AdrMyDllDir存放LoadLibraryW ,也就是说把LoadLibraryW当做线程处理函数,传入的参数bufRemote存放的是目标DLL文件的地址。




二。下面讲解一下如何用hook既钩子注入DLL文件。
首先给不懂钩子的人简单介绍一下原理:所谓hook,既钩子。hook会在应用程序接到消息之前,拦截应用程序的信息,比如鼠标键盘钩子会拦截一个应用程序的鼠标键盘信息。要做盗号木马?用WH_KEYBOARD类型的hook
1.我们要跨进程使用钩子,要把hook函数写在DLL文件中,这是微软明确规定的。也有其他方法,这里不多叙述
2.在DLL文件中 设置钩子.
这里需要调用线程ID,threadId,我们会在下面调用DLL的调用端中写入
hhookGetMsg=::SetWindowsHookEx(WH_GETMESSAGE,GetMessageHookProc,::GetModuleHandle(TEXT("dll.dll")),threadId);
//参数1:钩子类型
//参数2:钩子处理函数
//参数3:钩子所在的模块
//参数4:钩子要拦截的线程ID,如果要设置全局钩子,这里给0。
把这个SetWindowsHookEx()函数写在一个导出函数中,允许调用dll文件的程序调用
_declspec(dllexport) void SetHook(DWORD threadId)
{
 hhookGetMsg=::SetWindowsHookEx(WH_GETMESSAGE,GetMessageHookProc,::GetModuleHandle(TEXT("dll.dll")),threadId);
}
SetHook()就是本dll的导出函数
3.在钩子处理函数中写入功能,当钩子截取到WM_NULL消息的时候,注入DLL文件。由于WM_NULL消息,是个没用的消息,应用程序一般不会收到这个消息,除非我们自己发送一个这个消息,所以我们在注入DLL的时候,只要给要注入的应用程序发一个WM_NULL消息,当钩子截取到WM_NULL的时候就注入钩子,就可以了。
LRESULT CALLBACK GetMessageHookProc(int nCode,WPARAM wParam,LPARAM lParam)
{
MSG* pMsg=(MSG*)lParam;
if(WM_NULL==pMsg->message)
 ::LoadLibraryW(TEXT("D://MyDLL.dll"));
}
好了,编译DLL项目,产生DLL文件。


4.编写调用端,调用钩子
首先获取窗口句柄
HWND FindWindow(          LPCTSTR lpClassName,
    LPCTSTR lpWindowName
);
返回窗体句柄。hWnd.
hWnd=FindWindow(0,要注入dll的窗体的名称(例如:千千静听))
利用hWnd,查找窗体线程ID
threadId=GetWindowThreadProcessId(hWnd,0);
好了,我们有了线程ID了,可以调用钩子了。
SetHook(threadId);
这时钩子已经加载到目标线程中了。
向目标窗体发送WM_NULL消息
SendMessage(hWnd,WM_NULL,0,0);
钩子会在目标窗体受到消息前受到WM_NULL消息。由于钩子处理函数中做了判断,当受到WM_NULL消息时,加载DLL文件。所以DLL文件就注入到目标线程中了。


你可以把你的DLL文件中写入许多功能,而且DLL已经被目标程序加载了,也就是说,你的DLL程序已经打入到目标程序内部了,所以现在你可以为所欲为了

  • 1
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Delphi是一种编程语言,而DLL(Dynamic-Link Library)是一种模块化的文件格式,用于存储代码和数据,可以被多个应用程序共享。DLL注入是一种技术,它允许将DLL文件加载到正在运行的进程中,并使得该进程能够调用DLL中的函数和使用其中的数据。 在Delphi中实现DLL注入的方法有很多种。一种常见的方法是使用Windows API函数LoadLibrary和GetProcAddress。通过调用LoadLibrary函数,将DLL文件加载到进程的虚拟地址空间中。然后使用GetProcAddress函数获取DLL中导出函数的地址,并将其传递给需要调用的函数。通过这种方式,可以在运行时将DLL注入到目标进程中,并且通过调用DLL中的函数来扩展进程的功能。 DLL注入在实际应用中有多种用途。例如,可以使用DLL注入来为某个程序添加额外的功能或修改程序的行为。DLL注入还可以用于实现一些调试和监控的功能。通过注入DLL,可以截获程序的输入和输出,或者在程序执行某些指定的操作时进行额外的处理。 在Delphi中实现DLL注入需要一定的编程知识和技巧。需要考虑目标进程的架构和权限限制,以及如何管理注入DLL的生命周期和资源管理。同时,还需要处理一些安全性和稳定性方面的问题,以确保注入过程不会对目标进程造成损害或崩溃。 总之,Delphi可以通过调用Windows API函数来实现DLL注入,从而扩展和修改进程的功能。但在实际应用中,需要考虑各种方面的问题,并且遵守相关的法律和规定,以确保注入操作的安全性和合法性。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值