武.林.外.传 主进程 hook 相关 delphi 代码

Delphi编程实现Windows键盘消息Hook技术 本文还有配套的精品资源,点击获取 简介:Hook技术在IT领域用于监控和控制系统或应用程序中的特定事件,如键盘输入。在Delphi 7.0环境下,可以通过Windows API实现键盘Hook。本文深入探讨了如何设置Hook,定义回调函数,安装和卸载Hook,以及处理多线程环境下的问题。这允许开发者在Delphi中拦截和处理键盘消息,以实现系统监控、安全软件或游戏外挂等功能... 阅读详情

elementclient HOOK 文档.doc

 

修改 elementclient.exe 文件步骤

一.

1.patcher.dll   中的 hook_p();    函数的主要功能是修改 elementclient.exe 文件,让其启动时,自动加载我们的插件文件 sougoupy.dll。

2.hook_p 函数首先备份 elementclient.exe  防止我们的程序修改后,游戏不能运行,方便用户修复使用。

3.hook_p 修改 elementclient.exe 文件,把插件 sougoupy.dll 的全路径写到其代码段的零区域,此处文件地址定位:0x797801。

4.执行文件 hook 的地址如下:

   

 (图 1.1)

00B97729     0000           add byte ptr ds:[eax],al

00B9772B     0000           add byte ptr ds:[eax],al

00B9772D     0000           add byte ptr ds:[eax],al

00B9772F     0000           add byte ptr ds:[eax],al

00B97731     0000           add byte ptr ds:[eax],al

00B97733     0000           add byte ptr ds:[eax],al

00B97735     0000           add byte ptr ds:[eax],al

00B97737     0000           add byte ptr ds:[eax],al

00B97739     0000           add byte ptr ds:[eax],al

00B9773B     0000           add byte ptr ds:[eax],al

PS:以上的地址将会写入具体的 hook 代码,然后跳转回 (图 1.1)所指定的地址。 

修改后的 hook  code 代码为:

00B97729     60             pushad

00B9772A     68 0178B900    push elementc.00B97801       ; ASCII "C:\win\hell\1.dll"

00B9772F     FF15 9482B900  call dword ptr ds:[<&KERNEL32.LoadLibraryA>] ; kernel32.LoadLibraryA

00B97735     61             popad

00B97736     8965 E8        mov dword ptr ss:[ebp-18],esp

00B97739     33DB           xor ebx,ebx

00B9773B   ^ E9 4898F7FF    jmp elementc.00B10F88

//二进制为:

60 68 01 78 B9 00 FF 15 94 82 B9 00 61 89 65 E8 33 DB E9 48 98 F7 FF

 

patcher HOOK 文档.doc

 

修改 Patcher.exe 文件步骤

一.

1.在文件偏移 $64100 处,写入外部dll 所在的全路径。(ps:此处的外部 dll,功能为拦截住用户点“开始”游戏时,保证 elementclient.exe 文件被正确改正。)

此处外部 dll 名称定义为:patcher.dll  

2.我们的启动程序做的 inline hook :

  

               (图 1.1)

上图画红框的地址,为我们需要inline  hook 的地址。

00464035     0000            add byte ptr ds:[eax],al   //上图 hook 后会跳转到此处做

00464037     0000            add byte ptr ds:[eax],al   //加载外部 dll 的工作,然后跳转

00464039     0000            add byte ptr ds:[eax],al  // 回到地址:0x443723

0046403B     0000            add byte ptr ds:[eax],al

0046403D     0000            add byte ptr ds:[eax],al

0046403F     0000            add byte ptr ds:[eax],al

       

                      (图 1.2  patcher.exe 的IAT 表)

Ps: iat 表用于汇编写入时,调用系统动态库。

3.Hook

A.

0044371E    /E9 12090200     jmp patcher.00464035   //已经修改的地址

//二进制代码:E9 12 09 02 00

对应的文件地址为 : 0044371E - 400000 = 4371E

修改长度:5 字节

B.

00464035    > \60            pushad

00464036    .  68 00414600   push patcher1.00464060

0046403B       FF15 DC504600 call dword ptr ds:[<&KERNEL32.LoadLibraryA>]

00464041       61            popad

00464042       E8 6047FEFF   call patcher1.004487A7

00464047     ^ E9 D7F6FDFF   jmp patcher1.00443723

//二进制代码:60 68 00 4146 00 FF 15 DC 50 46 00 61 E8 60 47 FE FF E9 D7 F6 FD FF

对应的文件地址为 : 00464035 - 400000 = 64035

修改长度:23 字节

4.备份 patcher.exe 文件细节。

 A.我们的启动程序首先判断是否存在配置文件,不存在则直接拷贝一份命名为:patcher.exe.bak。

B.当存在备份文件时,修改代码之前,对比我们记录在配置文件中的 lastmd5 值(此值为修改后的 patcher.exe 文件的 md5),如果此时的 patcher.exe 的 md5 值跟 lastmd5  不同时,则说明游戏对 patcher.exe 文件有更新,此时我们再拷贝一份新的 patcher.exe 为 patcher.exe.bak。

C.这样有效的保证了当我们软件修改 patcher.exe 后导致无法运行游戏,用户可以通过我们的软件修复 patcher.exe 文件。

二.

Patcher.dll  做的工作如下:

1.在 CreateProcessW 处进行跳转 hook.

CreateProcessW:

7C802336 k>  8BFF           mov edi,edi

7C802338     55             push ebp

7C802339     8BEC           mov ebp,esp

7C80233B     6A 00          push 0

7C80233D     FF75 2C        push dword ptr ss:[ebp+2C]

7C802340     FF75 28        push dword ptr ss:[ebp+28]

修改为:

7C802336 k>- E9 151DC683    jmp patcher.00464050

