4

いくつかのソフトウェアからこのアセンブリ コードを抽出しましたが、残念ながら私はアセンブラについて何も知りません。私が触れたアセンブラのビットは、68000 の Commodore Amiga に戻ってきました。

アセンブラを一から学ばなくても、このコードを理解する方法を教えてくれる人、またはそれが何をするのか教えてくれる人はいますか?

これを実行して動作を確認できる「シミュレーター」はありますか?

   -[ObjSample Param1:andParam2:]:
    00000c79    pushl   %ebp
    00000c7a    movl    %esp,%ebp
    00000c7c    subl    $0x48,%esp
    00000c7f    movl    %ebx,0xf4(%ebp)
    00000c82    movl    %esi,0xf8(%ebp)
    00000c85    movl    %edi,0xfc(%ebp)
    00000c88    calll   0x00000c8d
    00000c8d    popl    %ebx
    00000c8e    cmpb    $-[ObjSample delegate],_bDoOnce.26952-0xc8d(%ebx)
    00000c95    jel 0x00000d47
    00000c9b    movb    $-[ObjSample delegate],_bDoOnce.26952-0xc8d(%ebx)
    00000ca2    movl    0x7dc0-0xc8d(%ebx),%eax
    00000ca8    movl    %eax,0x04(%esp)
    00000cac    movl    0x7df4-0xc8d(%ebx),%eax
    00000cb2    movl    %eax,(%esp)
    00000cb5    calll   _objc_msgSend
    00000cba    movl    0x7dbc-0xc8d(%ebx),%edx
    00000cc0    movl    %edx,0x04(%esp)
    00000cc4    movl    %eax,(%esp)
    00000cc7    calll   _objc_msgSend
    00000ccc    movl    %eax,0xe4(%ebp)
    00000ccf    movl    0x7db8-0xc8d(%ebx),%eax
    00000cd5    movl    %eax,0x04(%esp)
    00000cd9    movl    0xe4(%ebp),%eax
    00000cdc    movl    %eax,(%esp)
    00000cdf    calll   _objc_msgSend
    00000ce4    leal    (%eax,%eax),%edi
    00000ce7    movl    %edi,(%esp)
    00000cea    calll   _malloc
    00000cef    movl    %eax,%esi
    00000cf1    movl    %edi,0x08(%esp)
    00000cf5    movl    $-[ObjSample delegate],0x04(%esp)
    00000cfd    movl    %eax,(%esp)
    00000d00    calll   _memset
    00000d05    movl    $0x00000004,0x10(%esp)
    00000d0d    movl    %edi,0x0c(%esp)
    00000d11    movl    %esi,0x08(%esp)
    00000d15    movl    0x7db4-0xc8d(%ebx),%eax
    00000d1b    movl    %eax,0x04(%esp)
    00000d1f    movl    0xe4(%ebp),%eax
    00000d22    movl    %eax,(%esp)
    00000d25    calll   _objc_msgSend
    00000d2a    xorl    %edx,%edx
    00000d2c    movl    %edi,%eax
    00000d2e    shrl    $0x03,%eax
    00000d31    jmp 0x00000d34
    00000d33    incl    %edx
    00000d34    cmpl    %edx,%eax
    00000d36    ja  0x00000d33
    00000d38    movl    %esi,(%esp)
    00000d3b    calll   _free
    00000d40    movb    $0x01,_isAuthenticated-0xc8d(%ebx)
    00000d47    movzbl  _isAuthenticated-0xc8d(%ebx),%eax
    00000d4e    movl    0xf4(%ebp),%ebx
    00000d51    movl    0xf8(%ebp),%esi
    00000d54    movl    0xfc(%ebp),%edi
    00000d57    leave
    00000d58    ret
4

2 に答える 2

18

これは、スタック フレームを設定し、ローカル変数に 0x48 バイトを割り当て、ebx、esi、および edi を節約します。これはかなり標準的な関数プロローグです。

00000c79    pushl   %ebp
00000c7a    movl    %esp,%ebp
00000c7c    subl    $0x48,%esp
00000c7f    movl    %ebx,0xf4(%ebp)
00000c82    movl    %esi,0xf8(%ebp)
00000c85    movl    %edi,0xfc(%ebp)

これは、コードを指すように設定された ebx を取得するためのアセンブラーのトリックです。これが完了すると、ebx には 00000c8d が含まれます。

00000c88    calll   0x00000c8d
00000c8d    popl    %ebx

このビットは、関数が 1 回だけ実行されることを保証します。2 回目に呼び出すと、最後までスキップします (jel 0x00000d47)

00000c8e    cmpb    $-[ObjSample delegate],_bDoOnce.26952-0xc8d(%ebx)
00000c95    jel 0x00000d47
00000c9b    movb    $-[ObjSample delegate],_bDoOnce.26952-0xc8d(%ebx)

このビットは、ebx に関連する値をローカル (スタック) 変数空間にコピーしています。ebx は現在の関数を指していますが、ebx からのオフセットは非常に大きいことに注意してください。ほとんどの場合、これはコードに埋め込まれた定数データであり、関数を呼び出す引数として設定されています。

