babymips(下) 寒假逆向生涯(14/100)
babymips上
主要核心代码
var_10= -0x10
var_8= -8
var_4= -4
arg_0= 0addiu $sp, -0x28
sw $ra, 0x28+var_4($sp)
sw $fp, 0x28+var_8($sp)
move $fp, $sp
sw $a0, 0x28+arg_0($fp)
li $v0, 5
sw $v0, 0x28+var_10($fp)
b loc_400910
nop
loc_400910: # s
lw $a0, 0x28+arg_0($fp)
jal strlen
nop
move $v1, $v0
lw $v0, 0x28+var_10($fp)
nop
sltu $v0, $v1
bnez $v0, loc_400814
nop
第六行代码:
li $v0, 5
sw $v0, 0x28+var_10($fp)
把5塞到v0
寄存器里面,然后v0里面的值塞到0x28+var_10($fp)
这个内存单元
jal strlen
这个函数调用完成后,返回值直接放在v0
寄存器中,紧接着
move $v1, $v0
v0赋值给v1,即把返回值放在v1里面,
lw $v0, 0x28+var_10($fp)
取出内存单元中的5放在v0里面。然后来两个比较
sltu $v0, $v1
bnez $v0, loc_400814
BENZ R1,NAME;
//R1!=0,程序跳转,以NAME为偏移地址
v1即是字符串长度。
v1>5则跳,v1<=5则不跳(因为前面已经判断"Q|j{g"
这五个的原因吧)即选择跳
loc_400814:
lw $v0, 0x28+var_10($fp)
nop
andi $v0, 1
beqz $v0, loc_400898
nop
把5取出来,然后和1进行与操作
(重点:和1进行与操作,这样是为了判断这个字符的位置是奇数还是偶数,奇数的话与操作也就是非0,偶数的话,与操作后为0),
BEQZ R1,NAME;
//R1=0
,程序跳转到,以NAME为偏移地址
这里两处都应该看,因为奇偶数位都在变,得分析他们的变化。
偶数位
loc_400898:
lw $v0, 0x28+var_10($fp)
lw $v1, 0x28+arg_0($fp)
nop
addu $v0, $v1, $v0
lb $v0, 0($v0)
nop
sll $v0, 2
sll $a0, $v0, 24
sra $a0, 24
lw $v0, 0x28+var_10($fp)
lw $v1, 0x28+arg_0($fp)
nop
addu $v0, $v1, $v0
lb $v0, 0($v0)
nop
sra $v0, 6
sll $v1, $v0, 24
sra $v1, 24
lw $v0, 0x28+var_10($fp)
lw $a1, 0x28+arg_0($fp)
nop
addu $v0, $a1, $v0
or $v1, $a0, $v1
sll $v1, 24
sra $v1, 24
sb $v1, 0($v0)
lw $v0, 0x28+var_10($fp)
lw $v1, 0x28+arg_0($fp)
第一行把位数取出来,第二行把参数取出来,因为我们前面传参的时候传的时字符串的地址。
所以v0里面是位数,v1里面是字符串首地址。
addu $v0, $v1, $v0
lb $v0, 0($v0)
取出相应字节的字符,然后进行下面一系列操作。
sll $v0, 2
sll $a0, $v0, 24
sra $a0, 24
lw $v0, 0x28+var_10($fp)
lw $v1, 0x28+arg_0($fp)
nop
addu $v0, $v1, $v0
lb $v0, 0($v0)
首先左移两位,再左移24位,再进行右移24位(绝对不是简简单单的左移两位。。。别搞错。。)
然后取出位数放在v0
中,取出数组首地址放在v1
中,紧接着也取出相应位数字节的字符放在v0
里面。
总结:也就是取出一字节字符的低6位放在a0
寄存器
sra $v0, 6
sll $v1, $v0, 24
sra $v1, 24
lw $v0, 0x28+var_10($fp)
lw $a1, 0x28+arg_0($fp)
nop
右移6位,再左移24位,再进行右移24位(绝对不是简简单单的右移6位。。。别搞错。。)
取出位数放在v0
中,取出数组首地址放在v1
中。
总结:也就是取出一字节字符的高2位放在v1
寄存器
addu $v0, $a1, $v0
or $v1, $a0, $v1
sll $v1, 24
sra $v1, 24
sb $v1, 0($v0)
第一行,把相应字节的字符地址取出放在v0
寄存器中,
然后把v1
寄存器(取出一字节字符的高2位)和a0
寄存器(取出一字节字符的低6位)进行或运算放在v1
寄存器中,
紧接着进行左移24,右移24,保留低八位(即一字节),然后把运算结果塞入上面取出的地址处的内存单元
(即一字节循环左移2位)
奇数位
lw $v0, 0x28+var_10($fp)
lw $v1, 0x28+arg_0($fp)
nop
addu $v0, $v1, $v0
lb $v0, 0($v0)
nop
sra $v0, 2
sll $a0, $v0, 24
sra $a0, 24
lw $v0, 0x28+var_10($fp)
lw $v1, 0x28+arg_0($fp)
nop
addu $v0, $v1, $v0
lb $v0, 0($v0)
nop
sll $v0, 6
sll $v1, $v0, 24
sra $v1, 24
lw $v0, 0x28+var_10($fp)
lw $a1, 0x28+arg_0($fp)
nop
addu $v0, $a1, $v0
or $v1, $a0, $v1
sll $v1, 24
sra $v1, 24
sb $v1, 0($v0)
b loc_400900
nop
同样的方法,来分析奇数位字符
lw $v0, 0x28+var_10($fp)
lw $v1, 0x28+arg_0($fp)
第一行把位数取出来,第二行把参数取出来,因为我们前面传参的时候传的时字符串的地址。
所以v0里面是位数,v1里面是字符串首地址。
addu $v0, $v1, $v0
lb $v0, 0($v0)
取出相应字节的字符,然后进行下面一系列操作。
sra $v0, 2
sll $a0, $v0, 24
sra $a0, 24
lw $v0, 0x28+var_10($fp)
lw $v1, 0x28+arg_0($fp)
nop
addu $v0, $v1, $v0
lb $v0, 0($v0)
首先右移两位,再左移24位,再进行右移24位(绝对不是简简单单的右移两位。。。别搞错。。)
然后取出位数放在v0
中,取出数组首地址放在v1
中,紧接着也取出相应位数字节的字符放在v0
里面。
总结:也就是取出一字节字符的高6位放在a0
寄存器
sll $v0, 6
sll $v1, $v0, 24
sra $v1, 24
lw $v0, 0x28+var_10($fp)
lw $a1, 0x28+arg_0($fp)
nop
左移6位,再左移24位,再进行右移24位(绝对不是简简单单的左移6位。。。别搞错。。)
取出位数放在v0
中,取出数组首地址放在v1
中。
总结:也就是取出一字节字符的低2位放在v1
寄存器
addu $v0, $a1, $v0
or $v1, $a0, $v1
sll $v1, 24
sra $v1, 24
sb $v1, 0($v0)
第一行,把相应字节的字符地址取出放在v0
寄存器中,
然后把v1
寄存器(取出一字节字符的高6位)和a0
寄存器(取出一字节字符的低2位)进行或运算放在v1
寄存器中,
紧接着进行左移24,右移24,保留低八位(即一字节),然后把运算结果塞入上面取出的地址处的内存单元
(即一字节循环右移2位)
尾声
loc_400900:
lw $v0, 0x28+var_10($fp)
nop
addiu $v0, 1
sw $v0, 0x28+var_10($fp)
取出位数,进行加1操作
loc_400910: # s
lw $a0, 0x28+arg_0($fp)
jal strlen
nop
move $v1, $v0
lw $v0, 0x28+var_10($fp)
nop
sltu $v0, $v1
bnez $v0, loc_400814
nop
当操作到最后一个时
sltu $v0, $v1
bnez $v0, loc_400814
BENZ R1,NAME;
//R1!=0,程序跳转,以NAME为偏移地址,当移动到最后一个字符的下一个时,v0=v1相等。条件跳转不成立,紧接着进行一系列比较
lw $v0, 0x28+arg_0($fp)
nop
addiu $v1, $v0, 5
lw $v0, off_410D04
li $a2, 0x1B # n
move $a1, $v0 # s2
move $a0, $v1 # s1
jal strncmp
nop
bnez $v0, loc_40097C
nop
off_410D04
地址处
52 FD 16 A4 89 BD 92 80 13 41 54 A0 8D 45 18 81 DE FC 95 F0 16 79 1A 15 5B 751F
比较结束后,返回值为1,则不跳,即
lui $v0, 0x40
addiu $a0, $v0, (aRight - 0x400000) # "Right!"
jal puts
nop
b loc_40098C
nop
成功喽!!!!!!!!
GAMEOVER
part1=b'Q|j{g'
part2='52 fd 16 a4 89 bd 92 80 13 41 54 a0 8d 45 18 81 de fc 95 f0 16 79 1a 15 5b 75 1f'
part2=list(bytes.fromhex(part2))
for i in range(5,len(part2)+5):t = part2[i-5]if i&1==0: #偶数时&1 为0part2[i-5]=(t&0x3)<<6|(t&0xfc)>>2 #低2位左移6位,高6位右移2位 相当于循环右移2位else:part2[i-5]=(t&0x3f)<<2|(t&0xc0)>>6 #低6位左移2位,高2位右移6位 相当于循环左移2位temp=list(part1)+part2
flag=''
for i in range(len(temp)):flag+=chr(temp[i]^0x20 -i)
print(flag)
qctf{ReA11y_4_B@89_mlp5_4_XmAn_}
babymips(下) 寒假逆向生涯(14/100)相关推荐
- babymips(上) 寒假逆向生涯(14/100)
babymips 这题呢,看名字就知道,不出所料,还是mips指令,挺简单的,懒得找插件,直接分析吧,锻炼锻炼自己 开战 lui $v0, 0x40 addiu $a0, $v0, (aGiveMeY ...
- notsequence 寒假逆向生涯(9/100)
notsequence 这题目,挺简单的,首先无壳,直接拖进ida,然后查看了一下伪代码 轻易发现只需要满足三点就行 sub_80486CD((int)&unk_8049BE0) (unsig ...
- secret-galaxy-300 Replace(印象深刻) 寒假逆向生涯(8/100)
secret-galaxy-300 脑洞题,直接没说法,就以后别碰这种脑洞题就行,,,,没任何帮助 显示界面 OD打开后,显示这个鬼东西.然后就没了. ida静态分析 看到上方输出框有字符串,所以我们 ...
- easy_Maze 梅津美治郎 寒假逆向生涯(16/100)
easy_Maze 这个题简单,迷宫题目,需要动调,或者不用动调也行,可以自己算出地图,我用的是动调. 生成地图的两个函数 只需要动调到这两个函数的下一步后,找到储存矩阵的空间的地址, 把这个地址转到 ...
- easyre-153 testre寒假逆向生涯(13/100)
easyre-153 简单题目,流程走起,首先查壳, 脱壳 upx壳,利用工具把它脱掉 ida静态分析 int __cdecl main(int argc, const char **argv, co ...
- re-for-50-plz-50 寒假逆向生涯(6/100)
re-for-50-plz-50 这题目属实没法看伪代码(当然,可以下载插件进行一系列帮助),在这里呢,我直接读mips的指令集,因为涉及到的指令挺简单的 MIPS32指令集对照 全部指令 .text ...
- EasyRE 寒假逆向生涯(5/100)
EasyRE 声明 挺简单的一道题目,流程不必注意太多,直接上核心伪代码 首先注意一点 v2 = (char *)&v8 + 7;这行代码属于编译出错,我们需要直接 查看它的汇编代码, 这行代 ...
- hackme Guess-the-Number 寒假逆向生涯(4/100)
hackme 声明 简单题目,没必要查壳,动调. 话不多说,上核心伪代码 大致思路: 一个for循环,外加一个while循环 while循环是找出相应条件下v12的值 for循环作用: 1.制造whi ...
- IgniteMe debug 寒假逆向生涯(2/100)
IgniteMe 声明 这是道超级简单的题目,就不重复啰嗦了,找到需要加密的关键代码后,直接一步到位. memset(&v4, 0xCCu, 0xF4u);if ( strlen(a1) &g ...
最新文章
- 关于最长公共子序列的执行过程
- OpenCASCADE:Modeling Data之形状的属性
- InsightFace及其mxnet、tensorflow代码实现
- ZooKeeper命令、命令行工具及简单操作
- php是否支持64位,phpstudy默认不支持64位php的解决方法
- 背景图宽度自适应及背景图合并的CSS思想
- FFmpeg学习(5)——视频加水印
- 企业办理CMMI认证是怎么收费的?
- 通过eclipse对apk加密混淆的方法
- 电梯plc的io分配_用PLC构成液体混合控制系统IO分配及梯形图编程
- 加拿大前十大学计算机硕士学费,2018年加拿大各大学硕士学费一览表!
- xcode8插件管理工具
- 不谋一时不足以谋一域_“不谋万世者,不足谋一时。不谋全局者,不足谋一隅”出自哪里?是什么意思?...
- 项目上传图片报:Can't create output stream!
- 计算机休眠是意思,电脑休眠是什么意思(电脑休眠和睡眠的区别)
- js中的JSON对象转换,过滤特殊字符数据
- 微信中H5+java+vue获取微信定位等JS-SDK
- dnf红眼补丁在哪下载_dnf红眼变红补丁下载
- pc端,移动端,客户端的区别
- windows git bash 设置多个php版本和composer版本
热门文章
- python优先级排序_Python实现优先级队列结构的方法详解
- Computer:路由器、交换机、猫Modem的简介、区别之详细攻略
- 成功解决numpy.linalg.LinAlgError: singular matrix
- Paper:《Graph Neural Networks: A Review of Methods and Applications》翻译与解读
- 成功解决ValueError: Cannot feed value of shape (1, 10, 4) for Tensor Placeholder:0 , which has shape
- DL:听着歌曲《成都》三分钟看遍主流的深度学习的神经网络的发展框架(1950~2018)
- Crawler之Scrapy:Scrapy简介、安装、使用方法之详细攻略
- 在Linux上如何安装Oracle数据库
- Docker 三架马车
- 莫队(不带修改)模板