2017-09-09 7 views
-1

Heres入力を受け取り、爆弾の爆発を止める機能のHe。リバースエンジニアを試すためにこのアセンブリコードを理解するのに役立つ人はいますか?

0x00000000004011ca <+0>:  sub $0x8,%rsp     #reserve 8 bytes on stack 
0x00000000004011ce <+4>:  cmpb $0x37,0x1(%rdi)   #compare 0x37 ('7') with second character of input 
0x00000000004011d2 <+8>:  jne 0x4011df <phase_1+21>  #explode bomb if not equal 
0x00000000004011d4 <+10>: cmpb $0x5d,0x2(%rdi)   #compare 0x5d (']') with third character of input 
0x00000000004011d8 <+14>: jne 0x4011df <phase_1+21>  #explode bomb if not equal 
0x00000000004011da <+16>: cmpb $0x5a,(%rdi)    #compare 0x5a ('Z') with first character of input 
0x00000000004011dd <+19>: je  0x4011ed <phase_1+35>  #if all equal, skip bomb explosion 
0x00000000004011df <+21>: callq 0x401c01 <bomb_ignition> #bomb explode 
0x00000000004011e4 <+26>: mov $0xffffffffffffffff,%rax #rax = -1 
0x00000000004011eb <+33>: jmp 0x401200 <phase_1+54>  #end 
0x00000000004011ed <+35>: movsbl 0xf(%rdi),%eax   //need help here 
0x00000000004011f1 <+39>: add $0x1b,%eax 
0x00000000004011f4 <+42>: movsbl 0xe(%rdi),%edx 
0x00000000004011f8 <+46>: cmp %edx,%eax 
0x00000000004011fa <+48>: sete %al 
0x00000000004011fd <+51>: movzbl %al,%eax 
0x0000000000401200 <+54>: add $0x8,%rsp 
0x0000000000401204 <+58>: retq 

私は#と何をしているのかを注釈しました。どこか間違っていたら教えてください。私は最初のときとその後に何をしているのかを理解する助けが必要ですmovsbl。ちょうど読んでから、私はそれが%rdiを15だけ広げて、それを%eaxに入れていると思います。 27を追加する。何に、私は知らない。それから%rdiを14で広げて%edxに入れてください。比較し、等しい場合は、フラグ%alを設定しますか?その後、%al%eaxに移動します。次に、スタックスペースをクリアします。その後、返されます。

何かを理解してどこでも間違っていましたか?誰かがmovsblがこれで何をしているのか明らかにすることはできますか?承認されたすべての助け。おかげ

+0

https://stackoverflow.com/questions/7861095/what-does-movsbl-instruction-do –

+0

@MitchWheat私はそれを見ました。彼らはすべて私の頭を越えているようだし、それが何をしているのか、どういう人たちが彼らのやり方で行動するのかを明確に説明していないようだ。私が5であるかのように説明してもらえますか? –

+0

これは 'mov 0xf(%rdi)、%eax'と書かれていればそれはあなたにとって意味がありますか?ソース( '0xf(%rdi)')はバイトであり、宛先は32ビットのint( 'eax')なので、(かなり)書き込むことはできません。宛先は32ビット長であるため、アセンブラに他の24ビットをどうするかを伝える必要があります。符号ビットを拡張するように(つまり、バイトが負の場合、intを負にする)ことがその方法の1つです。 –

答えて

1
movsbl 0xf(%rdi),%eax 

movsblが長い IGN拡張子を使用してバイトを移動するので、int8_tint32_tに昇格されます。即ち

int32_t eax = *((int8_t *)(rdi + 0xf)); 

int8_tは、例えば保持ので、もしこれは、そのsigned value as interpreted according to the two's complement stays the same手段-1int32_t-1を保持します。しかし、符号なしと解釈された場合、対応する値は明らかに同じではない0xFF0xFFFFFFFFとなります。署名されていないプロモーションは代わりにゼロ拡張されるため、ここでmovzblを使用すると、0xFF0x000000FFに拡張されます。拡張子がゼロの場合、拡張子の後の符号なしの値は同じになります。

は、別のそれほど明白ではない命令は、命令

uint8_t al = <previous comparison equal/set zero flag> ? 1: 0; 

は、eaxraxの残りのビットをリセットしないal設定に等しい

sete %al 

ので、

movzbl %al,%eax 

移動Z ERO拡張子を使用して長いのバイト、すなわち符号なしプロモーション:eaxを設定することも上位ビットをリセットするため

uint32_t eax = (uint8_t)al; 

これは本質的に、全ての上位ビットraxで8- をゼロ。

デフォルトの戻り値は、アキュムレータ内にあるので、関数プロトタイプに戻り型のために同様に働く8のN、16、32、64のため1又は0、すべてintN_tuintN_tかを返します。

関連する問題