锦州市广厦电脑维修|上门维修电脑|上门做系统|0416-3905144热诚服务,锦州广厦维修电脑,公司IT外包服务
topFlag1 设为首页
topFlag3 收藏本站
 
maojin003 首 页 公司介绍 服务项目 服务报价 维修流程 IT外包服务 服务器维护 技术文章 常见故障
锦州市广厦电脑维修|上门维修电脑|上门做系统|0416-3905144热诚服务技术文章
使用IDAPython自动映射二进制文件替换默认函数名

作者: 佚名  日期:2018-11-10 14:48:23   来源: 本站整理

 这篇文章简要介绍了我编写的一个脚本,该脚本用调试输出的名称替换了IDA中的默认函数名,希望它能为你创建自己的函数名提供基本知识。
免责声明:这是我写的一个小脚本的解释,它帮助我可以在几秒内(而不是数周)映射大型二进制文件。我鼓励任何人修改脚本以供自己使用。我将这段代码用于我自己的私人研究——如果你发现它有用或者修复了一个bug,那就要买瓶啤酒好好谢谢我了。存在的问题我遇到的主要问题是我需要映射一个没有任何符号的大型二进制文件。对于二进制文件的第一个映射,我只有一个有限的时间框架,所以我必须找到一个更有效的方法来做到这一点。我非常喜欢为IDA编写脚本,尤其是映射部分,这也是我在此情况下所做的。为了自动化映射过程,我使用了一个简单的方式:查看是否有任何调试输出——幸运的是,二进制文件有很多调试输出。实例分析从装配方面来看,调试输出真是一个宝藏。它可以显示函数的用途,还可以显示真正的文件名,这有助于理解此函数所属的模块。值得注意的是,我最初研究的代码是在x64 OS上运行的8086程序集,而大多数函数都使用fastcall调用约定,因此我在我的文章中使用fastcall作为示例。

图1:调试输出带指示性错误字符串

图2:使用源文件名调试输出
查找日志函数名称由于这段代码有太多的调试输出,我决定写一些东西来处理它们。有几种方法可以找出哪些函数处理调试输出,其中一种方法是根据其内部的libc函数调用或行为来查找这些函数,这是一种比较复杂和耗时的方法,但它看起来更优雅。第二种方式是快速且粗暴的,特别是当你没有很多时间又急需时,我建议你使用它。在这种情况下,只需查看可执行文件中的字符串并找到可疑的调试输出,在找到它们之后,查看一些函数是否将它们作为参数接收。如果使用调试输出作为参数重复调用函数,那么你可以在脚本中使用它。在创建脚本之前,我发现大约有10个不同的函数正在处理调试输出,并且我还发现了寄存器中的字符串参数存储在其中。我的解决方案我们的目标是根据调试输出更改IDA的默认函数名称。例如:

图3:使用脚本更改函数名前后
接下来我将阐明脚本的不同部分。把它们放在一起正如我所说的,至少有两种方法可以找到调用的日志函数,一个懒人方案,一个非懒人方案。懒人方案遍历所有程序集并查找“call”指令,然后查找带有日志函数名称的参数。我决定将函数名称组织为全局字典的一部分:
FUNCTIONS_REGISTERS = {Function_Name:Register, Function_Name_1, Register_1... }
函数名称作为键,它们的值是调试输出的相关寄存器。例如:
FUNCTIONS_REGISTERS = {'g_WriteLogFile': 'rdx', 'g_LogError': 'rdx'}
我为该部分编写的脚本如下:
curr_addr = MinEA()
end = MaxEA()
while curr_addr 
非懒人方案我想到的不那么懒惰的方法是将xref用于找到的相关函数。通过这种方式,我使用了相同的函数名字典。在这里,我所做的是找到每个函数的外部参照地址,即函数调用的地址。
for function_name in FUNCTIONS_REGISTERS.keys():
  func_addr = idc.LocByName(function_name)
    a = idautils.XrefsTo(func_addr, 1)
    for xref in a:
        curr_addr = xref.frm  # ea in func
        if curr_addr == idc.BADADDR:
            pass
