为什么当我重新启动窗口时,这个函数调用偏移移动


3

每次我重新启动Windows时,它会将我对一个可执行文件所做的补丁打破,我已经从dll user32.dll中调用了一个函数。目前函数调用的偏移量驻留在0x76E3CDB4,但是当我重新启动计算机时,它将更改为其他地址。为什么是这样的,我能做些什么来确保我的汇编代码始终正确地调用函数?

+3

阅读地址空间布局随机化又名aslr 06 11月. 172017-11-06 02:48:07

4

这可能是由于地址空间布局随机 又名ASLR(例如,参见this overview by Symantec

系统模块的加载地址随机化在每次引导和 可执行映像被在OS每次执行随机> Vista的

可以检查一些简单的代码,这样

:\>cat aslr.cpp 
#include <windows.h> 
#include <stdio.h> 
void main (void) 
{ 
    HMODULE hMod = LoadLibraryA("user32.dll"); 
    if(hMod){ 
     printf("My Load Addr\t%p My user Addr\t%p\n" , &main,hMod); 
     FreeLibrary(hMod); 
    } 
} 

编译和执行结果如下

:\>for /L %i in (1,1,10) do aslr.exe 

:\>aslr.exe 
My Load Addr 00121000 My user Addr 773A0000 

:\>aslr.exe 
My Load Addr 00031000 My user Addr 773A0000 

:\>aslr.exe 
My Load Addr 00FB1000 My user Addr 773A0000 

:\>aslr.exe 
My Load Addr 002F1000 My user Addr 773A0000 

:\>aslr.exe 
My Load Addr 011B1000 My user Addr 773A0000 

:\>aslr.exe 
My Load Addr 011B1000 My user Addr 773A0000 

:\>aslr.exe 
My Load Addr 011B1000 My user Addr 773A0000 

:\>aslr.exe 
My Load Addr 011B1000 My user Addr 773A0000 

:\>aslr.exe 
My Load Addr 00181000 My user Addr 773A0000 

:\>aslr.exe 
My Load Addr 01121000 My user Addr 773A0000 

,以确保你打补丁的权利,你应该用RVA(相对虚拟地址)工作

那就是每次都获得模块的基础,并添加一个固定偏移您之前每次确定

假设你修补@ 0×12345678,当你修补的模块是在0x10000000加载,那么你有0x2345678

下一个时间差,如果模块在0x20000000加载,可以使用地址0x2000.0000 + 0x2345678 == 0x22345678