実行ファイルデータのアドレスはWin32 APIのGetModuleHandle
関数やWinMain
関数の引数、スタックのアドレスはローカル変数のアドレスとして取得できます。また、関数のアドレスを取得することで関数が実行ファイルデータとして配置されることが推測できます。
// x64環境 #define STRICT #define NOMINMAX #include <Windows.h> int main() { auto base_address = ::GetModuleHandleW(nullptr); // 実行ファイルデータのアドレス auto main_fn_address = &main; // 関数のアドレス auto stack_address1 = &base_address; // スタックのアドレス1 auto stack_address2 = &main_fn_address; // スタックのアドレス2 }
アドレスはメモリ配置設定(ASLR等)に依存しており、また実行の度に変わりますが、一例は以下の通りです。
auto base_address = ::GetModuleHandleW(nullptr); // 0x00007ff622d20000 auto main_fn_address = &main; // 0x00007ff622d3124e auto stack_address1 = &base_address; // 0x0000007e885af8d8 auto stack_address2 = &main_fn_address; // 0x0000007e885af8f8
実行ファイルデータのアドレスinstance_handle
と関数のアドレスmain_fn_address
は差が小さく、メモリ上でまとまって配置されていると推測できます(具体的にはテキスト領域)。また、スタックのアドレスstack_address1
、stack_address2
は実行ファイルデータのアドレス、関数のアドレスとは差が大きく、それらと離れて配置されていると推測できます(具体的にはスタック領域)。
なお、グローバル変数のアドレスもテキスト領域に配置されるため、実行ファイルデータのアドレスおよび関数のアドレスと近い値になります。