首页
社区
课程
招聘
[原创]解决Ida Pro 4.9 free version的一个有关Help的bug
发表于: 2008-2-27 15:17 8997

[原创]解决Ida Pro 4.9 free version的一个有关Help的bug

2008-2-27 15:17
8997

尽管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需要两个参数eaxedx(典型的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

-----------------------------------------------------------------

然后可以用任何二进制文件编辑器如WinHexUltraEditidag.exe进行手工修改(修改前要先备份原文件以防意外)。

也可用我开发的小程序AnyPatch.exe打补丁(要求idag.exe和Ida49FreePatch.dif两个文件在同一文件夹下),在命令行窗口中的用法如下:

"anypatch Ida49FreePatch.dif"

按提示操作即可。



遗憾的是我没有上传附件的权限。庆幸的是可以在临时空间下载anyPatch.exe。地址为:
http://rapidshare.de/files/38687295/AnyPatch.exe.html


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

收藏
免费 7
支持
分享
最新回复 (2)
雪    币: 267
活跃值: (16)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
2
帮楼主上传一份
上传的附件:
2008-2-27 16:05
0
雪    币: 200
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
3
哦谢谢上面的咯..嘿嘿很不错哦
2008-3-9 11:38
0
游客
登录 | 注册 方可回帖
返回
//