DELPHI盒子
!实时搜索: 盒子论坛 | 注册用户 | 修改信息 | 退出
检举帖 | 全文检索 | 关闭广告 | 捐赠
技术论坛
 用户名
 密  码
自动登陆(30天有效)
忘了密码
≡技术区≡
DELPHI技术
移动应用开发
Web应用开发
数据库专区
报表专区
网络通讯
开源项目
论坛精华贴
≡发布区≡
发布代码
发布控件
文档资料
经典工具
≡事务区≡
网站意见
盒子之家
招聘应聘
信息交换
论坛信息
最新加入: zyt1990
今日帖子: 44
在线用户: 17
导航: 论坛 -> DELPHI技术 斑竹:liumazi,sephil  
作者:
男 jingzu (123456) ★☆☆☆☆ -
盒子活跃会员
2020/3/14 13:59:04
标题:
hook CALL目标进程崩溃 浏览:316
加入我的收藏
楼主: 首先非常感谢武哥提供的免费代码。
我用的是:Lsuper 修改过的代码
下面代码,已能钩到,但是导至目标进程崩溃,请大老们看看什么原因。

2016.10.01 - Lsuper          }
{          }
{   1、参考 wr960204 武稀松 的原始实现:          }
{      https://code.google.com/p/delphi-hook-library          }
{   2、修改 BeaEngine 引擎为 LDE64 长度反编译引擎,大幅降低大小          }
{      https://github.com/BeaEngine/lde64          }
{      http://www.beaengine.org/download/LDE64-x86.zip ;         }
{      http://www.beaengine.org/download/LDE64-x64.rar ;         }
{   3、去除原始实现对多线程冻结的处理,通常建议 Hook/Unhook 放到单元      }
{      初始化、析构中做,否则可能因改写内存没挂起其他线程造成错误   

//////////
我的目的就是
1:HOOK CALL   可以hook call前面,执行完我的过程再返回后继续执行call.
2:,直接hook 掉call,替换我的过程。然后返回。
3:等CALL执行完后,得到结果后再HOOK执行我的过程并返回。

下面的代码目的是第1种,HOOK CALL 前面,执行完我的过程再返回后继续执行call.


---------- 


unit hookUnit1;

interface
uses
   Winapi.Windows, System.SysUtils, System.Variants, System.Classes,HookUtils;

var
   hook地址:DWORD;
   备份地址: Pointer;//POldProc;// DWORD;
   hookadd: DWORD;
   apiaddr: Integer;
   dwRetAddr: DWORD; // = (DWORD)GetModuleHandle(L"unt.dll") + QrCodeOffset + 5;  //返回地址
   pEsi: DWORD = 0;    //esi寄存器

procedure InitHook(); stdcall;
procedure UninitHook(); stdcall;
procedure 截取消息();  stdcall;


implementation
procedure OutputDebugStr(const ADebugInfo: string);  //输出调试信息
begin
   OutputDebugString(PChar(ADebugInfo + #13 + #10));
end;

procedure InitHook();
var //a1,a2:dword;
   p1, p2: Pointer;
   m_基址: dword;
begin
   m_基址 := LoadLibrary('unt.dll');
   OutputDebugStr(inttostr(m_基址));

   hook地址 :=3492515;// 3495443;
   hookadd := m_基址 + hook地址;
   dwRetAddr:=m_基址 + hook地址+5; // = (DWORD)GetModuleHandle(L"unt.dll") + QrCodeOffset + 5;  //返回地址
   p1 := Pointer(hookadd);
   OutputDebugStr('hookadd=' + inttostr(hookadd) + '  备份地址=' + inttostr(Integer(备份地址)));
   if HookProc(p1, @截取消息, 备份地址) then
       OutputDebugStr('hook  OK')
   else
       OutputDebugStr('hook  no');
   OutputDebugStr('hookadd=' + inttostr(hookadd) + '  备份地址=' + inttostr(Integer(备份地址)));
end;

procedure UninitHook();
var
   p: Pointer;
begin
   p := @备份地址;
   UnHookProc(p);
end;
procedure saveCALL();
asm
  //备份寄存器
  pushad;
   pushfd;
  //取出esi的内容
  mov pEsi, esi;//ecx;

end;
procedure loadcall();
asm
  //恢复寄存器
  popfd;
  popad;

  //跳转到返回地址
  jmp dwRetAddr;

end;


procedure 截取消息();
begin
   saveCALL();          //这句去掉,有显示“有消息”说明已被钩中,不去掉,没显示。 是否去掉目标进程都崩溃.
   OutputDebugStr('有消息:');
   loadcall();
end;

end.
----------------------------------------------
-
作者:
男 xuchuantao (暗黑天使) ▲▲▲▲△ -
注册会员
2020/3/14 18:43:08
1楼: 没有跳转到原来的函数.
----------------------------------------------
按此在新窗口浏览图片
作者:
男 xuchuantao (暗黑天使) ▲▲▲▲△ -
注册会员
2020/3/14 19:26:38
2楼: 刚看看了DelphiHookUtils项目的Demos,你没有实现目标函数的引用声明,估计是内存被破坏了.
library Dll;

uses
  Windows, WinInet, HookUtils;

var
  HttpOpenRequestWNext: function(hConnect: HINTERNET; lpszVerb: LPWSTR;
    lpszObjectName: LPWSTR; lpszVersion: LPWSTR; lpszReferrer: LPWSTR;
    lplpszAcceptTypes: PLPSTR; dwFlags: DWord;
    dwContext: DWORD_PTR): HINTERNET; stdcall;

function HttpOpenRequestWCallBack(hConnect: HINTERNET; lpszVerb: LPWSTR;
  lpszObjectName: LPWSTR; lpszVersion: LPWSTR; lpszReferrer: LPWSTR;
  lplpszAcceptTypes: PLPSTR; dwFlags: DWord;
  dwContext: DWORD_PTR): HINTERNET; stdcall;
var
  S: string;
begin
  // 先直接调用原始函数
  Result := HttpOpenRequestWNext(hConnect, lpszVerb, lpszObjectName, lpszVersion,
    lpszReferrer, lplpszAcceptTypes, dwFlags, dwContext);

  if Result = nil then
  begin
    // 打印错误...
    Exit;
  end;
  // 添加自定义的http标头
  S := 'X-MyHttpHeader: HeaderValue';
  if not Wininet.HttpAddRequestHeaders(Result, PChar(S), Length(S),
    Wininet.HTTP_ADDREQ_FLAG_ADD or Wininet.HTTP_ADDREQ_FLAG_REPLACE) then
  begin
    // 打印错误...
    Exit;
  end;
end;

//////////
//设计:Lsuper 2016.10.09
//功能:初始化、挂接 API
//参数:
//注意:如果 HookProc 的 DLL 没有被 LoadLibrary 下 Hook 会失败,建议先手工 Load
//////////
procedure DllEntryPoint(dwReason: DWord);
begin
  case dwReason of
    DLL_PROCESS_ATTACH:
      begin
        if HookUtils.HookProc('WinInet.dll', 'HttpOpenRequestW', @HttpOpenRequestWCallBack, @HttpOpenRequestWNext) then
        begin
          // Hook 成功...
        end
        else
        begin
          // Hook 失败...
        end;
      end;
    DLL_PROCESS_DETACH:
      begin
        if HookUtils.UnHookProc(@HttpOpenRequestWNext) then
        begin
          // UnHook 成功...
        end
        else
        begin
          // UnHook 失败...
        end;
      end;
    DLL_THREAD_ATTACH:
      begin
      end;
    DLL_THREAD_DETACH:
      begin
      end;
  end;
end;

begin
  DllProc := @DllEntryPoint;
  DllEntryPoint(DLL_PROCESS_ATTACH);
end.

function HookProc(const ATargetModule, ATargetProc: string; ANewProc: Pointer;
  out AOldProc: Pointer): Boolean;
var
  nHandle: THandle;
  pProc: Pointer;
begin
  Result := False;
  nHandle := GetModuleHandle(PChar(ATargetModule));
  if nHandle = 0 then
    Exit;
  pProc := GetProcAddress(nHandle, PChar(ATargetProc));
  if pProc = nil then
    Exit;
  Result := HookProc(pProc, ANewProc, AOldProc);
end;
----------------------------------------------
按此在新窗口浏览图片
作者:
男 xuchuantao (暗黑天使) ▲▲▲▲△ -
注册会员
2020/3/14 19:28:09
3楼: 你的代码编译应该没有问题,问题是错误的方式进行了Hook
----------------------------------------------
按此在新窗口浏览图片
作者:
男 helyna (Person) ▲▲▲▲▲ -
注册会员