2013-01-01から1年間の記事一覧

配列要素を参照するシンタックスバリエーション

C言語では、以下のシンタックスは、すべて'B'に展開される。 (文字列リテラル"ABCDE"の格納領域の先頭アドレスを、0x8048560と仮定します。) # syntax 1 "ABCDE"[1] 2 ((char *)0x8048560)[1] 3 1["ABCDE"] 4 (&"ABCDE")[0][1] 5 0[(&"ABCDE")][1] 式中の…

argvのメモリ構造

main関数のargvの構造がどうなっているのか調べてみた。 1 #include <stdio.h> 2 3 int main(int argc, char *argv[]) 4 { 5 int i; 6 7 printf("%p : argc %d\n", &argc, argc); 8 printf("%p : argv %p\n", &argv, argv); 9 printf("%p : argv+1 %p\n", &argv+1, *(</stdio.h>…

T型の配列

「ポインタ虎の巻」を読んでいたら、今更ながら、こんな盲点に気づかされた。 /* !!! 間違ったコード例 */ int data[3][5]; int **p; p = data; /* Syntax Error !!! */ 二次元配列の値を、ポインタのポインタ変数に代入しているので、なんとな〜く正しそう…

free(3)

#include <stdlib.h> void free(void *ptr); free(3)で注意すべきは、 引数ptrの値は、malloc、calloc、またはreallocの返却値と同じでなければならない。 すでに解放された領域に対してfree(3)すること(二重解放)は動作未定義である。 NULLポインタに対するfree(3)</stdlib.h>…

sizeof演算子

以下について、sizeofでサイズを調べてみます。 文字列リテラル 初期値を持つchar型配列 初期値を持つint型配列 char型配列を指すポインタ変数 文字リテラル 空文字列 1 #include <stdio.h> 2 3 int main() 4 { 5 char data[] = "ABCDE"; 6 int data2[] = {1,2,3,4,5}</stdio.h>…

gcc4.7.3におけるvoid型の実装

void型について実験。gccのバージョンは、以下です。 gcc バージョン 4.7.3 (Ubuntu/Linaro 4.7.3-1ubuntu1) われわれはvoidを当たり前のように使っているけど、そもそもvoidとは何だろ?実装レベルで、どのようにコンパイラに解釈されているのか、また逆ア…

SIBのフォーマットと符号化

今回は、SIBとディスプレースメントを持つニーモニックについて見ていきます。まず、命令フォーマットにおけるSIBとディスプレースメントの位置ですが、それぞれ以下の位置に配置されます。 // 一般的命令フォーマット +-------+-------------------+-------…

アドレッシングモード別のModR/MとSIBの値

アドレッシングモードと、ModR/M・SIBの相関性がいまいち分からないので、アドレッシングモードのバリエーションを変えてみて実験してみる。 0: b8 78 56 34 12 mov eax,0x12345678 5: 89 04 24 mov DWORD PTR [esp],eax 8: 89 f0 mov eax,esi a: a1 ff ff f…

NOT命令(not r)

レジスタに対するNOT命令です。 0: f6 d0 not %al 2: f6 d3 not %bl 4: f6 d1 not %cl 6: f6 d2 not %dl 8: 66 f7 d0 not %ax b: 66 f7 d3 not %bx e: 66 f7 d1 not %cx 11: 66 f7 d2 not %dx 14: f7 d0 not %eax 16: f7 d3 not %ebx 18: f7 d1 not %ecx 1a:…

XOR命令(r xor imm)

レジスタに対する即値とのXOR命令です。 0: 34 7f xor $0x7f,%al 2: 66 35 ff 7f xor $0x7fff,%ax 6: 35 ff ff ff 7f xor $0x7fffffff,%eax b: 80 f3 7f xor $0x7f,%bl e: 80 f1 7f xor $0x7f,%cl 11: 80 f2 7f xor $0x7f,%dl 14: 66 81 f3 ff 7f xor $0x7ff…

OR命令(r or imm)

