吾爱破解 - 52pojie.cn

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 3971|回复: 12
收起左侧

[调试逆向] 2012DASCTF逆向第一题汇编分析

[复制链接]
Rootkit123 发表于 2021-5-30 13:53

第一次在论坛发帖,多有不慎,还请多多包涵,如有错误,还请不吝赐教!
这个题其实如果用ida7.5来反编译其实很简单,但是这里我是ida7.0,多少有些问题,所以直接在汇编层面来解决,顺便锻炼了我的汇编阅读能力,本人技术很菜,如有错误,还望师傅们不吝赐教,谢谢!
先看到main函数,找到经过判断之后的关键函数:
1.png
这里看到传进来三个参数,但是在函数里面没有 用的这些参数,而且还有一些奇观的函数,这里判断应该是低版本的ida反编译了高版本的编译器编译的程序,所以直接在gdb里面看到汇编代码,直接对汇编进行分析。
先看到这是main函数在调用关键函数的时候的汇编代码
2.png
不难看出他只传进去了两个参数,这里看到[rbp-0x8]是我输入,$rsi里面是给出的加密字符串【DASCTF{5c715207e3abed7dfb7c8ea9c82d0e29}】
看到关键函数的汇编:
3.png
这里直接把我参数的内容保存下来,【rbp-0x38】是我的输入。
往下看:
4.png
这里解析出来了我ida里面没有解析出来的函数,我们把ida修补下:
5.png 修完的效果。
接下来就是确定关键函数的参数和这些局部变量的关系,以此来找到关键操作:
首先看前两行直到我们的输入被保存在了两个局部变量里面,然后看到:
61.png
相当于是【[rbp-0x20]=malloc(0x80)     [rbp-0x20]=我的输入】
所以我的输入的放在了rbp-0x20指向的空间里
7.png
因为函数调用规则是从右到左,所以这里应该是:

rsi=[rax-0x7]//去除flag头的flag
rdi=[rbp-0x20]//输入
strcpy(rdi,rsi);

这里看到有一个[rax+0x7],这里是把我输入的flag的头去了,就剩中间的东西了
根据关键的异或,往上往下找到循环异或的代码块:
8.png
对其进行分析

 0x00005555555553ca <+156>:        mov    eax,DWORD PTR [rbp-0x24]
   0x00005555555553cd <+159>:        movsxd rdx,eax                                        #这里eax是计数器i,放到rdx的低位
   0x00005555555553d0 <+162>:        mov    rax,QWORD PTR [rbp-0x20] #将输入放进rax里面
   0x00005555555553d4 <+166>:        add    rax,rdx                                        #rax+rdx就相当于array[i++]的意思,基地址+偏移
   0x00005555555553d7 <+169>:        movzx  esi,BYTE PTR [rax]                #给esi赋值,后面异或用到
   0x00005555555553da <+172>:        mov    rdx,QWORD PTR [rip+0x2c2f] # 0x555555558010 <unk_6984657>
   0x00005555555553e1 <+179>:        mov    eax,DWORD PTR [rbp-0x24]
   0x00005555555553e4 <+182>:        cdqe   
   0x00005555555553e6 <+184>:        add    rax,rdx                                        #和上面一样,这里是【偏移量+段地址】
   0x00005555555553e9 <+187>:        movzx  ecx,BYTE PTR [rax]                #较小的值拷贝给大的值,剩下0填充例如【0x00000xxxx】
   0x00005555555553ec <+190>:        mov    eax,DWORD PTR [rbp-0x24]
   0x00005555555553ef <+193>:        movsxd rdx,eax
   0x00005555555553f2 <+196>:        mov    rax,QWORD PTR [rbp-0x20]
   0x00005555555553f6 <+200>:        add    rax,rdx                                        #原理同上,这里rax指向了输入的第[i]位
   0x00005555555553f9 <+203>:        xor    esi,ecx                //关键异或
   0x00005555555553fb <+205>:        mov    edx,esi                                        #结果保留在edx里面
   0x00005555555553fd <+207>:        mov    BYTE PTR [rax],dl
   0x00005555555553ff <+209>:        add    DWORD PTR [rbp-0x24],0x1                //计数器+1
   0x0000555555555403 <+213>:        mov    eax,DWORD PTR [rbp-0x24]        #计数器+1给到eax
   0x0000555555555406 <+216>:        movsxd rbx,eax                                        #相当于计数器的值给到rbx的低八位
   0x0000555555555409 <+219>:        mov    rax,QWORD PTR [rbp-0x20] #再把输入放进eax里面,恢复eax在【<+200>】的状态
   0x000055555555540d <+223>:        mov    rdi,rax                                        #把指向输入字符的指针给rdi,当参数给strlen
   0x0000555555555410 <+226>:        call   0x555555555100 <strlen@plt>        //返回输入字符串的长度
   0x0000555555555415 <+231>:        cmp    rbx,rax                                        #当前计数器的值(rbx)和strlen返回值rax比较
   0x0000555555555418 <+234>:        jb     0x5555555553ca <subfhsadkhjbfleiowiuoyfgshjdvbsmnakl+156>#回到循环头
                #rbx小于rax就跳,也就是说:计数器小于字符串长度就继续执行

