.net dll注入技术

bigbaldy 2016-05-28 01:30:37
加精
之前我发了一贴是关于hook的,http://bbs.csdn.net/topics/391958344

现在继续上篇文章,讲一下自己是如何把一个.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了"

哈哈,是不是很好玩,这个东西我就是写着玩的,觉得过程很有意思所以分享出来,也没有什么新鲜东西,一切都是兴趣使然

最后插个题外话,也是我自己对于编程的看法:
我学什么是因为我喜欢什么而不是他能挣多少钱,掌握一门新语言并不难,难的是你能一直保持着最初的兴趣,我从编码中获得快乐,这对于我来讲更有意义
...全文
7133 29 打赏 收藏 转发到动态 举报
写回复
用AI写文章
29 条回复
切换为时间正序
请发表友善的回复…
发表回复
百变狸猫 2020-04-27
  • 打赏
  • 举报
回复
为啥要搞得这么复杂?直接枚举本进程模块不是就可以获得模块地址和函数地址了么? 另外,调用C# dll除了使用COM接口以外,也可以使用加载CLR运行环境然后执行指定函数得方式。
夏虫1 2017-11-10
  • 打赏
  • 举报
回复
请教: 想实现播放器是边解密边播放,相当于内存里解密播放,而不是生产一个解密文件之后再打开播放。播放器用迅雷aplayer sdk它只提供了void open(String filename),只能播放未加密视频,参数仅有文件路径。 既然sdk没有接口就想到了用hook,但hook它的open是没有用的,应该要hook readfile之类的函数才有用,把他读取到的byte直接替换成解密后的byte应该就能实现目的了,但是不知道如何找到hook哪个函数,如何找到读取byte文件方法呢? 希望高手给点提示?感谢!
ohyoyo2014 2017-10-13
  • 打赏
  • 举报
回复
mark 下载了。正在研究,谢谢楼主分享。
JustA21 2017-09-17
  • 打赏
  • 举报
回复
win10 64点注入直接退出了
sun_dre_cn 2017-07-03
  • 打赏
  • 举报
回复
为你点赞,必须的,HOOK C#不多啊
zhongasen 2017-04-03
  • 打赏
  • 举报
回复
首先,感谢一下楼主, 是真大神, 技术好,人好! 再次我来吐槽一下,其实国人不缺有技术的人, 缺的就是共享的精神,不管做点什么都要钱。 然而度娘,我也不想说太多,搜索出来的,都。。。。 好怀念Google和国外的一些源代码共享网站。 国内的一些共享网,下载下来的要不是病毒,就是带着一堆的广告的东西 。 楼主,关注你! 给你点100个赞!
newpowersky 2017-02-12
  • 打赏
  • 举报
回复
想 搞个时时全局得到鼠标位置的c#,就找到了这篇文章。但是看不懂。 这里的信息太丰富了。。。。。
e2d941 2016-12-22
  • 打赏
  • 举报
回复
大神,请问32位的代码在哪啊?
e2d941 2016-12-22
  • 打赏
  • 举报
回复
看不懂 copy 咦 成了 洗涮睡觉
yingfeng_ 2016-09-30
  • 打赏
  • 举报
回复
学习一下,不过DEMO,直接点"注入"就崩溃了! WIN10 X64
长空X 2016-06-14
  • 打赏
  • 举报
回复
感觉涉及到了低层,有点看不懂。。不过给楼主点个赞,教程写的很好啊
astor6688 2016-06-13
  • 打赏
  • 举报
回复
java_liyi 2016-06-06
  • 打赏
  • 举报
回复
大神 请收下我的膝盖
程序员鼓励师 2016-06-05
  • 打赏
  • 举报
回复
joyhen 2016-06-03
  • 打赏
  • 举报
回复
楼主,咱都通道中人啊,现定再看
MoshangYanYu 2016-06-03
  • 打赏
  • 举报
回复
本人才疏学浅,原理没怎么看懂。。。但是对于楼主最后那句话”我学什么是因为我喜欢什么而不是他能挣多少钱,掌握一门新语言并不难,难的是你能一直保持着最初的兴趣,我从编码中获得快乐,这对于我来讲更有意义”深表赞同
laociweizz 2016-06-03
  • 打赏
  • 举报
回复
膜拜
风吹腚腚凉 2016-06-02
  • 打赏
  • 举报
回复
妈的傻逼公司,居然屏蔽了我的收藏功能,找好回复一下标记一下了
lxllb8 2016-06-02
  • 打赏
  • 举报
回复
上帝的慈悲 2016-06-01
  • 打赏
  • 举报
回复
学习了,感谢大神
加载更多回复(9)

110,545

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 C#
社区管理员
  • C#
  • Web++
  • by_封爱
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

让您成为最强悍的C#开发者

试试用AI创作助手写篇文章吧