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)這個內(nèi)存單元
jal strlen這個函數(shù)調(diào)用完成后,返回值直接放在v0寄存器中,緊接著
move $v1, $v0v0賦值給v1,即把返回值放在v1里面,
lw $v0, 0x28+var_10($fp)取出內(nèi)存單元中的5放在v0里面。然后來兩個比較
sltu $v0, $v1 bnez $v0, loc_400814
BENZ R1,NAME;//R1!=0,程序跳轉(zhuǎn),以NAME為偏移地址
v1即是字符串長度。
v1>5則跳,v1<=5則不跳(因為前面已經(jīng)判斷"Q|j{g"這五個的原因吧)即選擇跳
把5取出來,然后和1進(jìn)行與操作
(重點:和1進(jìn)行與操作,這樣是為了判斷這個字符的位置是奇數(shù)還是偶數(shù),奇數(shù)的話與操作也就是非0,偶數(shù)的話,與操作后為0),
BEQZ R1,NAME;//R1=0,程序跳轉(zhuǎn)到,以NAME為偏移地址
這里兩處都應(yīng)該看,因為奇偶數(shù)位都在變,得分析他們的變化。
偶數(shù)位
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)第一行把位數(shù)取出來,第二行把參數(shù)取出來,因為我們前面?zhèn)鲄⒌臅r候傳的時字符串的地址。
所以v0里面是位數(shù),v1里面是字符串首地址。
取出相應(yīng)字節(jié)的字符,然后進(jìn)行下面一系列操作。
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位,再進(jìn)行右移24位(絕對不是簡簡單單的左移兩位。。。別搞錯。。)
然后取出位數(shù)放在v0中,取出數(shù)組首地址放在v1中,緊接著也取出相應(yīng)位數(shù)字節(jié)的字符放在v0里面。
總結(jié):也就是取出一字節(jié)字符的低6位放在a0寄存器
右移6位,再左移24位,再進(jìn)行右移24位(絕對不是簡簡單單的右移6位。。。別搞錯。。)
取出位數(shù)放在v0中,取出數(shù)組首地址放在v1中。
總結(jié):也就是取出一字節(jié)字符的高2位放在v1寄存器
第一行,把相應(yīng)字節(jié)的字符地址取出放在v0寄存器中,
然后把v1寄存器(取出一字節(jié)字符的高2位)和a0寄存器(取出一字節(jié)字符的低6位)進(jìn)行或運算放在v1寄存器中,
緊接著進(jìn)行左移24,右移24,保留低八位(即一字節(jié)),然后把運算結(jié)果塞入上面取出的地址處的內(nèi)存單元
(即一字節(jié)循環(huán)左移2位)
奇數(shù)位
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同樣的方法,來分析奇數(shù)位字符
lw $v0, 0x28+var_10($fp) lw $v1, 0x28+arg_0($fp)第一行把位數(shù)取出來,第二行把參數(shù)取出來,因為我們前面?zhèn)鲄⒌臅r候傳的時字符串的地址。
所以v0里面是位數(shù),v1里面是字符串首地址。
取出相應(yīng)字節(jié)的字符,然后進(jìn)行下面一系列操作。
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位,再進(jìn)行右移24位(絕對不是簡簡單單的右移兩位。。。別搞錯。。)
然后取出位數(shù)放在v0中,取出數(shù)組首地址放在v1中,緊接著也取出相應(yīng)位數(shù)字節(jié)的字符放在v0里面。
總結(jié):也就是取出一字節(jié)字符的高6位放在a0寄存器
左移6位,再左移24位,再進(jìn)行右移24位(絕對不是簡簡單單的左移6位。。。別搞錯。。)
取出位數(shù)放在v0中,取出數(shù)組首地址放在v1中。
總結(jié):也就是取出一字節(jié)字符的低2位放在v1寄存器
第一行,把相應(yīng)字節(jié)的字符地址取出放在v0寄存器中,
然后把v1寄存器(取出一字節(jié)字符的高6位)和a0寄存器(取出一字節(jié)字符的低2位)進(jìn)行或運算放在v1寄存器中,
緊接著進(jìn)行左移24,右移24,保留低八位(即一字節(jié)),然后把運算結(jié)果塞入上面取出的地址處的內(nèi)存單元
(即一字節(jié)循環(huán)右移2位)
尾聲
loc_400900: lw $v0, 0x28+var_10($fp) nop addiu $v0, 1 sw $v0, 0x28+var_10($fp)取出位數(shù),進(jìn)行加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當(dāng)操作到最后一個時
sltu $v0, $v1 bnez $v0, loc_400814
BENZ R1,NAME;//R1!=0,程序跳轉(zhuǎn),以NAME為偏移地址,當(dāng)移動到最后一個字符的下一個時,v0=v1相等。條件跳轉(zhuǎn)不成立,緊接著進(jìn)行一系列比較
off_410D04地址處
比較結(jié)束后,返回值為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: #偶數(shù)時&1 為0part2[i-5]=(t&0x3)<<6|(t&0xfc)>>2 #低2位左移6位,高6位右移2位 相當(dāng)于循環(huán)右移2位else:part2[i-5]=(t&0x3f)<<2|(t&0xc0)>>6 #低6位左移2位,高2位右移6位 相當(dāng)于循環(huán)左移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_}總結(jié)
以上是生活随笔為你收集整理的babymips(下) 寒假逆向生涯(14/100)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: babymips(上) 寒假逆向生涯(1
- 下一篇: easy_Maze 梅津美治郎