我正在尝试重新使用VS 2008编译的Windows可执行文件。但是,有些结束地址有误-出于某种原因,IDA较早地放置了函数的末尾,从而留下了与任何函数都不相关的代码块。未检测到的功能获取noreturn属性,并经常显示sp-based autoanalysis failed消息。我已经手工解决了大多数这些问题。问题在于Hex-Rays似乎使用了自动检测到的函数边界,因此在函数内部跳转后反编译失败,这看起来像是在Hex-Rays之外跳转。

void __thiscall sub_403CE0(void *this, unsigned int a2, int a3)
{
    sub_407F30(this, a2, a3);
    JUMPOUT(locret_403CFD);
}


如您所见,函数末尾有一个JUMPOUT语句。在调整功能边界之前这是正确的,但是现在locret_403CFD属于功能本身,而不是“跳出”。有没有办法告诉十六进制射线功能未在此处结束并向其传递正确的功能起始/结束地址?

#1 楼

就在这里。 HexRays从IDA分解中获取功能边界,因此,只要您可以在反汇编视图中更改功能边界,就可以按以下方式管理功能边界(解决方案针对您的特定情况,共同解决此问题可能更加复杂): br />

在反汇编窗口中找到功能
转到与任何功能均不相关但应该在您正在使用的功能中的代码末尾,在此处按下光标。
按E。这会将当前位置标记为该功能结束之前的区域
返回反编译器窗口。按F5。如果现在跳转到的地址属于您正在使用的功能,则JUMPOUT应该消失。


评论


这几乎就是我所做的(尽管我对E并不了解-谢谢您-所以我未定义函数并再次定义它)。不幸的是,函数边界是正确的,并且JUMPOUT不会消失。对于特定的数据库,这似乎是一个问题,因为它不会在相同二进制文件的副本上重现,但我宁愿不要重新启动它-浪费了数小时的工作。

–John Doe
2015年9月20日14:28



抱歉,您的问题很愚蠢-在重新定义功能以刷新视图后,是否在反编译器窗口中按F5键?如果没有帮助,请尝试以下操作:1-关闭反编译器窗口并删除该函数(编辑->函数->删除函数,您应该留在函数边界的反汇编窗口中)2-再次重新定义函数(选择所有说明,按P)3-再次按F5。无论如何,祝你好运。

– w s
2015年9月20日14:41



是的,我做到了。我也尝试删除该功能。现在,我正在尝试编写一个调用mark_cfunc_dirty函数的插件。

–John Doe
2015年9月20日15:09



不幸的是,即使调用clear_cached_cfuncs也无济于事。我将尝试其他方法,但我最大的猜测是,我将不得不从一个干净的数据库开始。

–John Doe
2015年9月20日在17:21

#2 楼

在使用数据库进行一些工作之后,我找出了IDA异常行为的原因。我尝试反编译的二进制文件是使用MFC的GUI应用程序;我已经从Microsoft Symbol Store获得的PDB文件中导入了许多MFC类型。这可能是IDA错误或PDB损坏-如果我不导入类型,则可以正确检测到所有函数,并且可以按预期进行反编译,如果可以的话-许多函数边界出错,反编译失败,函数属性被Hex-Rays和

可能的解决方法之一是将数据库导出为IDC文件,然后在干净的数据库上运行生成的脚本。这样,功能原型和类型信息将保持不变。但是,十六进制射线反编译的结果将有所不同(变量映射信息丢失,局部变量名称也丢失)。

评论


也许IDA试图将MFC DLL的功能边界应用于您的EXE?

– SamB
16 Mar 15 '16 at 23:45

不幸的是,我遇到了一个不使用MFC的非常简单的程序的问题...无论我尝试什么,伪代码将始终包含JUMPOUT ...

–雷
17年2月27日在19:58

@RayKoopa您是否导入了任何类型?您确定实际代码不是以这种方式编写的吗?

–John Doe
17-2-28在8:23

它实际上是打包程序的主要功能,什么也没做,是一个新的数据库。只需跳过其后面的CC调试器陷阱,即可调用该位置的电话。但是,该位置是调用它的主要功能的一部分。

–雷
17-2-28在11:01



反编译打包程序不太可能产生任何有意义的结果。解压缩程序代码可能是用汇编语言编写的和/或有意修改的代码。

–John Doe
17年2月28日在16:30

#3 楼


检查跳转目标是否在函数后面是连续区域,如果为true,则alt + p,调整函数范围。
如果不是,首先取消定义目标区域,然后使用IDA内置函数“ append_func_tail”将该块添加到所有者函数。这是IDA参考文档链接
一个跳转完成。如果太多,则编写脚本以使其自动化。