004425 ランダム
 ホーム | 日記 | プロフィール 【フォローする】 【ログイン】

uma3blog

PR

キーワードサーチ

▼キーワード検索

プロフィール


うま__

カレンダー

楽天カード

お気に入りブログ

まだ登録されていません

コメント新着

コメントに書き込みはありません。

フリーページ

ニューストピックス

サイド自由欄

はてなブログ(内容は同じ感じ) http://uma3san.hatenablog.com/
2014.11.14
XML
6章

よく使われるパターンについて

【if文】
if(x > 0x100){
    printf("x > 100\n");
}

を逆アセンブルすると以下のようになる

cmp    eax, 100h
jle    short loc_401038    ; 左の引数≦右の引数のときジャンプ(ZF=1 | SF ! OF)
push    offset aX100    ; "x > 100\n"
call    sub_401050    ; printf
add    esp, 4
loc_401038:
pop    ecx
retn

上記のif文をif(x == 0x100)に変えるとjle    short loc_401038の部分が以下のように変わる

jnz    short loc_401038    ; x≠100hのときジャンプ(ZF=0)

if(x < 0x100)に変えると以下のように変わる

jge    short loc_401038    ; 左の引数≧右の引数のときジャンプ(SD=OF)

else printf("else");を加えると以下の通り

cmp    eax, 100h
jbe    short loc_401218    ; 左の引数≦右の引数のときジャンプ(CF=1 | ZF=1)
push    offset aX100    ; "x > 100\n"
call    sub_401260    ; printf
add    esp, 4
retn
loc_401218:        ; CODE XREF: sub_401200+8 j
push    offset aElse    ; "else"
call    sub_401260
pop    ecx
retn
sub_401200    endp

    

if(x > 0x100 && x < 0x200)のような場合、分岐条件が2つになる

cmp    eax, 100h
jbe    short loc_401220    ; 左の引数≦右の引数のときジャンプ(CF=1 | ZF=1)
cmp    eax, 200h
jnb    short loc_401220    ; 左の引数≧右の引数のときジャンプ(CF=0)
push    offset aX100
call    sub_401260
add    esp, 4
retn

「ll」についてもjbeとjnbの部分がそれぞれjaとjbに変わるだけ。

【ループ】
int loop(int c){
    int d=0;
    for(int i=0; i<=0x100; i++){
        printf("loop : %d\n", d);
        d++;
    }
    return c+d;
}

push    ebp
mov    ebp, esp
sub    esp, 8
mov    [ebp+var_4], 0        ; d=0
mov    [ebp+var_8], 0        ; i=0
jmp    short loc_401331
loc_401328:
mov    eax, [ebp+var_8]    ; eaxにiを
add    eax, 1            ; eax++(i++)
mov    [ebp+var_8], eax    ; eaxをiに
loc_401331:
cmp    [ebp+var_8], 100h    ; iと0x100の比較
jg    short loc_401356    ; i>0x100のときジャンプ
mov    ecx, [ebp+var_4]    ; dをecxレジスタに
push    ecx            ; ecxをスタック
push    offset aLoopD        ; "loop : %d\n"
call    sub_4013B8        ; printf
add    esp, 8            ; esp+8
mov    edx, [ebp+var_4]    ; dをedxレジスタに
add    edx, 1            ; edx++(d++)
mov    [ebp+var_4], edx    ; edxレジスタをdに
jmp    short loc_401328    ; 無条件ジャンプ
loc_401356:
mov    eax, [ebp+arg_0]
add    eax, [ebp+var_4]
mov    esp, ebp
pop    ebp
retn
sub_401312    endp

break文を入れた場合、jnzの次にjmpが続くようなジャンプ命令が連続する形になる。

mov
cmp
jnz    ; if文の処理
jmp    ; break

continue文もほぼ同じでjmpのジャンプ先がループの最初に変わるだけ。

途中にreturnが入った場合、xor eax, eaxでeaxをクリアし、jmpでループを抜ける。

【文字列制御】
・strcpy
char *szSource = "Hello World !";
char szTarget[MAX_PATH];
strcpy(szTarget, szSource);
printf("%s\n", szTarget);