7C80233B     6A 00          push 0

7C80233D     FF75 2C        push dword ptr ss:[ebp+2C]

7C802340     FF75 28        push dword ptr ss:[ebp+28]

7C802343     FF75 24        push dword ptr ss:[ebp+24]

Hook 代码处添加为:

00464050     60             pushad

00464051     68 F0404600    push patcher.004640F0

00464056     FF15 DC504600  call dword ptr ds:[<&KERNEL32.LoadLibraryA>]  ; kernel32.LoadLibraryA

0046405C     68 E8404600    push patcher.004640E8

00464061     50             push eax

00464062     B8 40AE807C    mov eax,kernel32.GetProcAddress

00464067     FFD0           call eax

00464069     FFD0           call eax

0046406B     61             popad

0046406C     B8 3623807C    mov eax,kernel32.CreateProcessW

00464071     83C0 05        add eax,5

00464074     8BFF           mov edi,edi

00464076     55             push ebp

00464077     8BEC           mov ebp,esp

00464079     FFE0           jmp eax

PS:由于 IAT 表,对于 GetProcAddress,CreateProcessW 两个函数地址的记录不完全,所以需要在 patcher.dll 模块中,计算函数地址,然后再次写入回去即可。

//***************************************************

同时添加字符串("hook_p","patcher.dll"):

004640E8     68 6F6F6B5F    push 5F6B6F6F

004640ED     70 00          jo short patcher.004640EF

004640EF     0070 61        add byte ptr ds:[eax+61],dh

004640F2     74 63          je short patcher.00464157

004640F4     68 65722E64    push 642E7265

004640F9     6C             ins byte ptr es:[edi],dx

004640FA     6C             ins byte ptr es:[edi],dx

PS:此时,当玩家点击游戏的 “开始”按钮时,就会首先执行我们的 hook_p 函数

 

 

library patcher;

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls,Registry,shellapi,MD5,IniFiles;

//-------------------  patcher.exe ---------------
const PAGE_EXECUTE_READWRITE = $40;
const hook_array_jmp:array[0..4] of byte = ($E9,$15,$1D,$C6,$83);
const hook_array_string:array[0..19] of Byte =($68,$6F,$6F,$6B,$5F,$70,$00,
                                              $00,$70,$61,$74,$63,$68,$65,
                                              $72,$2E,$64,$6C,$6C,$00);
const hook_array_code:array[0..42] of byte = ($60,$68,$F0,$40,$46,$00,$FF,
                                              $15,$DC,$50,$46,$00,$68,$E8,
                                              $40,$46,$00,$50,$B8,$40,$AE,
                                              $80,$7C,$FF,$D0,$FF,$D0,$61,
                                              $B8,$36,$23,$80,$7C,$83,$C0,
                                              $05,$8B,$FF,$55,$8B,$EC,$FF,
                                              $E0);
 //-------------------- elementclient.exe  ---------
const element_hook_array_jmp:array[0..4] of byte = ($E9,$A1,$67,$08,$00);
const element_hook_array_code:array[0..22] of byte = ($60,$68,$01,$78,$B9,
                                              $00,$FF,$15,$94,$82,$B9,$00,
                                              $61,$89,$65,$E8,$33,$DB,$E9,
                                              $48,$98,$F7,$FF);
var
  thisDllIni:TIniFile;
  ini_fileName:string = 'config.ini';                                           //配置文件名称
  //-------------------  patcher.exe ---------------
  iat_patcher_createProcessW_add:DWORD;                                         // iat 表中 CreateProcessW 函数地址
  iat_patcher_virtualProtectEx_add:DWORD;                                       //iat 表中  VirtualProtectEx 函数地址
  getprocaddress_add:dword;
  patcher_dll_name:string = 'patcher.dll';                                      //patcher 中的 dll 名称
  plugin_dll_name:string = 'sogoupy.dll';                                       //插件的名称
  work_dirpath:string;                                                          //工作目录
  current_dirpath:string;                                                       //当前模块所在路径
  elementclient_path:string;                                                    //游戏客户端路径
  elementclient_file_name:string = 'elementclient.exe';                         //游戏客户端名字
  hook_jmp_add:dword;                                                           //hook 代码跳转的地址
  hook_code_add:dword = $464050;                                                //hook 代码的地址
  hook_add_string_addr:DWORD = $4640e8;                                         //添加字符串到更新程序中
  plugin_pathAdd_toWrite_inPatcher:dword = $64100;                              //插件全路径在游戏中的记录
 //-------------------- elementclient.exe  ---------
  element_plugin_full_path_add:dword = $00B97801 - $400000;                     //在游戏文件中,插件的全路径
  element_jmp_file_hook_add:dword = $00B10F83 - $400000;                        //在文件中 hook 的地址
  element_code_file_hook_add:dword = $00B97729 - $400000;                       //在文件中写入 hook code 的地址
{$R *.res}
//***********************************************
procedure getFuncAdd();                                                         //获取函数地址
var
  h:dword;
begin
  h:=LoadLibraryA('kernel32.dll');
  iat_patcher_createProcessW_add:=DWORD(GetProcAddress(h,'CreateProcessW'));
  iat_patcher_virtualProtectEx_add:=DWORD(GetProcAddress(h,'VirtualProtectEx'));
  getprocaddress_add:=DWORD(GetProcAddress(h,'GetProcAddress'));
  FreeLibrary(h);
end;

//************************************************                              //修改内存属性
function modifyMemory(startAdd,attr,size:dword):Boolean;
var
  retValue:dword;
  hProcess:dword;
  num:dword;
  c:pointer;
