今までIntelアセンブリ言語だけ見てたけど、armは初めて見たので色々探しながら勉強した。

 

ARMレジスターの整理

R0 ~ R10 : 汎用レジスタ、一般演算及び、臨時セーブ場所等で使用

R11 : Current Stack Frame Pointer、現在関数のフレームポインター

R12 : Intra-Procedure call Scratch Register、臨時データをセーブするサブルーチンに使用

R13 : Stack Pointer(SP)、各動作モードごと別途で存在

R14 : Link Register(LR)、関数を呼び出す時リターンされる住所を持ってる

R15 : Program Counter(PC)、次に実行される命令語を持ってる。メモリから持ってくる

CPSR : Program Status Register(CPSR)、各モードごとに一つ存在し、モードが変更される度に変更される前のCPSRがSPSRにセーブされる

 

CPUアーキテクチャのPIPELINE

1.Fetchはプログラムメモリから命令語をロードする

2.DecodeはInstruction Registerの命令語を解釈する

3.Executeは命令語を処理する

4.Write-Backは処理された結果をレジスター又は、データメモリにセーブする

時間があれば、ARMとかCPUについてもっと勉強しなきゃ。。。

まず、ソースコードを見てみる

回答はkey1+key2+key3の値を入れればflagが出力されるようだ。

では、key1から見てみる

<+8>の部分でpcをr3に入れてr0にまた入れることが見える。(r0はリターンの値)

ここでpcはFetchを指している。(32bit基準+8)

なので、0x8ce4という事になる。

次はkey2を見てみる

add r6, pc, #1

bx r6部分でthumb modeに変更される。

thumb modeでのpcは最近の住所に+4がセーブされる。

なので、0x8d04 + 4になるし

adds r3, #4で+4になるので

0x8d04 + 4 +4 = 0x8D0Cという事になる

最後にkey3を見てみると

ここもr0にr3をいれるので、r3を追跡してみるとlrという値があるが

これはr14で関数を呼び出す時リターンされる住所を持ってる

つまり、main関数で呼び出したので、main関数を見なければいけない

なので、0x8d80という事になる。

key1+key2+key3を全部足して10進数に変換すると

0x8ce4 + 0x8d0c + 0x8d80 = 0x1A770 = 108400になる

成功!!