劫持DLL自动注入(delphi)
文章目录
用代码解析劫持dll自动注入的原理.可hook,编写外挂,木马,游戏MOD,破解补丁等用处.
原理
游戏运行的时候,会调用很多DLL文件.比如D3D9.DLL
D3D9.dll默认在系统目录,而不是游戏目录,如果游戏目录中有个相同文件.那么游戏会优先调用游戏目录的D3D9.dll文件,而不是系统目录的.
这就是劫持DLL自动注入的基本原理.比较简单.
虽然可以通过在游戏目录放一个DLL劫持,但是还是要执行原DLL里面的函数.不然游戏进程可能都无法运行.
我今天要劫持的文件是AudioSes.dll,这个是微软基本的声音dll文件.凡是游戏基本上都会调用这个dll.通用性比较高.而且不发声的其他游戏目录的程序不调用这个dll文件.可以比较友好的针对游戏进程.(因为游戏进程才发声音.比如腾讯游戏目录还有个TP,TP并不发声音不调用这个dll,它就不会被劫持注入.)
而且这个dll导入函数比较少,就算劫持代码出现问题,顶多导致游戏没有声音而已,最少游戏进程还是能执行的.调整好代码或者删除劫持的dll游戏就会恢复正常声音.
另外一个好处就是这个DLL
拿这个上手是'风险'最小的.
上代码
首先需要建一个DLL项目.项目名字就是AudioSes
首先需要定义5个指针声明,5个函数原型,对应AudioSes导出导出函数,写在项目顶部的var里面
POldDllCanUnloadNow: Pointer;
POldDllGetActivationFactory: Pointer;
POldDllGetClassObject: Pointer;
POldDllRegisterServer: Pointer;
POldDllUnregisterServer: Pointer;
procedure DllCanUnloadNow; asm jmp [POldDllCanUnloadNow] end;
procedure DllGetActivationFactory; asm jmp [POldDllGetActivationFactory] end;
procedure DllGetClassObject; asm jmp [POldDllGetClassObject] end;
procedure DllRegisterServer; asm jmp [POldDllRegisterServer] end;
procedure DllUnregisterServer; asm jmp [POldDllUnregisterServer] end;
然后添加5个导出声明,这就完全就是AudioSes相同的导出函数
exports
DllCanUnloadNow,
DllGetActivationFactory,
DllGetClassObject,
DllRegisterServer,
DllUnregisterServer;
为了32位和64位兼容.可以定义常量,64位直接用32位系统文件也是可以的.此步可能有点画蛇添足.
const
{$IF Defined(CPUX86)}
xpath = 'system32';
{$ELSEIF Defined(CPUX64)}
xpath = 'SysWOW64';
{$IFEND}
而真正的核心代码就几行在begin里,变量自己定义ModHandle: Cardinal;dll_path:string;
begin
dll_path := GetEnvironmentVariable('SYSTEMROOT') + '\'+ xpath + '\AudioSes.dll' ;
ModHandle:= LoadLibrary(PWideChar( dll_path) ); //调用原dll.
if ModHandle > 0 then
begin
POldDllCanUnloadNow:= GetProcAddress(ModHandle, 'DllCanUnloadNow'); //取对应模块地址地址
POldDllGetActivationFactory:= GetProcAddress(ModHandle, 'DllGetActivationFactory');
POldDllGetClassObject:= GetProcAddress(ModHandle, 'DllGetClassObject');
POldDllRegisterServer:= GetProcAddress(ModHandle, 'DllRegisterServer');
POldDllUnregisterServer:= GetProcAddress(ModHandle, 'DllUnregisterServer');
end;
begin
inject_exe; 函数,或者直接代码写这里,也就是注入后要实现的功能.
end;
end.
执行过程
游戏执行-->调用AudioSes.dll(假)-->执行假dll的 inject_exe函数 --> 游戏如果欲调用DllRegisterServer --> 假dll DllRegisterServer 获取 真dll 对应DllRegisterServer函数模块地址 --> asm jump 跳转 实现函数的无缝对接.