PE补丁技术
这章很多东西之前都见过,也单独总结过,比如动态补丁里说的远程代码注入,还有hijack什么的。之前整理过的这里就不细说了,大体说下思路。这里总结一些之前没总结过的东西。
资料中把补丁分为两类,静态补丁和动态补丁。然后有总结了下补丁的基本要素:进程通讯能力、良好的读写其他进程地址能力、正确识别要补丁目标进程、在其他进程地址空间执行代码的能力。
进程通信:
管道通信(有名管道和匿名管道)、邮件槽、剪切板、共享内存、消息机制、socket等等具体细节概念请自行百度。
(1)动态补丁
读写进程内存:
OpenProcess()、ReadProcessMemory()、WriteProcessMemory()
也就是常用的代码注入那一套:
OpenProcess()打开目标进程,获取进程操作句柄。
VirtualAllocEx()在目标进程分配内存。
WriteProcessMemory()函数将远程代码写入。
CreateProcessMemory()在目标进程中创建远程县城并执行。
[远程线程注入记得所有引用都要拷贝进去,注意重定位问题,尽量不要使用全局变量,最好是直接在里面实现LoadLibrary和GetProcAddress或者直接把dll load到目标进程里。]
其实还有很多,比如EIP注入,消息注入什么的。之前我系统的总结过,可以到我主页上看下。
(2)整体替换PE文件:
比如通常的软件升级,或者Hijack或者是输入法注入再或者LSP注入等,都是属于这一类。
软件升级:
这个不解释了,通常的软件升级逻辑。下载升级包对应替换文件。这里有个地方可以注意,可以只替换需要替换的东西,减少流量损失,这种也用于安装上。先装上基本模块,然后后续的陆续更新,或者惰性更新。这样用户体验会相对好很多。
Hijack或者输入法注入等:
这个很好理解,A想调用B.dll,我们分析下B.dll的导出函数,然后自己实现一个假的B.dll,直接替换本来的dll,如果是想要继续注入后在调用原来的功能,可以在假的B.dll里调用原来的dll来计算值。类似与hook 和inlinehook。很简单,不多说。
对了想起个事,做这类事情的时候注意一个问题,就是Windows默认的寻找dll的路径顺序,这个有的时候比较有用。
还有就是注意宿主进程加载dll的时候是静态还是动态。静态的话在运行过程中有可能无法替换相应dll。文件会被占用的。虽然有办法强行基础文件占用,之前我在驱动里弄过这个再或者直接调用微软的相关程序强行结束掉句柄,但是并不能达到我们的效果。动态加载的可以随时替换劫持dll.
(3)部分修改PE文件:
直接修改PE相关机器码,或者把自己的机器码找个地方拷贝进去,通过需改入口地址执行我们的代码,然后再跳转回去原来的机器码,这个姿势之后的章节会细说。再或者干脆就直接把自己代码拷贝覆盖到入口地址处,同时也还可以这样,在入口处直接jmp到我们的代码,干完活在jmp回来。
程序入口
IMAGE_OPTIONAL_HEADER32.AddressOfEntryPoint
OK接下来 来一波测试,编写一个程序。代码如下:
运行则显示:
看下入口地址:
注意上面的并不是main函数入口地址,是这个:
Main函数也是被别人调起来的。通过IDA看下就知道了。OK下载我想的是直接把入口地址换成main2,注意,之前也不是main,是main之前的一些函数。看下main2的地址:
相对RVA是0x1000,OK直接改FOA0x120的地方就行:
改完之后:
OK上面的这些就是测试着玩玩,也就是说可以通过改变PE入口函数来修改相关逻辑。之后这个思路会用到。
后面还有一个内嵌机器码到记事本的程序,明天会用单独整理。