begin
  hProcess:=GetCurrentProcess();
  result:=false;
  retValue:=0;
  c:=@num;                                                                      //此处一定要用指针,否则函数执行失败
   asm
      pushad
      mov ecx,c
      push ecx
      mov ebx,attr
      push ebx
      mov ebx,size
      push ebx
      mov ebx,startAdd
      push ebx
      mov ebx,hProcess
      push ebx
      mov ebx,iat_patcher_virtualProtectEx_add
      call ebx
      mov retValue,eax
      popad
   end;
   if(retValue <> 0) then result:=true;
end;
//***********************************************
procedure hook_process_modify();                                                //hook CreateProcess
begin

  getFuncAdd();
  hook_jmp_add:= iat_patcher_createProcessW_add;

  modifyMemory(hook_jmp_add,PAGE_EXECUTE_READWRITE,5);                          //修改内存属性
  modifyMemory(hook_code_add,PAGE_EXECUTE_READWRITE,42);                        //修改内存属性
  modifyMemory(hook_add_string_addr,PAGE_EXECUTE_READWRITE,20);                 //修改内存属性

  asm
    pushad                                                                      //执行内存写入  jmp
     lea eax,hook_array_jmp
     xor ecx,ecx
     mov ebx,hook_jmp_add
     @back:
     mov dl,Byte ptr[eax]
     mov Byte ptr[ebx],dl
     inc eax
     inc ebx
     inc ecx
     cmp ecx,5
     jnz @back
    popad
  end;

  asm
    pushad                                                                      //执行内存写入  code
     lea eax,hook_array_code
     xor ecx,ecx
     mov ebx,hook_code_add
     @back:
     mov dl,Byte ptr[eax]
     mov Byte ptr[ebx],dl
     inc eax
     inc ebx
     inc ecx
     cmp ecx,43
     jnz @back
    popad
  end;

  asm
    pushad                                                                      //执行内存写入 string
     lea eax,hook_array_string
     xor ecx,ecx
     mov ebx,hook_add_string_addr
     @back:
     mov dl,Byte ptr[eax]
     mov Byte ptr[ebx],dl
     inc eax
     inc ebx
     inc ecx
     cmp ecx,20
     jnz @back
    popad
  end;

  asm                                                                           //再次修改函数地址
    mov eax,hook_code_add
    add eax,19
    mov ebx,getprocaddress_add
    mov [eax],ebx

    mov eax,hook_code_add
    add eax,29
    mov ebx,iat_patcher_createProcessW_add
    mov [eax],ebx
  end;
end;
//***********************************************                               //修改 elementclient.exe 文件
function modify_elementclient_file(gm_path,plug_full_path:string):boolean;
var
  f:THANDLE;
  ret:Boolean;
  num,zero:dword;
  ret_offset:dword;
  md5_file_exe:string;
  md5_last_modify:string;
  ini_dll_full_path:string;
begin
  result:=false;
  md5_file_exe:=MD5DigestToStr(MD5File(gm_path));
  md5_last_modify:=thisDllIni.ReadString('elementclient','lastmd5','');
  ini_dll_full_path:= thisDllIni.ReadString('elementclient','dllpath','');
  if(not FileExists(gm_path + '.bak')) then
  begin
    copyfile(PChar(gm_path),PChar(gm_path + '.bak'),false);
  end
  else
  begin
    if(FileExists(work_dirpath + ini_fileName)) then                            //如果配置文件存在
     begin
       if(Trim(md5_last_modify) <> '') then                                     //如果配置文件中 lastmd5 节点不为空
       begin
         if(md5_file_exe <> md5_last_modify) then
          begin
           copyfile(PChar(gm_path),PChar(gm_path + '.bak'),false);
          end;
       end;
     end;
  end;

if(md5_last_modify = '') or (md5_last_modify <> md5_file_exe) or
   (ini_dll_full_path = '') or
   (ini_dll_full_path <> MD5DigestToStr(MD5String((plug_full_path)))) then
begin
 f:=CreateFileA(
                 PChar(gm_path),
                 GENERIC_ALL,
                 0,
                 nil,
                 OPEN_EXISTING,
                 FILE_ATTRIBUTE_NORMAL,
                 0);

   if(f = INVALID_HANDLE_VALUE) then                                            //打开文件失败
   begin
      ShowMessage('插件无法加载,请关闭所有正在运行的游戏再重试');
      Exit;
   end;

  ret_offset:=SetFilePointer(f,element_plugin_full_path_add,nil,FILE_BEGIN);
  if(ret_offset <> element_plugin_full_path_add) then                           //在文件中移动指针失败
  begin
    ShowMessage('移动文件指针失败');
    Exit;
  end;

  //将插件的全路径写入目标程序中
  ret:= writefile(f,dword(Pointer(plug_full_path)^),length(plug_full_path),num,nil);
  if(not ret) then Exit;
  zero:=0;
  writefile(f,zero,1,num,nil);
  //执行 hook 文件的写入 ---- element_jmp_file_hook_add

  ret_offset:=SetFilePointer(f,element_jmp_file_hook_add,nil,FILE_BEGIN);
  if(ret_offset <> element_jmp_file_hook_add) then                           //在文件中移动指针失败
  begin
    ShowMessage('移动文件指针失败');
    Exit;
  end;
  ret:= writefile(f,element_hook_array_jmp,5,num,nil);
  if(not ret) then Exit;


  ret_offset:=SetFilePointer(f,element_code_file_hook_add,nil,FILE_BEGIN);
  if(ret_offset <> element_code_file_hook_add) then                           //在文件中移动指针失败
  begin
    ShowMessage('移动文件指针失败');
    Exit;
  end;
  ret:= writefile(f,element_hook_array_code,23,num,nil);
  if(not ret) then Exit;
 
  CloseHandle(f);
  thisDllIni.WriteString('elementclient','lastmd5',MD5DigestToStr(MD5File(gm_path)));
  thisDllIni.WriteString('elementclient','dllpath',MD5DigestToStr(MD5String(plug_full_path)));
 end;
 result:=True;
