欢迎访问 生活随笔!

生活随笔

当前位置: 首页 > 编程资源 > 编程问答 >内容正文

编程问答

babymips(下) 寒假逆向生涯(14/100)

发布时间:2025/3/21 编程问答 42 豆豆
生活随笔 收集整理的这篇文章主要介绍了 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)的全部内容,希望文章能够帮你解决所遇到的问题。

如果觉得生活随笔网站内容还不错,欢迎将生活随笔推荐给好友。