攻防世界逆向高手题的babymips

99 篇文章 33 订阅

攻防世界逆向高手题之babymips

继续开启全栈梦想之逆向之旅~
这题是攻防世界逆向高手题的babymips
在这里插入图片描述

下载附件,照例扔入exeinfope中查看信息:
在这里插入图片描述
.
.
32位无壳,照例扔入IDA32中查看伪代码,有main函数看main函数:
在这里插入图片描述
.
.
(这里积累第一个经验)
第一个框是对用户输入进行每位的异或操作,因为i的地址和input_flag的地址在main函数栈中相差4而已。
第二个框就是取异或后的前五个字符与明文比较,如果相同就继续对剩下的27个字符继续操作。这里要注意的是sub_4007F0(input_flag)函数是在前面对input_flag异或后的基础上进一步操作,也就是双层操作,而input_flag是单层的对前5个字符的异或操作。
我犯的错误就是逆向后面27位字符后忘记了前面还有一层异或操作,以至于生成错误的答案。

在这里插入图片描述
.
.
.
跟踪sub_4007F0函数,一个移位一个比较:
在这里插入图片描述
.
.
(这里积累第二个经验)
逻辑就是移位操作,但是我是真不知道这里的或运算符 ‘|’ 的作用是前后移位双向进行。我一直以为是算术运算操作,所以我一开始的思路是把或运算符 ‘|’ 变成与运算符 ‘&’ ,结果怎么逆都不对。
现在知道了,这里以8位为一个单位,高2位往右移动6位变成底2位。同时底6位往左移动2位变成高6位,相当于循环右移,000000_11变成 11_0000。(如图一样,是交叉进行的。)
在这里插入图片描述

下面的(4 * input_flag[i])是一个迷惑,其实也是(2<<input_flag[i])。

.
附上移位的汇编指令笔记:
在这里插入图片描述
.
.
.
(这里积累第三个经验)
然后移完位之后和数组off_410D04内容比较,这里嵌入IDA脚本dump下来:
这里.byte一开始我也懵了一下,后来发现用Byte也可以获取,.byte可能是MIPS的一个特性吧:

addr=0x400B98
list1=[]
for i in range(0x400BB3-0x400B98):
    list1.append(Byte(addr+i))
print(list1)
print(len(list1))

在这里插入图片描述
.
.
.
.
(这里积累第四个经验)
知道是移位操作之后就可以写脚本了,原代码逻辑中(i&1)其实是判断奇数还是偶数来的,照抄即可,然后移位逻辑是以8位为一个循环的,所以我们要用&FF来限制在8位才行:

key1="Q|j{g"
flag=list(map(ord,key1))
flag+=[82, 253, 22, 164, 137, 189, 146, 128, 19, 65, 84, 160, 141, 69, 24, 129, 222, 252, 149, 240, 22, 121, 26, 21, 91, 117, 31]

print(flag)
for a in range(5,32,1):
	if (a&1)!=0:
		flag[a]=((flag[a]<<2)|(flag[a]>>6))&0xFF
	else:
		flag[a]=((flag[a]>>2)|(flag[a]<<6))&0xFF
for i in range(32,):
	flag[i]=chr(flag[i]^(32-i))
print(''.join(flag))

说到这种用&限制位数的,不得不回顾一下以前做题中类似的操作来加深记忆。
在这里插入图片描述

总结:

1:
(这里积累第一个经验)
第一个框是对用户输入惊醒每位的异或操作,因为i的地址和input_flag的地址在main函数栈中相差4而已。
第二个框就是取异或后的前五个字符与明文比较,如果相同就继续对剩下的27个字符继续操作。这里要注意的是sub_4007F0(input_flag)函数是在前面对input_flag异或后的基础上进一步操作,也就是双层操作,而input_flag是单层的对前5个字符的异或操作。
我犯的错误就是逆向后面27位字符后忘记了前面还有一层异或操作,以至于生成错误的答案。

2:
(这里积累第二个经验) 逻辑就是移位操作,但是我是真不知道这里的或运算符 ‘|’ 的作用是前后移位双向进行。我一直以为是算术运算操作,所以我一开始的思路是把或运算符 ‘|’ 变成与运算符 ‘&’ ,结果怎么逆都不对。
现在知道了,这里以8位为一个单位,高2位往右移动6位变成底2位。同时底6位往左移动2位变成高6位,相当于循环右移,000000_11变成 11_0000。(如图一样,是交叉进行的。)
在这里插入图片描述

下面的(4 * input_flag[i])是一个迷惑,其实也是(2<<input_flag[i])。
.
附上移位的汇编指令笔记:
在这里插入图片描述

3:
(这里积累第三个经验) 然后移完位之后和数组off_410D04内容比较,这里嵌入IDA脚本dump下来:
这里.byte一开始我也懵了一下,后来发现用Byte也可以获取,.byte可能是MIPS的一个特性吧:

4:
(这里积累第四个经验)
知道是移位操作之后就可以写脚本了,原代码逻辑中(i&1)其实是判断奇数还是偶数来的,照抄即可,然后移位逻辑是以8位为一个循环的,所以我们要用&FF来限制在8位才行。
.
说到这种用&限制位数的,不得不回顾一下以前做题中类似的操作来加深记忆。
在这里插入图片描述

解毕!敬礼!

  • 4
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

沐一 · 林

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值