12558网页游戏私服论坛

 找回密码
 立即注册
游戏开服表 申请开服
游戏名称 游戏描述 开服状态 游戏福利 运营商 游戏链接
攻城掠地-仿官 全新玩法,觉醒武将,觉醒技能 每周新区 经典复古版本,长久稳定 进入游戏
巅峰新版攻 攻城掠地公益服 攻城掠地SF 新兵种、新武将(兵种) 进入游戏
攻城掠地公 散人玩家的天堂 新开 进入游戏
改版攻城掠 上线即可国战PK 稳定新区 全新改版,功能强大 进入游戏
少年江山 高福利高爆率 刚开一秒 江湖水落潜蛟龙 进入游戏
太古封魔录 开服送10亿钻石 福利多多 不用充钱也可升级 进入游戏
神魔之道 签到送元宝 稳定开新区 送豪华签到奖励 进入游戏
神奇三国 统帅三军,招揽名将 免费玩新区 激情国战,征战四方 进入游戏
龙符 三日豪礼领到爽 天天开新区 助你征战无双 进入游戏
王者之师 免费领豪华奖励 免费玩新区 6元送6888元宝 进入游戏
查看: 275|回复: 0

2012DASCTF逆向第一题汇编分析

[复制链接]

303

主题

303

帖子

616

积分

实习版主

Rank: 7Rank: 7Rank: 7

积分
616
发表于 2022-1-28 15:30:00 | 显示全部楼层 |阅读模式
第一次在论坛发帖,多有不慎,还请多多包涵,如有错误,还请不吝见教!
这个题实在假如用ida7.5来反编译实在很简单,但是这里我是ida7.0,多少有些问题,以是直接在汇编层面来解决,趁便锻炼了我的汇编阅读能力,本人技能很菜,如有错误,还望师傅们不吝见教,谢谢!
先看到main函数,找到经过判断之后的关键函数:

这里看到传进来三个参数,但是在函数内里没有 用的这些参数,而且还有一些奇观的函数,这里判断应该是低版本的ida反编译了高版本的编译器编译的程序,以是直接在gdb内里看到汇编代码,直接对汇编举行分析。
先看到这是main函数在调用关键函数的时候的汇编代码

不难看出他只传进去了两个参数,这里看到[rbp-0x8]是我输入,$rsi内里是给出的加密字符串【DASCTF{5c715207e3abed7dfb7c8ea9c82d0e29}】
看到关键函数的汇编:

这里直接把我参数的内容保存下来,【rbp-0x38】是我的输入。
往下看:

这里解析出来了我ida内里没有解析出来的函数,我们把ida修补下:
修完的效果。
接下来就是确定关键函数的参数和这些局部变量的关系,以此来找到关键操作:
首先看前两行直到我们的输入被保存在了两个局部变量内里,然后看到:

相称于是【[rbp-0x20]=malloc(0x80)     [rbp-0x20]=我的输入】
以是我的输入的放在了rbp-0x20指向的空间里

因为函数调用规则是从右到左,以是这里应该是:
rsi=[rax-0x7]//去除flag头的flag
rdi=[rbp-0x20]//输入
strcpy(rdi,rsi);
这里看到有一个[rax+0x7],这里是把我输入的flag的头去了,就剩中心的东西了
根据关键的异或,往上往下找到循环异或的代码块:

