VC驿站

 找回密码
 加入驿站

QQ登录

只需一步,快速开始

搜索
查看: 4390|回复: 11

[技术文章] VC实现DLL注入

[复制链接]
Miss丿小沫 发表于 2016-7-14 16:33:01 | 显示全部楼层 |阅读模式
本帖最后由 Miss丿小沫 于 2016-7-15 13:50 编辑

最近在学逆向破解,有必要将自己学习的经验和方法总结下来,自己既巩固了知识,也方便了大家!
依然是我,【Miss丿小沫】,废话不多说,上教程!(代码当是用VC6.0写的,大家如果是Unicode注意加宏)
---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
先来了解一下DLL文件:(详见百度百科,不再赘述)
百度百科:http://baike.baidu.com/link?url= ... s2hr48tcez0eBizuqha

关于DLL注入技术的大概了解:
DLL注入就是在远程进程加入一段代码,随时监控程序运行并可以根据运行情况自动运行相应的内容。
DLL注入难在DLL的编写,由于DLL远程运行,所以在调试很困难,需要熟练地编程功底才能编写,而且DLL注入是给远程进程增加了一个线程,对于一些会自检线程的程序,会有被发现的风险。
DLL注入技术的用途广泛:
1、对目标进程中的函数进行拦截(API勾取)(由此编写个拦截SetTimer的程序,变速齿轮不就出来了)。
2、编写一些函数用于改善或增加目标进程功能(譬如各种插件,修复BUG,增加新功能)。
3、隐藏自己的程序,即使你将恶意程序的进程结束掉也毫无意义,因为它自己已经插入到很多进程中去了,唯一有效的办法只有注销windows.。如果你是个爱搞破坏的人就更应该掌握该技术了,不但可以利用该技术隐藏自己的进程,还可以破坏某个目标进程。
4、...
5、...
6、...

DLL注入就是向正在运行中的进程强制插入DLL文件,DLL注入命令目标进程调用LoadLibrary()函数,从而加载指定DLL文件


