WinXP SP3 で、実際にEXEやDLLがロードされたアドレスがどうなっているか: アドレス値は左から順にMEMORY_BASIC_INFORMATIONの BaseAddress, RegionSize, AllocationBase ... # ここからexe本体 # PE Header 0x00400000, 0x00001000, 0x00400000 commit,ReadOnly # ".text" 0x00401000, 0x00009000, 0x00400000 commit,ExecutableReadOnly # ".rdata" 0x0040a000, 0x00002000, 0x00400000 commit,ReadOnly " ".data" 0x0040c000, 0x00003000, 0x00400000 commit,ReadWrite # ここまでexe本体 0x0040f000, 0x7c3f1000, 0x00000000 free,Hidden # ここからkernel32.dll # PE Header 0x7c800000, 0x00001000, 0x7c800000 commit,ReadOnly # ".text" 0x7c801000, 0x00084000, 0x7c800000 commit,ExecutableReadOnly # ".data" 0x7c885000, 0x00003000, 0x7c800000 commit,ReadWrite 0x7c888000, 0x00002000, 0x7c800000 commit,CopyOnWrite # ".rsrc" + ".reloc" 0x7c88a000, 0x000a9000, 0x7c800000 commit,ReadOnly 0x7c933000, 0x0000d000, 0x00000000 free,Hidden ... という具合に、モジュール毎に"AllocationBase"が一緒。つまり、VirtualAlloc()した後に、各セクション領域に応じてVirtualProtect()で保護モードを変更したのと同じ状態になっているようだ。 #more|| 以下サンプルコード, va02.cpp: #code|c|> #include #include void PrintErrorMsg(DWORD err) { LPTSTR lpMsgBuf; FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, NULL, err, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPTSTR)&lpMsgBuf, 0, NULL); printf("%s\n", lpMsgBuf); LocalFree(lpMsgBuf); } void VirtualWalk(void) { unsigned char *p = (unsigned char*)0x0; MEMORY_BASIC_INFORMATION mbi; printf("Address, Size(bytes), AllocationBase, Status, Access Limit\n"); printf("--------------------------------------------\n"); while (1) { if (VirtualQuery(p, &mbi, sizeof(mbi))) { printf("0x%08lx, 0x%08lx, 0x%08lx ", mbi.BaseAddress, mbi.RegionSize, mbi.AllocationBase ); switch (mbi.State) { case MEM_COMMIT: printf("commit,"); break; case MEM_RESERVE: printf("reserve,"); break; case MEM_FREE: printf("free,"); break; default: printf(","); } switch (mbi.Protect) { case PAGE_NOACCESS: printf("Hidden"); break; case PAGE_READONLY: printf("ReadOnly"); break; case PAGE_READWRITE: printf("ReadWrite"); break; case PAGE_WRITECOPY: printf("CopyOnWrite"); break; case PAGE_EXECUTE: printf("Executable"); break; case PAGE_EXECUTE_READ: printf("ExecutableReadOnly"); break; case PAGE_EXECUTE_READWRITE: printf("ExecutableReadWrite"); break; case PAGE_EXECUTE_WRITECOPY: printf("ExecutableCopyOnWrite"); break; default: break; } printf("\n"); p = (unsigned char*)mbi.BaseAddress + mbi.RegionSize; if (p == 0) { break; } } else { printf("%0x%08lx -- Access Denied\n", p); break; } } printf("--------------------------------------------\n\n"); } int main(void) { VirtualWalk(); return 0; } ||<