↓逆アセンブル

or    ecx, FFFFFFFF
xor    eax, eax    ; eaxで何かをカウントするための準備
lea    edx, dword ptr ss:[esp]    ; espのアドレスをedxに入れる
push    esi    ; 変数使用のため(ソースアドレス)
push    edi    ; 変数使用のため(デスティネーションアドレス)
mov    edi, example.00407034    ; ediに"Hello"を入れる
repne    scas byte ptr es:[edi]    ; eaxとediを比較(ZF=0, ecx>0のあいだ繰り返し)
not    ecx    ; 1と0を変換(null文字含め14文字(0xE)が入った)
sub    edi, ecx    ; ポインタ位置修正(Helloの先頭文字を指す)
mov    eax, ecx    ; 元のカウンタ値をeaxに保存
mov    esi, edi    ; edi→esi(Hello World !)
mov    edi, edx    ; edx→edi(espのアドレスを入れる)
shr    ecx, 2    ; ecxに3が入る(14/4の商)
rep    movs dword ptr es:[edi], dword ptr ds:[esi]    ; esi→ediコピー(12文字だけ)
mov    ecx, eax    ; repを使うために元のecxの値を取ってくる
and    ecx, 3    ; 0xEが0x2になる(残りの2文字もコピーするため)
rep    movs byte ptr es:[edi], byte ptr ds:[esi]    ; 2文字コピー

・strcat
char szMalware[MAX_PATH];
GetSystemDirectory(szMalware, MAX_PATH); //system32フォルダの場所を取得
strcat(szMalware, "\\expllorer.dll"); //C:\Windows\System32\explorer.dll
printf("szMalware: %s\n", szMalware);

↓逆アセンブル

lea    eax, dword ptr ss:[esp]    ; espのアドレスをeaxに
push    ebx
push    esi
push    edi
push    104    ; 第2引数。MAX_PATH分の大きさを指定
push    eax    ; 第1引数。system32のパスを出力するアドレス
call    near dword ptr ds:[<&KERNEL32.GetSystemDirectoryA>]
mov    edi, example.00407064    ; "\\explorer.dll"
or    ecx, FFFFFFFF    ; 0x13とFFFFFFFFをor
xor    eax, eax    ; eax初期化
lea    edx,dword ptr ss:[esp+C]
repne    scas byte ptr es:[edi]
not    ecx    ; 0xE
sub    edi, ecx    ; 元の位置に戻す
mov    esi, edi    ; \\explorer.dll
mov    ebx, ecx    ; ecxの値をebxに保存
mov    edi, edx
or    ecx, FFFFFFFF
repne    scas byte ptr es:[edi]    ; C:\Windows\System32の長さを求める
mov    ecx, ebx    ; 文字列の長さ
dec    edi    ; 文字を連結するためにnull文字の1つ前を指すようにする
shr    ecx, 2    ; 文字列の長さ/4
rep    movs dword ptr es:[edi], dword ptr ds:[esi]    ; 商のぶんだけ4バイトずつコピー
mov    ecx, ebx
lea    eax, dword ptr ss:[esp+C]
and    ecx, 3    ; 残りをコピー
push    eax
rep    movs byte ptr es: [edi], byte ptr ds:[esi]    ; 残りをコピー

・strlwr
char *_strlwr(char *string);

↓逆アセンブル

mov    cl, byte ptr ds:[edx]
cmp    cl, 0x41    ; 0x41はA
jl    short example.00405B93
cmp    cl, 0x5A    ; 0x5AはZ
jg    short example.00405B93
add    cl, 0x20    ; 小文字に変換(ASCIIで小文字は大文字+20)
mov    byte ptr ds:[edx], cl
inc    edx
cmp    byte ptr ds:[edx], bl
jnz    short example.00405B82






最終更新日  2014.11.14 23:12:37
[リバースエンジニアリングバイブル] カテゴリの最新記事

Copyright (c) 1997-2019 Rakuten, Inc. All Rights Reserved.