固定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结合判断一下比较好~

时间: 2024-12-29 11:55:25

固定dll的加载基址的方法的相关文章

dll注册加载失败解决方法

当输入命令regsvr32 A.dll注册时,跳出下面错误提示: 模块C:\windows\System32\A.dll加载失败. 请确保该二进制存储在指定的路径中,或者调试它检查该二进制或相关的 .DLL文件是否有问题 查了很多资料,总而言之是64位系统的system32与syswow64的混淆原因,解决方法就是到syswow64目录下使用regsvr32 命令.但我根据这种解决方法,还是不能解决问题. 这里感谢老师提醒,在次与大家分享. B.dll的生成引用了A.dll,在注册B.dll时出

DLL动态加载时调用类成员函数小结

//dll 动态加载  调用 类 函数小结: 静态加载时,调用类成员函数,很简单.此次研究了下动态加载. 首先困难点:The first problem is that C++ member function names are decorated names (Specifying extern "C" does not help).The second problem is that C++ language specifications do not allow pointer

CS0009:未能打开元数据文件System.ComponentModel.DataAnnotations.dll 试图加载格式不正确的程序。

问题描述: CS0009: 未能打开元数据文件“c:\Windows\Microsoft.NET\assembly\GAC_MSIL \System.ComponentModel.DataAnnotations\v4.0_4.0.0.0__31bf3856ad364e35 \System.ComponentModel.DataAnnotations.dll”--“试图加载格式不正确的程序. 网上搜索出来的资源比较少,修复VS也没有用,特地写这小文章. 试了网上方法: 把"C:\Windows\M

64位win2008下IIS未开启32位支持导致DLL无法加载问题

部署一个WEB项目,在本机.本地服务器都没有问题,但部署到远程服务器以后,提示有个DLL无法加载: Server Error in '/' Application. Could not load file or assembly 'Common.Component.Repository' or one of its dependencies. An attempt was made to load a program with an incorrect format. 首先肯定的是,系统声称无法

[ida] 重新设置文件加载基址

当动态调试的时候,跟踪到dll中的函数,由于dll动态加载,dll的动态地址不方便在IDA中定位,那么IDA有一项功能可以重新设置EXE/DLL在IDA中的加载基址.

js实现动态加载脚本的方法实例汇总

本文实例讲述了js实现动态加载脚本的方法.分享给大家供大家参考,具体如下: 最近公司的前端地图产品需要做一下模块划分,希望用户用到哪一块的功能再加载哪一块的模块,这样可以提高用户体验. 所以到处查资料研究js动态脚本的加载,不过真让人伤心啊!,网上几乎都是同一篇文章,4种方法,讨厌其中拷贝别人成果的人,也不加个原文的链接.哎!关键是最后一种方法还有点错误.经过两天的研究查阅资料,在这里和大家分享一下. 首先我们需要一个被加载的js文件,我在一个固定文件夹下创建了一个package.js,打开后在

C#开发奇技淫巧二:根据dll文件加载C++或者Delphi插件

原文:C#开发奇技淫巧二:根据dll文件加载C++或者Delphi插件 这两天忙着把框架改为支持加载C++和Delphi的插件,来不及更新blog了.      原来的写的框架只支持c#插件,这个好做,直接用c#的反射功能便可.但是公司不是所有人都搞C#,也不是所有的程序C#都能很好的完成,又或者其他公司提供的API不是C#的,这个时候,就需要这个框架能够支持多种语言了.      废话不多说,进入正题.     上网一搜,C#加载非托管的dll,无非就是使用 DllImportAttribut

Excel催化剂开源第3波-修复ExcelCom加载项失效问题及WPS可调用Com加载项的方法

为了还原一个干净无侵扰的网络世界,本文将不进行大规模地分发,若您觉得此文有用,不妨小范围地分享到真正有需要的人手中 功能概述 修复ExcelCom加载项常见问题,如每次需重新勾选COM加载项或COM加载项被列入禁用清单中不用使用,同时也提供让WPS计用COM加载项的方法 使用场景 因用户在使用COM技术开发的加载项过程中,难免各种意外操作,致使加载项处理非活动状态或失效状态,虽然可以通过界面的方式去解决,但步骤偏多,对普通用户来说,较难以去理解及操作,将其封装成一个exe文件,让用户自行双击运行

优化加载jQuery的方法

请看下面的一段代码: 1 <script src="http://ajax.googleapis.com/ajax/libs/jquery/2.0.3/jquery.min.js"></script> 2 <script type="text/javascript"> 3 window.jQuery || document.write("<script src='__ADMIN_JS__/jquery-2.0.3.