レジスタに対する即値とのOR命令です。 0: 0c 7f or $0x7f,%al 2: 66 0d ff 7f or $0x7fff,%ax 6: 0d ff ff ff 7f or $0x7fffffff,%eax b: 80 cb 7f or $0x7f,%bl e: 80 c9 7f or $0x7f,%cl 11: 80 ca 7f or $0x7f,%dl 14: 66 81 cb ff 7f or $0x7fff,%bx 19…

AND命令(r and imm)

レジスタに対する即値指定とのAND命令です。 0: 24 7f and $0x7f,%al 2: 66 25 ff 7f and $0x7fff,%ax 6: 25 ff ff ff 7f and $0x7fffffff,%eax b: 80 e3 7f and $0x7f,%bl e: 80 e1 7f and $0x7f,%cl 11: 80 e2 7f and $0x7f,%dl 14: 66 81 e3 ff 7f and $0…

SUB命令(r-imm→r)

レジスタに対するSUB命令です。 0: 2c 7f sub $0x7f,%al 2: 80 eb 7f sub $0x7f,%bl 5: 80 e9 7f sub $0x7f,%cl 8: 80 ea 7f sub $0x7f,%dl b: 66 2d ff 7f sub $0x7fff,%ax f: 66 81 eb ff 7f sub $0x7fff,%bx 14: 66 81 e9 ff 7f sub $0x7fff,%cx 19: 66 8…

DEC命令(r)

レジスタに対するDEC命令です。 0: fe c8 dec %al 2: fe cb dec %bl 4: fe c9 dec %cl 6: fe ca dec %dl 8: 66 48 dec %ax a: 66 4b dec %bx c: 66 49 dec %cx e: 66 4a dec %dx 10: 48 dec %eax 11: 4b dec %ebx 12: 49 dec %ecx 13: 4a dec %edxおお、DEC…

INC命令(r)

レジスタに対するINC命令です。 0: fe c0 inc %al 2: fe c3 inc %bl 4: fe c1 inc %cl 6: fe c2 inc %dl 8: 66 40 inc %ax a: 66 43 inc %bx c: 66 41 inc %cx e: 66 42 inc %dx 10: 40 inc %eax 11: 43 inc %ebx 12: 41 inc %ecx 13: 42 inc %edxワードレジ…

ADD命令(imm+r→r)

ADD命令の即値→レジスタ間転送の逆アセンブル結果です。 0: 04 7f add $0x7f,%al 2: 80 c3 7f add $0x7f,%bl 5: 80 c1 7f add $0x7f,%cl 8: 80 c2 7f add $0x7f,%dl b: 66 05 ff 7f add $0x7fff,%ax f: 66 81 c3 ff 7f add $0x7fff,%bx 14: 66 81 c1 ff 7f a…

MOV命令(imm→r)

MOV命令(即値→レジスタの転送)の、アセンブリコードとニーモニックの対応です。 ニーモニック アセンブリ b0 7f mov $0x7f,%al b3 7f mov $0x7f,%bl b1 7f mov $0x7f,%cl b2 7f mov $0x7f,%dl b8 ff ff ff 7f mov $0x7fffffff,%eax bb ff ff ff 7f mov $0x…

機械語の解読

8086の機械語を読んでみます。私にも、「アセンブリ命令と16進のオペコードは、1対1で対応している。アセンブリコード→機械語の翻訳って、手間だけの問題じゃん!」と思っていた時期がありました。でも、逆アセンブルの結果を見ると、同じmov命令なのに、ど…

逆アセンブルで遊んでみる(9)構造体変数の返却

