首页
社区
课程
招聘
[原创]将EXE作为线程注入
发表于: 2009-1-15 10:07 25698

[原创]将EXE作为线程注入

2009-1-15 10:07
25698

注册半年有余也潜水半年有余。今天发一个原创处女贴,希望大家顶一下。
前段时间处理EXE文件进程隐藏的问题,在网上看到过很多方法,都不太满意。最终决定自己写一个,主体思路是代码重定位和线程的注入。首先,介绍一下我参考过的一些方法。
如果单纯从隐藏的角度来说,罗云彬的《Windows环境下32位汇编语言程序设计》中的方法基本可以说完美。然而从开发角度来看却有以下几个问题:
1.        他没有进行数据的重定位,他的代码中也不包含全局变量。
2.        所有需要的API全部手动写进去。比较繁琐。
3.        其代码重定位采用注入后的代码实现:
call        @F
@@:
pop        ebx
这种方式的重定位只能采用汇编语言实现。
而其他的进程隐藏方式,总结起来有以下几种;
1.        Windows 钩子把你的DLL映射到目标进程。
2.        把你的代码放到一个DLL中,然后放入其他进程空间,用 CreateRemoteThread 和 LoadLibrary 让它跑起来
3.        直接把你的代码注入目标进程。
另外,Shoooo的文章“野猪的力量—注入”的方法非常的独到,把Ollydbg.exe文件改成DLL来跑(OD中有重定位数据)。
不过通过DLL实现进程隐藏可以通过查看进程加载的模块来发现,并没有实现完全的隐藏。而注入代码段则无法实现复杂功能(有耐性慢慢磨的除外)。
我在这里介绍一种思路,可以实现一种对自身或其他整个EXE的完全注入。(本文以自身注入为例)
如果一个EXE想要在别的进程运行自己,所面临的问题主要有下面几个。
1.        数据重定位。因为EXE文件的运行基地址默认都是一样的,在你的程序中CALL 全局变量在其他进程根本就是错误的。
2.        输入函数地址。在别的进程,不能保证你所需要的DLL文件已经被载入,即使被载入了。其地址也未必正确。所以必须对每个输入函数地址进行获取。
3.        资源的使用。因为Windows在资源的时候会使用:
HRSRC FindResource
(
HMODULE hModule,
LPCTSTR lpName,
LPCTSTR lpType
);
注意第一个参数,你的程序采用GetModuleHandle(0)传递参数时必然会发生错误,因为你的起始地址不是0x00400000。当然,你可以不使用这个函数。但你不能确保别的程序不使用,当你想将某个含有GetModuleHandle(0)代码的EXE程序注入其他进程的时候就必须进行处理。
4.        ExitProcess –> ExitThread。
具体方法如下:
首先,你的EXE程序需要有2个入口(本人比较懒,不喜欢用复杂的判断,还是用2个入口方便些)。第一个入口是程序OEP,这个不必多说。第二个入口是你自定义的函数。用来获取你程序输入表中函数的地址。而第二个入口建议使用导出表来实现。因为使用偏移等方式每次更改代码编译都会变,不太方便。(注:VC中EXE需要导出的函数只要在前面加上__declspec(dllexport)即可,和DLL文件没什么区别,只是不能重定位和调用的时候不能使用LoadLibrary而已。)
其次,你的程序需要有重定位表,而有些编译器生成的EXE文件中是没有重定位表的。你需要强制编译器生成,否则无法实现数据的重定位。以VC为例子,加入#pragma        comment(linker,"/fixed:no")即可。对于没有重定位表的EXE,我想通过判断E8,E9后的地址并修正应该也可以实现。不过我没有动手测试。
函数的流程主要如下:
1.        读取你自己,按照PE文件在内存中的方式展开。
2.        提升程序权限以确保具有注入的权限。主要用到以下几个函数:OpenProcess,LookupPrivilegeValue,OpenProcessToken,AdjustTokenPrivileges。
3.        打开你需要注入的进程,分配大小和你展开PE文件大小的内存。获取基地址指针A
4.        通过指针A对你读取的代码实施重定位(处理重定位表)。
5.        获取本程序kernel32.dll中GetProcAddress和LoadLibrary的地址(所有进程中位置一样),《Windows环境下32位汇编语言程序设计》中有动态获取API地址的方法,怕不兼容可以采用。我比较懒,没有采用。
6.        获取你的第二个入口的地址偏移(通过输出函数偏移加上指针A)。
7.        将处理过的内存数据写入目标进程。
8.        将GetProcAddress和LoadLibrary地址和基址(指针A)作为参数来CreateRemoteThread,函数是你的输出函数。
9.        收尾工作,退出程序。
现在放入别的进程的目标代码已经重定位好了。但是输入表函数地址确还是原来的。这个就需要你的入口函数进行处理了。因为LoadLibrary和GetProcAddress地址以及PE文件的基地址已经被作为参数传了进来,现在你要做的就是通过基地址定位输入表,再遍历你的输入表载入所有的DLL并将函数地址填入。
现在你的程序的运行环境已经修正完毕。接着你就可以执行你所要执行的代码了,与正常EXE文件没有什么区别。而这个程序完全是内存拷贝,不会再读取原EXE,如果写病毒的话可以删除原EXE并在你设定的情况下重组以躲避查杀。呵呵。
再来说一下资源的问题。
由于资源都是采用相对地址偏移来存储数据,所以没必要重定位。使用资源主要在于传入参数的地址。创建对话框的时候你可以直接吧你传入的基地址作为首参数来创建,或者使用GetModuleHandle来获取地址,只要你将GetModuleHandle的地址改为自己的函数,然后进行判断参数是否是O,如果是O则返回基地址,不然再调用GetModuleHandle。
不过有个问题我一直还没解决。普通的对话框或窗口资源都没有问题,然而Child类型的无边框对话框却无法创建成功。(我用TAB控件时发现的)
这种思路我在WIN XP下测试通过。
注意:你的程序结束的时候会调用ExitProcess,会把宿主进程给Kill掉。因此你需要把ExitProcess的地址改为ExitThread。
同样的方法用在DLL文件中也一样,但是缺陷是DLL文件不能单独运行,必须编写一个程序负责载入dll。
这种方式的进程隐藏,避免了以上几种问题,采用C、C++语言编写即可。封装起来也实现了代码的可重复利用。
附:
由于水平有限,本文不足和遗漏之处请大家批评指正。


