首页
社区
课程
招聘
[讨论]开新贴讨论GetProcAddress被AppHelp在内部到底干了什么?
发表于: 2015-6-24 10:53 5971

[讨论]开新贴讨论GetProcAddress被AppHelp在内部到底干了什么?

2015-6-24 10:53
5971
问题的起因:
1.setup安装包肯定是带uac的
2.安装包启动了进程A
3.进程A启动了进程B
4.进程B启动了winkawas进程,winkawas大家玩街机模拟器的人可能知道,很好用的。

按理来说,winkawas进程应该是从setup安装包进程继承了一些东西的,权限以及兼容性?还有哪些特性我不清楚

但我猜想应该不仅仅是管理员权限,因为下列问题在进程b右键以管理员启动时并不会出现,而一定要安装包带起来的时候才出问题

在winkawas启动时,我通过远程线程将hook模块注入,并hook LoadLibraryExW,意图在加载DDraw.dll时Hook住DirectDrawCreate这个API,进而hook住整个DDraw

问题现象:
我在Hook住LoadLibraryExW后,在加载ddraw.dll时通过GetProcAddres这个API取得DirectDrawCreate的地址
注意,这时候就出问题了,问题比较复杂,请细看
1.如果在安装包继承过来的情况下,我得到的返回地址,vs显示为apphelp中的DWM8AND16BitHook_DirectDrawCreate!
2.如果在桌面运行的情况下,我得到的返回地址是ddraw.dll中的真实函数地址,这种情况下,我hook它,后面的一切都正常工作

所以我们重点看在安装包继承情况下,为什么我的代码会出问题?理论上我getprocaddress得到的和winkawas得到的应该一样啊,就算都用DWM8AND16BitHook_DirectDrawCreate,理论上我也能hook到啊

接着分析:
为什么我hook不到,原因在于:我调用的getprocaddresst得到的是DWM8AND16BitHook_DirectDrawCreate,而winkawas自己也调用getprocaddress(winkaws加壳了,自己加载的导入函数),得到的确实是DirectDrawCreate!
经分析及多次汇编测试,我们调用的Getprocaddress代码绝对一样,不管是地址还是汇编,确定完全一样!
这就奇怪了,不合理啊,同样的代码,同样的参数,为啥得到的结果却不同呢?

重点来了,看以下汇编代码:
_GetProcAddressStub@8:
76DC980C 8B FF                mov         edi,edi  
76DC980E 55                   push        ebp  
76DC980F 8B EC                mov         ebp,esp  
76DC9811 FF 75 04             push        dword ptr [ebp+4]  
76DC9814 FF 75 0C             push        dword ptr [ebp+0Ch]  
76DC9817 FF 75 08             push        dword ptr [ebp+8]  
76DC981A FF 15 68 00 E3 76    call        dword ptr [__imp__GetProcAddressForCaller@12 (76E30068h)]  
76DC9820 5D                   pop         ebp  
76DC9821 C2 08 00             ret         8  
76DC9824 CC                   int         3  
76DC9825 CC                   int         3  
76DC9826 CC                   int         3  
76DC9827 CC                   int         3  
76DC9828 CC                   int         3  


我们在调用GetProcAddress函数时,其实是对上面代码的调用,我们能看得出来,我们一般情况输入2个参数,模块及函数名,但到了里面却还使用了多一个参数,而这个参数是ebp+4,实际上是调用者下一行的返回地址,这样,我们能猜测,GetProcAddress时,内部还使用了调用者分析,可能内部用来分析调用者模块属性?

我不知道这样做是想干啥?对内核熟悉的人可以发表一下看法,ms的人员肯定知道是为了做啥

经多次测试,我用同样的代码调试时修改push的第一个参数的值(上面的push        dword ptr [ebp+4]  )
将该值随便改成其它模块(并不一定是返回值,只要限定要模块内就行了),来测试对返回值的影响
我得到了下面这个表:
winkawas        DirectDrawCreate
我的模块             DWM8AND16BitHook_DirectDrawCreate
ddraw.dll         DirectDrawCreate
user32.dll        DirectDrawCreate
kernel32.dll     DWM8AND16BitHook_DirectDrawCreate

这我就迷茫了,为什么不同的调用者,导致了GetProcAddress的返回值有区别?
模块到底有啥特殊标识,能让系统内部分析出来,决定是否被Hook到apphelp中去?
我在vs2010里随便改了些链接属性,无果……

看上去像是apphelp重点相关的兼容性部分功能导致的影响,所以我上面才说,不仅仅是权限问题,对系统内核不了解,求讨论

[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!

收藏
免费 0
支持
分享
最新回复 (6)
雪    币: 121
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
2
apphelp 这个东西会勾住getprocxxx.自己实现一个就会避开这个问题!
2015-6-26 16:09
0
雪    币: 174
活跃值: (620)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
3
明显是勾了
但它如何根据模块判断应该返回哪个地址的呢?模块的区别特性在哪个标志?
如果能讨论清楚,我直接修改模块的标志说不定就好了
2015-6-26 17:32
0
雪    币: 174
活跃值: (620)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
4
顶顶顶顶
2015-6-29 16:06
0
雪    币: 81
活跃值: (100)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
5
自己读一下pe导出表获取你要的函数不是更快么
2015-7-1 16:14
0
雪    币: 174
活跃值: (620)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
6
我是认为这不是标准方法,稳定性兼容性不放心
另外一方面是技术钻研的角度,知道希望知道到底它是怎么知道应该给哪个地址的,怎么区分模块而给不同的值的
意义不一样
2015-7-2 11:54
0
雪    币: 81
活跃值: (100)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
7
GetProcAddress做的事情也是一样的,没有什么不标准
你可以试试在内存里加载一个dll以后把它内存PE的导出表抹掉然后再用GetProcAddress
想技术钻研的话干嘛不跟进函数逆个痛快
2015-7-3 12:42
0
游客
登录 | 注册 方可回帖
返回
//