【源码 + 教程】 VB6 DLL注入的攻与防
vb吧
全部回复
仅看楼主
level 7
vb66666ss 楼主
最近对Hook有兴趣,于是用VB6试了一下,没想到能用(本来以为会以花式崩IDE告终的[黑线]),实际上做的过程中VB也崩了很多次,崩到怀疑人生[黑线]。不过总算是弄出来了,发上来跟大家分享一下。
主要分为DLL注入教程,VB6调用汇编命令的简单教程以及反DLL注入教程。这几个过程是循序渐进的。源码和教程见下面。前几楼都被我承包了[阴险]别抢
2018年01月09日 07点01分 1
level 7
vb66666ss 楼主
首先我们要知道一个DLL是怎么被注入到一个进程中的,而这方面的代码在网上数不胜数,简单介绍一下就带过,详细请见代码。
DLL注入的主要思路是在目标进程创建远程线程,让线程加载我们需要注入的DLL。我们假设A进程需要注入DLL到B进程,那么通常都是如下的步骤:
1. 使用OpenProcess打开B进程,取得一个进程句柄。
hProcess = OpenProcess(PROCESS_ALL_ACCESS, False, Pid)
2. 使用GetProcAddress和GetModuleHandleA获取LoadLibraryA函数的地址,为接下来的调用做准备。LoadLibraryA函数于kernel32.dll中,所以先要获取kernel32.dll的句柄,
lpLoadLib =GetProcAddress(GetModuleHandleA("kernel32.dll"),"LoadLibraryA")
3. 使用VirtualAllocEx在B进程分配可以存下DLL路径的空间并把DLL路径然后用WriteProcessMemory写入到这片空间里。因为A进程和B进程的内存不是共用的,不能互相访问,所以A进程要先在B进程分配内存,然后把需要注入的DLL路径写进去,让B进程知道要注入的DLL文件路径。
WriteAddr = VirtualAllocEx(ByVal hProcess, ByVal 0, ByValUBound(DllPath), MEM_RESERVE Or MEM_COMMIT, PAGE_READWRITE)
WriteProcessMemory ByVal hProcess, ByVal WriteAddr,DllPath(0), ByVal UBound(DllPath), 0
4. 使用CreateRemoteThread在B进程创建远程线程,令其调用LoadLibraryA加载DLL。
hThread = CreateRemoteThread(ByVal hProcess, ByVal 0, ByVal0, ByVal lpLoadLib, ByVal WriteAddr, ByVal 0, Tid)
现在如果不出意外A进程应该成功把DLL注入到B进程了。以上是注入DLL最常用的步骤,上张DLL成功注入的图(Word很不幸的当了白老鼠)。DLL是用C++编写的,负责在成功注入后弹出一个消息框。注意看下方任务栏的图标,说明消息框是属于Word的。
2018年01月09日 07点01分 2
level 7
vb66666ss 楼主
然后我们来试试用VB6实现汇编代码的调用。我们知道汇编代码是一字节一字节堆砌而成的,所以在VB6里用Byte数组来存储代码。
我弄的例子是调用jmp命令,使程序跳转到另一个过程中。在VB6中实现调用汇编代码通常需要以下几个步骤:
1. 定义一个数组并往里面写入汇编代码。这里使用的是jmp命令作为示例。
Dim MyCode(5) AsByte
MyCode(0) = &HE9 ‘&HE9为jmp的命令码
CopyMemory MyCode(1), jmpAddr, 4 ‘jmpAddr为跳转的地址,把地址放在命令码后面
至于跳转地址如何计算,之后代码中有详细说明,不在这里累述。
2. 使用CallWindowProcA函数来执行Byte数组里的代码。
CallWindowProcA ByVal VarPtr(MyCode(0)), 0, 0, 0, 0
看上去并不复杂,不过确确实实的在VB6里执行了自己编写的汇编命令了。上张图。
2018年01月09日 07点01分 3
level 7
vb66666ss 楼主
好不容易打好的又被系统自动删了。。说有违规内容。。气死
2018年01月09日 07点01分 6
level 7
vb66666ss 楼主
从上面我们可以知道DLL注入主要依靠的是创建远线程然后调用LoadLibraryA加载DLL。但是有时候我们不希望自己的程序被别的程序随便注入– 怎么办