[招生]科锐逆向工程师培训(2024年11月15日实地,远程教学同时开班, 第51期)

收藏
免费 7
支持
分享
最新回复 (30)
雪    币: 2110
活跃值: (21)
能力值: (RANK:260 )
在线值:
发帖
回帖
粉丝
2
非常好的方法。支持共享思路与方法。
2009-1-15 16:48
0
雪    币: 362
活跃值: (25)
能力值: ( LV7,RANK:100 )
在线值:
发帖
回帖
粉丝
3
郁闷,帖子没人顶,还是继续潜水的好。
2009-1-19 09:20
0
雪    币: 214
活跃值: (24)
能力值: ( LV6,RANK:90 )
在线值:
发帖
回帖
粉丝
4
想法不错,支持一下。不过存在通用性问题,如果能够把任意EXE注入其他进程运行就不错。LOAD EXE运行最重要的问题是重定位,遇到没有重定位表的EXE,处理起来应该比较麻烦。
2009-1-19 09:38
0
雪    币: 97
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
5
源代码看起来可能更直观一些,呵呵
2009-1-19 11:30
0
雪    币: 217
活跃值: (35)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
6
这个网上已经有现成代码了。
2009-1-19 13:37
0
雪    币: 362
活跃值: (25)
能力值: ( LV7,RANK:100 )
在线值:
发帖
回帖
粉丝
7
我在这里主要说的是一种思路,其实没有什么技术含量。对于没有重定位表的EXE来说,处理思路上是一样的。不过实现起来就复杂了很多,因为别的EXE中本身就没有对输入函数地址的重新处理函数,因此需要加入一些代码段,就像外壳引导部分一样,之后一起注入。此外就是重定位的问题。没有重定位表的EXE需要对转跳后的地址进行处理。至于代码,网上找一些相关代码组合组合也就成了。
2009-1-19 14:54
0
雪    币: 217
活跃值: (35)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
8
没有重定位表的exe,除非你能加载到0x00400000,也就是要停止原进程的活动,不然根本没法处理的。
2009-1-19 19:32
0
雪    币: 339
活跃值: (1510)
能力值: ( LV13,RANK:970 )
在线值:
发帖
回帖
粉丝
9
相当于把exe添加重定位表弄成dll,不过直接用dll是不是更好些,如果感觉dll不能运行,可以写个小exe把它加载起来啊
2009-1-19 20:03
0
雪    币: 65
活跃值: (811)
能力值: ( LV12,RANK:210 )
在线值:
发帖
回帖
粉丝
10
支持大牛文章`~~~~
另,收藏,学习……
2009-1-19 20:31
0
雪    币: 205
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
11
收藏,肯定有用!多谢楼主共享您的思路!^_^
2009-1-19 21:42
0
雪    币: 200
活跃值: (16)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
12
我来的不算晚,收藏了,谢谢大牛分享
2009-1-20 01:58
0
雪    币: 247
活跃值: (11)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
13
dll不能完全隐藏 用冰刃可以看见
2009-1-20 10:02
0
雪    币: 149
活跃值: (344)
能力值: ( LV8,RANK:130 )
在线值:
发帖
回帖
粉丝
14
很强,很木马
2009-1-20 17:38
0
雪    币: 200
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
15
初学者,学习中
2009-1-21 14:41
0
雪    币: 209
活跃值: (10)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
16
不知道说的对不对,似乎是可以把DLL拷贝到目标内存中运行吧?
2009-1-29 22:53
0
雪    币: 846
活跃值: (221)
能力值: (RANK:570 )
在线值:
发帖
回帖
粉丝
17
OD的原版本来就是带重定位表的,并且作为DLL将自己加载
为的是方便插件调用OD的导出功能
2009-2-2 19:03
0
雪    币: 435
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
18
嘿嘿。顶一下。。。记得当年的ByShell是用的DLL注入。。。不过是利用系统的LoadLibary先把各种定位,导入表搞定了再来注入。。。简单。。。现在结合这个。。。还可以在注入的时候把一些DOS和PE文件头的数据抹掉^_^真在写类似于这样的代码
2009-2-2 21:14
0
雪    币: 195
活跃值: (23)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
19
嗯,这个技术不错,仔细研究一下
2009-5-14 22:44
0
雪    币: 1272
活跃值: (746)
能力值: ( LV13,RANK:810 )
在线值:
发帖
回帖
粉丝
20
yoda的InExeCon不是早就开源了吗?
增加重定位信息后EXE可以重定向到任何基址。。。
这点有点作弊嫌疑了Delphi和BCB还好说
VC不厚道呀不厚道呀。。默认是没有的

此类技术。。bo2k和bifrost等国外的远程控制软件早就使用了
bo2k 1.0,1.1的代码早就有了。。有点来晚了
2009-5-21 14:58
0
雪    币: 10
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
21
谢谢分享,学习了
2009-5-21 15:39
0
雪    币: 211
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
22
大力推广,是远程注入必备工具
2009-5-24 05:19
0
雪    币: 362
活跃值: (25)
能力值: ( LV7,RANK:100 )
在线值:
发帖
回帖
粉丝
23
InExeCon 我在刚才在Google和百度上面都没搜到,能否给我一份,谢谢.我写这个帖子的时候接触安全这块半年多点,菜鸟一只.很多东西没看到过.我当时还以为是独创呢,汗.要是有对无重定位程序的处理代码就好了,解析起来太麻烦了.我后来听说过有类似成品,可以处理所有EXE.
2009-5-25 09:29
0
雪    币: 213
活跃值: (147)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
24
楼主说了,用dll会在进程的加载模块中看到
2009-5-26 09:00
0
雪    币: 144
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
25
终于可以不用再createremotethread传参的时候,穿一大堆二进制代码了
2009-5-30 00:56
0
游客
登录 | 注册 方可回帖
返回
//