00000ca2    movl    0x7dc0-0xc8d(%ebx),%eax
00000ca8    movl    %eax,0x04(%esp)
00000cac    movl    0x7df4-0xc8d(%ebx),%eax
00000cb2    movl    %eax,(%esp)

関数を呼び出します。

00000cb5    calll   _objc_msgSend

さらに定数値がスタックにプッシュされ、同じ関数が再度呼び出されます。今回は、関数呼び出しの戻り値がローカル変数 0xe4(%ebp) に保存されます。

00000cba    movl    0x7dbc-0xc8d(%ebx),%edx
00000cc0    movl    %edx,0x04(%esp)
00000cc4    movl    %eax,(%esp)
00000cc7    calll   _objc_msgSend
00000ccc    movl    %eax,0xe4(%ebp)

関数呼び出しのためにスタックに追加の値がプッシュされます。今回は、1 つの値は ebx に関連する定数であり、もう 1 つの値は前の呼び出しからの戻り値です。

00000ccf    movl    0x7db8-0xc8d(%ebx),%eax
00000cd5    movl    %eax,0x04(%esp)
00000cd9    movl    0xe4(%ebp),%eax
00000cdc    movl    %eax,(%esp)
00000cdf    calll   _objc_msgSend

その呼び出しからの戻り値を取得し、それを2倍にして、その量のメモリをmallocします。

00000ce4    leal    (%eax,%eax),%edi
00000ce7    movl    %edi,(%esp)
00000cea    calll   _malloc

[ObjSample デリゲート] で見つかったバイトでメモリを埋める

00000cef    movl    %eax,%esi
00000cf1    movl    %edi,0x08(%esp)
00000cf5    movl    $-[ObjSample delegate],0x04(%esp)
00000cfd    movl    %eax,(%esp)
00000d00    calll   _memset

別のメッセージを送信します。これは引数を取ります: 0xe4(%ebp)、ebx からの定数、mallocd ptr、malloc サイズ、4。おそらく、これはメッセージを malloc されたバッファーに送信します (バッファーは後で解放されます。呼び出し側)

00000d05    movl    $0x00000004,0x10(%esp)
00000d0d    movl    %edi,0x0c(%esp)
00000d11    movl    %esi,0x08(%esp)
00000d15    movl    0x7db4-0xc8d(%ebx),%eax
00000d1b    movl    %eax,0x04(%esp)
00000d1f    movl    0xe4(%ebp),%eax
00000d22    movl    %eax,(%esp)
00000d25    calll   _objc_msgSend

edx をクリアし、sendmessage 呼び出しからの戻り値を edi に保存します。

00000d2a    xorl    %edx,%edx
00000d2c    movl    %edi,%eax

eax >> 3while (edx < eax) ++edx; これはあまり意味がありません。

00000d2e    shrl    $0x03,%eax
00000d31    jmp 0x00000d34
00000d33    incl    %edx
00000d34    cmpl    %edx,%eax
00000d36    ja  0x00000d33

mallocd メモリを解放する

00000d38    movl    %esi,(%esp)
00000d3b    calll   _free

_isAuthenticated を true に設定し、戻り値も true に設定します。この変数はコード内にあるか、おそらくグローバルにあるようです。

00000d40    movb    $0x01,_isAuthenticated-0xc8d(%ebx)
00000d47    movzbl  _isAuthenticated-0xc8d(%ebx),%eax

レジスタを復元して戻ります。

00000d4e    movl    0xf4(%ebp),%ebx
00000d51    movl    0xf8(%ebp),%esi
00000d54    movl    0xfc(%ebp),%edi
00000d57    leave
00000d58    ret
于 2010-03-11T23:27:41.397 に答える
12

難しい仕事です...あなたのアセンブラはただのルーチンですが、それは他のサブルーチンとグローバル変数または静的変数を参照しています。でも…やってみよう!(Cライク言語)

int unknown_function(/* Parameters? */)
{
static char bDoOnce;
static char isAuthenticated;
uint32 tmp1,tmp2,tmp3;
void *p;
int i;

       if (bDoOnce == ObjSample_delegate) {
             return isAuthenticated;
       }
       bDoOnce = ObjSample_delegate;
       tmp1= objc_msgSend(some_data1, some_data2);
       tmp2 = objc_msgSend(tmp1, some_data3);
       tmp3 = objc_msgSend(tmp2, some_data4);
       p = malloc(tmp3*2);
       memset(p, ObjSample_delegate, tmp3*2);
       objc_msgSend(tmp2,some_data5,p, tmp3*2,4);
       for (i = 0; i < tmp3/4; ++i) {
       }
       free(p);
       isAuthenticated = 1;
       return isAuthenticated;
}

うーん...実際に何が起こっているのかを理解するのに十分な情報がありません(私が何か間違ったことをしたとは言いません;))プログラムには「some_data」が多すぎます. うーん... gnu ObjectiveCでコンパイルされた関数ですか?

申し訳ありませんが、試してみましたが、これ以上役立つとは言えません。とにかく、お役に立てば幸いです。よろしく

于 2010-03-11T23:14:07.233 に答える