end;
//***********************************************                               //导出函数,主要用于修改 elementclient.exe 程序
procedure hook_p();
var
  ret:Boolean;
  dllPath:string;
  plugin_dll_full_path:string;
  position:integer;
  gameClientFullPath:string;
begin
  dllPath:= PChar(plugin_pathAdd_toWrite_inPatcher + $400000);
  if(dllPath = '') then
  begin
   showmessage('获取工作目录路径失败');
   Exit;
  end;

  dllPath:=ExtractFilePath(dllPath);
  if(dllPath = '') then
  begin
    ShowMessage('获取的工作目录参数错误');
    Exit;
  end;

  work_dirpath:=dllPath;
  plugin_dll_full_path:=dllPath + plugin_dll_name;                              //插件的全路径
  current_dirpath:=ExtractFilePath(Application.ExeName);
  position:=Pos('patcher',current_dirpath);                                     //获得上层目录字符串

  elementclient_path:=Copy(current_dirpath,1,position - 1);
  elementclient_path:= elementclient_path + 'element\';                         //拼接路径
  gameClientFullPath:=elementclient_path + elementclient_file_name;             //游戏客户端全路径
  thisDllIni:=TIniFile.Create(work_dirpath + ini_fileName);
  ret:=modify_elementclient_file(gameClientFullPath,plugin_dll_full_path);
  thisDllIni.Free;
end;
//***********************************************
exports
  hook_p;
//***********************************************
begin
  hook_process_modify();
end.
 

 

 

 

unit StartGame;

interface
uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls,Registry,shellapi,MD5,IniFiles;
//------------------------------------------------
procedure modify_file();                                                        //修改 patcher 文件

//------------------------------------------------
const hook_array_jmp:array[0..4] of byte = ($E9,$12,$09,$02,$00);               //hook 跳转代码
const hook_array_code:array[0..22] of byte = (                                  //hook 修改的代码
      $60,$68,$00,$41,$46,$00,$FF,$15,$DC,$50,$46,$00,
      $61,$E8,$60,$47,$FE,$FF,$E9,$D7,$F6,$FD,$FF);
var
  thisSoftIni:TIniFile;
  update_class_Name:string = 'ZPerfectWorldPatcherClass';
  patcher_path:string;                                                          //game patcher.exe 文件的全路径
  gm_path_registry:string = 'Software\PWRD\zhuxian2';                           //在注册表中保存游戏路径的键
  gm_registry_key:string = 'launcher';                                          //键值
  plugin_name:string = 'patcher.dll';                                           //外部动态库插件名称
  hook_add_jmp_file_offset:DWORD = $4371E;                                      //hook修改文件偏移
  hook_add_jmp_code_offset:DWORD = $64035;                                      //hook修改文件偏移
  plugin_pathAdd_toWrite_inPatcher:dword = $64100;                              //pathcer 文件偏移,用于写入插件的工作目录
  this_soft_ini_fileName:string = 'config.ini';                                 //本软件的配置文件名称
implementation
uses Unit1;

//**********  从注册表中读取游戏路径   **********
function getGamePathFromRegistry():string;
var
  ARegistry : TRegistry;
begin
  ARegistry := TRegistry.Create;
  result:='';
   with ARegistry do
   begin
     RootKey:=HKEY_CURRENT_USER;
      if OpenKey(gm_path_registry,false) then
      begin
        result:=ReadString(gm_registry_key);
      end;
      CloseKey;
      Destroy;
   end;
end;

//**************   修改文件 ***********************
procedure modify_patcher();
var
  plugin_dir:string;
  str_to_write:string;
  f:THANDLE;
  ret_offset:dword;
  ret:boolean;
  num:dword;
  zero:Byte;
  md5_file_exe,md5_file_exe_bak:string;
  md5_last_modify:string;
  ini_dll_full_path:string;
begin
   patcher_path:= Trim(getGamePathFromRegistry());
   if(patcher_path = '') then Exit;
   //备份 patcher 文件
   if(not FileExists(PChar(patcher_path+'.bak'))) then
   begin
    copyfile(PChar(patcher_path),PChar(patcher_path + '.bak'),false);
   end
   else
   begin
     if(FileExists(this_soft_ini_fileName)) then                                //如果配置文件存在
     begin
       md5_last_modify:=thisSoftIni.ReadString('patcher','lastmd5','');
       if(Trim(md5_last_modify) <> '') then                                     //如果配置文件中lastmd5节点不为空
       begin
         md5_file_exe:=MD5DigestToStr(MD5File(patcher_path));
         if(md5_file_exe <> md5_last_modify) then
          begin
           copyfile(PChar(patcher_path),PChar(patcher_path + '.bak'),false);
          end;
       end;
      
     end;
   end;
   plugin_dir:= ExtractFilePath(Application.ExeName);
   str_to_write:= plugin_dir + plugin_name;                                     //需要加载 dll 的全路径

   ini_dll_full_path:=thisSoftIni.ReadString('patcher','dllpath','');

   if(ini_dll_full_path = '') or (ini_dll_full_path <> MD5DigestToStr(MD5File(str_to_write))) then
   begin
   f:=CreateFileA(
                 PChar(patcher_path),
                 GENERIC_ALL,
                 0,
                 nil,
                 OPEN_EXISTING,
                 FILE_ATTRIBUTE_NORMAL,
                 0);

   if(f = INVALID_HANDLE_VALUE) then Exit;                                      //打开文件失败

   ret_offset:=SetFilePointer(f,plugin_pathAdd_toWrite_inPatcher,nil,FILE_BEGIN);
   if(ret_offset <> plugin_pathAdd_toWrite_inPatcher) then Exit;                //在文件中移动指针失败

   ret:= writefile(f,dword(Pointer(str_to_write)^),length(str_to_write),num,nil);
   if(not ret) then Exit;                                                       //写入外部dll路径失败
   zero:=0;
   writefile(f,zero,1,num,nil);
   thisSoftIni.WriteString('patcher','dllpath',MD5DigestToStr(MD5File(str_to_write)));                    //写入配置文件
   CloseHandle(f);
   end;
