(二十五)、ChildRE

一、查壳

64位无壳
二、IDA静态分析
字符串搜索定位到main函数

向上看,有两处循环在进行字符串的判断比较,一共用到了四组字符串,其中三组已知,另外一组来自输入,因此可以推出
outputString字符串
三、获得outputString字符串
脚本如下
awer = "1234567890-=!@#$%^&*()_+qwertyuiop[]QWERTYUIOP{}asdfghjkl;" awer += chr(0x27) awer += 'A' awer += 'SDFGHJKL:"ZXCVBNM<>?zxcvbnm,./' #62 a18 = "(_@4620!08!6_0*0442!@186%%0@3=66!!974*3234=&0^3&1@=&0908!6_0*&" a52 = "55565653255552225565565555243466334653663544426565555525555222" outstring = "" fir = [-1 for i in range(62)] sec = [-1 for j in range(62)] thi = [-1 for k in range(62)] for i in range(0,62): flag = 0 for j in range(0,23): if awer[j] == a18[i]: fir[i] = j flag = 1 if flag == 0: print("Nothing") print("") for i in range(0,62): flag = 0 for j in range(0,12): if awer[j] == a52[i]: sec[i] = j flag = 1 if flag == 0: print("Nothing") for z in range(0,62): thi[z] = sec[z] * 23 + fir[z] outstring += chr(thi[z]) print(outstring)
字符串为:
private: char * __thiscall R0Pxx::My_Aut0_PWN(unsigned char *)

一个类中的函数
继续向上看
四、UnDecorateSymbolName函数
函数功能是取消修饰指定修饰C++符号名称

这里引入函数签名与符号名的概念,具体细节可看一下两篇文章进行了解
我们要把得到的函数签名转化成函数的符号名,转化后,即为
?My_Aut0_PWN@R0Pxx@@AAEPADPAE@Z
继续向上看

这个if语句,我们需要从这个语句中获取v4字符串
五、分析sub_7FF6794C15C0函数
点开后

猜测为二叉树的后序算法,v4即为二叉树的根节点地址
继续分析主函数,再向上看

注意这个函数sub_7FF6794C1280
六、分析sub_7FF6794C1280函数

很长的代码,这里我们IDA动态调试一下
在这里下断点

由于输入的字符串上限为31.我们尝试从0到9再从a到u输入31个数
rax的值是v4的地址

查看其地址

看到其对应的值为0,看其节点地址
0x13f3fd0c270
查看其地址

对应值为1
0x13f3fd0c2c0
查看其地址

对应值为2
0x13f3fd0c310
查看其地址

对应值为3
到这里,猜测到该二叉树的构造是层序进行的
七、层序遍历与后序遍历转化
经过转化后即为
Z0@tRAEyuP@xAAA?M_A0_WNPx@@EPDP
将其md5加密即得到flag
Fins = "Z0@tRAEyuP@xAAA?M_A0_WNPx@@EPDP" import hashlib hl = hashlib.md5() hl.update(Fins.encode(encoding='utf-8')) print(hl.hexdigest())
八、拿到flag
63b148e750fed3a33419168ac58083f5
flag即为flag{63b148e750fed3a33419168ac58083f5}
九、存疑
在网上我见别的大佬用 __FUNCDNAME__ 宏直接可求得符号名
但我这里求得的符号名却长这样:?My_Aut0_PWN@R0Pxx@@AEAAPEADPEAE@Z
与正确的符号名有些出入,而且我用IDA查看的时候也是这样...

不太理解。。。

浙公网安备 33010602011771号