首先运行程序,直接挑明了它用的是flatbuffer:
静态分析,读取函数为sub_1100,读取之后由sub_18B0和sub_1970进行解析:
解析出来的对象(?)为v33,结构暂时未知,之后有很多函数从v33中解析数据:
猜测应该和protobuf差不多,先根据flatbuf的语法定义一个数据结构,并在某个语言中通过这个数据结构生成对象,再把对象进行序列化,输入到这个程序中进行反序列化得到原来的对象,然后再通过这些函数来取出原来的对象中的数据。所以只需要还原出来数据结构即可。
函数sub_1BE0明显就是取出了一个字符串,程序根据这个字符串进行相应的操作,可以将其重命名为get_operation。
在create操作中,首先sub_1C00从v33中取出了v32,暂时看不出来有什么作用。然后sub_1C30从v33中取出了size,用于后面的malloc操作,所以可以确定sub_1C30为get_size。
v5和v6是一个东西,都是sub_1C60函数从v33中取出来的,为了搞清楚他是个什么东西,需要先看一下函数sub_1C80和函数sub_1CA0,函数sub_1C80直接对v5进行了解引用,得到了一个__int64,并与v32进行比较;sub_1CA0就比较明显了,直接告诉了我们它是干什么用的:
现在搞清楚了,v5和v6是一个flatbuffers中的vector,v32是vector的索引。通过简单的分析得出flatbuffers中的vector前四个字节为长度,后面为数据。现在可以确定sub_1C60为Get_vec,sub_1C00为Get_vecidx,sub_1C80为vec_size,sub_1CA0为Get_value_from_vec。
接下来函数sub_1D10又从value_from_vec中取出了v30,由此可以推断出value_from_vec也是个对象。v30被用作了idx往heaplist里存储申请的堆块和堆块的size,所以sub_1D10为Get_idx。至此create中所有从对象中取值的操作分析完毕。点开每个Get函数会看到里面还套了一层函数,里面的那一层函数第二个参数都是数字,而且对同一个对象操作的不同函数,这个数字都不相同,Get_opeartion里为4、Get_vecidx里为6、get_size里为8、Get_vec里为10:
推测数字和每个成员在对象中的偏移有关。整合现有信息即可得出大概的数据结构:
接下来要先搞清楚flatbuffer中的vector代表什么,查阅文档可知,在flatbuffer中定义的数组结构,在c++中实现的时候会变成vector,并且string是由byte数组实现的(也就是flatbuffer中定义的string在c++中实现的时候也是vector):
并且根据文档可以找到flatbuffer中的数据类型,原来的数据结构可以写成:
之所以还有省略号是因为还没分析完(Edit操作中还有新的函数)
分析edit操作,edit中使用Get_value_from_vec从vec中取出对象后除了使用了Get_idx函数获得对象中的idx,又使用了sub_1D40函数获取了对象中的未知数据v26:
要想知道v26的身份就得先分析函数sub_1D60和sub_1D80,查看sub_1D60发现是对v26进行了解引用得到一个int,和vec_size一样的操作,所以v26不出意外也是个vector。sub_1D80函数返回了v26+4位置的指针,下面memcpy直接用这个指针的数据对堆块进行了编辑,前面我们分析得到flatbuffers中的vector前四个字节为长度,后面为数据,所以v26确实是vector而且是byte数组,那byte数组不就是string吗
所以可以得到完整的数据结构:
github搞一份源码编译得到flatc,新建文件heap.fbs写入上面得到的数据结构,使用如下命令生成头文件:
tips:应该先根据猜测的数据结构在C++中生成对象,然后将对象序列化再反序列化之后,根据题目的操作分别对对象中的成员进行取值,编译为二进制文件之后拉下来放到ida里验证那些取值操作和题目里的操作是不是一致。(原来写的代码被我删了,懒得演示了.jpg)
写test.cpp:
使用如下命令编译:
编写脚本用来中转序列化数据:
交互成功:
对于flatbuffer没找到像protobuf一样的现成的逆向工具,头铁硬猜
字符串 operation
整数 vecidx
整数 size
Vector vec
字符串 operation
整数 vecidx
整数 size
Vector vec
table Heapinfo{
idx:ulong;
......
}
table Player {
operation:string;
vectoridx:ulong;
create_size:ulong;
vec:[Heapinfo];
}
table Heapinfo{
idx:ulong;
......
}
table Player {
operation:string;
vectoridx:ulong;
create_size:ulong;
vec:[Heapinfo];
}
table Heapinfo{
idx:ulong;
heap:string;
}
table Player {
operation:string;
vectoridx:ulong;
create_size:ulong;
vec:[Heapinfo];
}
root_type Player;
table Heapinfo{
idx:ulong;
[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课
最后于 2023-8-16 00:15
被/x01编辑
,原因: 添加附件