babymips(上) 寒假逆向生涯(14/100)
babymips
這題呢,看名字就知道,不出所料,還是mips指令,挺簡單的,懶得找插件,直接分析吧,鍛煉鍛煉自己
開戰(zhàn)
lui $v0, 0x40 addiu $a0, $v0, (aGiveMeYourFlag - 0x400000) # "Give me your flag:" jal printf nop addiu $v0, $fp, 0x48+var_2C move $a1, $v0 lui $v0, 0x40 addiu $a0, $v0, (a32s - 0x400000) # "%32s" jal scanf nop sw $zero, 0x48+var_30($fp) b loc_400A78 noplui $v0, 0x40這行是把0x40放在v0寄存器的高16位,低16位填零處理。
addiu $a0, $v0, (aGiveMeYourFlag - 0x400000) # "Give me your flag:"這行的話,也就是把aGiveMeYourFlag輸出字符串地址放在寄存器a0寄存器里面
緊接著跳到輸出函數(shù)去,很正常,也就是通過寄存器傳參,然后調用一個函數(shù)
addiu $v0, $fp, 0x48+var_2C這個的話我猜是輸入的東西的地址,放在v0寄存器里面
move $a1, $v0然后把v0寄存器里面的東西放在,a1寄存器,也就是調用scanf函數(shù)的時候需要傳參,下面幾行代碼道理和printf一樣,只不過所傳參數(shù)不一樣而已
lui $v0, 0x40 addiu $a0, $v0, (a32s - 0x400000) # "%32s" jal scanf無條件跳轉
sw $zero, 0x48+var_30($fp) b loc_400A78用0初始化0x48+var_30($fp),接著跳轉到loc_400A78
lw $v0, 0x48+var_30($fp) nop slti $v0, 0x20 bnez $v0, loc_400A1C第一行把0x48+var_30($fp)放在v0寄存器,第二行對齊,
第三行用這個數(shù)去和36比較,比較后的關系用1和0放在v0里面
解釋一下,v0<20的話,那么v0會被賦值為1,v0>=20的話,那么v0會被賦值為0
而BENZ R1,NAME;//R1!=0,程序跳轉,以NAME為偏移地址
BEQZ R1,NAME;//R1=0,程序跳轉到,以NAME為偏移地址
所以的話,這里將會跳轉到loc_400A1C:
循環(huán)
loc_400A1C: lw $v0, 0x48+var_30($fp) addiu $v1, $fp, 0x48+var_30 addu $v0, $v1, $v0 lb $v1, 4($v0) lw $v0, 0x48+var_30($fp) nop andi $v0, 0xFF li $a0, 0x20 subu $v0, $a0, $v0 andi $v0, 0xFF sll $v0, 24 sra $v0, 24 xor $v0, $v1, $v0 sll $v1, $v0, 24 sra $v1, 24 lw $v0, 0x48+var_30($fp) addiu $a0, $fp, 0x48+var_30 addu $v0, $a0, $v0 sb $v1, 4($v0) lw $v0, 0x48+var_30($fp) nop addiu $v0, 1 sw $v0, 0x48+var_30($fp) lw $v0, 0x48+var_30($fp)第一行代碼,也就是把0放在v0寄存器里面
addiu $v1, $fp, 0x48+var_30緊接著,把0的地址放在v1寄存器里面
addu $v0, $v1, $v0這個把長度存放的地址加上一個偏移(這里偏移第一次為0,數(shù)組偏移那種意思)得到一個地址放在v0寄存器里面,用法未知
lb $v1, 4($v0)把v0+4地址處的內容取出放在v1(也就是我們輸入字符的第一個字節(jié))
lw $v0, 0x48+var_30($fp)把0(這里雖然是0,但是下一次循環(huán)就會變成1,即for循環(huán)里面的i值)再次放在v0寄存器里面
andi $v0, 0xFF進行與操作,即把高位滅掉,只保留低八位
li $a0, 0x20把0x20加載到a0寄存器里面
subu $v0, $a0, $v00x20和0(這里雖然是0,但是下一次循環(huán)就會變成1,即for循環(huán)里面的i值)相減(提示:異或操作的優(yōu)先級低于減法)然后放在v0里面
andi $v0, 0xFF然后進行與操作,即把高位滅掉,只保留低八位(即一個字節(jié))
sll $v0, 24 sra $v0, 24左移24,然后右移24,即保留低八位(一字節(jié))
xor $v0, $v1, $v0然后v0和v1異或之后放在v0寄存器里面
sll $v1, $v0, 24 sra $v1, 24把v0里面的值,左移24之后,有右移24,同樣道理,保留低八位。。
lw $v0, 0x48+var_30($fp)取出0值(i值,第一次為0而已)
lw $v0, 0x48+var_30($fp) addiu $a0, $fp, 0x48+var_30 addu $v0, $a0, $v0 sb $v1, 4($v0)這四行和上面一樣,即找出我們輸入字符的
地址,然后把v1寄存器里面的值放進去。
然后0值(即i值)
nop addiu $v0, 1 sw $v0, 0x48+var_30($fp)加1之后,又塞回去,然后進行判斷,是否跳出循環(huán),不跳出的話,繼續(xù)進行以上循環(huán)代碼
比較
slti $v0, 0x20 bnez $v0, loc_400A1C當這里,v0一直增,然后等于32后,即不跳轉,然后來到
lui $v0, 0x41 lw $v1, _fdata addiu $v0, $fp, 0x48+var_2C li $a2, 5 # n move $a1, $v1 # s2 move $a0, $v0 # s1 jal strncmp nop bnez $v0, loc_400ACC nop
然后判斷一下,轉換后的字符前五個是不是"Q|j{g",如果不是的話直接wrong,在這里呢,我們必須選擇是,否則下一步就沒了。。
過渡
addiu $v0, $fp, 0x48+var_2C move $a0, $v0 jal judge nop b loc_400ADC nop緊接著,把我們輸入的字符串的地址放在v0里面,然后v0放在a0寄存器,當做參數(shù)傳過去,即寄存器傳參。。
jal跳轉這里,就不用說了,都能看懂。
接下來還有個核心函數(shù):
babymips下
https://blog.csdn.net/CSNN2019/article/details/112788619
總結
以上是生活随笔為你收集整理的babymips(上) 寒假逆向生涯(14/100)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: *CTF MineGame
- 下一篇: babymips(下) 寒假逆向生涯(1