SPIM

(rev50, solved by 204)

Description: My friend keeps telling me, that real hackers speak assembly fluently. Are you a real hacker? Decode this string: "IVyN5U3X)ZUMYCs"

Attachment: rev50.zip

解凍すると、MIPSのアセンブリプログラムができます。以下のサイトを参考にプログラムの動作を確認します。

http://www.swlab.cs.okayama-u.ac.jp/~nom/lect/p3/concise-mips-instruction-set.html

User Text Segment [00400000]..[00440000]
[00400000] 8fa40000  lw $4, 0($29)              ; 183: lw $a0 0($sp) # argc
[00400004] 27a50004  addiu $5, $29, 4        ; 184: addiu $a1 $sp 4 # argv
[00400008] 24a60004  addiu $6, $5, 4          ; 185: addiu $a2 $a1 4 # envp
[0040000c] 00041080  sll $2, $4, 2                ; 186: sll $v0 $a0 2
[00400010] 00c23021  addu $6, $6, $2         ; 187: addu $a2 $a2 $v0
[00400014] 0c100009  jal 0x00400024 [main]; 188: jal main
[00400018] 00000000  nop                            ; 189: nop
[0040001c] 3402000a  ori $2, $0, 10             ; 191: li $v0 10          //$v0 = 10
[00400020] 0000000c  syscall                       ; 192: syscall # syscall 10 (exit)
[00400024] 3c081001  lui $8, 4097 [flag]       ; 7: la $t0, flag           //$t0 = flag
[00400028] 00004821  addu $9, $0, $0         ; 8: move $t1, $0       //$t1 = $0
[0040002c] 3401000f  ori $1, $0, 15               ; 11: sgt $t2, $t1, 15 //if($t1>15) $t2=1 else $t2=0
[00400030] 0029502a  slt $10, $1, $9       
[00400034] 34010001  ori $1, $0, 1               ; 12: beq $t2, 1, exit     //if($t2==1) exit
[00400038] 102a0007  beq $1, $10, 28 [exit-0x00400038]
[0040003c] 01095020  add $10, $8, $9         ; 14: add $t2, $t0, $t1 //$t2 = $t0 + $t1
[00400040] 81440000  lb $4, 0($10)              ; 15: lb $a0, ($t2)        //$a0 = *(char)$t2
[00400044] 00892026  xor $4, $4, $9            ; 16: xor $a0, $a0, $t1 //$a0 = $a0 ^ $t1
[00400048] a1440000  sb $4, 0($10)             ; 17: sb $a0, 0($t2)     //
[0040004c] 21290001  addi $9, $9, 1            ; 19: add $t1, $t1, 1     //$t1 = $t1 + 1
[00400050] 0810000b  j 0x0040002c [for]      ; 20: j for             //
[00400054] 00082021  addu $4, $0, $8          ; 24: move $a0, $t0    //$a = $t0
[00400058] 0c100019  jal 0x00400064 [printstring]; 25: jal printstring
[0040005c] 3402000a  ori $2, $0, 10              ; 26: li $v0, 10         //$v0 = 10
[00400060] 0000000c  syscall                        ; 27: syscall             //exit
[00400064] 34020004  ori $2, $0, 4            ; 30: li $v0, 4         //$v0 = 4
[00400068] 0000000c  syscall                ; 31: syscall             //print string
[0040006c] 03e00008  jr $31                    ; 32: jr $ra             //呼び出し元へ復帰
$t1がループカウンタで、0で初期化、1ずつ加算され、15回ループします。その中でflag文字列に対して、頭から1文字ずつ$t1とXORをしています。その結果が問題で与えられた文字列になります。従って、その文字列をもう一度同じようにXORすることで、元のflag文字列を得ることができます。

$a0 2進表記 $t1 2進表記 XOR flag
I 01001001 0 00000000 1001001 I
V 01010110 1 00000001 1010111 W
y 01111001 2 00000010 1111011 {
N 01001110 3 00000011 1001101 M
5 00110101 4 00000100 110001 1
U 01010101 5 00000101 1010000 P
3 00110011 6 00000110 110101 5
X 01011000 7 00000111 1011111 _
) 00101001 8 00001000 100001 !
Z 01011010 9 00001001 1010011 S
U 01010101 10 00001010 1011111 _
M 01001101 11 00001011 1000110 F
Y 01011001 12 00001100 1010101 U
C 01000011 13 00001101 1001110 N
s 01110011 14 00001110 1111101 }

フラグは、
IW{M1P5_!S_FUN}
です。