CnPack Forum


 
Subject: 一个有些类似APIHOOK的问题,请高手帮忙看看
精灵猪
新警察
Rank: 1



UID 5299
Digest Posts 0
Credits 25
Posts 15
点点分 25
Reading Access 10
Registered 2007-2-3
Status Offline
Post at 2007-4-5 03:07  Profile | Blog | P.M. 
一个有些类似APIHOOK的问题,请高手帮忙看看

function TrueFunctionAddress(func: Pointer): Pointer;
var
  Code: PlmportCode;
begin
  Result := func;
  if func = nil then exit;
  try
    Code := func;
    if (Code.jumplnstruction = $25FF) then
    begin
      Result := Code.AddressOfPointer_ToFunction^;
    end;
  except
    Result := nil;
  end;
end;


procedure doit;
begin
messagebox(0,'执行动作','',mb_ok);
end;

用TrueFunctionAddress(@doit);可以得到doit的地址比如我要修改 $00404200 这个地方改为指向doit的jmp应该如何做 有点类似API钩子的那种方法 可是钩的不是API是段代码而已
================================================
我的目的是 让程序执行到00404200这个位置的时候跳到我指定的函数上执行完再跳回去 不知道这种办法成不成 研究了好长时间没解决 求高手指点一下 或者有更好的方法给小弟介绍一下 小弟感激不禁
Top
zjy
管理员
Rank: 9Rank: 9Rank: 9



UID 2
Digest Posts 6
Credits 2385
Posts 1543
点点分 2385
Reading Access 102
Registered 2002-12-16
Location China
Status Offline
Post at 2007-4-5 08:17  Profile | Site | Blog | P.M. 
可以使用或参考CnWizards中提供的CnWizMethodHook.pas文件

可以用来Hook普通的函数或对象方法等,见附件


Attachment: CnWizMethodHook.pas (2007-4-5 08:17, 6.62 K)
Download count 557




Zhou JingYu
CnPack Administrator
http://www.cnpack.org/
Top
Passion (LiuXiao)
管理员
Rank: 9Rank: 9Rank: 9


UID 359
Digest Posts 19
Credits 6750
Posts 3551
点点分 6750
Reading Access 102
Registered 2004-3-28
Status Offline
Post at 2007-4-5 09:07  Profile | Blog | P.M. 
确实,CnWizMethodHook可以很方便的做到这个事情,
前提是在同一进程内。
Top
精灵猪
新警察
Rank: 1



UID 5299
Digest Posts 0
Credits 25
Posts 15
点点分 25
Reading Access 10
Registered 2007-2-3
Status Offline
Post at 2007-4-5 18:37  Profile | Blog | P.M. 
可否给个CnWizMethodHook的例子 比如把00404200的地址改为 jmp xxxxxxxx 其中xxxxxxxx为doit函数的地址 ?
Top
kendling (小冬)
高级版主
Rank: 8Rank: 8
MyvNet


Medal No.1  
UID 703
Digest Posts 5
Credits 978
Posts 580
点点分 978
Reading Access 101
Registered 2005-2-18
Location 广东
Status Offline
Post at 2007-4-5 21:02  Profile | Site | Blog | P.M.  | QQ | Yahoo!
呵呵,CW里就有例子。




小冬
http://MyvNet.com
Top
Passion (LiuXiao)
管理员
Rank: 9Rank: 9Rank: 9


UID 359
Digest Posts 19
Credits 6750
Posts 3551
点点分 6750
Reading Access 102
Registered 2004-3-28
Status Offline
Post at 2007-4-5 22:47  Profile | Blog | P.M. 
对,CW的源码里头,搜索这个MethodHook的类名就行了。
Top
精灵猪
新警察
Rank: 1



UID 5299
Digest Posts 0
Credits 25
Posts 15
点点分 25
Reading Access 10
Registered 2007-2-3
Status Offline
Post at 2007-4-6 00:29  Profile | Blog | P.M. 
多谢各位老哥的回家 不过新的问题出现了 我成功修改程序跳到我指定的函数上了 我的函数是这样写的
procedure doit;
var
s:string;
bagin
asm
mov s,esi
end;
end;
可是执行完我的代码后程序就报错了 主要是我的程序不能跳回到被修改的代码里了 而delphi 的汇编里不能指定 jmp xxxxxx这样的语句

doit的这个函数的目的就是读esi的字符串 读到 00为止 请教各位大哥这个函数我应该如何设计?如果可以不用汇编写我想会方便很多 应该如何做呢?
Top
精灵猪
新警察
Rank: 1



UID 5299
Digest Posts 0
Credits 25
Posts 15
点点分 25
Reading Access 10
Registered 2007-2-3
Status Offline
Post at 2007-4-6 00:41  Profile | Blog | P.M. 
jmp 不灵我又用了
push xxxxxx
ret
的方法 虽然是跳回去了 但是还是报错了 看来这个方法也不灵
Top
精灵猪
新警察
Rank: 1



