type
status
date
slug
summary
tags
category
icon
password
源码编译成二进制代码的过程中,大量辅助信息被删除,其中最重要的就是类型信息
为什么要修复伪代码中的类型?
- 提高伪代码的准确度
- 指导 IDA 反编译器中的优化器使用正确的优化方案
- 让 IDA 生成的伪代码更接近源码
我们需要手动修复哪些类型?
- 函数返回值类型
- 参数类型 / 局部变量类型 / 全局变量类型
- 数组类型 / 数组大小
- 结构体类型
- 虚表类型
判断函数的返回值是否有意义
很显然这个函数是没有返回值的
修复完就看起来简便了很多
IDA 中最常见的类型识别错误:指针型识别为整数型
图中赋值语句的左侧有两次内存访问
第一次内存访问: t = *(_DWORD *)(a1 + 4 * v5)
第二次内存访问: *(_BYTE *)(a3 + t)
第一次内存访问: v5 为下标,a1 为四字节整数数组基地址,IDA 将 a1 的类型识别为 int,正确的类型应该是 int *
第二次内存访问: a3 为 char * 数组基地址,t 为数组下标
修复后
IDA 数组修复主要有两种:
1.局部变量中定义的数组
2.全局变量中定义的数组
数组修复要考虑:数据类型 + 数组大小
局部变量中的数组修复
If 中存在 Source[32] 引用,Source 是一个未初始化数组【看上去莫名其妙】
问题:
- IDA 错误识别了 Str 数组大小,导致 Str 数组的一部分变成了 Source 数组
解决:
- 修正 Str 数组的大小为 52
修复后
全局变量中的数组修复
- 这是一个整数数组数据,全局变量,数据位于 .data 段
- 我们通过对 a1 地址引用的代码分析后得出:
- a1 是整数数组
- a1 数组的大小为 32
如何修正呢?
- 点击第一项地址按 d 键,调整 a1 第一个元素的大小为数组元素类型对应的类型字节大小,dd(4) dw(2) db(1)
- 右键选择 【Array】,在 【Array Size】填上数组对应的元素个数
- 最后点击 【ok】
修复枚举值
IDA 的类型数据库内置了常见的枚举(宏)的值,可以直接引入并修复。
例如下面对于 ptrace 的调用
第一个数字代表的是它要实现的功能
选中 12 这个数字,按下快捷键 "M",在弹出的窗口中选择对应的常量值。
IDA结构体修复
- 确定结构体大小
- 内存分配可以直接确定结构体大小
- memcpy / 局部变量偏移差 -> 间接确定 (结构体/类局部变量)
- 创建相等大小匿名结构体,并将相关变量、参数的类型修改为该结构体
- 创建相等大小匿名结构体,并将相关变量、参数的类型修改为该结构体
- 方法一:Convert ..
在函数里面将第一个参数改为结构体指针后,我们发现还有LODWORD,因为我们设置的是dqword
我们只需把它设置成DWORD就行
- 可以看出 field_4C 是 DWORD 数组 5 个元素。
- 在 field_4C 位置右键,点击 [Array] ,创建数组,如下图。
- 给 field_4C 取一个名字,叫 array1
- 这里初始化了很多对象,共 64 个(看构造函数交叉引用数)
- 对象的指针的存到了连续全局内存 A1C0
- 因此 0xA1C0 是 struc_1 * [66] 数组
- 字符串名是大富翁里的地图房子类型名。
- 0xA1C0 可能是地图, struc_1 改名成 house
- 分析另外一个结构体,这个结构体没有使用 new / malloc 分配内存,如何确定大小?
- 同一个函数,猜测这两个结构体相邻,地址做差得到 0x80
- 全局字段交叉引用 Ctrl + alt + X (要尽可能将相关函数找出来并修复类型,有利于查找)
IDA 虚表修复
- 虚表修复主要是为了重建虚表交叉引用
- 没有修复,不知道引用的是什么函数
- 找到一个虚表的函数表
按照以上函数表创建结构体 vtable
- 创建结构体如下:
- 创建类结构体,并将第一个成员的类型设置成虚表指针
修复之后
- Author:5m10v3
- URL:https://5m10v3.top/article/90a9c801-0e3d-40f8-8099-a45b216f7eeb
- Copyright:All articles in this blog, except for special statements, adopt BY-NC-SA agreement. Please indicate the source!
Relate Posts