-
-
[原创]解决Ida Pro 4.9 free version的一个有关Help的bug
-
2008-2-27 15:17
7567
-
[原创]解决Ida Pro 4.9 free version的一个有关Help的bug
尽管
IdaPro Advanced版本很好、很强大,但那毕竟是商业版,要合法使用就得掏银子。可是
DataRescue公司也很好、很厚道,提供了
Ida Freeware Version 4.9版本可以免费下载使用。该版本对于仅分析
Windows 32-bit平台的粉丝们而言也很好、很够用。下载地址为:
http://tiarater.datarescue.be/freefiles/idafree49.exe
下载完双击
idafree49.exe可按提示安装
Ida Freeware Version4.9。安装好后运行
idag.exe时,在
About对话框将选项
Do not display PDF file next time打勾,以免自动显示
idafreeware.pdf文件。当调用帮助信息(单击菜单Help->Help Index)时会出现找不到
idahelp.hlp文件的消息框,并询问是否亲自查找该文件。因为
Ida Freeware Version 4.9的帮助文件是
chm格式的,而不是
hlp格式,所以找不到。但是如果按帮助键
F1却可以正常打开
chm格式的帮助文件。
下面看看如何用
Ida Freeware Version 4.9来解决问题。可以用
idag.exe打开
idag.exe自身进行分析。在运行
idag.exe之前先用
notepad或其他文本编辑器对配置文件
cfg\idagui.cfg进行修改如下:
1)为了启用补丁及idc脚本命令功能,将
DISPLAY_PATCH_SUBMENU = NO // Display the Edit,Patch submenu
DISPLAY_COMMAND_LINE = NO // Display the expressions/IDC command line
改为
DISPLAY_PATCH_SUBMENU = YES // NO // Display the Edit,Patch submenu
DISPLAY_COMMAND_LINE = YES // NO // Display the expressions/IDC command line
2)为了禁用“未定义”及“设置函数末尾”提示选项,将
CONFIRM_UNDEFINE_COMMAND = CONFIRM_UNDEFINE_YES // Confirm the "undefine" command
CONFIRM_SETFUNCEND_COMMAND = YES // Confirm the "set function end" command (E hotkey)
改为
CONFIRM_UNDEFINE_COMMAND = CONFIRM_UNDEFINE_BLOCK // CONFIRM_UNDEFINE_YES // Confirm the "undefine" command
CONFIRM_SETFUNCEND_COMMAND = NO // YES // Confirm the "set function end" command (E hotkey)
3)为了启用“文件偏移跳转”快捷键(Alt+O),将
"JumpFileOffset" = 0
改为
"JumpFileOffset" = "Alt-O" // 0
4)为了启用“符号改变”快捷键(Shift+-),将
//"ChangeSign" = "Shift+-"
改为
"ChangeSign" = "Shift+-"
5)为了启用“计算”快捷键,将
//"Calculate" = '?'
改为
"Calculate" = '?'
修改好以上内容后,将
cfg\idagui.cfg文件存盘。
双击
idag.exe,启动ida后单击菜单
File->Open找到
idag.exe后将其打开,ida会自动分析执行文件。等待分析完毕后,单击菜单
Search->text...(或按快捷键
Alt+T)出现
Text search (slow)对话框,输入
Help1Click单击
OK搜索文本"Help1Click"可以找到如下信息:
.data:0053AE9F dd offset sub_406640
.data:0053AEA3 aHelp1click db 10,'Help1Click'
双击
sub_406640可以找到如下代码:
.text:00406640 sub_406640 proc near ; DATA XREF: .data:0053AE9Fo
.text:00406640 mov eax, [eax+158h]
.text:00406646 mov edx, ds:@Forms@Application ; Forms::Application
.text:0040664C push eax ; dwData
.text:0040664D push 1 ; uCommand
.text:0040664F mov edx, [edx]
.text:00406651 add edx, 50h
.text:00406654 mov eax, [edx]
.text:00406656 test eax, eax
.text:00406658 jz short loc_40665E
.text:0040665A mov ecx, [edx]
.text:0040665C jmp short loc_406663
.text:0040665E ; 哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪?
.text:0040665E
.text:0040665E loc_40665E: ; CODE XREF: sub_406640+18j
.text:0040665E mov ecx, offset szHelp
.text:00406663
.text:00406663 loc_406663: ; CODE XREF: sub_406640+1Cj
.text:00406663 push ecx ; lpszHelp
.text:00406664 push 0 ; hWndMain
.text:00406666 call WinHelpA
.text:0040666B retn
.text:0040666B sub_406640 endp
可见函数
sub_406640就是实现"Help1Click"功能的,而且还调用API中的
WinHelpA函数,该函数将打开
hlp格式的帮助文件。于是就出现了一开始提到的bug:找不到
idahelp.hlp文件。
既然按快捷键
F1能正常调出
idahelp.chm帮助文件,我们可以通过将函数
sub_406640改造成快捷键
F1来实现“Help1Click"功能。单击菜单
Search->text...(或按快捷键
Alt+T)搜索文本".chm"可以找到如下信息(函数
sub_466020):
.text:00466020 sub_466020 proc near ; CODE XREF: sub_403EE0+14Dp
.text:00466020
.text:00466020 var_11C = dword ptr -11Ch
.text:00466020 var_108 = dword ptr -108h
.text:00466020
.text:00466020 push ebx
.text:00466021 push esi
.text:00466022 mov esi, eax
.text:00466024 push edi
.text:00466025 add esp, 0FFFFFEFCh
.text:0046602B xor ebx, ebx
.text:0046602D mov eax, [esi+4]
.text:00466030 mov edi, edx
.text:00466032 test eax, eax
.text:00466034 jz short loc_4660A0
.text:00466036 push offset a_chm ; ".chm"
.text:0046603B mov edx, ds:@Forms@Application ; Forms::Application
.text:00466041 mov eax, [edx]
.text:00466043 add eax, 50h
.text:00466046 mov edx, [eax]
.text:00466048 test edx, edx
.text:0046604A jz short loc_466050
.text:0046604C mov ecx, [eax]
.text:0046604E jmp short loc_466055
.text:00466050 ; 哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪?
.text:00466050
.text:00466050 loc_466050: ; CODE XREF: sub_466020+2Aj
.text:00466050 mov ecx, offset unk_555AF8
.text:00466055
.text:00466055 loc_466055: ; CODE XREF: sub_466020+2Ej
.text:00466055 push ecx
.text:00466056 push 104h
.text:0046605B lea eax, [esp+114h+var_108]
.text:0046605F push eax
.text:00466060 call IDA_1016
.text:00466065 push esp
.text:00466066 call IDA_992
.text:0046606B test al, al
.text:0046606D jz short loc_4660A0
.text:0046606F test edi, edi
.text:00466071 jnz short loc_46608B
.text:00466073 push 0
.text:00466075 push 1
.text:00466077 lea edx, [esp+124h+var_11C]
.text:0046607B push edx
.text:0046607C push 0
.text:0046607E call dword ptr [esi+4]
.text:00466081 test eax, eax
.text:00466083 setnz bl
.text:00466086 and ebx, 1
.text:00466089 jmp short loc_4660A0
.text:0046608B ; 哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪?
.text:0046608B
.text:0046608B loc_46608B: ; CODE XREF: sub_466020+51j
.text:0046608B push edi
.text:0046608C push 0Fh
.text:0046608E lea eax, [esp+124h+var_11C]
.text:00466092 push eax
.text:00466093 push 0
.text:00466095 call dword ptr [esi+4]
.text:00466098 test eax, eax
.text:0046609A setnz bl
.text:0046609D and ebx, 1
.text:004660A0
.text:004660A0 loc_4660A0: ; CODE XREF: sub_466020+14j
.text:004660A0 ; sub_466020+4Dj ...
.text:004660A0 mov eax, ebx
.text:004660A2 add esp, 104h
.text:004660A8 pop edi
.text:004660A9 pop esi
.text:004660AA pop ebx
.text:004660AB retn
.text:004660AB sub_466020 endp
因为仅有一处出现".chm",所以可以断定这就是打开
idahelp.chm帮助文件的函数。再双击交叉引用
sub_403EE0,可得到如下代码:
.text:00404026 loc_404026: ; CODE XREF: sub_403EE0+13Dj
.text:00404026 mov eax, offset byte_57F4C0
.text:0040402B mov edx, esi
.text:0040402D call sub_466020
由此可见
sub_466020需要两个参数
eax和
edx(典型的Delphi调用)。
eax的参数为
offset byte_57F4C0,但
edx的参数为
esi不能确定其值是多少。我们可以在"
.text:00404026 loc_404026:"处下断点(快捷键为
F2)对其进行跟踪。单击菜单
Debugger->Start process(或快捷键
F9)对
idag.exe进行调试,这时又会出现一个
Ida图形界面(点击
Yes关闭
Debugger warning对话框,再点击
OK关闭
About对话框)。然后按
F1,这时程序就停在断点
loc_404026:处,观察寄存器
esi发现其值为
0。这样两个参数就定下来了。
如果想确认
sub_466020的功能,可以单步跟踪到
sub_466020内部,连按三下快捷键
F7就会出现
sub_466020的代码同前(为了便于阅读这里再抄写一遍):
.text:00466020 sub_466020 proc near ; CODE XREF: sub_403EE0+14Dp
.text:00466020
.text:00466020 var_11C = dword ptr -11Ch
.text:00466020 var_108 = dword ptr -108h
.text:00466020
.text:00466020 push ebx
.text:00466021 push esi
.text:00466022 mov esi, eax
.text:00466024 push edi
.text:00466025 add esp, 0FFFFFEFCh
.text:0046602B xor ebx, ebx
.text:0046602D mov eax, [esi+4]
.text:00466030 mov edi, edx
.text:00466032 test eax, eax
.text:00466034 jz short loc_4660A0
.text:00466036 push offset a_chm ; ".chm"
.text:0046603B mov edx, ds:@Forms@Application ; Forms::Application
.text:00466041 mov eax, [edx]
.text:00466043 add eax, 50h
.text:00466046 mov edx, [eax]
.text:00466048 test edx, edx
.text:0046604A jz short loc_466050
.text:0046604C mov ecx, [eax]
.text:0046604E jmp short loc_466055
.text:00466050 ; 哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪?
.text:00466050
.text:00466050 loc_466050: ; CODE XREF: sub_466020+2Aj
.text:00466050 mov ecx, offset unk_555AF8
.text:00466055
.text:00466055 loc_466055: ; CODE XREF: sub_466020+2Ej
.text:00466055 push ecx
.text:00466056 push 104h
.text:0046605B lea eax, [esp+114h+var_108]
.text:0046605F push eax
.text:00466060 call IDA_1016
.text:00466065 push esp
.text:00466066 call IDA_992
.text:0046606B test al, al
.text:0046606D jz short loc_4660A0
.text:0046606F test edi, edi
.text:00466071 jnz short loc_46608B
.text:00466073 push 0
.text:00466075 push 1
.text:00466077 lea edx, [esp+124h+var_11C]
.text:0046607B push edx
.text:0046607C push 0
.text:0046607E call dword ptr [esi+4]
.text:00466081 test eax, eax
.text:00466083 setnz bl
.text:00466086 and ebx, 1
.text:00466089 jmp short loc_4660A0
.text:0046608B ; 哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪?
.text:0046608B
.text:0046608B loc_46608B: ; CODE XREF: sub_466020+51j
.text:0046608B push edi
.text:0046608C push 0Fh
.text:0046608E lea eax, [esp+124h+var_11C]
.text:00466092 push eax
.text:00466093 push 0
.text:00466095 call dword ptr [esi+4]
.text:00466098 test eax, eax
.text:0046609A setnz bl
.text:0046609D and ebx, 1
.text:004660A0
.text:004660A0 loc_4660A0: ; CODE XREF: sub_466020+14j
.text:004660A0 ; sub_466020+4Dj ...
.text:004660A0 mov eax, ebx
.text:004660A2 add esp, 104h
.text:004660A8 pop edi
.text:004660A9 pop esi
.text:004660AA pop ebx
.text:004660AB retn
.text:004660AB sub_466020 endp
简言之在
.text:0046607B处下断点(
F2)或将光标定位在
.text:0046607B(按快捷键
G出现
Jump to address对话框,输入
0046607B后点击
OK)处按快捷键
F4,此时双击寄存器
edx可以发现它指向帮助文件
idahelp.hlp(我将
ida Freeware Vesion 4.9安装在文件夹
C:\ida49free\):
Stack[00000B2C]:0013F460 aFTemp49freeApp db 'C:\ida49free\idahelp.chm',0
按快捷键
Ctrl+F2结束程序调试。
有了参数就可以修改函数
sub_406640了,将光标定位到如下一行代码(按快捷键
G出现
Jump to address对话框,输入
406640后点击
OK):
.text:00406640 mov eax, [eax+158h]
点击菜单
Edit->Patch program->Assemble...出现
Assemble instruction对话框,进行如下操作:
输入
mov eax, 57F4C0h点击
OK;
输入
xor edx, edx点击
OK;
输入
xor edx, edx点击
OK;
输入
xor edx, edx点击
OK;
输入
call 466020h点击
OK;
输入
ret点击
OK;
点击
Cancel。
操作完成后得到如下代码:
.text:00406640 unk_406640 db 0B8h ; ? ; DATA XREF: .data:0053AE9Fo
.text:00406641 db 0C0h ; ?
.text:00406642 db 0F4h ; ?
.text:00406643 db 57h ; W
.text:00406644 db 0
.text:00406645 ; 哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪?
.text:00406645 xor edx, edx
.text:00406647 xor edx, edx
.text:00406649 xor edx, edx
.text:0040664B call sub_466020
.text:00406650 retn
.text:00406651 ; 哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪?
.text:00406651 add edx, 50h
......
在
.text:00406640行按快捷键
C(Code命令)及快捷键
P(Program命令)得到如下代码:
.text:00406640 sub_406640: proc near ; DATA XREF: .data:0053AE9Fo
.text:00406640 mov eax, offset off_57F4C0
.text:00406645 xor edx, edx
.text:00406647 xor edx, edx
.text:00406649 xor edx, edx
.text:0040664B call sub_466020
.text:00406650 retn
.text:00406651 ; 哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪?
.text:00406651 add edx, 50h
.text:00406654 mov eax, [edx]
.text:00406656 test eax, eax
.text:00406658 jz short loc_40665E
.text:0040665A mov ecx, [edx]
.text:0040665C jmp short loc_406663
.text:0040665E ; 哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪?
.text:0040665E
.text:0040665E loc_40665E: ; CODE XREF: .text:00406658j
.text:0040665E mov ecx, offset szHelp
.text:00406663
.text:00406663 loc_406663: ; CODE XREF: .text:0040665Cj
.text:00406663 push ecx ; lpszHelp
.text:00406664 push 0 ; hWndMain
.text:00406666 call WinHelpA
.text:0040666B retn
到此为止补丁就打好了。
至于为何有三行
xor edx, edx指令,那是因为在
.text:00406648处有一个外部引用。在
.text:00406647处按快捷键
U(Undefine命令)得到以下内容:
.text:00406640 sub_406640 proc near ; DATA XREF: .data:0053AE9Fo
.text:00406640 mov eax, offset off_57F4C0
.text:00406645 xor edx, edx
.text:00406645 ; 哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪?
.text:00406647 db 31h ; 1
.text:00406648 db 0D2h ; ?OFF32 SEGDEF [_idata,58F688]
.text:00406649 db 31h ; 1
.text:0040664A db 0D2h ; ?
.text:0040664B db 0E8h ; ?
.text:0040664C db D0h ; [
.text:0040664D db 0F9h ; ?
.text:0040664E db 5
.text:0040664F db 0
.text:00406650 db 0C3h ; ?
.text:00406650 sub_406640 endp
即[I].text:00406648 db 0D2h ; ?OFF32 SEGDEF [_idata,58F688][/I]有外部引用。为了避免出问题,就多加了两行
xor edx,edx代码,从而保证调用
call sub_466020更加可靠。
下面可以生成打好补丁与源文件的比较结果:
点击菜单
File->Produce file->Create DIF file...出现对话框
Please enter DIF file name for idag.exe,此时可以将文件保存为
Ida49FreePatch.dif。该文件内容如下:
----------------------------------------------------------------
This difference file is created by The Interactive Disassembler
idag.exe
00005C40: 8B B8
00005C41: 80 C0
00005C42: 58 F4
00005C43: 01 57
00005C45: 00 31
00005C46: 8B D2
00005C47: 15 31
00005C48: 88 D2
00005C49: F6 31
00005C4A: 58 D2
00005C4B: 00 E8
00005C4C: 50 D0
00005C4D: 6A F9
00005C4E: 01 05
00005C4F: 8B 00
00005C50: 12 C3
-----------------------------------------------------------------
然后可以用任何二进制文件编辑器如
WinHex或
UltraEdit对
idag.exe进行手工修改(修改前要先备份原文件以防意外)。
也可用我开发的小程序AnyPatch.exe打补丁(要求idag.exe和Ida49FreePatch.dif两个文件在同一文件夹下),在命令行窗口中的用法如下:
"anypatch Ida49FreePatch.dif"
按提示操作即可。
遗憾的是我没有上传附件的权限。庆幸的是可以在临时空间下载anyPatch.exe。地址为:
http://rapidshare.de/files/38687295/AnyPatch.exe.html
实战CVE漏洞分析与防范(第1季)