这里看到有一个变量:【rbp-0x24】,【rbp-0x20】,【rip+0x2c2f】。
【rbp-0x24】:这是计数器【i】;
9.png
赋初始值为0;
10.png
抑或完+1。
【rbp-0x20】:输入的字符串也就是flag在循环完事之后就是存放输入经过循环的结果
【rip+0x2c2f】:这里存放的是异或用的数组
看具体的异或过程,到底是谁和谁在异或:

  0x00005555555553f9 <+203>:        xor    esi,ecx                //关键异或

对象是esi和ecx,看到对esi的操作:
12.png
就是输入的每一位。

看到ecx的操作:
12.png
总结:我输入的和给出的数组进行按位异或

关键循环分析完毕,在看到下面的代码:

  0x000055555555541a <+236>:        mov    rcx,QWORD PTR [rip+0x2bff]       # 0x555555558020 <unk_sa7ydu3jb432>
   0x0000555555555421 <+243>:        mov    rdx,QWORD PTR [rbp-0x18]                #rdx==mallco(0x80),给出的flag
   0x0000555555555425 <+247>:        mov    rax,QWORD PTR [rbp-0x20]                #输入经过循环异或的flag
   0x0000555555555429 <+251>:        mov    rsi,rdx                                                
   0x000055555555542c <+254>:        mov    rdi,rax                                                #传参
   0x000055555555542f <+257>:        call   rcx                                                        #跳到rcx指向的地址,
   0x0000555555555431 <+259>:        add    rsp,0x38                                #堆栈平衡,函数准备结束
   0x0000555555555435 <+263>:        pop    rbx
   0x0000555555555436 <+264>:        pop    rbp
   0x0000555555555437 <+265>:        ret                                                    #函数结束

发现有一个[rbp-0x18],没有出现在循环异或的程序里,往上看一下:
14.png
发现也是一个类似于[rbp-0x20]的结构,相当于【[rbp-0x18]=mallco(0x80)】
动态调试发现rcx就是一个strcmp函数,比较的是 输入经过循环之后的值 和 一开始给出的值 是否相等。
相等返回1
这题就解了。

然后下载了ida7.5来验证自己的思路,发现每一个函数都判断正确,但是在最后的call rcx那里还需要再完善一下。

13.png

免费评分

参与人数 2威望 +1 吾爱币 +21 热心值 +1 收起 理由
Hmily + 1 + 20 + 1 感谢发布原创作品,吾爱破解论坛因你更精彩!
离心秋 + 1 谢谢@Thanks!

查看全部评分

发帖前要善用论坛搜索功能,那里可能会有你要找的答案或者已经有人发布过相同内容了,请勿重复发帖。

dingyu914 发表于 2021-8-5 10:45
学习,看不懂,也尝试理解
爱你小吉君 发表于 2021-6-3 09:45
Hmily 发表于 2021-5-30 23:04
@Rootkit123 论坛支持MD格式,但不要分多个MD的的段,直接一头一尾加上就行了。
hans2000 发表于 2021-5-31 10:46
楼主顺便发个题目附件上来吧。
再就是主题是不是写错了?2012?2021?
DawnZii 发表于 2021-5-31 11:18
只能刷666666666了!
CAPFWJ 发表于 2021-6-2 13:55
只能刷666666666了!
shuye001 发表于 2021-6-3 10:45
膜拜CTF大佬。。
 楼主| Rootkit123 发表于 2021-6-18 12:46
hans2000 发表于 2021-5-31 10:46
楼主顺便发个题目附件上来吧。
再就是主题是不是写错了?2012?2021?

对不起,确实写错了,感谢指正。我尝试发一下源文件(第一次发帖属实不会操作)
 楼主| Rootkit123 发表于 2021-6-18 12:48
Hmily 发表于 2021-5-30 23:04
@Rootkit123 论坛支持MD格式,但不要分多个MD的的段,直接一头一尾加上就行了。

学习了,感谢!
 楼主| Rootkit123 发表于 2021-6-18 12:55
这是题目的源文件,题目文件,elf64位

re1.zip

3.78 KB, 下载次数: 2, 下载积分: 吾爱币 -1 CB

这是这个题目的原件,elf64位

您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则

返回列表

RSS订阅|小黑屋|处罚记录|联系我们|吾爱破解 - LCG - LSG ( 京ICP备16042023号 | 京公网安备 11010502030087号 )

GMT+8, 2024-11-21 20:03

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

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