获取函数参数这些函数中包含在调用指令之前分配的寄存器中存储的调试输出。因为我有调用指令本身的地址,所以我需要向后查找,并从调用指令地址开始找到相关的寄存器值。
获取寄存器分配的地址名称的代码如下:
def get_string_for_function(call_func_addr, register):
   """
   :param start_addr: The function call address
   :return: the string offset name from the relevant register
   """
   cur_addr = call_func_addr
   start_addr = idc.GetFunctionAttr(cur_addr, idc.FUNCATTR_START)
   cur_addr = idc.PrevHead(cur_addr)
   # go through previous opcodes looking for assignment to the register
   while cur_addr >= start_addr:
       if idc.GetMnem(cur_addr)[:3] == "lea" and idc.GetOpnd(cur_addr, 0) == register:
           str_func = idc.GetOpnd(cur_addr, 1)
           return str_func
       cur_addr = idc.PrevHead(cur_addr)
   return str_func
我们有调试输出地址了,现在我们需要考虑如何得到它引用的实际字符串。下面的代码显示了它是如何完成的:(例如:更改“aErrorSavingFil”->“Error saving file %1”。我们可以通过简单地从其名称中提取地址然后获取存储在其中的字符串来实现。)
 func_name = idc.GetString(idc.LocByName(addr)
从调试输出到函数名在更改函数名称之前,我们应该稍微修改调试输出格式,因为要呈现的最终函数名称应该是干净且可读的,因此我在脚本中创建了一个函数。免责声明:我在这里介绍的函数不是我使用的整个函数,它只对调试输出进行了一般性更改,如果你想为自己创建这样的脚本,你应该编写一个函数来更改调试中的相关部分输出格式。在此函数中,还从地址名称中提取调试输出字符串。def get_fixed_source_filename(addr):
   """
   :param addr: The address of the source filename string
   :return: The fixed source filename's string
   """
   func_name = idc.GetString(idc.LocByName(addr)).replace("/", "_").replace(" ", "_")
   func_name = "AutoFunc_" + func_name
   # if the debug print is a path, delete the extension
   if func_name.endwith(".c") or func_name.endwith(".h"):
       func_name = func_name[:-2]
   # you can add whatever you want here in order to have your preferred function name
   return func_name
更改函数名称更改函数名是脚本的最后一部分,可以通过运行以下命令轻松完成:
idaapi.set_name(function_start, new_filename, idaapi.SN_FORCE)
值得注意的是,idaapi.SN_FORCE标志只能用于IDA 7及更高版本。错误的处理由于我有一个大型的二进制文件,所以我偶尔会发现一些调试函数的不同点,虽然在99.9%的情况下不会发生错误,但我也不能忽略其可能性。即使发生了一些错误,脚本也会继续在其他所有的函数上运行,不过我还是想跟踪错误并更改失败的函数名称。发生这些错误时,消息将显示在输出窗口中:

图4:IDA输出窗口,出错
错误消息包含失败的地址,日志函数名称和函数的当前名称。结论总的来说,它不是什么高深的事,这通常是我脚本中的所有代码部分。希望它能帮助人们在他们的道路上增加代码覆盖率,或者只是打开他们到IDAPython的神奇世界。我希望你能喜欢这篇文章,也欢迎任何反馈。
 



热门文章
  • 机械革命S1 PRO-02 开机不显示 黑...
  • 联想ThinkPad NM-C641上电掉电点不...
  • 三星一体激光打印机SCX-4521F维修...
  • 通过串口命令查看EMMC擦写次数和判...
  • IIS 8 开启 GZIP压缩来减少网络请求...
  • 索尼kd-49x7500e背光一半暗且闪烁 ...
  • 楼宇对讲门禁读卡异常维修,读卡芯...
  • 新款海信电视机始终停留在开机界面...
  • 常见打印机清零步骤
  • 安装驱动时提示不包含数字签名的解...
  • 共享打印机需要密码的解决方法
  • 图解Windows 7系统快速共享打印机的...
  • 锦州广厦电脑上门维修

    报修电话:13840665804  QQ:174984393 (联系人:毛先生)   
    E-Mail:174984393@qq.com
    维修中心地址:锦州广厦电脑城
    ICP备案/许可证号:辽ICP备2023002984号-1
    上门服务区域: 辽宁锦州市区
    主要业务: 修电脑,电脑修理,电脑维护,上门维修电脑,黑屏蓝屏死机故障排除,无线上网设置,IT服务外包,局域网组建,ADSL共享上网,路由器设置,数据恢复,密码破解,光盘刻录制作等服务

    技术支持:微软等