UID 5299
Digest Posts 0
Credits 25
Posts 15
点点分 25
Reading Access 10
Registered 2007-2-3
Status Offline
Post at 2007-4-6 02:25  Profile | Blog | P.M. 
小弟又测试了一下 结果不报错了 不过小弟用 mov ser,esi 不能把ESI所指的字符串传递到str里 请问各位大哥如何才能传递到str里 用汇编实在太麻烦了 另外如果高手有其他方法可以在程序经过的时候把esi的字符串传递到str里 而不用汇编也请指点小弟一下  小弟等各位高手的回答 辛苦各位了
Top
zjy
管理员
Rank: 9Rank: 9Rank: 9



UID 2
Digest Posts 6
Credits 2385
Posts 1543
点点分 2385
Reading Access 102
Registered 2002-12-16
Location China
Status Offline
Post at 2007-4-6 08:29  Profile | Site | Blog | P.M. 
CnWizMethodHook的函数Hook是通过修改被Hook的函数执行体前5个字节为相对跳转指令来实现的,如果需要在执行完Hook函数后重新执行被Hook的函数,需要在Hook函数中先Unhook恢复原函数的前5个字节代码,调用完原函数后再重新Hook。

要获得 esi 的字符串,用汇编是可以的,不过不要用 string 类型的变量,用 PChar 类型即可。

从你提供的资料来看,似乎并不是做函数的Hook,而是想在函数执行体(某个DLL的?)内部插入个钩子来取得 esi 寄存器的值。如果是这样的需求,可以用下面的方法:
1、创建一个TCnMethodHook对象Hook掉目标地址。
2、在Hook函数中用,根据需要用汇编先保存寄存器现场,再将 esi 读到 pchar 全局变量。
3、在Hook函数中用UnhookMethod恢复被Hook函数体。
4、恢复寄存器现场,再用绝对跳转指令或者push 地址加 ret 的方法跳回到原地址执行。
5、如果需要多次挂接,在适应的时机重新挂接。

注:如果在Hook函数中用汇编直接返回原函数,则Hook函数中不能定义任何局部变量。因为局部变量会从堆栈中分配,如果没有正常退出函数而是直接跳转,就会导致堆栈错误,除非你自己去修改堆栈指针。另外,保存寄存器现场也是很重要的,否则Hook函数中修改了EAX等寄存器的内容,可能导致返回后影响原函数正常执行。

调这样的程序,建议用汇编窗口来调试。




Zhou JingYu
CnPack Administrator
http://www.cnpack.org/
Top
精灵猪
新警察
Rank: 1



UID 5299
Digest Posts 0
Credits 25
Posts 15
点点分 25
Reading Access 10
Registered 2007-2-3
Status Offline
Post at 2007-4-6 12:35  Profile | Blog | P.M. 
感谢zjy大哥的回答 现在的问题是
1我用TCnMethodHook.Create方法HOOK掉了指定的地址跳到了我的函数上了
2 定义str为pchar变量 可是如何把esi地址上的字符串传递到 str上?  mov str,esi 这样吗?
3 在Hook函数中用UnhookMethod恢复被Hook函数体 这句没理解意思 ,由于程序是修改了原程序的代码 所以我在我的函数上先用pushad保存了各寄存器然后popad 后面又把修改的5字节写上再跳回去的 难道zjy大哥说的方法 UnhookMethod可以不用做这些吗? 小弟新手请教UnhookMethod应该如何调用? TCnMethodHook.UnhookMethod; 这样编译不通过
4 在delphi里用汇编 jmp xxxxxx的绝对跳转用不了的 只能用push 地址加 ret的方法 如果要用jmp xxxxxx 应该如何做?


我的代码是这样的 先用
TCnMethodHook.Create(pointer($005b2617), @doit);
这样就HOOK到了005b2617地址上了
一下是我的doit函数
  procedure doit;
  asm
   cmp edx,0  //判断edx是否为0
   je @getadd //如果是就到getadd上去
   jmp @exit//不是就调用exit

   @getadd:
   pushad
   mov str,esi //str是pchar变量,这里存储的并不是esi的字符串 而是地址 关键是这里不知道如何处理
   popad
   jmp @exit

   @exit:
   add     eax, 8  //这里是恢复被修改的自己 由于我不会用UnhookMethod恢复被Hook函数体 请教如果用的话是不是不用写这些了?应该怎么用?
   test    edi, edi
   push $5B261C  
   ret
  end;
Top
 




All times are GMT++8, the time now is 2024-3-29 07:59

    本论坛支付平台由支付宝提供
携手打造安全诚信的交易社区 Powered by Discuz! 5.0.0  © 2001-2006 Comsenz Inc.
Processed in 0.007352 second(s), 8 queries , Gzip enabled

Clear Cookies - Contact Us - CnPack Website - Archiver - WAP