VC dll注入基础教程新手级
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
学习各种高级外挂制作技术,马上去百度搜索(魔鬼作坊),点击第一个站进入,快速成为做挂达人。
首先要明白什么是线程
说到线程就不得不提到进程
SDK文档里是这样描述的
进程是一个正在运行的程序,它拥有自己的地址空间,拥有自己的代码、数据和其他系统资源。一个进程包含了一个或者多个运行在此进程内的线程。
说白了,其实进程就是一个磁盘上的程序载入内存执行后的东西
打开任务管理器看看,里面有好多进程...
从定义上看出进程一定要有线程,线程是进程内存中的独立实体。
讲了这么多废话
其实就是想说程序运行后就变成了进程,你的代码由线程来执行。
回到正题上,线程插入是什么呢?就是把一个线程弄到别的进程执行
你也许觉得奇怪,自己不是有个进程好好的吗?
其实这个作用大了,先说说开头提到的木马
一来,有些比较由经验的用户有时会打开任务管理器,发现陌生进程?!想想你的木马还能活吗?
那么插入Explorer等关键进程,你还想用电脑的话最好不要杀那个进程(不信试试)
二来,大家现在都装防火墙了,网络连接经常会被虑掉,木马岂不是没用了?
好,插入IE,防火墙想虑?除非你不想看网页
当然,还有很多用处,比如插入系统级别的进程,哈哈,我们有Ring0权限了,(不要告诉我你不知道Ring0...就是连物理内存都可以写的超级权限)
HookAPI也需要把代码注入别的进程
知道了他的作用想知道怎么实现吧?
别着急,慢慢来
首先,这个应该属于系统编程,系统编程就不能不知道API
API是什么?简单点讲就是Windows为我们提供的一些函数,利用他们我们可以做很多事情
Delphi花了很大力气用VCL还有一些乱七八糟的类把让我们可以尽量不要API
所以会编程序但不了解API还是可能的
API被封装在kernel32.dll、user32.dll等动态链接库里,程序使用时候把DLL映射到自己的内存了
编写的时候我们通常需要从DLL导出这些函数
function Beep;external'kernel32.dll'name'Beep';
这样导出一个beep函数
当然,实际上不要这么麻烦
Delphi已经把这些导出声明写在一些单元里面了(比如windows单元)
uses windows后就可以直接用了
(而且建立窗口时候默认就会引用很多单元)
所以实际上我们可以直接用的
这个理解一下就好了
开始讲线程插入了
一般来说线程插入有2种方法
1.DLL注入
2.直接的远程线程插入
DLL注入编写的时候比较简单,方法也多,但有个缺点进程会多出个模块来,可能被发现远程线程是直接修改对方内存的方法,虽然隐蔽性好,但是不小心可能会出点问题,比如你让不能有界面的进程弹出个窗口,不能上网的进程开个端口,那就等着系统崩溃吧
今天重点讲DLL注入
首先要知道什么是DLL,dll就是动态链接库,大家应该知道吧?
怎么编写DLL呢?
和写普通程序差不多是一样的
新建一个工程,选DLL Wizard
发现了吧?除了program改成library
剩下几乎是一样的,只是需要程序加载他的入口点
我们先编写个简单的DLL
library TestDll;
uses
Windows;{$R*.res}
procedure func_a;
begin
MessageBox(0,'I love delphi','Function form Tset DLL',0);
end;
procedure func_b(MSG:pchar);
begin
MessageBox(0,MSG,'Function form Tset DLL',0);
end;
begin
func_a;
func_b('I like it too!');
end.
就是那个testdll.dpr
看得懂吧,弹出2个信息框
好了保存下,F9运行..出错,哈哈,DLL是不能直接运行的
那怎么办?编译下(按过F9就不用了,也会编译好)
看见那个DLL了吧?
我们弄个程序加载它的入口点
新建一个普通程序
加一个按钮
按钮事件只要写一句loadlibrary('testdll.dll');
MainShow.dpr
运行,单击按钮,怎么养?弹出东西了吧
当然DLL还可以做函数库,资源库等今天暂不讨论
现在DLL懂得写了吧?就是program改成library而已
你可以写自己的程序了
DLL会写了,现在的问题就是怎么注入了
我们目的只是让对方的程序运行一句loadlibrary('testdll.dll');而已
一切就OK了
通常有这么几种注入方法
1.利用全局消息钩子
Win32下程序一般都要用收发消息
用钩子函数下全局钩子,程序收到任何消息都加载我们的DLL的入口点
当然,用这种方法DLL进入后要判断自己是不是被插进目标进程
是的话,执行代码
不是退出
这个方法很麻烦但通用性很好,只要WINDOWS都可以用(但是有的系统进程消息是勾不住的,所以注入不了)
早期的DLL注入大部分是用这个原理实现的
2.写注册表
写HKEY_LOCAL_MAHINE\Software\Microsoft\Windows NT\CurrentVersion\Windows\AppInit_DLLs
但是只能是NT下,而且必须是调用过user32.dll(Windows的一个内核,只要有界面的程序都调用它)的程序,在开机后所有程序会自动加载DLL,但是这个dll不能被卸载,而且不能调用某些函数,不然系统会挂掉(有危险性哦)
不推荐使用
3.利用远程线程注入来实现DLL注入
只要能打开句柄,就能成功(强吧?)而且实现起来比较简单
缺点就是9X内核的有点难度(也不是很困难)
我们今天就讲利用远程线程注入来实现DLL注入吧!
你可能要问,既然刚才说了远程线程可以直接注入一个线程,为什么还要多此一举反过来再调用DLL呢?
这是因为,远程线程技术一般是直接对目标程序的内存进行操作
我们知道不同程序的虚拟内存是不一样的
所以很多函数的地址不一定一样
而程序运行的时候实际上是Call函数地址进行函数调用的
所以我们要注意计算很多偏移之类的
这是非常烦琐的事情
而且像上面说的让不能有界面的进程弹出个窗口,那就不好玩了
而DLL呢?
DLL调用时其实是被映射到进程内存里面
DLL拥有自己的导入表、资源、函数等东西,实际上就是一个完整的程序
映入内存后和执行一个程序效果是一样的
这样我们就不用考虑那些乱七八糟的东西,只要安心的写功能即可
好了,
要明白远程线程首先当然要把程序本地线程搞清楚了
不知道大家编多线程程序的时候是不是都用tthread类?
反正我是不喜欢那个
我们看看Windows给我们的原始API吧(tthread类也是用它写的)
function CreateThread(