从上图可以看到,myhack.dll被强制插入notepad.exe进程,此时,myhack.dll已经和kernel32.dll、user32.dll一样,拥有访问notepad.exe内存的权限,这样就可以做任何想做的事了。
(DLL文件被加载后,自动执行DllMain()入口函数,将代码放在DllMain()函数里面,每次加载DLL时,就会自动执行,利用该特性就可以实现修复BUG,添加新特性等功能)
下面是一个DllMain()入口函数的示例:(关于DLL编程详细教程,我推荐《http://www.cctry.com/forum-27-1.htmlVC驿站站长SYC大哥的视频,绝对良心)
  1. BOOL WINAPI DllMain(HINSTANCE,hinstDll,DWORD dwReason,LPVOID lpvReserved)
  2. {
  3.     switch(dwReason)
  4.     {
  5.         case DLL_PROCESS_ATTACH:
  6.         break;
  7.         case DLL_THREAD_ATTACH:
  8.         break;
  9.         case DLL_PROCESS_DETACH:
  10.         break;
  11.         case DLL_THREAD_DETACH:
  12.         break;
  13.     }

  14.     return TRUE;
  15. }
复制代码

关于switch中四个宏的介绍:
DLL_PROCESS_ATTACH(进程载入)
DLL_THREAD_ATTACH(线程载入)
DLL_THREAD_DETACH(线程卸载)
DLL_PROCESS_DETACH(进程卸载)

下面讲解DLL注入的实现:
DLL注入有多种办法(我着重讲解第一种办法,剩下几种我会以后补充)
①:创建远程线程(CreateRemoteThread())
②:使用注册表(AppInit_DLLs值)
③:消息钩子(SetWindowsHook())




<1>:编写DLL文件
  1. BOOL WINAPI DllMain(HINSTANCE hInstance,DWORD dwReason,LPVOID lpvReserved)
  2. {
  3.         switch(dwReason)
  4.         {
  5.                 case DLL_PROCESS_ATTACH:
  6.                         //输出Debug信息
  7.                         MessageBox(NULL,"Test!","Test!",MB_OK);
  8.                         break;
  9.         }
  10.        
  11.         return TRUE;
  12. }
复制代码

DLL文件很简单,就是当目标进程调用LoadLibrary()加载DLL时,执行DllMain(),然后弹出对话框。
这里弹出对话框后,主程序就会堵塞,点击确定后恢复正常(显而易见),大家可以新建一个线程(CreateThread()),然后把代码放到自己的线程函数里面,就OK了!
<2>:编写主程序(暂时不考虑DLL的卸载)
(此处的代码可以更加一般化,比如根据进程名获取PID,这在下一章DLL卸载里面会讲)

  1. void CCodeInjectDlg::OnButtonInject()
  2. {
  3.         CString strPID;
  4.         CString str = "E:/VC6/MyProjects/MyDLL/Debug/MyDLL.dll";
  5.         HMODULE hMod = NULL;
  6.         LPTHREAD_START_ROUTINE lpThread = NULL;

  7.         //获取PID
  8.         GetDlgItemText(IDC_EDIT_PID,strPID);
  9.         int nPid = _ttoi(strPID);
  10.         //获取目标进程句柄
  11.         HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS,FALSE,nPid);
  12.         //在目标进程内存中分配DllName(DLL文件绝对路径)大小的内存
  13.         DWORD dwSize = (DWORD)(str.GetLength() + 1) * sizeof(char);
  14.         LPVOID pRemoteBuf = VirtualAllocEx(hProcess,NULL,dwSize,MEM_COMMIT,PAGE_READWRITE);
  15.         //将MyDll路径写入目标进程内存
  16.         WriteProcessMemory(hProcess,pRemoteBuf,(LPVOID)str.GetBuffer(0),dwSize,NULL);
  17.         //获取LoadLibrary()地址
  18.         hMod = GetModuleHandle("kernel32.dll");
  19.         lpThread = (LPTHREAD_START_ROUTINE)GetProcAddress(hMod,"LoadLibraryA");
  20.         //在目标进程里运行线程
  21.         HANDLE hThread = CreateRemoteThread(hProcess,NULL,0,lpThread,pRemoteBuf,0,NULL);


  22.         WaitForSingleObject(hThread,INFINITE);
  23.         CloseHandle(hThread);
  24.         CloseHandle(hProcess);
  25. }
复制代码

详细看一下注入函数
①:OpenProcess()用来获取目标进程句柄。获取PROCESS_ALL_ACCESS后,就可以通过进程句柄操作进程
②:VirtualAllocEx()用来将DLL路径写入目标进程内存。因为任何内存空间不允许写入操作,所以先使用VirtualAllocEx()先分配一块换缓冲区,且缓冲区大小为DLL路径长度大小(注意包含末尾NULL),其返回值即为分配的缓冲区的起始地址
③:WriteProcessMemory()用来将DLL路径写入分配的缓冲区GetModuleHandle()和GetProcAddress()用来获取LoadLibrary()函数地址,进而用来调用LoadLibrary()(Unicod为LoadLibraryW,ANSI为LoadLibraryA)
读者诸君,不知道看到这里有没有一点疑惑?
我们明明要调用目标进程的LoadLibrary(),然而获取的是我们的注入进程的“kernel32.dll”和LoadLibrary()的地址,他们地址相同吗?
其实,在windows系统中,kernel32.dll在每个进程中的加载地址都是一样的。
④:CreateRemoteThread()用来在远程进程中运行线程

不考虑DLL卸载的情况下,DLL注入就写得差不多了,现在来看看效果。
首先我们需要一款工具,process explorer,百度即可。
打开process explorer和一个记事本,

至于process explorer下面的dll查看窗口,可以点击 View -> Show Lower Pane;然后View->Lower Pane View -> DLLs就可以看到进程加载的DLLs
记一下notepad.exe的PID为11536,然后就是注入


