固定dll的加载基址的方法
调试dll的时候会有一件事情比较烦人,就是dll加载的地址不会很固定(默认设置下编译的dll基址总是0x10000000,多个同基址的dll加载时,后面的肯定会被重定位),这给前后多次调试时对比分析结果造成了一些麻烦,要解决这个问题,有两种办法。
方法一:直接修改dll文件PE头中的ImageBase为一个不大可能被占用的地址。
但是这个方法有一个小小的局限,就是有些文件是存在校验的,改了文件之后会出一些问题,比如拒绝加载之类的。 这种情况就要用第二种方法了。
方法二:动态修改dll的加载基址
当然,首先要搞清楚是哪里决定了dll的加载基址。
下面是dll的加载过程
kernel32!LoadlibraryA
->kernel32!LoadLibraryExA
->kernel32!LoadLibraryExW
->ntdll!LdrLoadDll
->ntdll!LdrpLoadDll
->ntdll!LdrpMapDll
->ntdll!LdrpCreateDllSection
->ntdll!ZwOpenFile //打开目标文件
->ntdll!ZwCreateSection //创建映射
->ntdll!ZwMapViewOfSection //映射
关键就在映射这一步~ 函数原型如下:
NTSTATUS
ZwMapViewOfSection(
IN HANDLE SectionHandle,
IN HANDLE ProcessHandle,
IN OUT PVOID *BaseAddress,
IN ULONG_PTR ZeroBits,
IN SIZE_T CommitSize,
IN OUT PLARGE_INTEGER SectionOffset OPTIONAL,
IN OUT PSIZE_T ViewSize,
IN SECTION_INHERIT InheritDisposition,
IN ULONG AllocationType,
IN ULONG Win32Protect
);
第三个参数就是要映射的基址了,关于这个参数,MSDN上有这样的说明:
BaseAddress
Pointer to a variable that receives the base address of the view. If the value of this parameter is not NULL, the view is allocated starting at the specified virtual address rounded down to the next 64-kilobyte address boundary.
也就是说,如果这个参数不是NULL的话,就会以这个地址向后对齐后作为基址,而系统加载dll时调用该函数时参数指向的值是0,也就是自行分配空闲地址
我们只需要在这里挂钩该函数,判断是目标dll在加载时,设置该值不为NULL就可以了,使其指向一个未分配的固定地址,比如0x60000000什么的~
这个挂钩可以在ring3进行也可以在ring0进行,但是ring3的话需要保证持钩的dll在目标dll之前加载,所以我干脆ring0了~
if(PreviousMode == UserMode && 是目标dll)
{
*BaseAddress = 0x60000000 ;//要固定的基址
}
return OriginalZwMapViewOfSection(SectionHandle,ProcessHandle,BaseAddress...);
在ZwMapViewOfSection的Hook函数中要判断是不是目标dll,只有一个SectionHandle参数可以用,但是单从一个SectionHandle不好判断是哪个dll(ring0可以直接取SectionObject.Segment.ControlArea.FilePointer进行判断,比较精确),我用的方法是ZwQuerySection查询这个句柄的SectionImageInformation信息,然后取ImageFileSize进行判断,这个ImageFileSize就是目标dll的真实文件大小,这个方法ring3和ring0都可以用,拿来判断问题不是很大,但是想绝对精确的话还是和ZwCreateSection时的FileHandle结合判断一下比较好~
固定dll的加载基址的方法的更多相关文章
- 模块"xxxx.dll"已加载,但对DllRegisterServer的调用失败,错误代码为 XXXXXXXXX
WIN7.WIN8 注册 卸载dll 报错: 模块"xxxx.dll"已加载,但对DllRegisterServer的调用失败,错误代码为 XXXXXXXXX 解决方法: 若为 ...
- dll的加载方式主要分为两大类,显式和隐式链接
之前简单写过如何创建lib和dll文件及简单的使用(http://blog.csdn.net/betabin/article/details/7239200).现在先再深入点写写dll的加载方式. d ...
- js实现动态加载脚本的方法实例汇总
本文实例讲述了js实现动态加载脚本的方法.分享给大家供大家参考,具体如下: 最近公司的前端地图产品需要做一下模块划分,希望用户用到哪一块的功能再加载哪一块的模块,这样可以提高用户体验. 所以到处查 ...
- 模块 DLL C:\WINDOWS\system32\inetsrv\aspnetcore.dll 未能加载。返回的数据为错误信息。
更新了win10的版本后,就启动原来的iis发布的程序 程序池就自动关闭.后来 启动网站 iis程序池自动关闭. 在为应用程序池“.NET v4.5”提供服务的工作进程“21908”中,协议“http ...
- 64位win2008下IIS未开启32位支持导致DLL无法加载问题
部署一个WEB项目,在本机.本地服务器都没有问题,但部署到远程服务器以后,提示有个DLL无法加载: Server Error in '/' Application. Could not load fi ...
- C#开发奇技淫巧二:根据dll文件加载C++或者Delphi插件
原文:C#开发奇技淫巧二:根据dll文件加载C++或者Delphi插件 这两天忙着把框架改为支持加载C++和Delphi的插件,来不及更新blog了. 原来的写的框架只支持c#插件,这个好做 ...
- Excel催化剂开源第3波-修复ExcelCom加载项失效问题及WPS可调用Com加载项的方法
为了还原一个干净无侵扰的网络世界,本文将不进行大规模地分发,若您觉得此文有用,不妨小范围地分享到真正有需要的人手中 功能概述 修复ExcelCom加载项常见问题,如每次需重新勾选COM加载项或COM加 ...
- DLL延时加载技术与资源释放
DLL延时加载技术与资源释放 0x00 前言 诸如调用非Windows的第三方库,我们或许会使用到dll文件,而这个时候原本程序运行需要相应的dll文件才能加载启动.通过DLL延时加载技术,使用延时加 ...
- Windows7 安装vs2015 之后 调试Web项目IIS启动不了 aspnetcore.dll未能加载
安装windows企业版,整整折腾了两天了,一个本身家里网络环境不好,时不时掉线,终于披荆斩棘,克服了所有困难,结果VS2015 EnterPrise 版本在调试Web环境的时候,始终在任务栏里找不到 ...
随机推荐
- Ubuntu 16.04安装Mac OS 12虚拟机资源(没成功,但资源还是可以用)
整理的Mac OS 12虚拟机资源.装虚拟机基本是按这样的套路: 1.先装VM 2.破解VM使其支持Mac OS 12,这个脚本基本是全平台支持,可以看里面的教程文档. 3.用镜像安装系统. 资源: ...
- Vue.js组件的通信之子组件向父组件的通信
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...
- 【java】java 中 byte[]、File、InputStream 互相转换
========================================================================= 使用过程中,一定要注意close()掉各个读写流!! ...
- Qt编写串口通信程序全程图文讲解 .
在Qt中并没有特定的串口控制类,现在大部分人使用的是第三方写的qextserialport类,我们这里也是使用的该类.我们可以去 http://sourceforge.net/projects/qex ...
- BUPT复试专题—最小距离查询(2013)
题目描述 给定一个由小写字母a到z组成的字符串S,其中第i个字符为S[i](下标从0开始).你需要完成下面两个操作:INSERT c 其中c是一个待输入的字符.你需要在字符串的末尾添加这个字符.保证 ...
- vim列块操作
一.可视模式 进入可视模式有三种方法:v,V,CTRL+V (1)按v启用可视模式,能够按单个字符选择内容,移动光标能够选择. 如: (2)按V启用可视模式,立马选中光标所在行.按单行符选择内容.移动 ...
- PS 如何把大嘴变小嘴
Photoshop整容教程:让MM美唇大嘴变小嘴 2009-06-17 14:15作者:佚名出处:天极网软件频道责任编辑:王健 下面就开始实际操作了. 1.首先从Photosh ...
- break 用法
// break 在循环中的功能测试 # include <stdio.h> int main(void){ int i, j; for (i = 0; i<3; ++i) { j ...
- LeetCode题解(20)--Valid Parentheses
https://leetcode.com/problems/valid-parentheses/ 原题: Given a string containing just the characters ' ...
- 设计模式学习笔记——Decorator装饰模式
装饰模式的作用或动机就是,尽量避免继承,而使用关联.原因是层层继承下来,内容会越来越多,有失控的危险.就扩展性而言,用关联比用继承好.所谓的关联,A使用了B,就叫A关联了B. Component 抽象 ...