end;

//*****  修改代码,让其主动加载外部 dll  **********
function modify_code_for_load_dll():boolean;
var
  f:THANDLE;
  ret:boolean;
  last_md5_str:string;
  ret_offset,num:dword;
begin
   result:=false;
   last_md5_str:=thisSoftIni.ReadString('patcher','lastmd5','');
   if (last_md5_str = '') or (MD5DigestToStr(MD5File(patcher_path)) <> last_md5_str) then
   begin
   f:=CreateFileA(
                 PChar(patcher_path),
                 GENERIC_ALL,
                 0,
                 nil,
                 OPEN_EXISTING,
                 FILE_ATTRIBUTE_NORMAL,
                 0);
                
  if(f = INVALID_HANDLE_VALUE) then Exit;                                      //打开文件失败
  ret_offset:=SetFilePointer(f,hook_add_jmp_file_offset,nil,FILE_BEGIN);
  if(ret_offset <> hook_add_jmp_file_offset) then Exit;                        //在文件中移动指针失败
  ret:= writefile(f,hook_array_jmp,5,num,0);
 
   ret_offset:=SetFilePointer(f,hook_add_jmp_code_offset,nil,FILE_BEGIN);
  if(ret_offset <> hook_add_jmp_code_offset) then Exit;                        //在文件中移动指针失败
  ret:= writefile(f,hook_array_code,23,num,0);
  CloseHandle(f);
  thisSoftIni.WriteString('patcher','lastmd5',MD5DigestToStr(MD5File(patcher_path)));
  end;
  Result:=True;
end;
//*************************************************                             //修改文件入口函数
procedure modify_file();
var
  h:hwnd;
begin
  h:=FindWindow(PChar(update_class_Name),nil);
  if(h <> 0) then
  begin
    ShowMessage('你已经运行了一个更新程序');
    Exit;
  end;
 thisSoftIni:= TIniFile.Create(ExtractFilePath(Application.ExeName)+this_soft_ini_fileName);
 modify_patcher();
 modify_code_for_load_dll();
 thisSoftIni.Free;
end;

//**************************************************
end.

 

Delphi键盘Hook技术实例分析与应用 在Delphi中,函数被封装在一个更容易使用的声明中,同时Delphi提供了几个辅助函数,使得钩子的安装和管理变得更加直观。一个典型的Delphi中设置钩子的示例代码如下:stdcall;beginend;这里,idHook参数和lpfn参数与C++中相对应,而hInst参数是目标模块的句柄,0表示当前进程。Windows消息机制是整个Windows应用程序的核心,它允许操作系统通知应用程序各种事件,例如键盘输入、鼠标移动或窗口状态变化等。 阅读详情

相关推荐

深入解析Ring3环境下Inline Hook绕过技术与Delphi实战