可以看到,我们的DLL已经成功注入到进程中去了!
并且弹出了DllMain()中的MessageBox!
请各位读者务必自己动手亲身演练一遍,了解原理,明白过程!

敬请期待下节教程【VC实现DLL注入之DLL卸载】

(在此向SYC大哥提出一个不合理的请求,我希望SYC大哥,如果可以的话,请求大哥分享小弟一套POST的教程(就是玩转QQ空间类似的),教程刚出的时候,就一直渴求了,无奈自己学生党,╮(╯▽╰)╭,自己也准备,把这几天来学习的所有逆向破解的知识写成经验博文发到驿站来(目标10篇),比如API勾取,OD反汇编,调试器之类(如果有时间,也写一写kali linux 上metasploit渗透利器使用(一条龙))的逆向核心知识,不知道SYC大哥同不同意?

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?加入驿站

x

评分

参与人数 3威望 +2 驿站币 +4 贡献 +3 热心值 +2 收起 理由
C.olive + 1 赞一个!
libocdf + 1 + 1 很给力!
Syc + 2 + 3 + 3 很给力!

查看全部评分

发帖求助前要善用论坛搜索功能,那里可能会有你要找的答案;

如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请编辑帖子并把分类改成【已解决】

如何回报帮助你解决问题的坛友,一个好办法就是给对方加【热心】【驿站币】,加分不会扣除自己的积分,做一个热心并受欢迎的人!

Syc 发表于 2016-7-14 16:41:27 | 显示全部楼层
何止同意,求之不得啊!

发帖求助前要善用论坛搜索功能,那里可能会有你要找的答案;

如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请编辑帖子并把分类改成【已解决】

如何回报帮助你解决问题的坛友,一个好办法就是给对方加【热心】【驿站币】,加分不会扣除自己的积分,做一个热心并受欢迎的人!

回复 支持 反对

使用道具 举报

 楼主| Miss丿小沫 发表于 2016-7-14 16:43:18 | 显示全部楼层
Syc 发表于 2016-7-14 16:41
何止同意,求之不得啊!

哈哈 谢谢SYC大哥了,已经渴望好久了,我会继续写自己的经验,为驿站做贡献!!!
用自己的劳动来求取知识!!!

发帖求助前要善用论坛搜索功能,那里可能会有你要找的答案;

如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请编辑帖子并把分类改成【已解决】

如何回报帮助你解决问题的坛友,一个好办法就是给对方加【热心】【驿站币】,加分不会扣除自己的积分,做一个热心并受欢迎的人!

回复 支持 反对

使用道具 举报

libocdf 发表于 2016-7-15 10:08:32 | 显示全部楼层
小建议,dll注入方式何止三种,光是ring3下就不下十种。你说的这三种看内容是《windows核心编程》里提及的,建议注明一下!!文章很初级,很适合入门看,对楼主表示赞赏!!!

发帖求助前要善用论坛搜索功能,那里可能会有你要找的答案;

如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请编辑帖子并把分类改成【已解决】

如何回报帮助你解决问题的坛友,一个好办法就是给对方加【热心】【驿站币】,加分不会扣除自己的积分,做一个热心并受欢迎的人!

回复 支持 反对

使用道具 举报

 楼主| Miss丿小沫 发表于 2016-7-15 13:50:13 | 显示全部楼层
libocdf 发表于 2016-7-15 10:08
小建议,dll注入方式何止三种,光是ring3下就不下十种。你说的这三种看内容是《windows核心编程》里提及的 ...

多谢指点!!!

发帖求助前要善用论坛搜索功能,那里可能会有你要找的答案;

如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请编辑帖子并把分类改成【已解决】

如何回报帮助你解决问题的坛友,一个好办法就是给对方加【热心】【驿站币】,加分不会扣除自己的积分,做一个热心并受欢迎的人!

回复 支持 反对

使用道具 举报

caojun1979 发表于 2016-11-21 14:59:53 | 显示全部楼层
支持一下

发帖求助前要善用论坛搜索功能,那里可能会有你要找的答案;

如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请编辑帖子并把分类改成【已解决】

如何回报帮助你解决问题的坛友,一个好办法就是给对方加【热心】【驿站币】,加分不会扣除自己的积分,做一个热心并受欢迎的人!

回复 支持 反对

使用道具 举报

voidVCOL 发表于 2017-5-25 12:15:25 | 显示全部楼层
果然论坛才是技术交流的圈子

发帖求助前要善用论坛搜索功能,那里可能会有你要找的答案;

如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请编辑帖子并把分类改成【已解决】

如何回报帮助你解决问题的坛友,一个好办法就是给对方加【热心】【驿站币】,加分不会扣除自己的积分,做一个热心并受欢迎的人!

回复 支持 反对

使用道具 举报

harecn 发表于 2017-6-3 08:56:47 | 显示全部楼层
不错不错.很适合我等新手.

发帖求助前要善用论坛搜索功能,那里可能会有你要找的答案;

如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请编辑帖子并把分类改成【已解决】

如何回报帮助你解决问题的坛友,一个好办法就是给对方加【热心】【驿站币】,加分不会扣除自己的积分,做一个热心并受欢迎的人!

回复 支持 反对

使用道具 举报

runfog 发表于 2017-6-17 22:29:17 | 显示全部楼层
DLL注入就是在远程进程加入一段代码,随时监控程序运行并可以根据运行情况自动运行相应的内容。
DLL注入难在DLL的编写,由于DLL远程运行,所以在调试很困难,需要熟练地编程功底才能编写,而且DLL注入是给远程进程增加了一个线程,对于一些会自检线程的程序,会有被发现的风险。
DLL注入技术的用途广泛:

发帖求助前要善用论坛搜索功能,那里可能会有你要找的答案;

如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请编辑帖子并把分类改成【已解决】

如何回报帮助你解决问题的坛友,一个好办法就是给对方加【热心】【驿站币】,加分不会扣除自己的积分,做一个热心并受欢迎的人!

回复 支持 反对

使用道具 举报

fashion530 发表于 2017-6-19 23:30:14 | 显示全部楼层
感谢感谢感谢

发帖求助前要善用论坛搜索功能,那里可能会有你要找的答案;

如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请编辑帖子并把分类改成【已解决】

如何回报帮助你解决问题的坛友,一个好办法就是给对方加【热心】【驿站币】,加分不会扣除自己的积分,做一个热心并受欢迎的人!

回复 支持 反对

使用道具 举报

runfog 发表于 2017-6-22 23:27:54 | 显示全部楼层
DLL注入的实现

发帖求助前要善用论坛搜索功能,那里可能会有你要找的答案;

如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请编辑帖子并把分类改成【已解决】

如何回报帮助你解决问题的坛友,一个好办法就是给对方加【热心】【驿站币】,加分不会扣除自己的积分,做一个热心并受欢迎的人!

回复 支持 反对

使用道具 举报

dzyong 发表于 2017-9-20 21:56:31 | 显示全部楼层
高山仰止!!!!!!!

发帖求助前要善用论坛搜索功能,那里可能会有你要找的答案;

如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请编辑帖子并把分类改成【已解决】

如何回报帮助你解决问题的坛友,一个好办法就是给对方加【热心】【驿站币】,加分不会扣除自己的积分,做一个热心并受欢迎的人!

回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 加入驿站

本版积分规则

展开

QQ|小黑屋|手机版|VC驿站 ( 辽ICP备09019393号 )

返回顶部
x

VC驿站微信公众号cctry2009

GMT+8, 2017-10-21 23:49

Powered by Discuz!

© 2009-2017 cctry.com

快速回复 返回顶部 返回列表