首页
社区
课程
招聘
[原创] 京东-看雪 2018 - 春季赛 第二题 - 数据结构
发表于: 2018-6-19 01:30 3350

[原创] 京东-看雪 2018 - 春季赛 第二题 - 数据结构

aqs 活跃值
5
2018-6-19 01:30
3350

拿到的是一个 win32 控制台程序

运行一下, 输入一个字符串,返回正确或错误,没有其他

ida 打开程序看看

main 主要逻辑如下,传入一个字符串,长度为 22
对传入的 字符串有一个check 函数,一个字符一个字符判断

字符check 过了之后会调用一个 main_logic_401C40 函数,这里就是主要逻辑了

main logic 函数, 将我们输入的字符串切割,然后存放到局部变量上
有点乱,后面直接调试看内存可以比较快看出来

_Ref_count_obj 这个函数进行一些内存分配的操作
注意 &TrieTree::`vftable' 这里,这是 c++ 对象的写法
Tire Tree ?? 想起题目名字叫数据结构,是不是和这个有关?
找了一下资料,Tire Tree ,字典树,大概就是数据放到树上方便检索的操作
这个函数主要就是 创建一个 TireTree 对象,然后返回其指针,后续操作都在这个上面进行

再次回到 main_logic 函数 后续的内容
这里在两个函数重复操作了 8 次, 后续分析之后发现这里是

如果两个树一样,后面还会有一个 check 函数, 对 字符串 子串进行一些值的判断,现在还没有用,这个可以在后面帮助反推输入的值

okay 到这里思路就很明确了,程序利用我们的输入构建了一棵字典树
这棵树要和一棵预先准备好的树一样,那么我们就需要先找到这棵树
ida 看一下引用
找到函数 sub_40190
看其调用可以知道
这里程序是通过

这个函数进行了一些预处理,然后再通过它调用main 函数,去除一些初始化的操作, 预先准备好的字典树 的初始化大体是下面
程序调用了 initterm 函数,这个函数的效果大致是传两个地址,这两个地址之间的值不为0的 指针都当作函数从头到尾调用一遍

somefunc 里面是下面, 前面是一些初始化 TireTree 对象的操作,主要是最后一个函数

sub_401150 函数包含了 我们用于比较的字典树的生成的操作
主要逻辑如下
下面的几个函数都是一样的操作,生成一个字符串然后存放到 一个地址里面
比如 f_4015D0(&v12) 这个函数 生成了 'f' 然后存放到 v12 这个局部变量里面

后面执行了和之前 前面 main logic 生成字典树差不多的操作
猜测这里就是在 构造字典树了

存放之后会进行一系列的操作,一开始不知道是干什么
观察 copysome_403940 函数 可以猜测这里应该是在构建字典树的过程
给一个节点孩子什么的
比如 copysome_403940(&node_M, &node_k)
操作的效果就是 node_M 是父节点, node_k 加入成为 node_M 的子节点
通过下面的操作我们也可以构建出一棵树出来

字典树构建完成之后, 会给每个节点 执行 sub_403650 函数,赋一个数字值,估计就是引用计数了

很好,到了这里,自己重构一下 字典树就可以找出所有可能的字符串了
mspaint 画了一棵树,勿喷

因为 M 的引用计数是两个,所以猜测需要有两个一样的串,和前面构建字典树的字符的数量也相符
不过这里有些 字符串的长度是一样的,不是到哪个先哪个后,这就需要前面提到的 last_check_401B80 函数了, 将对应的字符 的byte 异或一下就可以知道哪个是哪个了

其实自己排列组合爆破一下也是可以的
最后得到的flag

 
 
2018CMv4.exe: PE32 executable (console) Intel 80386, for MS Windows

[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!

上传的附件:
收藏
免费 1
支持
分享
最新回复 (2)
雪    币: 484
活跃值: (18)
能力值: ( LV4,RANK:40 )
在线值:
发帖
回帖
粉丝
2


您是怎么判断这个函数是生成字符串的,我怎么都解不明白
我运行代码怎么都是解不出来
a1 = [141,180,251,69,81,152,144,139,175,218,207,96,171,100,39,0]
# a1 = [0xb4,0xFB,0x45,0x51,0x98,0x90,0x8B,0xAF,0xDA,0xCF,0x60,0xAB,0x64,0x27,0x00]
for i in range(0,15):
	a1[i] ^= i * 34 * i + i * i * 58 * i - 78 * i - 52
	result = i + 1
print(a1)

[-191, -146, 371, 1655, 3941, 7538, 13088, 20841, 31091, 44064, 60503, 80498, 104047, 132206, 164711, 0]
[-136, -223, 461, 1635, 4012, 7546, 13115, 20813, 30982, 44085, 60664, 80569, 104096, 132141, 164672]
最后于 2018-6-23 21:08 被zjhkx学院编辑 ,原因:
2018-6-23 16:34
0
雪    币: 2754
活跃值: (346)
能力值: ( LV15,RANK:828 )
在线值:
发帖
回帖
粉丝
3
额,我是直接调试看的
2018-6-23 22:39
0
游客
登录 | 注册 方可回帖
返回
//