「文書化されていない機能」とはどういう意味ですか?ほとんどの場合、アセンブリは高水準コードをコンパイルするだけです。それについて「文書化されていない」ものはほとんどありません。
EBP
関数のスタックフレームポインタとして最も頻繁に使用されます。特にC呼び出し規約(名前でも知られていますcdecl
)で使用されます。この規則では、パラメーターは逆の順序でスタックに渡され(たとえば、最後のパラメーターが最初にプッシュされます)、呼び出された関数はEBP
それらにアクセスするために使用します。あなたが投稿したコードに基づいて、データ構造は最初のパラメーターによって示されているのではないかと思います。見てください:
MOV EAX, DWORD PTR SS:[EBP+8]
LEA ECX, DWORD PTR DS:[EAX+4]
MOV DWORD PTR DS:[EAX], EDX
MOV DWORD PTR DS:[ECX+4],ECX
MOV DWORD PTR DS:[ECX],ECX
MOV DWORD PTR DS:[EAX+C],ECX
MOV ECX, DWORD PTR SS:[EBP+C]
最初の命令は、最初の引数をに移動しEAX
ます。次に、オフセット4がその引数に追加され、に移動されECX
ます。LEA
これは、「LoadEffectiveAddress」の省略形である命令によって行われることに注意してください。これは符号なし演算に使用され、コンパイラはポインタ演算を実行してオフセットを追加するときに使用するのが好きです。したがって、この命令が表示されるたびに、操作対象が構造体へのポインタである可能性があることに注意する必要があります。もちろん、確実に知る方法はありません。MOV
後で、そのアドレスとの間でいくつかのsを取得します。ここで、ECX
はメモリへのアクセスに使用されます。構造が存在する場合、Cでは次のようになります。
struct a { /* pointed to by EAX / [EBP+8] */
int memb1; /* MOV DWORD PTR DS:[EAX], EDX */
struct b* memb2; /* LEA ECX, DWORD PTR DS:[EAX+4] */
int memb3; /* unused? */
int memb4; /* MOV DWORD PTR DS:[EAX+C],ECX */
};
struct b {
int memb1; /* MOV DWORD PTR DS:[ECX],ECX */
int memb2; /* MOV DWORD PTR DS:[ECX+4],ECX */
};
これがどういうわけか物事をクリアすることを願っています。アセンブリコードのリバースエンジニアリングは、特にアプリケーションで使用される引数のタイプを示すAPI呼び出しがない場合は、非常に困難で時間のかかる作業です。