现在继续上篇文章,讲一下本人是怎么样把一个.net写的dll注入到其他进程的
同样,先是给出全部源码:https://github.com/bigbaldy1128/DotNetInjector
1.为何想做这个
其实dll注入是烂大街的东西了,不过都是C++的(这块特指注入的dll是C++的),本人这个人比较喜欢研究个东西,所以就搞出这么个东西来,也许大家觉得没什么用或已经有更好的实现方式,但本人只是兴趣使然,也欢迎大家吐槽
2.技术要点
首先要说几点:
1.实现用到了asm,C++,C#,并不是一个纯C#的实现,其中有些东西可以用C#实现,但为了省事选择了C++
2.只测试了win7 32bit/64bit,其他系统没跑,原因是有C和汇编估计会有系统兼容问题,希望大家反馈
下面来说说总体思路:
C#程序通过远程线程注入的方式注入一个C++的dll,该dll中以com方式调用C#的dll,然后再用shellcode执行C#dll中的方法,具体远程线程dll注入原理本人就不再敖述了,网上文章一大片,请大家自行google
本人的原理图:
详细流程:
(1) 用C#编写一个com(B.dll),里面声明一个接口,你需要做的事情都写在里面,例如:
[Guid("00C74C42-D58C-40E9-B09F-B09D129A4057")] public interface IHook { void Apply(); } [Guid("56C2BC3F-942F-4967-BFD2-D5E07281DB49")] public class Hook : IHook { public void Apply() { Monitor.Install("monitors"); } }
(2) 用C++编写一个Dll(A.dll),里面就一个方法,以com方式调用B.dll中Apply方法
EXTERN_C __declspec(dllexport) VOID Hook() { CoInitialize(NULL); ComForHook::IHookPtr hook(__uuidof(ComForHook::Hook)); hook->Apply(); CoUninitialize(); }
其实到这里,有人会问,把这个Hook方法放入DllMain中不就可以了吗,可惜并不是这样,原因是以com方式加载最终还是调用了LoadLibaray函数,这样进程会卡死在DllMain中,所以得用其他办法来调用Hook函数了,这里本人给出的办法是编写shellcode
(3) 编写shellcode实现Hook方法的调用
首先说一下什么是shellcode,shellcode就是一段编译好了的汇编指令,一般来讲都是用汇编实现,但写起来对于新手来说并不容易,具体可以参考《0day安全:软件漏洞分析技术》这本书的第三章(开发shellcode的艺术),后来,人们也想出了一套用C来编写shellcode的方式,大幅度降低了开发难度,本人参考的就是https://nickharbour.wordpress.com/2010/07/01/writing-shellcode-with-a-c-compiler/。
主要流程就是在内存中找到本人的dll并找到本人的函数,然后调用它,即:
PEB->LDR->本人的dll(A.dll)->PE头->导出表->本人的函数(Hook),call Hook
32位的很好实现,原因是C是支持内联汇编的,按照上述流程,需要先找到PEB:
PPEB __declspec(naked) get_peb(void) { __asm { mov eax, fs:[0x30] ret } }
但64位的就不太方便了,原因是VS是不支持64位内联汇编和裸函数的,nickharbour 的那篇文章中也没有64bit的实现,所以只能本人搞了,本人想的是直接编译asm文件再链接,但也遇到了一些问题,例如调用时函数地址超出了shellcode的范围,所以放弃了,改用本人写的方式,也许本人的方法比较笨,但是还是说一下,希望高手能指点更好的方法。
本人先声明了一个函数,如下所示,里面的代码仅仅是为了让函数有足够的空间
PPEB get_peb(void) { int a = 0; return 0; }
编译本人的ShellCode工程运行后会生成shellcode.bin文件,用IDA打开定位get_peb的位置:
可以看到文件偏移是0x211,先记录下来
然后使用x64dbg随便加载一个64位程序,编写汇编指令mov rax,gs:[0x60],记录前面的16进制数
最后用winhex打开shellcode.bin,定位到0x211的位置,将上图中的16进制数敲入,后面的指令全部填入90直到遇到C3为止,当然你直接填一个C3也可以
到了这里,64位shellcode编写完成了
3.测试流程
(1) 进入BinTest_x64,这里有本人编译后的完整测试文件
(2) 运行Target.exe并点击【Call】,提示“想hook本人没戏!”
(3) 运行HookMain.exe,点击【注入】
(4),再点击【Call】按钮,提示”竟然被hook了”
哈哈,是不是很好玩,这个东西本人就是写着玩的,觉得过程很有意思所以分享出来,也没有什么新鲜东西,一切都是兴趣使然
最后插个题外话,也是本人本人对于编程的看法:
本人学什么是原因是本人喜欢什么而不是他能挣多少钱,掌握一门新语言并不难,难的是你能一直保持着最初的兴趣,本人从编码中获得快乐,这对于本人来讲更有意义
5
先收藏,有空时再研究一下。
5
5
5
5
5
5
5