Api Hook与 屏幕取词

xpmao 2001-07-19 05:44:03
各位有没有类似的经验。

我采用修改代码的方法截获ExtTextOutA函数,修改原函数前5个字节,
Jmp MyExtTextOutA,我的MyExtTextOutA放在全局动态连接库Hook.dll中,Hook.dll采用Mouse Hook 和 CBT Hook 放入全局内存(System Wide),不过在切换窗口时会有问题。

比如切换到 msdev.exe 会发生非法错误,不知道是不是因为这个时候 msdev.exe还没有把 hook.dll 加载到自己的进程空间,然而 ExtTextOutA 被马上调用,从而跳转到一个并不存在的地址,而发生非法错误。
难道我还需要用 Jeffrey Richter 的 InjLib把我的hook.dll加载到每一个进程中去吗?

若有高手,请留下地址,我把源代码发过去,请指点。
...全文
343 点赞 收藏 13
写回复
13 条回复
切换为时间正序
当前发帖距今超过3年,不再开放新的回复
发表回复
fxrw 2001-12-12
能不能给我也发一个!fxrw@263.net
回复
dgb 2001-12-08
给我一个分析一下吧。d_g_b@chinaren.com
回复
thd111 2001-12-08
学习,给我发一个吧thd123@sohu.com
回复
sxbyl 2001-12-08
我觉得还是挂WH_GETMESSAGE比较好。
当你切换窗口的时候,在新窗口完全显示出来全,系统肯定要先执行ExtTextOutA之类的函数重新输出很多东西,此时WH_CBT和WH_MOUSE还没有机会被调用,你的DLL也没有被加载到目的进程中,而原有ExtTextOutA函数已经被你改过了,就出现了错误。
以上只不过是我估计的。
其实把hook.dll加载到每一个进程中也没什么,动态库被多调用一次,也就是累加器加1而已,又不会多占用内存。
回复
snlee 2001-12-08
study
回复
thinp 2001-12-08
有可能给我发一个,让我也参考参考
eming114@sohu.com
回复
zjg751206 2001-12-08
http://www.programsalon.com/download.asp?type_id=19去看看!!
把你的代码发过来!!zjgnj@263.net我也开始搞这个了
回复
zjg751206 2001-12-08
http://www.programsalon.com/download.asp?type_id=19去看看!!
把你的代码发过来!!zjgnj@263.net我也开始搞这个了
回复
Anaki 2001-07-19
对这个话题我向来是关注的,只是没那水平试。 :(
回复
samueler 2001-07-19
发给我研究一下吧
sam3000@sina.com
回复
myb123 2001-07-19
听课
回复
ahphone 2001-07-19
首先声明
转贴自http://bbs.nsfocus.com/
作者:袁哥
回复
ahphone 2001-07-19
有经验的人恐怕不多,但看到过的应该不少

开着金山词霸浏览网页的时候经常就会浏览器自动关闭,实在烦人。刚才又遇到,就稍微分析了一下,觉得因为我们也经常使用钩子,可能会有借鉴,就把分析结果稍微写写,让大家以后编程少犯这样的错误。
翻译软件等关键技术之一就是拦截操作系统的显示函数,从中抓到显示的单词,这点大家都明白不用再多说。比如金山词霸会拦截系统库GDI32.DLL的输出函数ExtTextOutA等,拦截方法是找到这个函数地址,在这入口填写一个JMP 指令,跳转到金山词霸的一个入口,当然其也保存了这个入口开始被JMP指令覆盖的几个字节。金山词霸的这个入口里面又要用这个函数,所以其得到控制权后又恢复了ExtTextOutA这个函数开始的指令,进行调用。这种不好的钩子处理办法就埋下了祸根。可能是其内部信号标记等处理不好,某种情况下钩子想调用恢复后的ExtTextOutA函数的时候,但可能没有恢复成功,就又进入了金山词霸的钩子,这样就导致循环了,堆栈迅速消耗,最终因为堆栈消耗完再进行堆栈操作的时候出现非法操作而导致程序关闭退出。
这就告诉我们如果钩子里面要调用要钩的函数本身,最好要错过钩子。比如在函数入口用写JMP指令做钩子,那么再调用的时候最好调用其下面的哪个入口,或者钩子种在上面调用这个函数的指令那。要不就要保证恢复入口指令一定正确。再就是注意重入问题,就是钩子里面再调用别的函数的时候可能别的函数会用到钩子钩的函数,那你就得保证你的代码是可重入的。其实写过病毒的人恐怕都或多或少接触了重入问题。



程序1: call dword ptr [ExtTextOutA]

要钩的函数:
GDI32.DLL
ExtTextOutA:
push ebp
...
call ExtTextOutW
....
ret

假设环境如上面,钩子方案可以:

1、改写程序1的call dword ptr [ExtTextOutA]中[]内存的值,指向钩子,钩子里面要再用到ExtTextOutA的话正常调用GDI32.DLL中的这个函数就是了。这个方法缺点可能就是要修改地方多。
2、修改GDI32.DLL的函数ExtTextOutA开始指令,指向钩子,但钩子里面再调用这个函数就用里层的ExtTextOutW(这儿是假设的,我也不知道这里面有什么接口)。
3、就是金山词霸用的修改开始指令,要用的时候就恢复开始指令后调用。
(2、3两点有个不好就是要钩的函数开始一定要有几个这个函数体的指令,这几个指令这儿还不能是别的什么函数入口,这点对一般函数没问题,对于一些特殊函数恐怕就不行了)。
4、修改GDI32.DLL的函数引出表的ExtTextOutA的值,指向钩子,这样加载别的DLL的时候用到此函数操作系统就会自动把钩子地址填写,这样就不用程序操心去改写第1个方法要改写的地方了。缺点嘛就是先加载了的DLL无效,再就是恢复麻烦。
5、......
大家可以综合考虑使用自己喜欢的。





回复
相关推荐
发帖
VC/MFC
创建于2007-09-28

1.5w+

社区成员

VC/MFC相关问题讨论
申请成为版主
帖子事件
创建了帖子
2001-07-19 05:44
社区公告

        VC/MFC社区版块或许是CSDN最“古老”的版块了,记忆之中,与CSDN的年龄几乎差不多。随着时间的推移,MFC技术渐渐的偏离了开发主流,若干年之后的今天,当我们面对着微软的这个经典之笔,内心充满着敬意,那些曾经的记忆,可以说代表着二十年前曾经的辉煌……
        向经典致敬,或许是老一代程序员内心里面难以释怀的感受。互联网大行其道的今天,我们期待着MFC技术能够恢复其曾经的辉煌,或许这个期待会永远成为一种“梦想”,或许一切皆有可能……
        我们希望这个版块可以很好的适配Web时代,期待更好的互联网技术能够使得MFC技术框架得以重现活力,……