__declspec(naked)詳細


__declspec(naked)は、コンパイラに関数コードを教えるためのアセンブリ言語であり、コンパイラにアセンブリコードを追加する必要はありません.
注意点:
void __declspec(naked) funname()

{
_asm
{
...
ret
}
}

注意、_declspec(naked)はコンパイラが直接使用するアセンブリ関数コードであるため、開始時にコンテキストフラグビット(スタック)を保存し、終了時にコンテキスト(スタック)を復元することを覚えておく必要があります.最後にretコマンドを追加します
次の2つのコードを比較します:(strcmp関数を呼び出す)
VOID __declspec(naked) MyNakedFunction()
{
strcmp(...);
// __cdecl  , , ,  ADD ESP, 8
}

VOID __declspec(naked) MyNakedFunction()
{
//...
__asm CALL strcmp;
__asm ADD ESP, 8; //  
}


jmpタイプのhookでは、自分のプロセスが使用されていない場合は_declspec(naked)では、システムは自動的に追加のコードを追加し、スタックのバランスを制御しますが、これらの追加のコードはhook関数のスタックを破壊します.callタイプのhookの場合、_declspec(naked)修飾は,スタックバランスを回復することに注意する.使用__declspec(naked)キーワード定義関数:
1,nakedキーワードを使用するにはEBPポインタを自分で構築しなければならない(使用した場合、最後にJMPから元の関数であれば、自分でpush ebp mov ebpの構築を開始し、esp pushad pushfdが最後にpopfd popad mov esp,ebp,pop ebp jmp xxxを追加する).
2、自分でRETまたはRET n命令を使用して返さなければなりません(JMPから元の関数など、返さない限り).一般的なアセンブリ埋め込みコード(_declspec(naked)を使用していない)では、コンテキストを保存する必要はありません.保存しても大丈夫ですが、retコマンドを追加することはできません.コンパイラも1つ追加するので、retコマンドは同時に2回実行できません.境界を越えたエラーを引き起こす
 
発見されたばかりで、naked関数にはint i=0のように現れない.このような付与
nakedを示す関数では、付与値を使用してはいけません.許可されていません.どうしても別の関数で処理したい場合は、処理が完了したら結果を返します.VSを使用すると、次のエラーが表示されます.
 initialized auto or register variable not allowed at function scope in 'naked' function
実は原因もよく説明されています.nakedと親関数はebpを共有しているので、サブローカル変数はespを使います.
naked関数はパラメータを持たないでください.パラメータ付きはnaked関数と書く必要はありません.