?从上面的代码我们可以知道DLL最终能否加载跟目标进程调用LoadLibraryA函数是否成功有很大的关系。那么就有了一种反DLL注入的思路–我们何不取消掉LoadLibraryA这个函数所做的事情,这样自己的程序就不会随便被别的程序注入了?
于是思路就出来了– 我们让程序不执行LoadLibraryA函数,而是执行一个假冒的LoadLibraryA函数– 就像狸猫换太子一样。这就是传说中的Hook技术,也叫钩子。Hook的种类有很多,像上面这样的叫内联Hook。
从上面我们知道汇编代码在内存中都是一个个字节组成的,既然系统能够执行Byte数组里的代码,也就说明代码可以复制到Byte数组里,代码也可以在运行时替换。于是便有了以下步骤:
1. 编写一个钩子函数。其参数类型和返回值类型必须与LoadLibraryA相同– 否则就不叫狸猫换太子了嘛。
Public Function MyLoadLibraryA(ByVal DllName As Long) AsLong
End Function
2. 获取LoadLibraryA函数的地址(DLL注入有相似的步骤,见上面二楼)
LoadLibAddr =GetProcAddress(GetModuleHandleA("kernel32.dll"),"LoadLibraryA")
3. 计算自己编写的函数(即钩子函数)的地址。
'注意计算jmp跳转地址的方式!是 (新的地址 - 原来的地址- 5)。其中5是jmp命令的大小。GetAddr为自己编写的函数,用来获取函数的地址
jmpAddr =GetAddr(AddressOf MyLoadLibraryA) - LoadLibAddr - 5
4. 像上一楼写汇编代码一样– 自己在Byte数组中制造一个跳转命令
Public NewCode(5) AsByte
NewCode(0) = &HE9
CopyMemory NewCode(1), jmpAddr, 4
5. 命令制造好之后就可以把新的代码写入到LoadLibraryA的函数入口处了。这样当调用LoadLibraryA的时候就不会执行它原有的东西,而是跳转到了自己编写的函数。在写入前先备份原本入口处的代码,用来恢复Hook。这一步主要靠读写进程内存实现。
'读取进程内存。把LoadLibraryA函数入口的代码备份一份
ReadProcessMemory GetCurrentProcess, ByVal LoadLibAddr,PrevCode(0), 5, 0
'写入进程内存。把LoadLibraryA函数入口的代码改成新的代码,强制其跳转以实现Hook
If WriteProcessMemory(GetCurrentProcess, ByVal LoadLibAddr,NewCode(0), 5, 0) Then
‘Hook成功
End If
6. 恢复Hook的方法跟上面相仿,只不过是把原本的代码写入回去。
If WriteProcessMemory(GetCurrentProcess, ByVal LoadLibAddr,PrevCode(0), 5, 0) Then
‘Hook已取消
End If
【注意】程序退出前应该恢复Hook了的函数,尤其是在IDE中。。否则IDE很可能会花式炸鸡。写完Hook记得恢复。否则将来出了问题,可是要负责任的,明白不?
以上就是Hook的基本步骤了,来上几张图看看效果。
图一– Hook之前程序能被其他程序注入
图二、三– Hook之后程序不能被其他程序注入了
图四– Hook前与Hook后的汇编代码对比
可以看出已经能达到反DLL注入的目的了~虽然这是从比较基础的层面拦截DLL注入,不过也能防掉一般程序的注入了。可以看出从一开始的DLL注入,再到后面的防DLL注入,过程是循序渐进的。
呼… 教程到这里也差不多结束了。源码看下面
几层楼的帖子打了挺久的,希望能让大家从中有所收获吧。(感觉本帖很快会被提问帖淹掉的
2018年01月09日 07点01分 7
为什么我Hook LoadLibraryA之后,只能拦截程序自身的调用,而无法拦截dll的注入?(也可以拦截,但是一但执行到回调函数中时再单步执行就会崩溃,并引发429错误)
2022年05月03日 08点05分
level 7
vb66666ss 楼主
源码链接:pan点百度点com/s/1pMfLSaJ 密码:9vkm
希望别又给系统吞了。。气死了发了好几次链接都直接被系统删掉[不高兴]
2018年01月09日 07点01分 9
[真棒][真棒][真棒][真棒][真棒][真棒]
2018年01月12日 07点01分
能不能Hook其他进程的API?
2022年05月03日 08点05分
level 14
好东西,先收藏
2018年01月09日 13点01分 10
感谢兹磁~
2018年01月10日 04点01分
level 15
厉害了,只是可以更详细些就好
2018年01月09日 22点01分 11
好的,感谢。
2018年01月10日 04点01分
level 11
技术贴 帮顶
2018年01月09日 23点01分 12
感谢帮顶~
2018年01月10日 04点01分
level 11
不错,顶一下
2018年01月09日 23点01分 13
感谢帮顶~
2018年01月10日 04点01分
level 13
技术贴,赞一个
2018年01月10日 01点01分 14
感谢帮顶~
2018年01月10日 04点01分
level 10
顶一下。[哈哈]
2018年01月10日 03点01分 15
感谢帮顶~
2018年01月10日 04点01分
level 11
先赞再学!!!
2018年01月10日 04点01分 16
吧务
level 10
技术贴,赞!!!
2018年01月10日 05点01分 17
感谢鼓励[哈哈]
2018年01月10日 06点01分
level 11
学了一遍,可是学完后发现啥也没有记住.............
2018年01月10日 05点01分 18
没事这东西都得慢慢来的 我也学了挺久才弄懂一点
2018年01月10日 06点01分
2018年01月10日 06点01分
1 2 尾页