首页
社区
课程
招聘
[求助]HOOK API的同步问题
发表于: 2008-6-1 16:07 10707

[求助]HOOK API的同步问题

2008-6-1 16:07
10707
最近做的一个东东涉及到HOOK API,需要修改API的前5个字节达到HOOK的目的。整个HOOK流程没问题,但就是碰到了一个线程同步的问题(通过查资料发现是个老问题,但是没找到有什么解决方法):就是在我们写的新API中,如果需要调用原API,需要先将前5个字节恢复,这时如果其它线程调用同样的API时,就会出现漏钩的现象!这个问题该如何解决呢,请各位大虾指点,非常感谢,谢谢!

[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课

收藏
免费 0
支持
分享
最新回复 (29)
雪    币: 200
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
2
哪位大哥能帮帮我嘛?谢谢!
2008-6-1 19:53
0
雪    币: 581
活跃值: (149)
能力值: ( LV12,RANK:600 )
在线值:
发帖
回帖
粉丝
3
其实不用恢复也可以的.....俺之前的那个HOOK就是调用自己HOOK的函数,,,,,当然我那里是关闭中断...对性能音像很大,,,,,后来改了改,,,,你不用恢复啊....直接__ASM执行被你修改的字节再跳到没被修改的地方开始执行....这样就OK了
2008-6-1 22:39
0
雪    币: 210
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
4
其实可以利用EVENT对象来通知的。

g_hEvent = ::CreateEvent(NULL,

 TRUE,     //手动设置EVENT的状态,这里选择手动设置,因为只有手动设置的时候,当线程函数得到信号量通知时,所有
               //等待在该EVENT对象的线程才会运行起来
。拿到你的例子中就是
              //当你运行完真实的api(被hook前的)后,然后运行那段替换入口点函数的代
              //码(这时hook掉原函数,用你的假函数替换之),然后调用SetEvent,这时所有
            //等待在这个对象上的线程才可以运行
               
          

 
FALSE,   //未受信的(nonsignaled)

NULL);

==============

大体代码:
g_hEvent 全局变量
g_hEvent = ::CreateEvent(NULL,TRUE, FALSE, NULL);
//此时由于信号量是没有信号的状态,其他等待该信号的线程不会运行的,也就是不会运行真实的api了。这里你就可以想运行真实的api多少次就多少次。 

          ...........//调用真实api的处理过程
然后是hook api的过程。。。
完了以后记得设置::SetEvent(g_hEvent);
将信号设置为有信号状态,这时等待的线程由于得到了运行的提示,所有等待的线程才可以运行

     

其他 线程的入口点必须加上如下代码:
VOID ThreadProc()
{   ::WaitForSingleObject(g_hEvent, INFINITE);

     。。。。。//这里是原先线程处理函数的代码
}

===================

写完了回复才发现,这段代码只是适合你自己写的线程处理函数  。如果其他的线程(比如记事本的主线程)调用你的api的时候,线程函数的执行代码前必须加上
WaitForSingleObject(g_hEvent, INFINITE);
这是比较难做到的。毕竟你不知道是哪个线程要调用。

仅提供思路,高手继续跟帖,自己也跟着学习一下。。。
2008-6-1 23:52
0
雪    币: 215
活跃值: (11)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
5
看海风的HOOKAPIlib
2008-6-2 06:50
0
雪    币: 200
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
6
谢谢各位的热情帮助,
Sysnap ,您能简单的提供下代码嘛,我对汇编不是很懂,HOOK的模型是引用的开源的代码,谢谢。
wpclub,正如您所说的,您的方法可能不适合全局钩子,不过还是要谢谢你。
caocunt,海风的HOOKAPIlib有关于线程同步的解决方法嘛?我去看看,谢谢!
希望更多的大虾能够指点一下,谢谢!
2008-6-2 12:23
0
雪    币: 7325
活跃值: (3803)
能力值: (RANK:1130 )
在线值:
发帖
回帖
粉丝
7
VOID Proc()
{   ::WaitForSingleObject(g_hEvent, INFINITE);

     //处理HookApi的代码
   [COLOR="Red"] ::ReleaseMutex(g_hEvent);[/COLOR]
}



更详细的可以去看看变速齿轮
2008-6-2 14:24
0
雪    币: 1946
活跃值: (263)
能力值: (RANK:330 )
在线值:
发帖
回帖
粉丝
8
更详细的可以去看fengyue的DD
2008-6-2 14:30
0
雪    币: 126
活跃值: (189)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
9
我写的Hook是替换了函数的前五个字节以后.新函数执行的是备份的前五个字节,然后跳到原函数的第六个字节处执行.
不过我的是基于反汇编基础的,动态分析函数入口前几个字节是有效的.未必一定是5个.
2008-6-3 11:51
0
雪    币: 359
活跃值: (41)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
10
有难度!!!
首先不恢复是不行的,因为无法肯定原先的5个字节刚好构成一个指令,所以不太方便在别处处理完再jmp回来。
但是如果恢复的话,不管是什么互斥量都没有作用,因为可能执行不到。
但是如果真要作互斥的话,可能只有不恢复的方法,但这样就必须自己给原始的前五个字节断句,如果遇到跳转或call指令,就烦死了。
2008-6-3 21:44
0
雪    币: 249
活跃值: (10)
能力值: ( LV3,RANK:30 )
在线值:
发帖
回帖
粉丝
11
有个东西叫长度反汇编引擎..................

..............
无语的飘过
2008-6-3 22:36
0
雪    币: 359
活跃值: (41)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
12
后来又想了一下,发现不恢复确实不行,只要下面遇到jmp回到前五个字节的指令就直接死翘翘,不知道这概率有多少……
2008-6-3 23:24
0
雪    币: 200
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
13
我也遇到了同样的问题,没有解决HOOK API的同步问题,在挂钩qq的网络程序的时候,总是会出现内存访问冲突,请问这个错误是由于同步问题造成的吗?有没有高手来解决这个问题??(注:我做的是一个网络封包截获程序)
2008-6-4 08:34
0
雪    币: 200
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
14
谢谢海风,我用的是全局钩子,用EVENT有用吗?
2008-6-4 22:46
0
雪    币: 200
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
15
我再顶!我再顶!
2008-6-7 01:08
0
雪    币: 200
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
16
这个问题简直太愚蠢了.
2008-6-7 08:26
0
雪    币: 200
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
17
你好,你能说说为什么蠢嘛?
2008-6-9 16:59
0
雪    币: 249
活跃值: (10)
能力值: ( LV3,RANK:30 )
在线值:
发帖
回帖
粉丝
18
已经有两个人告诉你正确方法了.第三个人提醒你....
你还问..为什么..
2008-6-9 19:08
0
雪    币: 249
活跃值: (10)
能力值: ( LV3,RANK:30 )
在线值:
发帖
回帖
粉丝
19
不用恢复也可以
2008-6-9 19:09
0
雪    币: 249
活跃值: (10)
能力值: ( LV3,RANK:30 )
在线值:
发帖
回帖
粉丝
20
2008-6-9 19:10
0
雪    币: 249
活跃值: (10)
能力值: ( LV3,RANK:30 )
在线值:
发帖
回帖
粉丝
21
你不知道有lde这么一个东西吗?

真晕死了
2008-6-9 19:11
0
雪    币: 143
活跃值: (17)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
22
修改IAT不可以吗?
2008-6-11 13:25
0
雪    币: 202
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
23
不用恢复,Hook之前在另一函数中备份好原始的API函数,微软的Detour就是这样做的。
2008-6-12 13:16
0
雪    币: 375
活跃值: (12)
能力值: ( LV8,RANK:130 )
在线值:
发帖
回帖
粉丝
24
1先用计算指令长度,确保修改的是完整的指令
2把原始指令写到一个naked的函数里面
3naked执行的是原始指令的一部分,最后要跳回原始函数的下面几条去执行
4修改函数的前*字节为jmp**

流程就是

原函数(jmp ***)->Hook->naked->原函数的下几条指令。
2008-6-12 14:13
0
雪    币: 200
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
25
一個指令完成hook與恢復的動作就不會有線程同步的問題
因為CPU一次只能執行一條指令,沒辦法同時執行2條指令
所以只要能用一條指令完成hook或是恢復hook就不會有問題了
可用2個jmp完成hook,一個2 bytes的短程jmp,jmp到長程jmp的地方
然後長程jmp(5 bytes)再跳至hook函數即可
hook與恢復只要改2 bytes的短程jmp即可,一個指令可完成
2008-6-12 16:31
0
游客
登录 | 注册 方可回帖
返回
//