用代码解析劫持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 跳转 实现函数的无缝对接.