同事遇到了一个问题(在DllMain函数之前抢控制权)
同事有个需求,他的进程会加载一个DLL,他需要在那个DLL的DllMain函数执行之前控制DLL,修改DLL的内存。
以上工作要求全部在应用层执行。
这个其实有点悲剧。
因为这个需求其实有点坑,因为需要在应用层来做,而且好多事情都是高难度事情。
最后我给提了几种解决方案。
1:HOOK LoadLibraryA/W,然后发现如果是目标DLL,那么使用LoadLibraryEx不执行DllMain加载,然后等加载成功了之后,先处理DLL,最后创建线程执行DllMain。
优点:简单方便,工作量少。
缺点:DllMain线程环境、调用栈是伪造的,可能会被检测发现。
2:为了规避上面的问题,就不能用其他函数来做了,只能乖乖使用LoadLibrary族正统的函数,刚好,有一个。
当LoadLibraryA/W抓到了目标DLL之后,可以根据文件解析它的入口点,然后再在入口点处写入一个“C3”,即“ret”,是写入文件中,
然后再调用真实的LoadLibraryA/W函数加载,之后再去找这个入口点,修复C3,最后创建线程执行DllMain。
优点:比上面还简单。只是按位置写文件即可。
缺点:工作量比较大,需要修改原模块,可能导致原模块在其他进程中无法启动,DllMain线程环境、调用栈是伪造的,可能会被检测发现。
3:如果不想那么麻烦的话,还有个办法。
当LoadLibraryA/W抓到了目标DLL之后,拷贝一份目标DLL的文件,到其他的地方,比如Temp目录,
硬编码修改DLL文件的入口点内容,到本地内存中的一个函数里面,然后直接放行加载即可,这样,在模块加载之后,立刻就会从DllMain入口跳转到我们的函数中。而且不会有副作用。
但是为了它,我们实际上是模拟了整个一套API的接口,来让它以为自己是运行在正确的环境中的。
优点:对原模块没有修改,DLL启动之后,入口点会直接调用我们的函数。
缺点:工作量很大,路径被替换了,所以要多HOOK几个其他的函数,如GetModuleHandleA/W、GetModuleFileName、GetModuleFileNameEx等,在LoadLibraryA/W中,也需要判断模块是否已经加载,如果已经加载,则直接返回已经加载的模块handle。
最新文章
- Spring学习笔记之五----Spring MVC
- JCCLIENT IP GET UDP
- eclipse 3.6 + tomcat 6.0 开发SSH框架学习
- 理解Java中的弱引用(Weak Reference)
- Codeforces Round #375 (Div. 2) A B C D F
- javascript作用域和作用域链摘录
- 我为什么选择使用Go语言?
- 深入浅出OOP(三): 多态和继承(动态绑定/运行时多态)
- RecyclerView的使用方法
- mybatis-generator 代码自动生成工具
- HDU 5312 Sequence (规律题)
- SQL Server中使用convert进行日期转换
- ASP.NET MVC轻教程 Step By Step 5——初识表单
- Ubuntu 12.04 下安装 Eclipse
- hdu1867之KMP
- Fabric单节点安装备忘
- MySQL数据库 Too many connections
- Ubuntu18.04安装SS(不是服务器端!!!)
- HoloLens开发手记-全息Hologram
- Atitit 项目文档规范化与必备文档与推荐文档列表
热门文章
- 浏览器报406 错误:The resource identified by this request is only capable of generating responses with characteristics not acceptable according to the request ";accept"; headers
- linux性能分析工具Vmstat
- C/C++字符串和其他类型转换
- Java代码乱象!
- (转载)python判断一个字符串是否是小数
- Winfrom 弹出窗体位置设定
- 正确读取resources目录下的文件
- Delphi abstract error异常
- SpringMvc处理模型数据(也就是从数据库中查询出来的数据放到请求域中)
- php strcasecmp()函数 语法