構造体変数をreturnする関数の内部処理を解析する。です。 1 struct d { 2 int num1; 3 int num2; 4 int num3; 5 }; 6 7 struct d func() 8 { 9 struct d d1; 10 11 d1.num1 = 0x7FFFFFFF; 12 d1.num2 = 0x8FFFFFFF; 13 d1.num3 = 0x9FFFFFFF; 14 15 return …

逆アセンブルで遊んでみる(8)long long型の自動変数

スタック上に確保した自動変数領域に、long long型(16バイト)のデータを格納する。です(エピローグとプロローグ、SSPのスタック破壊検知コードについては省略しています)。 1 void func() 2 { 3 long long n = 0x1234567890ABCDEF; 4 char str[] = "0123…

逆アセンブルで遊んでみる(7)スタック破壊検出コードの自動生成

今回は、関数内で配列を確保する。です。 1 void func() 2 { 3 char array[] = "12345678"; 4 } 00000000 <func>: 0: 55 push %ebp 1: 89 e5 mov %esp,%ebp 3: 83 ec 18 sub $0x18,%esp 6: 65 a1 14 00 00 00 mov %gs:0x14,%eax c: 89 45 f4 mov %eax,-0xc(%ebp) f</func>…

システムコールの発行について

アセンブリにおけるシステムコール発行は、プログラミング言語における関数呼出しと同じで、 ・関数呼出時の引数指定は、レジスタへの値セットに相当する。 ・使用するレジスタ(どのレジスタに何の値をセットするか)は固定。 ・EAXレジスタにセットする値…

逆アセンブルで遊んでみる(6)関数内の処理を追いかけてみた

今回は、関数呼出しにおけるスタックの実装について、逆アセンブルを執拗に解析していきます。スタックという概念については、「積み上げられた本を取り出す時、一番上にある本から優先して取り出しが行われる」というたとえ話で説明されることが多いですが…

逆アセンブルで遊んでみる(5)自動変数の領域を16バイトを超えて確保

「自動変数の領域を16バイトを超えて確保」です。 void func(void) { int i = 0x7F; int j = 0x8F; int k = 0x9F; int l = 0xAF; int m = 0xBF; } 0: 55 push %ebp 1: 89 e5 mov %esp,%ebp 3: 83 ec 20 sub $0x20,%esp 6: c7 45 ec 7f 00 00 00 movl $0x7f,-…

逆アセンブルで遊んでみる(4)自動変数に値をセット

「自動変数に値をセット」です。 /* asm004.c */ void func(void) { int n = 0x7F; } 0: 55 push %ebp 1: 89 e5 mov %esp,%ebp 3: 83 ec 10 sub $0x10,%esp 6: c7 45 fc 7f 00 00 00 movl $0x7f,-0x4(%ebp) d: c9 leave e: c3 ret3行目で、スタックポインタ…

逆アセンブルで遊んでみる(3)signed long longの最大値を返す関数

「signed long longの最大値を返す関数」です。 unsigned long long func(void) { return 0x7FFFFFFFFFFFFFFFLL; } 0: 55 push %ebp 1: 89 e5 mov %esp,%ebp 3: b8 ff ff ff ff mov $0xffffffff,%eax 8: ba ff ff ff 7f mov $0x7fffffff,%edx d: 5d pop %ebp…

逆アセンブルで遊んでみる(2)signed intの最大値を返す関数

「signed intの最大値(2,147,483,647)を返す関数」です。 int func(void) { return 0x7FFFFFFF; } 0: 55 push %ebp 1: 89 e5 mov %esp,%ebp 3: b8 ff ff ff 7f mov $0x7fffffff,%eax 8: 5d pop %ebp 9: c3 ret intの最大値は「0x7FFFFFFF」ですが、バイナ…

逆アセンブルで遊んでみる(1)0を返す関数

「定数0を返す関数」の逆アセンブルです。 /* asm001.c */ int func(void) { return 0; } 0: 55 push %ebp 1: 89 e5 mov %esp,%ebp 3: b8 00 00 00 00 mov $0x0,%eax 8: 5d pop %ebp 9: c3 ret asm000.oとの差分を拾ってみると… ・eaxレジスタに対するmov命…

逆アセンブルで遊んでみる(0)何もしない関数

「フィーリングで読むアセンブラ入門」の発売が待ち遠しくて、いかにも発狂しそうですが、発売日まで、自分の環境で逆アセンブルして我慢しようということで…。今回のソースコードは、こんな内容。内部で何も行わない関数の逆アセンブルを行ってみます。 /* …

2の冪乗

well-knownな2の冪乗は、丸暗記してしまいましょう。 毎日、呪文のように唱えていれば、自然に暗記します(^ ^;) intの最大値は、「ニジュウイチオクヨンセンナナヒャクヨンジュウハチマンサンゼンロッピャクヨンジュウナナ」とかね。 2の冪乗 10進数 2^0 1…