htmltable {th, td {th {pre {简介:在Windows系统中,Ring3即用户模式,是应用程序运行的常规环境,而Inline Hook作为一种常见的调试与监控手段,通过修改函数入口指令实现控制流劫持,广泛应用于恶意软件分析、逆向工程等领域。本文深入探讨在Ring3下如何有效绕过Inline Hook机制,并结合提供的Delphi源码进行技术剖析。

weixin_35019679的博客 1180

完美世界国际版的多开

 一直在玩这个游戏了,所以顺便搞个多开补丁来.游戏是用launcher/launcher.exe来调用element/elementclient.exe的,所以只要修改elementclient.exe使之可以双开就可以了.elementclient.exe有两个验证的地方,一个是验证是否是从launcher.exe执行,还有一个就是验证是否已存在游戏进程了.这游戏没做什么保护,估计是

徘徊中的X 1万+

delphi 自动打开输入法(搜狗)

delphi 自动打开输入法(搜狗) 在一个文本编辑窗口输入时,自动打开中文输入法(热键 Alt+A),默认打开=》【中文 (简体) - 搜狗拼 音输入法】。

在Delphi中隐藏程序进程

在开发某些软件的时候,为了保护程序自身,就需要用到隐藏程序进程。以下通过实例来讲解隐藏程序进程的方法: 1、创建一个新的项目 Project1 选择File,New Application。在表单Form1上放一Memo组件,一个OK按钮组件,改变OK按钮组件的Cation属性为 CreateProcess。再放一个timer组件。设置timer组件的Interval值为100

靠别人不如靠自已。 3905

agv调度系统3.0技术介绍

agv调度系统,穿梭车调度系统,调度系统技术介绍,教你做调度

持续分享调度系统开发过程 4868

UVM自学笔记3——项目之三——从零开始搭建ahb_sramc验证平台

创建如下所示的目录结构: 2.在tb的文件下:顶层的testbench如下:在tb中,第24行的代码将uvm宏相关的内容include进来,第26行的代码把uvm_pkg包导入进来,然后将agent相关的包(ahb_pkg/sram_pkg),testcase相关的包(uvm_ahb_sram_test_pkg)以及env相关的包(uvm_ahb_sram_env_pkg)都导入进来,在第38行和39行将接口以virtual interface的形式配置给ahb_agent和sramc_agent下

ZhangShuHuai11的博客 9474

武林外传辅助工具详细制作过程[第二篇:查看数据]

1.我们可以用CE打开武林外传。运行CE,按照下图的次序打开(...\武林外传\element\elementclient.exe) 2.游戏启动后,别忘了选择游戏窗口。 3.这是游戏中人物的数据。 4.好,现在我们要在CE中显示人物的生命值。同样按照图中的顺序打开“添加地址”对话框,在数据框中添加我们已知的内存地址。当然,我们要用指针的方式,因为存储这些数据的地址是不...

weixin_33857679的博客 1512

【正点原子STM32连载】第六十章 串口IAP实战:从Bootloader到APP的无缝升级

本文以正点原子STM32F103开发板为例,详细讲解了串口IAP(在应用编程)技术的实现原理与实战步骤。内容涵盖Bootloader与APP的分工、FLASH空间规划、核心代码解析以及Ymodem协议的应用,旨在帮助开发者掌握通过串口为嵌入式设备实现远程固件升级的关键技术,提升产品维护与迭代效率。

weixin_29161719的博客 445

注入Explorer.exe 并Hook CreateProcessW (MinHook库)

记录下学习的经历.. win10系统 被某杀毒给挂钩了.. 直接用虚拟机来操作 // dllmain.cpp : 定义 DLL 应用程序的入口点。 #include "stdafx.h" #include #include "MinHook.h" #include #if defined _M_X64 #pragma comment(lib, "libMinHoo

Care 3616

【ADCU详解】PMIC电源管理集成电路详解

自动驾驶域控制器(ADCU)中的电源管理集成电路(PMIC)是高度集成的关键部件,负责为计算核心、传感器等提供高效稳定的多路电源。其核心特点包括:符合车规AEC-Q100标准、支持功能安全ASIL等级、精确的时序控制及强抗干扰能力。PMIC由开关稳压器、LDO、时序控制器、监控保护电路等模块组成,通过分层电源树框架实现电能分配。设计需考虑效率、功率密度、噪声性能等关键维度,底层基于Buck转换器和LDO原理工作。使用中需满足严苛的车规环境要求,并通过静态/动态测试及故障注入测试进行验证,确保系统可靠性和安全

qq_40844444的博客 841

基于simulink的电动汽车电机驱动系统IGBT开路故障检测

本文介绍了基于Simulink的电动汽车电机驱动系统IGBT开路故障检测方法。通过搭建永磁同步电机(PMSM)驱动系统模型,实现IGBT开路故障注入,并设计基于电流平均值与PWM逻辑比较的故障检测算法。系统可实时采集三相电流信号,通过MATLAB Function模块实现故障诊断,当检测到PWM信号与电流不匹配时输出故障报警。仿真结果显示,系统能在2.05秒内准确识别A相上管开路故障,并通过Scope和XYGraph直观展示故障特征。该方法为电动汽车电力电子系统故障诊断与容错控制提供了实用解决方案,后续可扩

xiaoheshang_123的博客 149

魔恩:关于CE搜到基址是mov eax,[ElementClient.exe+933138] 这种类型变更

关于CE搜到基址是mov eax,[ElementClient.exe+933138] 这种类型变更 解决办法:   本帖隐藏的内容 CE6.1以上版本 会出现上面这种类型的 很简单 修改下CE设置即可 就能直接显示基址 打开CE 看到 CE界面上的“内存浏览或查看内存” 点开后  找到菜单“视图或查看”- 将“显示模块地址” 去掉勾  就会显示正常的基址模型 ...

2849

C++程序无法正常启动(报0xc000007b错误)问题的详细排查

本文详细介绍了应用程序启动时遇到0xC000007B错误的排查过程。问题源于32位程序与64位运行时库的不匹配,以及缺少依赖的运行时库。通过分析系统日志、使用Windbg和检查程序位数,最终确定问题在于32位程序误引用了64位系统目录下的库文件。

dvlinker的技术专栏 1万+

Delphi下如何实现32位和64位都能用的Inline Hook

Hook在计算机术语中无论是直译为“钩子”,还是意译为“挂接”,均指的是一种对于现有机制的拦截。这个拦截实现后,会在运行期拦住现有某个流程,拐进自己的流程,自己做完特定事儿后,再按需要决定是否走回原流程。

passion的专栏 1126

基于 FPGA 的 CNN 卷积神经网络之池化层 Verilog 实现

池化层是卷积神经网络(CNN)中的关键组件,用于降低特征图的维度,减少计算量和防止过拟合。常见的池化操作包括最大池化和平均池化。FPGA 提供了高效的并行处理能力,可以加速这些操作。池化层在 CNN 中扮演重要角色,通过降低数据维度提升计算效率。在 FPGA 上实现池化层,可以充分利用硬件资源实现高效的并行计算,有助于提高实时应用中的推理速度。

走向CTO的路上... 1256

【Claude】Invalid API key 无效密钥报错已解决

API 拒绝了你提供的 key。最高频的根因是老的/被撤销的 key 藏在某处自动加载的配置文件里,而你对此不知情。→ 检查所有可能注入 key 的来源(.env.envrc、shell 配置、IDE 设置、)→ 清除无效来源 → 用/status验证。参考:Claude Code 官方《错误参考》"身份验证"章节、社区 Invalid API key 排查记录。

博客 7923

Delphi - 关于钩子函数HOOK (二)

用DELPHI编制钩子函数Windows消息管理机构提供了能使应用程序访问控制消息流所谓的钩子(HOOK)机制。钩子有多种,分别用于捕获某一特定类型或某一范围的消息。如:键盘消息,鼠标消息等。我们这里仅以键盘钩子的使用为例,讨论在DELPHI下怎样编写DLL程序和怎样在自己的程序中安装使用键盘钩子函数,并讨论了不同程序使用同一DLL文件时怎样共享数据。一...

a572893208的博客 475

Statistics and Machine Learning Toolbox

Statistics and Machine Learning Toolbox(带书签),MATLAB统计学习工具

Delphi Hook的相关问题

<br />procedure TForm1.btnTestClick(Sender: TObject); var TmpWndHandle:THandle; Add:Pointer; wR:Boolean; oldprotect:DWORD; StrTmp:string; begin ProcessHandle := GetCurrentProcess; OldMsg :=@TForm1.MsgBeforeHook; Add := @TForm1.Msg

linyuzhi的专栏 392

深度学习工具包 DeepLearningToolbox

深度学习工具包Deprecation notice.-----This toolbox is outdated and no longer maintained.There are much better tools available for deep learning than this toolbox, e.g. [Theano](http://deeplearning.net/software/theano/), [torch](http://torch.ch/) or [tensorflow](http://www.tensorflow.org/)I would suggest you use one of the tools mentioned above rather than use this toolbox.Best, Rasmus.DeepLearnToolbox================A Matlab toolbox for Deep Learning.Deep Learning is a new subfield of machine learning that focuses on learning deep hierarchical models of data.It is inspired by the human brain's apparent deep (layered, hierarchical) architecture.A good overview of the theory of Deep Learning theory is[Learning Deep Architectures for AI](http://www.iro.umontreal.ca/~bengioy/papers/ftml_book.pdf)For a more informal introduction, see the following videos by Geoffrey Hinton and Andrew Ng.* [The Next Generation of Neural Networks](http://www.youtube.com/watch?v=AyzOUbkUf3M) (Hinton, 2007)* [Recent Developments in Deep Learning](http://www.youtube.com/watch?v=VdIURAu1-aU) (Hinton, 2010)* [Unsupervised Feature Learning and Deep Learning](http://www.youtube.com/watch?v=ZmNOAtZIgIk) (Ng, 2011)If you use this toolbox in your research please cite [Prediction as a candidate for learning deep hierarchical models of data](http://www2.imm.dtu.dk/pubdb/views/publication_details.php?id=6284)```@MASTERSTHESIS\{IMM2012-06284, author = "R. B. Palm", title = "Prediction as a candidate for learning deep hierarchical models of data", year = "2012",}```Contact: rasmusbergpalm at gmail dot comDirectories included in the toolbox-----------------------------------`NN/` - A library for Feedforward Backpropagation Neural Networks`CNN/` - A library for Convolutional Neural Networks`DBN/` - A library for Deep Belief Networks`SAE/` - A library for Stacked Auto-Encoders`CAE/` - A library for Convolutional Auto-Encoders`util/` - Utility functions used by the libraries`data/` - Data used by the examples`tests/` - unit tests to verify toolbox is workingFor references on each library check REFS.mdSetup-----1. Download.2. addpath(genpath('DeepLearnToolbox'));Example: Deep Belief Network---------------------```matlabfunction test_example_DBNload mnist_uint8;train_x = double(train_x) / 255;test_x = double(test_x) / 255;train_y = double(train_y);test_y = double(test_y);%% ex1 train a 100 hidden unit RBM and visualize its weightsrand('state',0)dbn.sizes = [100];opts.numepochs = 1;opts.batchsize = 100;opts.momentum = 0;opts.alpha = 1;dbn = dbnsetup(dbn, train_x, opts);dbn = dbntrain(dbn, train_x, opts);figure; visualize(dbn.rbm{1}.W'); % Visualize the RBM weights%% ex2 train a 100-100 hidden unit DBN and use its weights to initialize a NNrand('state',0)%train dbndbn.sizes = [100 100];opts.numepochs = 1;opts.batchsize = 100;opts.momentum = 0;opts.alpha = 1;dbn = dbnsetup(dbn, train_x, opts);dbn = dbntrain(dbn, train_x, opts);%unfold dbn to nnnn = dbnunfoldtonn(dbn, 10);nn.activation_function = 'sigm';%train nnopts.numepochs = 1;opts.batchsize = 100;nn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.10, 'Too big error');```Example: Stacked Auto-Encoders---------------------```matlabfunction test_example_SAEload mnist_uint8;train_x = double(train_x)/255;test_x = double(test_x)/255;train_y = double(train_y);test_y = double(test_y);%% ex1 train a 100 hidden unit SDAE and use it to initialize a FFNN% Setup and train a stacked denoising autoencoder (SDAE)rand('state',0)sae = saesetup([784 100]);sae.ae{1}.activation_function = 'sigm';sae.ae{1}.learningRate = 1;sae.ae{1}.inputZeroMaskedFraction = 0.5;opts.numepochs = 1;opts.batchsize = 100;sae = saetrain(sae, train_x, opts);visualize(sae.ae{1}.W{1}(:,2:end)')% Use the SDAE to initialize a FFNNnn = nnsetup([784 100 10]);nn.activation_function = 'sigm';nn.learningRate = 1;nn.W{1} = sae.ae{1}.W{1};% Train the FFNNopts.numepochs = 1;opts.batchsize = 100;nn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.16, 'Too big error');```Example: Convolutional Neural Nets---------------------```matlabfunction test_example_CNNload mnist_uint8;train_x = double(reshape(train_x',28,28,60000))/255;test_x = double(reshape(test_x',28,28,10000))/255;train_y = double(train_y');test_y = double(test_y');%% ex1 Train a 6c-2s-12c-2s Convolutional neural network %will run 1 epoch in about 200 second and get around 11% error. %With 100 epochs you'll get around 1.2% errorrand('state',0)cnn.layers = { struct('type', 'i') %input layer struct('type', 'c', 'outputmaps', 6, 'kernelsize', 5) %convolution layer struct('type', 's', 'scale', 2) %sub sampling layer struct('type', 'c', 'outputmaps', 12, 'kernelsize', 5) %convolution layer struct('type', 's', 'scale', 2) %subsampling layer};cnn = cnnsetup(cnn, train_x, train_y);opts.alpha = 1;opts.batchsize = 50;opts.numepochs = 1;cnn = cnntrain(cnn, train_x, train_y, opts);[er, bad] = cnntest(cnn, test_x, test_y);%plot mean squared errorfigure; plot(cnn.rL);assert(er<0.12, 'Too big error');```Example: Neural Networks---------------------```matlabfunction test_example_NNload mnist_uint8;train_x = double(train_x) / 255;test_x = double(test_x) / 255;train_y = double(train_y);test_y = double(test_y);% normalize[train_x, mu, sigma] = zscore(train_x);test_x = normalize(test_x, mu, sigma);%% ex1 vanilla neural netrand('state',0)nn = nnsetup([784 100 10]);opts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samples[nn, L] = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.08, 'Too big error');%% ex2 neural net with L2 weight decayrand('state',0)nn = nnsetup([784 100 10]);nn.weightPenaltyL2 = 1e-4; % L2 weight decayopts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex3 neural net with dropoutrand('state',0)nn = nnsetup([784 100 10]);nn.dropoutFraction = 0.5; % Dropout fraction opts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex4 neural net with sigmoid activation functionrand('state',0)nn = nnsetup([784 100 10]);nn.activation_function = 'sigm'; % Sigmoid activation functionnn.learningRate = 1; % Sigm require a lower learning rateopts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex5 plotting functionalityrand('state',0)nn = nnsetup([784 20 10]);opts.numepochs = 5; % Number of full sweeps through datann.output = 'softmax'; % use softmax outputopts.batchsize = 1000; % Take a mean gradient step over this many samplesopts.plot = 1; % enable plottingnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex6 neural net with sigmoid activation and plotting of validation and training error% split training data into training and validation datavx = train_x(1:10000,:);tx = train_x(10001:end,:);vy = train_y(1:10000,:);ty = train_y(10001:end,:);rand('state',0)nn = nnsetup([784 20 10]); nn.output = 'softmax'; % use softmax outputopts.numepochs = 5; % Number of full sweeps through dataopts.batchsize = 1000; % Take a mean gradient step over this many samplesopts.plot = 1; % enable plottingnn = nntrain(nn, tx, ty, opts, vx, vy); % nntrain takes validation set as last two arguments (optionally)[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');```[![Bitdeli Badge](https://d2weczhvl823v0.cloudfront.net/rasmusbergpalm/deeplearntoolbox/trend.png)](https://bitdeli.com/free "Bitdeli Badge")

Outlook Express 6 (OE6) for Win7/Win8/Win10

英文版 Outlook Express6.0, 兼容Win7/Win10/WinXP,解压就可用。

Delphi Hook API 已疯狂

作者: yangyxd   转载请注明出处 http://hi.baidu.com/yangyxd   2009-3-12     论坛里有关于HOOK API的贴子, 但其实现在方式显示得麻烦, 其实现在拦截API一般不用那种方式, 大都采用inline Hook API方式。其实也就是直接修改了要拦截的API源码的头部,让它无条件跳转到我们自己的处理过程。   不多说别的了,开始我们自己的Ho

hack_wg的专栏 3123

锂电池充电器电路设计 里面有电路

锂电池充电器电路设计 里面有电路 3.7V升压到5V电路设计。

DELPHI HOOK随手笔记

在 DOS 系统中编程,经常会采取截取中断向量的技术:我们可以设置新的中断服务程序,当系统其他的程序调用这个中断时,就让它先调用我们自己设置的新的中断服务程序,然后再调用原来的中断服务程序,这样就能够获得非凡的控制权。许多优秀的软件和大多数 DOS 病毒程序都采用了这个方法。 在 Windows 中,我们也可以采取类似技术。当系统调用某个 API 函数时,就会先进入我们自己的函数,然后再调用原...

kinvsn的博客 1360

[Delphi]钩子(HOOK)机制的使用

 SetwindowsHookEx函数提供15种不同的消息监视类型,也就是15中不同的钩子。 分别用于捕获某一特定类型或某一范围的消息(如:键盘消息,鼠标消息等)。 我们这里仅以鼠标钩子的使用为例,讨论在DELPHI下怎样编写DLL程序和怎样在自己的程序中安装使用鼠标钩子函数。 Windows提供API函数SetwindowsHookEx来建立一个Hook, 通过这个函数可以将一个程序添加到Hoo

愚公移山的专栏 1082

SSDT_Helper for Delphi v1(Ring3下查看SSDT HOOK的Delphi版)

SSDT(System Services Descriptor Table) 这几年被讲烂了,各大论坛、Blog相关文章都是成堆成堆的。检测SSDT HOOK的代码也相当多,只不过放眼望去都是C的。实在不忍自己苦苦捍卫的Delphi就此末落(D2009倒是让人振奋了一把),于是把自己感兴趣的几个代码都给翻成了Delphi的,现在拿来共享。 不会驱动,这方面涉水也比较浅,只能写个查看S

zbc_vc的专栏 1040

【亲测免费】 Delphi API Hook钩子dll资源文件介绍

Delphi API Hook钩子dll资源文件介绍 去发现同类优质开源项目:https://gitcode.com/ 此仓库包含了一个使用Delphi编写的API Hook钩子dll及其示例文件。该资源允许用户截获API调用,对于需要进行API拦截和修改的开发者来说,这是一个非常有用的工具。 资源内容 API Hook钩子dll: 一个Delphi编译的DLL文件,用于实现API Hook功能...

gitblog_06779的博客 678

delphi Hook 注入 V信

delphi Hook 注入 PC微信

musa2008的专栏 353
上一篇: 创业者,你为什么这么着急?
下一篇: 暗黑3 外挂开发资料
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值