对其举行分析
0x00005555555553ca :        mov    eax,DWORD PTR [rbp-0x24]   0x00005555555553cd :        movsxd rdx,eax                                        #这里eax是计数器i,放到rdx的低位   0x00005555555553d0 :        mov    rax,QWORD PTR [rbp-0x20] #将输入放进rax内里   0x00005555555553d4 :        add    rax,rdx                                        #rax+rdx就相称于array[i++]的意思,基地址+偏移   0x00005555555553d7 :        movzx  esi,BYTE PTR [rax]                #给esi赋值,后面异或用到   0x00005555555553da :        mov    rdx,QWORD PTR [rip+0x2c2f] # 0x555555558010    0x00005555555553e1 :        mov    eax,DWORD PTR [rbp-0x24]   0x00005555555553e4 :        cdqe      0x00005555555553e6 :        add    rax,rdx                                        #和上面一样,这里是【偏移量+段地址】   0x00005555555553e9 :        movzx  ecx,BYTE PTR [rax]                #较小的值拷贝给大的值,剩下0填充例如【0x00000xxxx】   0x00005555555553ec :        mov    eax,DWORD PTR [rbp-0x24]   0x00005555555553ef :        movsxd rdx,eax   0x00005555555553f2 :        mov    rax,QWORD PTR [rbp-0x20]   0x00005555555553f6 :        add    rax,rdx                                        #原理同上,这里rax指向了输入的第位   0x00005555555553f9 :        xor    esi,ecx                //关键异或   0x00005555555553fb :        mov    edx,esi                                        #结果保存在edx内里   0x00005555555553fd :        mov    BYTE PTR [rax],dl   0x00005555555553ff :        add    DWORD PTR [rbp-0x24],0x1                //计数器+1   0x0000555555555403 :        mov    eax,DWORD PTR [rbp-0x24]        #计数器+1给到eax   0x0000555555555406 :        movsxd rbx,eax                                        #相称于计数器的值给到rbx的低八位   0x0000555555555409 :        mov    rax,QWORD PTR [rbp-0x20] #再把输入放进eax内里,规复eax在【】的状态   0x000055555555540d :        mov    rdi,rax                                        #把指向输入字符的指针给rdi,当参数给strlen   0x0000555555555410 :        call   0x555555555100         //返回输入字符串的长度   0x0000555555555415 :        cmp    rbx,rax                                        #当前计数器的值(rbx)和strlen返回值rax比较   0x0000555555555418 :        jb     0x5555555553ca #回到循环头                #rbx小于rax就跳,也就是说:计数器小于字符串长度就继续执行这里看到有一个变量:【rbp-0x24】,【rbp-0x20】,【rip+0x2c2f】。
【rbp-0x24】:这是计数器【i】;

赋初始值为0;

抑或完+1。
【rbp-0x20】:输入的字符串也就是flag在循环完事之后就是存放输入经过循环的结果
【rip+0x2c2f】:这里存放的是异或用的数组
看具体的异或过程,到底是谁和谁在异或:
  0x00005555555553f9 :        xor    esi,ecx                //关键异或对象是esi和ecx,看到对esi的操作:

就是输入的每一位。
看到ecx的操作:

总结:我输入的和给出的数组举行按位异或
关键循环分析完毕,在看到下面的代码:
  0x000055555555541a :        mov    rcx,QWORD PTR [rip+0x2bff]       # 0x555555558020    0x0000555555555421 :        mov    rdx,QWORD PTR [rbp-0x18]                #rdx==mallco(0x80),给出的flag   0x0000555555555425 :        mov    rax,QWORD PTR [rbp-0x20]                #输入经过循环异或的flag   0x0000555555555429 :        mov    rsi,rdx                                                   0x000055555555542c :        mov    rdi,rax                                                #传参   0x000055555555542f :        call   rcx                                                        #跳到rcx指向的地址,   0x0000555555555431 :        add    rsp,0x38                                #堆栈平衡,函数预备结束   0x0000555555555435 :        pop    rbx   0x0000555555555436 :        pop    rbp   0x0000555555555437 :        ret                                                    #函数结束发现有一个[rbp-0x18],没有出现在循环异或的程序里,往上看一下:

发现也是一个雷同于[rbp-0x20]的结构,相称于【[rbp-0x18]=mallco(0x80)】
动态调试发现rcx就是一个strcmp函数,比较的是 输入经过循环之后的值 和 一开始给出的值 是否相称。
相称返回1
这题就解了。
然后下载了ida7.5来验证自己的思绪,发现每一个函数都判断正确,但是在最后的call rcx那里还需要再完善一下。

来源:http://www.12558.net
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?立即注册

x
楼主热帖
回复

使用道具 举报

*滑块验证:
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|Archiver|手机版|小黑屋|12558网页游戏私服论坛 |网站地图

GMT+8, 2024-4-26 16:49 , Processed in 0.125000 second(s), 31 queries .

Powered by Discuz! X3.4

© 2001-2017 Comsenz Inc.

快速回复 返回顶部 返回列表