本帖最后由 LShang 于 2014-5-14 21:10 编辑
ps:在更新29.0版本后,主题中描述问题已被修复。
最近在使用第三方编译版的Firefox浏览器PcxFirefox时,发现其x64版本在Win8.1系统中一旦触发文件选择框,如下载/打开文件时,浏览器就会崩溃。
在网上搜索相关问题及解决方案均无果后,只好祭出神器Windbg查找原因,因为自己对Windbg并不熟悉,所以求助某大牛同事帮忙分析,在这里对两位帮忙定位问题的同事bianfeng和KeyKernel由衷表示感谢。
以下为定位及解决该问题的过程记录。
问题定位
首先使用Windbg重新加载崩溃程序Firefox.exe,然后执行g命令执行程序并触发崩溃,Windbg捕获到如下异常
得知错误代码出现在00007ffa`5bbab9fd,在当前地址反汇编得到如下代码
查看当前出错模块路径如下
[Asm] 纯文本查看 复制代码 0:000> lmf a rip
start end module name
00007ffa\`5b9f0000 00007ffa\`5ce07000 SHELL32 C:\windows\system32\SHELL32.dll 使用IDA Pro反汇编该模块后,发现该地址原始反汇编代码如下,与正在执行代码不同
向前遍历发现,模块中代码从00007ffa`5bbab9f0处开始被覆写了14字节
从上图代码可知,该地址为SHGetSpecialFolderPathW函数地址,对比代码可知,该函数被inline hook,进而得知崩溃原因是hook过程中将00007ffa`5bbab9fd处一字节覆盖为0,导致cpu解释指令出错,产生异常并引起崩溃。
在Windbg中将其修正为48h后恢复进程执行,文件选择框正常被打开。
得知崩溃原因后,下一步开始定位是谁hook了SHGetSpecialFolderPathW函数
首先重新加载运行Firefox.exe,然后执行sxe ld:shell32.dll命令使调试器在加载该模块后中断程序
中断后对00007ffa`5bbab9f0处下写入断点,然后继续执行程序,发现程序被中断在如下地址
查看该地址模块路径如下
[Asm] 纯文本查看 复制代码 0:000> lmf a rip
start end module name
00000000`63000000 00000000`6300a000 tmemutil D:\MyTools\Tools\UserSoft\PcxFireFox\tmemutil.dll 使用IDA Pro反汇编该模块后,发现正是该地址上下文代码hook了SHGetSpecialFolderPathW函数
该段代码是将hook代码写入到SHGetSpecialFolderPathW函数起始处,但因为其使用的跳转方式为
[Asm] 纯文本查看 复制代码 jmp qword ptr [xxxxxxxx] 对应Opcode为
[Asm] 纯文本查看 复制代码 ff 25 00 00 00 00
xx xx xx xx xx xx xx xx 共需14字节。而从前文中可知SHGetSpecialFolderPathW函数地址距离之后代码只有13字节,故使用这种跳转方式进行hook,会覆盖掉函数后边的代码,进而导致异常,引起崩溃。
解决方案
得知产生问题的根本原因后,即可考虑如何解决问题了,因为该问题是由于temeutil模块对SHGetSpecialFolderPathW函数进行hook时使用了错误的跳转方式导致的,故考虑修改其跳转方式。
在64位系统下,除上述跳转方式外,还可使用如下方式进行绝对地址跳转
[Asm] 纯文本查看 复制代码 mov rax,xxxxxxxx
jmp rax
对应Opcode为
[Asm] 纯文本查看 复制代码 48 b8 xx xx xx xx xx xx xx xx
ff e0
这样仅需覆写12个字节即可完成hook,可以解决掉覆盖正常代码的问题。
因为没有找到可以直接patch64位程序的工具(Windbg/IDA Pro的patch功能均不支持带64位寄存器的指令),固只好在IDA Pro中进行Hex修改,然后将所有改动通过WinHex保存到文件中。
修正后的代码如下
需要注意的是,在hook函数内部会首先恢复SHGetSpecialFolderPathW的代码,调用完成后会重新inline hook,故需要对恢复hook的代码进行相同的修改,这里不再赘述。
完成上述步骤后,用修改后的dll文件替换掉原dll文件,再次测试触发文件选择框时,已可正常打开文件选择框。
修正后文件
版本:pcxFirefox-28.0-zhCN-vc2010-x64-sse2-betterpgo-140318
md5b6f5ce613e8d8c9e8b91ca4f6b6cc9039b0a6f5
下载:temeutil.dll
|