武.林.外.传 主进程 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

STM32:TTL串口调试

TTL只需要两个线就可以完成两个设备之间的双向通信,一个发送电平的I/O称之为TX,与另一个设备的接收I/O口RX相互连接。两设备之间还需要连接地线(GND),这样两设备就有相同的0V参考电势。

superSmart_Dong的博客 5636

单细胞转录组数据质控实战:如何用Seurat精准过滤低质量细胞(附完整代码)

本文详细介绍了使用Seurat进行单细胞转录组数据质控的实战方法,包括基因检出数、分子计数和线粒体基因比例等关键指标的解读与可视化技巧。通过动态阈值策略和高级质控技巧(如双细胞检测和红细胞过滤),帮助研究者精准过滤低质量细胞,提升数据分析可靠性。附完整代码示例,适合生物信息学研究人员参考实践。

ii567的博客 825

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

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

weixin_33857679的博客 1512

Mac用户必看:PD虚拟机网络初始化失败的3分钟修复指南(附详细截图)

本文针对Mac用户在Parallels Desktop(PD虚拟机)启动时遇到的“网络初始化失败”问题,提供了快速诊断与修复指南。核心原因是macOS系统更新后权限未正确授予。文章通过详细的三步修复法(关闭进程、修改配置文件、重新授权重启),帮助用户在3分钟内恢复虚拟机网络连接,并附有排查清单与预防建议。

weixin_29231027的博客 538

注入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

【Flink cdc】Data row is smaller than a column index, internal schema representation is probably xxx

翻译一下:当scan.startup.mode=EARLIEST_OFFSET时,如果在最早的offset之后表结构有过变化就无法支持。原因应该是在binlog 的earliest_offset之后,表结构被修改过。我的解决方案:source配置中使用。mysql source配置使用。,以时间戳为消费依据。

integrity 2085

5分钟搞定DataDome滑块验证码:最新Capsolver API实战教程(含代理配置)

本文提供了一份利用Capsolver API快速自动化破解DataDome滑块验证码的实战教程。文章深入剖析了DataDome验证码的环境指纹与行为分析机制,并重点详解了确保成功率的住宅代理配置、API集成步骤及令牌使用等核心环节,帮助开发者高效集成稳定可靠的自动化解决方案。

milk8的博客 493

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

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

2849

第8章-认知工程:构建Agent的认知飞轮与自进化《万物皆映射》

认知架构(Cognitive Architecture)是一个系统组织和运行其认知过程的整体设计。对人类而言,认知架构是大脑的结构和功能组织方式;对 AI Agent 而言,认知架构是它处理信息、做出决策、学习经验的系统设计。固定映射 vs 进化映射维度固定映射 Agent进化映射 Agent知识静态(训练时确定)动态(持续积累)策略固定(设计时确定)自适应(经验驱动)工具预定义自主发现/创建错误处理硬编码规则从错误中学习能力边界固定持续扩展在认知工程中,技能。

AI天才研究院 104

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

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

passion的专栏 1126

Oracle数据库表空间使用情况查询

在Oracle数据库中,表空间(Tablespace)是用于存储表、索引和其他数据库对象的逻辑存储单元。了解表空间的使用情况对于数据库管理员和开发人员来说是非常重要的,因为它可以帮助他们监控数据库的空间使用情况并进行容量规划。本文将介绍如何查询Oracle数据库中的表空间使用情况。通过执行以上SQL查询语句,你可以获得Oracle数据库中表空间的使用情况、文件大小和表空间大小等信息。这些信息可以帮助你了解数据库的存储情况,并进行适当的优化和容量规划。查看表空间的数据文件和表空间大小。查看表空间的使用情况。

CsmbPascal的博客 857

C# WinForm 基于DirectShow.dll编写的程序,可边预览边保存视频,音频和图片

基于微软的DirectShow.dll的二次开发1.自动识别连接的摄像头跟麦克风且可以对其进行选择(默认选中第一个)2.可录制wmv和avi两种格式的视频并且都带有音频,avi可以录制的分辨率和帧数进行选择,wmv默认进行了淸晰度优化如不喜欢可去除代码中有相关提示3.可在预览点开之后进行拍照,也可边录制视频边拍照4.添加了视频和音频的压缩功能(酌情使用)这次二次开发发现C#对DirectShow的相关信息太少,这次做完也不敢藏私共享出来,还望大家指正

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

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

a572893208的博客 475

ssm框架搭建

这个是一个在idea上成功跑起来的ssm框架项目,保存在这里方便以后使用直接下载

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

Data-Structures-and-Algorithm-Analysis-in-Java.pdf

作者: Weiss, Mark A. 出版社: Addison Wesley Data Structures and Algorithm Analysis in Java is an “advanced algorithms” book that fits between traditional CS2 and Algorithms Analysis courses. In the old ACM Curriculum Guidelines, this course was known as CS7. This text is for readers who want to learn good programming and algorithm analysis skills simultaneously so that they can develop such programs with the maximum amo...

STM32F407中文手册

STM32f407中文手册 本参考手册面向应用开发人员,提供有关使用 STM32F405xx/07xx、STM32F415xx/17xx、 STM32F42xxx 和 STM32F43xxx 微控制器存储器与外设的完整信息。STM32F405xx/07xx、STM32F415xx/17xx、STM32F42xxx 和 STM32F43xxx 构成一个微 控制器系列,各产品具有不同的存储器大小、封装和外设。有关订购信息以及器件的机械与电气特性,请参见数据手册。有关 ARM Cortex™-M4F 内核的信息,请参见《Cortex™-M4F 技术参考手册》。

Delphi Hook API 已疯狂

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

hack_wg的专栏 3123

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、付费专栏及课程。

余额充值