re-for-50-plz-50 寒假逆向生涯(6/100)
re-for-50-plz-50
这题目属实没法看伪代码(当然,可以下载插件进行一系列帮助),在这里呢,我直接读mips
的指令集,因为涉及到的指令挺简单的
MIPS32指令集对照
全部指令
.text:00401398 var_18 = -0x18
.text:00401398 var_10 = -0x10
.text:00401398 var_8 = -8
.text:00401398 var_4 = -4
.text:00401398 arg_0 = 0
.text:00401398 arg_4 = 4
.text:00401398
.text:00401398 addiu $sp, -0x28
.text:0040139C sw $ra, 0x28+var_4($sp)
.text:004013A0 sw $fp, 0x28+var_8($sp)
.text:004013A4 move $fp, $sp
.text:004013A8 li $gp, 0x4AC770
.text:004013B0 sw $gp, 0x28+var_18($sp)
.text:004013B4 sw $a0, 0x28+arg_0($fp)
.text:004013B8 sw $a1, 0x28+arg_4($fp)
.text:004013BC sw $zero, 0x28+var_10($fp)
.text:004013C0 j loc_401434
.text:004013C4 move $at, $at
.text:004013C8 # ---------------------------------------------------------------------------
.text:004013C8
.text:004013C8 loc_4013C8: # CODE XREF: main+A4j
.text:004013C8 lui $v0, 0x4A
.text:004013CC addiu $v1, $v0, (meow - 0x4A0000) # "cbtcqLUBChERV[[Nh@_X^D]X_YPV[CJ"
.text:004013D0 lw $v0, 0x28+var_10($fp)
.text:004013D4 addu $v0, $v1, $v0
.text:004013D8 lb $v1, 0($v0)
.text:004013DC lw $v0, 0x28+arg_4($fp)
.text:004013E0 addiu $v0, 4
.text:004013E4 lw $a0, 0($v0)
.text:004013E8 lw $v0, 0x28+var_10($fp)
.text:004013EC addu $v0, $a0, $v0
.text:004013F0 lb $v0, 0($v0)
.text:004013F4 xori $v0, 0x37
.text:004013F8 sll $v0, 24
.text:004013FC sra $v0, 24
.text:00401400 beq $v1, $v0, loc_401428
.text:00401404 move $at, $at
.text:00401408 lui $v0, 0x47
.text:0040140C addiu $a0, $v0, (aNooooooooooooo - 0x470000) # "NOOOOOOOOOOOOOOOOOO\n"
.text:00401410 jal print
.text:00401414 move $at, $at
.text:00401418 lw $gp, 0x28+var_18($fp)
.text:0040141C jal exit_funct
.text:00401420 move $at, $at
.text:00401424 lw $gp, 0x28+var_18($fp)
.text:00401428
.text:00401428 loc_401428: # CODE XREF: main+68j
.text:00401428 lw $v0, 0x28+var_10($fp)
.text:0040142C addiu $v0, 1
.text:00401430 sw $v0, 0x28+var_10($fp)
.text:00401434
.text:00401434 loc_401434: # CODE XREF: main+28j
.text:00401434 lw $v0, 0x28+var_10($fp)
.text:00401438 slti $v0, 0x1F
.text:0040143C bnez $v0, loc_4013C8
.text:00401440 move $at, $at
.text:00401444 lui $v0, 0x47
.text:00401448 addiu $a0, $v0, (aC0ngr4ssulatio - 0x470000) # "C0ngr4ssulations!! U did it."
.text:0040144C la $v0, puts
.text:00401450 move $t9, $v0
.text:00401454 jalr $t9 ; puts
.text:00401458 move $at, $at
.text:0040145C lw $gp, 0x28+var_18($fp)
.text:00401460 jal exit_funct
.text:00401464 move $at, $at
.text:00401468 lw $gp, 0x28+var_18($fp)
.text:0040146C li $v0, 1
.text:00401470 move $sp, $fp
.text:00401474 lw $ra, 0x28+var_4($sp)
.text:00401478 lw $fp, 0x28+var_8($sp)
.text:0040147C addiu $sp, 0x28
.text:00401480 jr $ra
.text:00401484 move $at, $at
逐步分析
.text:00401398 addiu $sp, -0x28
.text:0040139C sw $ra, 0x28+var_4($sp)
.text:004013A0 sw $fp, 0x28+var_8($sp)
.text:004013A4 move $fp, $sp
.text:004013A8 li $gp, 0x4AC770
.text:004013B0 sw $gp, 0x28+var_18($sp)
.text:004013B4 sw $a0, 0x28+arg_0($fp)
.text:004013B8 sw $a1, 0x28+arg_4($fp)
.text:004013BC sw $zero, 0x28+var_10($fp)
这几行作用是代码把栈顶抬升,然后进行一系列的存储指令 对其赋值操作
接下来遇到无条件跳转指令,
.text:004013C0 j loc_401434
无条件跳转
.text:00401434 lw $v0, 0x28+var_10($fp)
.text:00401438 slti $v0, 0x1F
.text:0040143C bnez $v0, loc_4013C8
.text:00401440 move $at, $at
.text:00401444 lui $v0, 0x47
.text:00401448 addiu $a0, $v0, (aC0ngr4ssulatio - 0x470000) # "C0ngr4ssulations!! U did it."
.text:0040144C la $v0, puts
.text:00401450 move $t9, $v0
.text:00401454 jalr $t9 ; puts
.text:00401458 move $at, $at
.text:0040145C lw $gp, 0x28+var_18($fp)
.text:00401460 jal exit_funct
.text:00401464 move $at, $at
.text:00401468 lw $gp, 0x28+var_18($fp)
.text:0040146C li $v0, 1
.text:00401470 move $sp, $fp
.text:00401474 lw $ra, 0x28+var_4($sp)
.text:00401478 lw $fp, 0x28+var_8($sp)
.text:0040147C addiu $sp, 0x28
.text:00401480 jr $ra
.text:00401484 move $at, $at
.text:00401434 lw $v0, 0x28+var_10($fp)
.text:00401438 slti $v0, 0x1F
这两行指令的话,取了一个数,0x28+var_10($fp)
里面放的是0(上面用zero寄存器去初始化的内存单元),然后取出放在v0
寄存器里面,这个数去和31比较,比较后的关系用1和0放在v0
里面
解释一下,v0<31
的话,那么v0
会被赋值为1,v0>=31
的话,那么v0
会被赋值为0
.text:0040143C bnez $v0, loc_4013C8
BENZ R1,NAME;
//R1!=0,程序跳转,以NAME为偏移地址
BEQZ R1,NAME;
//R1=0,程序跳转到,以NAME为偏移地址。
根据以上条件,然后0<31,成立,即跳转到loc_4013C8
条件跳转(主体代码)
.text:004013C8 lui $v0, 0x4A
.text:004013CC addiu $v1, $v0, (meow - 0x4A0000) # "cbtcqLUBChERV[[Nh@_X^D]X_YPV[CJ"
.text:004013D0 lw $v0, 0x28+var_10($fp)
.text:004013D4 addu $v0, $v1, $v0
.text:004013D8 lb $v1, 0($v0)
.text:004013DC lw $v0, 0x28+arg_4($fp)
.text:004013E0 addiu $v0, 4
.text:004013E4 lw $a0, 0($v0)
.text:004013E8 lw $v0, 0x28+var_10($fp)
.text:004013EC addu $v0, $a0, $v0
.text:004013F0 lb $v0, 0($v0)
.text:004013F4 xori $v0, 0x37
.text:004013F8 sll $v0, 24
.text:004013FC sra $v0, 24
.text:00401400 beq $v1, $v0, loc_401428
.text:00401404 move $at, $at
.text:00401408 lui $v0, 0x47
.text:0040140C addiu $a0, $v0, (aNooooooooooooo - 0x470000) # "NOOOOOOOOOOOOOOOOOO\n"
.text:00401410 jal print
.text:00401414 move $at, $at
.text:00401418 lw $gp, 0x28+var_18($fp)
.text:0040141C jal exit_funct
.text:00401420 move $at, $at
.text:00401424 lw $gp, 0x28+var_18($fp)
逐步分析主体
第一步
.text:004013C8 lui $v0, 0x4A
.text:004013CC addiu $v1, $v0, (meow - 0x4A0000) # "cbtcqLUBChERV[[Nh@_X^D]X_YPV[CJ"
lui
指令是load unsigned int 加载一个立即数进入v0寄存器的高16位
低16位填0,v0
此时值为0x4A0000
第二行 addiu $v1, $v0, (meow - 0x4A0000) #
此时即可解释为
v1=v0+meow - 0x4A0000
即v1=meow
,meow此时应该是这个字符串的首地址,即把字符串首地址放入了
v1
寄存器
.text:004013D0 lw $v0, 0x28+var_10($fp)
从一个fp
里面存放一个地址值,然后fp里面的地址值+0x28+var_10
这个地址中的值读取一个字到$v0
,而且根据
所述,fp里面的地址值+0x28+var_10
(处理相对于字符首地址的偏移,到后面就会发现,这个地方会依次+1)这个地址中的值是为0,即寄存器v0
存储是为0
第二步
接下来分析这里
.text:004013D4 addu $v0, $v1, $v0
.text:004013D8 lb $v1, 0($v0)
.text:004013DC lw $v0, 0x28+arg_4($fp)
.text:004013E0 addiu $v0, 4
.text:004013E4 lw $a0, 0($v0)
.text:004013E8 lw $v0, 0x28+var_10($fp)
.text:004013EC addu $v0, $a0, $v0
.text:004013F0 lb $v0, 0($v0)
.text:004013F4 xori $v0, 0x37
.text:004013D4 addu $v0, $v1, $v0
v0=v1+v0
也就是v0=v1+0
即v0=v1
,也就是v0
里面存放着字符串首地址
.text:004013D8 lb $v1, 0($v0)
取出v0
所指处的第一个字符串放在v1
里面。
.text:004013DC lw $v0, 0x28+arg_4($fp)
0x28+arg_4($fp)
这个里面东西,
是从a1
寄存器存进内存单元的,大概猜测是我们所输进去的字符首地址(可是实际上不是)
.text:004013E0 addiu $v0, 4
这个加4的话,需要+4才能找到从我们传进来的参数里面找到存储字符串地址的内存单元
.text:004013E4 lw $a0, 0($v0)
取出这个地址的一个字,这个字单元里面存储了我们输入字符串的首地址
.text:004013E8 lw $v0, 0x28+var_10($fp)
把v0
清零处理(处理相对于字符首地址的偏移,到后面就会发现,这个地方会依次+1)0x28+var_10($fp)
这个里面存放的是$zero
.text:004013EC addu $v0, $a0, $v0
这里是v0=v0+a0
,即v0=a0
,到这里我感觉才是我们输入字符串的首地址
.text:004013F0 lb $v0, 0($v0)
然后取出一个字节的字符出来放在v0
里面
.text:004013F4 xori $v0, 0x37
这个字符再和0x37
进行异或操作
.text:004013F8 sll $v0, 24
.text:004013FC sra $v0, 24
.text:00401400 beq $v1, $v0, loc_401428
.text:00401404 move $at, $at
.text:00401408 lui $v0, 0x47
.text:0040140C addiu $a0, $v0, (aNooooooooooooo - 0x470000) # "NOOOOOOOOOOOOOOOOOO\n"
.text:00401410 jal print
.text:00401414 move $at, $at
.text:00401418 lw $gp, 0x28+var_18($fp)
.text:0040141C jal exit_funct
.text:00401420 move $at, $at
.text:00401424 lw $gp, 0x28+var_18($fp)
异或结束后,再
把它们左移24位,然后再右移24位,它俩的意思也就是取后八位的意思,就是取一个字节
.text:00401400 beq $v1, $v0, loc_401428
相等的话,那就跳转喽,然后继续判断下一个字符
.text:00401428 loc_401428:
.text:00401428 lw $v0, 0x28+var_10($fp)
.text:0040142C addiu $v0, 1
.text:00401430 sw $v0, 0x28+var_10($fp)
第一步用0x28+var_10($fp)
把v0
清0,然后进行+1操作,再把它存储在0x28+var_10
这个里面,
以此类推,下次到达这里也就是用1去覆盖v0
喽,然后v0+1
再去放在0x28+var_10
这个里面,这个也就是那个字符串相对于首地址的偏移,以此来取出每个字符操作。
然后
text:00401434 loc_401434: # CODE XREF: main+28j
.text:00401434 lw $v0, 0x28+var_10($fp)
.text:00401438 slti $v0, 0x1F
.text:0040143C bnez $v0, loc_4013C8
这里呢,就把相对于字符的首地址的偏移和0x1F
比较,也就是能否成功比较到最后一个,如果能的话,那么就跳到成功的地方去了,因为比较每个字符是否相等的操作之间的跳转已经在前面比较了,这里只需要比较是否到达最后即可。
GAMEOVER
#include <iostream>
using namespace std;
int main()
{char a[] = { "cbtcqLUBChERV[[Nh@_X^D]X_YPV[CJ" };for (int i = 0; i < 31; i++) {a[i] = a[i] ^ 0x37;cout << a[i];}
}
注意点
存储 从左往右
加载 从右往左
.text:004013DC lw $v0, 0x28+arg_4($fp)
.text:004013E0 addiu $v0, 4
.text:004013E4 lw $a0, 0($v0)
.text:004013E8 lw $v0, 0x28+var_10($fp)
.text:004013EC addu $v0, $a0, $v0
.text:004013F0 lb $v0, 0($v0)
只需要注意着点,这个传进来的参数0x28+arg_4($fp)
存放的不是字符串的首地址,而是它存放的地址值+4之后才是存放输入字符串地址的内存单元,即
0x28+arg_4($fp)
取出里面的地址值+4 操作后,我们需要再往里面取一个word地址,即
.text:004013E4 lw $a0, 0($v0)
然后a0
里面存放的才是输入字符串的首地址
re-for-50-plz-50 寒假逆向生涯(6/100)相关推荐
- notsequence 寒假逆向生涯(9/100)
notsequence 这题目,挺简单的,首先无壳,直接拖进ida,然后查看了一下伪代码 轻易发现只需要满足三点就行 sub_80486CD((int)&unk_8049BE0) (unsig ...
- secret-galaxy-300 Replace(印象深刻) 寒假逆向生涯(8/100)
secret-galaxy-300 脑洞题,直接没说法,就以后别碰这种脑洞题就行,,,,没任何帮助 显示界面 OD打开后,显示这个鬼东西.然后就没了. ida静态分析 看到上方输出框有字符串,所以我们 ...
- IgniteMe debug 寒假逆向生涯(2/100)
IgniteMe 声明 这是道超级简单的题目,就不重复啰嗦了,找到需要加密的关键代码后,直接一步到位. memset(&v4, 0xCCu, 0xF4u);if ( strlen(a1) &g ...
- HWS计划 decryption 寒假逆向生涯(17/100)
decryption 前奏 没法搞,直接拖ida 全局 首先输入flag,然后一个if判断一下长度是否符合,不符合直接结束 然后再new处一个数组,接着一个加密函数,把加密后的存放在new出来的数组里 ...
- easy_Maze 梅津美治郎 寒假逆向生涯(16/100)
easy_Maze 这个题简单,迷宫题目,需要动调,或者不用动调也行,可以自己算出地图,我用的是动调. 生成地图的两个函数 只需要动调到这两个函数的下一步后,找到储存矩阵的空间的地址, 把这个地址转到 ...
- babymips(下) 寒假逆向生涯(14/100)
babymips上 主要核心代码 var_10= -0x10 var_8= -8 var_4= -4 arg_0= 0addiu $sp, -0x28 sw $ra, 0x28+var_4($sp) ...
- babymips(上) 寒假逆向生涯(14/100)
babymips 这题呢,看名字就知道,不出所料,还是mips指令,挺简单的,懒得找插件,直接分析吧,锻炼锻炼自己 开战 lui $v0, 0x40 addiu $a0, $v0, (aGiveMeY ...
- easyre-153 testre寒假逆向生涯(13/100)
easyre-153 简单题目,流程走起,首先查壳, 脱壳 upx壳,利用工具把它脱掉 ida静态分析 int __cdecl main(int argc, const char **argv, co ...
- deedeedee crazy 寒假逆向生涯(11/100)
deedeedee 这题没说法...直接用notepad++打开第二个文件,然后就看到了flag....人傻了... flag{t3mplat3_met4pr0gramming_is_gr8_4_3v ...
最新文章
- 用Quartus II Timequest Timing Analyzer进行时序分析 :实例讲解 (三)
- [WCF 4.0新特性] 默认终结点
- Attention的本质:从Encoder-Decoder(Seq2Seq)理解
- 单例-初始化动作只执行一次
- 《springcloud超级入门》Spring Cloud开发环境的准备和Lombok安装步骤《四》
- QueryDict对象
- Python 必备要点总结及环境搭建(上)
- Java编程练习题3
- 【WPS表格】函数的3种引用方式,4种切换模式
- 163个人邮箱注册申请流程,公司邮箱怎么注册?
- 摘果子问题(聚沙成塔问题)
- 用python画玫瑰花
- java里面不等于怎么打_不等于在c语言中怎么打
- 简明 Vim 练级攻略(转自酷壳)
- http服务器常见状态码
- 5.5G产业再提速!高通5GAdvanced-ready芯片商用终端下半年面世
- 求一个给定的n阶方阵的鞍点
- 开机后电脑只剩计算机和回收站,电脑开机后C盘拒绝访问,图标只剩下此电脑和回收站是怎么回事?...
- MacOS上效率神器 Alfred的基本用法
- 软件测试行业年度核心热点数据大揭秘(2018 )
热门文章
- 去掉状态条并全屏_一个人住180㎡,大大的落地窗,足够的收纳,简洁又舒适,宅在家是她最享受的状态!...
- 成功解决absl.flags._exceptions.UnrecognizedFlagError: Unknown command line flag 'data_format'
- Py之ipykernel:Python库之ipykernel简介、安装、使用方法之详细攻略
- Hyperopt中文文档:Cite引用
- WRF用户手册翻译:Chapter 5: WRF Model
- 【BZOJ5470】【FJOI2018】—所罗门王的宝藏(BFS)
- 数据结构实验之链表一:顺序建立链表(SDUT 2116)
- 霍金:AI或许能根除疾病和贫穷,但也可能摧毁人类 | GMIC 2017
- 在.Net中进行跨线程的控件操作(上篇:Control.Invoke)
- 视觉库—OpenCV