当前位置: 首页 > news >正文

go语言逆向-符号恢复

背景

IDA7.6以后对go语言编译的二进制程序能够自动恢复符号,获取某样本后放入IDA中发现其存在方法名信息,但是IDA并不能自动恢复符号。

还原符号

.go.buildinfo节区版本信息为unkown
在这里插入图片描述
查看.gopclntab节区中,其中magic存在明显异常,正常情况下.gopclntab一般为0xffffff开头
在这里插入图片描述
编译go1.21版本.gopclntab的节区如下,
在这里插入图片描述
对比样本中的.gopclntab节区,发现明显头信息的magic有问题,尝试修改后再进行反编译。发现IDA能够解析.gopclntab节区头信息,但是符号仍然没有自动还原。
在这里插入图片描述
因此我们尝试进行手动解析符号。其中比较重要的字段为如下三个
在这里插入图片描述
funcnametab为字符串数组,functab为函数地址偏移和funcInfo偏移组成的结构体
在这里插入图片描述
继续看funcinfo构成的结构体信息,第一个字段在该样本中存在明显异常。但是第二个字段表示了函数的名称
在这里插入图片描述
知道了functable的数量,且其中存在函数偏移和符号名称,因此我们可以写idapython脚本自动恢复。

还原脚本

最终idapython的还原脚本如下:

import ida_segment
import ida_bytes

def readstr(address):
    raw_data = ida_bytes.get_bytes(address, 100)
    if raw_data:
        string = b""
        for byte in raw_data:
            if byte == 0:  # 检测到 \x00
                break
            string += bytes([byte])
    return string
seg = ida_segment.get_first_seg()
start_addr = 0
end_addr = 0
while seg:
    # 获取段名称
    name = ida_segment.get_segm_name(seg)
    print(name)
    if name == ".gopclntab":
        start_addr = seg.start_ea  # 起始地址
        end_addr = seg.end_ea      # 结束地址
        print(f".gopclntab found at: {hex(start_addr)} - {hex(end_addr)}")
        break
    seg = ida_segment.get_next_seg(seg.start_ea)

if not seg:
    print(".gopclntab section not found.")

funcnamenum = ida_bytes.get_dword(start_addr+8)
funcnametab = ida_bytes.get_dword(start_addr+0x20) + start_addr
functabaddr = ida_bytes.get_dword(start_addr+0x40) + start_addr
funcaddrbase = ida_bytes.get_dword(start_addr+0x18)
print(hex(funcnamenum))
for i in range (funcnamenum):
    print(i)
    struct_FUNCTAB_ENTRY118_addr = functabaddr + 8 * i
    renameaddr = ida_bytes.get_dword(struct_FUNCTAB_ENTRY118_addr) + funcaddrbase
    struct_FUNCINFO120_addr = ida_bytes.get_dword(struct_FUNCTAB_ENTRY118_addr + 4) + functabaddr
    name_offset = ida_bytes.get_dword(struct_FUNCINFO120_addr + 4) + funcnametab
    renamename = readstr(name_offset)
    ida_bytes.del_items(renameaddr, ida_bytes.DELIT_SIMPLE, 4)
    ida_funcs.add_func(renameaddr)
    ida_name.set_name(renameaddr, renamename.decode('utf-8'), ida_name.SN_NOWARN)
    print(hex(renameaddr),renamename)

相关文章:

  • VUE集成Live2d
  • python3使用selenium打开火狐并全屏
  • DeepSeek掘金——DeepSeek-R1图形界面Agent指南
  • LeetCode(必刷75题)151. 反转字符串中的单词——字符串处理
  • 双碳战略下的智慧能源实践:安科瑞储能管理系统助力企业绿色转型
  • Microk8s Ingress实现七层负载均衡
  • 【零基础到精通Java合集】第三集:流程控制与数组
  • Nerf流程
  • Google C++ 开源风格指南
  • 【零基础到精通Java合集】第二集:数据类型与运算符
  • vue3学习-2(深入组件)
  • Python入门:3.Python的输入和输出格式化
  • 部署Windows Server自带“工作文件夹”实现企业网盘功能完整步骤
  • 国产编辑器EverEdit - 快速给字符串、表达式加引号、括号的方法
  • android TabLayout设置tab的时候文字默认居中,选中文字加粗
  • 【postman】postman找回接口数据
  • Linux中jdk-8u291-linux-x64 中jdk工具包
  • 一键安装Nginx部署脚本之Linux在线安装Nginx,脚本化自动化执行服务器部署(附执行脚本下载)
  • 智能家居的二次进化:当三维设计遇见场景芯片
  • 【架构】信息系统战略规划的三阶段演进及核心方法
  • 俄乌刚谈完美国便筹划与俄乌领导人通话,目的几何?
  • 国际博物馆日|在辽宁省博物馆遇见敦煌
  • 广东缉捕1名象牙走私潜逃非洲“红通”逃犯
  • 北京韩美林艺术馆党支部书记郭莹病逝,终年40岁
  • 嫩黑线货物列车脱轨致1名路外人员死亡,3人被采取刑事强制措施
  • 中国证券业协会修订发布《证券纠纷调解规则》