固件符号表恢复

admin 2022年2月14日12:40:41评论406 views字数 2961阅读9分52秒阅读模式

使用IDA打开固件的时候,有的时候无法识别真实的函数名,即便固件中能够找到符号表,这时就需要我们手动修复

通常情况下,我们会使用IDAPython来进行批量恢复

代码如下:

#coding=utf-8
from idaapi import *
from idc import *

symbol_interval = 16 # 符号表间隔
load_address = 0x10000 # 固件内存加载基址
symbol_table_start = 0x31eec4 + load_address   # 符号表起始地址
symbol_table_end = 0x348114 + load_address # 符号表结束地址
ea = symbol_table_start
eaEnd = symbol_table_end

while ea < eaEnd:
   offset = 0   # 4个字节为一组数据
   # 将函数名指针位置的数据转换为字符串
   create_strlit(Dword(ea-offset), BADADDR)
   # 将函数名赋值给变量sName
   sName = get_strlit_contents(Dword(ea - offset), -1ASCSTR_C)
   print(sName)
   if sName:
       # 开始修复函数名
       eaFunc = Dword(ea - offset +4)
       # 将eaFunc指向的地址重命名
       MakeName(eaFuncsName)
       # 在eaFunc处创建指令
       MakeCode(eaFunc)
       # 将eaFunc定义成一个新函数
       MakeFunction(eaFuncBADADDR)
   ea += symbol_interval

具体的功能在注释中都已备注,详细可以参考:https://hex-rays.com/products/ida/support/idadoc/

固件符号表恢复


固件符号表恢复

运行完后,的确可以识别符号表并恢复函数名称

但是实际上,该脚本只能在ida7.4(不包括ida7.4)之前的版本使用


在ida7.4版本之后,因为很多IDAPython的API都发生了改变,所以脚本也需要修改

API详细可以参考 https://hex-rays.com/products/ida/support/ida74_idapython_no_bc695_porting_guide.shtml

上述脚本中,主要是以下这几个函数发生了改变

before after
idc.Dword idc.get_wide_dword
idc.MakeName(ea, name) idc.set_name(ea, name, SN_CHECK)
idc.MakeCode idc.create_insn
idc.MakeFunction ida_funcs.add_func

所以,修改后的脚本

#coding=utf-8
from idaapi import *
from idc import *

symbol_interval = 16 #符号表间隔
load_address = 0x10000 #固件内存加载基址
symbol_table_start = 0x31eec4 + load_address   #符号表起始地址
symbol_table_end = 0x348114 + load_address #符号表结束地址
ea = symbol_table_start
eaEnd = symbol_table_end

while ea < eaEnd:
   offset = 0   #4个字节为一组数据
   #将函数名指针位置的数据转换为字符串
   create_strlit(get_wide_dword(ea-offset), BADADDR)
   #将函数名赋值给变量sName
   sName = get_strlit_contents(get_wide_dword(ea))
   print(sName)
   if sName:
       #开始修复函数名
       eaFunc = get_wide_dword(ea - offset +4)
       set_name(eaFuncsName)
       create_insn(eaFunc)
       ida_funcs.add_func(eaFuncBADADDR)
   ea += symbol_interval

该脚本可以在python7.4以后的版本中使用,测试的是7.4.191112-7.6.210427均可以使用

另外,在python7.4之后,ida开始支持python3,上述脚本是适用于python2环境下的

python3版本的话,所对应的脚本也需要更改

如何确定自己的ida中python版本

打开ida后,在左下角的交互窗口里输入

import sys
print(sys.version)
  • python2

固件符号表恢复

  • python3

固件符号表恢复


可以在回显里查看python版本

python2和python3不一样的是:在python3中,get_strlit_contents返回的是bytes类型

固件符号表恢复

set_name需要的是字符串类型

固件符号表恢复

如果python版本是3.x,则需要把上面的脚本加一行

#coding=utf-8
from idaapi import *
from idc import *

symbol_interval = 16 #符号表间隔
load_address = 0x10000 #固件内存加载基址
symbol_table_start = 0x31eec4 + load_address   #符号表起始地址
symbol_table_end = 0x348114 + load_address #符号表结束地址
ea = symbol_table_start
eaEnd = symbol_table_end

while ea < eaEnd:
   offset = 0   #4个字节为一组数据
   #将函数名指针位置的数据转换为字符串
   create_strlit(get_wide_dword(ea-offset), BADADDR)
   #将函数名赋值给变量sName
   sName = get_strlit_contents(get_wide_dword(ea))
   print(sName)
   if sName:
       #将bytes转为str
       sName = str(sName,encoding="utf-8")
       #开始修复函数名
       eaFunc = get_wide_dword(ea - offset +4)
       set_name(eaFuncsName)
       create_insn(eaFunc)
       ida_funcs.add_func(eaFuncBADADDR)
   ea += symbol_interval

sName = str(sName,encoding="utf-8")就可以将返回的bytes类型sName转为str类型sName,其他无需修改。


固件符号表恢复


原文始发于微信公众号(山石网科安全技术研究院):固件符号表恢复

  • 左青龙
  • 微信扫一扫
  • weinxin
  • 右白虎
  • 微信扫一扫
  • weinxin
admin
  • 本文由 发表于 2022年2月14日12:40:41
  • 转载请保留本文链接(CN-SEC中文网:感谢原作者辛苦付出):
                   固件符号表恢复https://cn-sec.com/archives/777131.html

发表评论

匿名网友 填写信息