以下默认windbg加载calc程序
dds、dps和dqs命令显示给定范围内存的内容,它们是把内存区域转储出来,并把内存中每个元素都视为一个符号对其进行解析,dds是四字节视为一个符号,dqs是每8字节视为一个符号,dps是根据当前处理器架构来选择最合适的长度
比如要看看当前stack 中保存了哪些函数地址,就可以检查ebp 指向的内存
0:000> dds ebp 0007fdfc 0007ff1c 0007fe00 010021b0 calc!WinMain+0x25f 0007fe04 0007fee8 0007fe08 00000000 0007fe0c 00000000 0007fe10 00000000 0007fe14 7c80b741 kernel32!GetModuleHandleA 0007fe18 000a232f 0007fe1c 00000000
由于 COM Interface 和C++ Vtable 里面的成员函数都是顺序排列的,所以这个命令可以方便 地找到虚函数表中具体的函数地址。比如用下面的命令可以找到OpaqueDataInfo 类型中虚 函数对应的实际函数地址:
0:002> x ole32!OpaqueData* 76aa6a41 ole32!OpaqueDataInfo::GetOpaqueData = <no type information> 76aa6b3b ole32!OpaqueDataInfo::UnSerialize = <no type information> 76aa6c16 ole32!OpaqueDataInfo::SerializableQueryInterface = <no type information> 76aa5748 ole32!OpaqueDataInfo::QueryInterface = <no type information> 76aa6393 ole32!OpaqueDataInfo::CopyOpaqueData = <no type information> 76aa5757 ole32!OpaqueDataInfo::AddRef = <no type information> 76a57107 ole32!OpaqueDataInfo::UnSerializeCallBack = <no type information> 76aa5766 ole32!OpaqueDataInfo::Release = <no type information> 769a697c ole32!OpaqueDataInfo::`vftable' = <no type information> 76aa69cb ole32!OpaqueDataInfo::AddOpaqueData = <no type information> 769bfae2 ole32!OpaqueDataInfo::GetOpaqueDataCount = <no type information> 76aa6b24 ole32!OpaqueDataInfo::Serialize = <no type information> 769c9df3 ole32!OpaqueDataInfo::AddRef = <no type information> 769c9ebc ole32!OpaqueDataInfo::Release = <no type information> 76aa6a97 ole32!OpaqueDataInfo::DeleteOpaqueData = <no type information> 76aa6bc9 ole32!OpaqueDataInfo::GetCLSID = <no type information> 76aa57c0 ole32!OpaqueDataInfo::OpaqueDataInfo = <no type information> 769c1cb0 ole32!OpaqueDataInfo::GetAllOpaqueData = <no type information> 76aa54b9 ole32!OpaqueDataInfo::~OpaqueDataInfo = <no type information> 76aa6be9 ole32!OpaqueDataInfo::SetParent = <no type information> 76aa5693 ole32!OpaqueDataInfo::`scalar deleting destructor' = <no type information> 76aa6b78 ole32!OpaqueDataInfo::GetSize = <no type information> 76aa6540 ole32!OpaqueDataInfo::QueryInterface = <no type information> 769a69a0 ole32!OpaqueDataInfo::`vftable' = <no type information> 0:002> dds 769a69a0 769a69a0 76aa6540 ole32!OpaqueDataInfo::QueryInterface 769a69a4 769c9df3 ole32!InstanceInfo::AddRef 769a69a8 769c9ebc ole32!InstantiationInfo::Release 769a69ac 76aa69cb ole32!OpaqueDataInfo::AddOpaqueData 769a69b0 76aa6a41 ole32!OpaqueDataInfo::GetOpaqueData 769a69b4 76aa6a97 ole32!OpaqueDataInfo::DeleteOpaqueData 769a69b8 769bfae2 ole32!ServerLocationInfo::GetRemoteServerName 769a69bc 769c1cb0 ole32!CComProcessInfo::GetProcessName 769a69c0 76a57107 ole32!InstanceInfo::UnSerializeCallBack 769a69c4 00000021 769a69c8 76a2d73d ole32!CClassMoniker::QueryInterface 769a69cc 76a339fb ole32!CErrorObject::AddRef 769a69d0 76a0679a ole32!CClassMoniker::Release 769a69d4 76a06a39 ole32!CClassMoniker::GetUnmarshalClass 769a69d8 76a06a56 ole32!CClassMoniker::GetMarshalSizeMax 769a69dc 76a06a99 ole32!CClassMoniker::MarshalInterface 769a69e0 76a2d2b9 ole32!CClassMoniker::UnmarshalInterface 769a69e4 76a07099 ole32!CClassMoniker::ReleaseMarshalData 769a69e8 769e288e ole32!CDdeObject::COleItemContainerImpl::IsRunning 769a69ec 76a2d72e ole32!CClassMoniker::QueryInterface 769a69f0 76a339dd ole32!CErrorObject::AddRef 769a69f4 76a06ab8 ole32!CClassMoniker::Release 769a69f8 76a069d1 ole32!CClassMoniker::GetComparisonData 769a69fc 90909090 769a6a00 76a066c9 ole32!CClassMoniker::QueryInterface 769a6a04 76a05efd ole32!CSCMergedEnum<IEnumCATEGORYINFO,tagCATEGORYINFO>::AddRef 769a6a08 76a067a6 ole32!CClassMoniker::Release 769a6a0c 76a068f3 ole32!CClassMoniker::GetClassID 769a6a10 769acee9 ole32!CDdeServerCallMgr::AddRef 769a6a14 76a2d7f2 ole32!CClassMoniker::Load 769a6a18 76a06931 ole32!CClassMoniker::Save 769a6a1c 76a07055 ole32!CClassMoniker::GetSizeMax
start end module name 01230000 0124b000 test1 C (private pdb symbols)
0:001> dt IMAGE_DOS_HEADER 01230000 test1!IMAGE_DOS_HEADER +0x000 e_magic : 0x5a4d +0x002 e_cblp : 0x90 +0x004 e_cp : 3 +0x006 e_crlc : 0 +0x008 e_cparhdr : 4 +0x00a e_minalloc : 0 +0x00c e_maxalloc : 0xffff +0x00e e_ss : 0 +0x010 e_sp : 0xb8 +0x012 e_csum : 0 +0x014 e_ip : 0 +0x016 e_cs : 0 +0x018 e_lfarlc : 0x40 +0x01a e_ovno : 0 +0x01c e_res : [4] 0 +0x024 e_oemid : 0 +0x026 e_oeminfo : 0 +0x028 e_res2 : [10] 0 +0x03c e_lfanew : 224来确认下这个是PE文件:
0:001> da 01230000 +0 01230000 "MZ."2.nt头
0:001> da 01230000 +0n224 012300e0 "PE" 0:001> dt IMAGE_NT_HEADERS 01230000 +0n224 test1!IMAGE_NT_HEADERS +0x000 Signature : 0x4550 +0x004 FileHeader : _IMAGE_FILE_HEADER +0x018 OptionalHeader : _IMAGE_OPTIONAL_HEADER3.文件头
0:001> dt IMAGE_FILE_HEADER 01230000 +0n224+0x4 test1!IMAGE_FILE_HEADER +0x000 Machine : 0x14c +0x002 NumberOfSections : 7 +0x004 TimeDateStamp : 0x55cae429 +0x008 PointerToSymbolTable : 0 +0x00c NumberOfSymbols : 0 +0x010 SizeOfOptionalHeader : 0xe0 +0x012 Characteristics : 0x102由Characteristics : 0x102可以得出这是个 #define IMAGE_FILE_EXECUTABLE_IMAGE 0x0002 // 文件可执行 #define IMAGE_FILE_32BIT_MACHINE 0x0100 // 32位机器
0:001> dt _IMAGE_OPTIONAL_HEADER 01230000 +0n224+0x18 test1!_IMAGE_OPTIONAL_HEADER +0x000 Magic : 0x10b +0x002 MajorLinkerVersion : 0x9 '' +0x003 MinorLinkerVersion : 0 '' +0x004 SizeOfCode : 0x3600 +0x008 SizeOfInitializedData : 0x4200 +0x00c SizeOfUninitializedData : 0 +0x010 AddressOfEntryPoint : 0x1107d +0x014 BaseOfCode : 0x1000 +0x018 BaseOfData : 0x1000 +0x01c ImageBase : 0x1230000 +0x020 SectionAlignment : 0x1000 +0x024 FileAlignment : 0x200 +0x028 MajorOperatingSystemVersion : 5 +0x02a MinorOperatingSystemVersion : 0 +0x02c MajorImageVersion : 0 +0x02e MinorImageVersion : 0 +0x030 MajorSubsystemVersion : 5 +0x032 MinorSubsystemVersion : 0 +0x034 Win32VersionValue : 0 +0x038 SizeOfImage : 0x1b000 +0x03c SizeOfHeaders : 0x400 +0x040 CheckSum : 0 +0x044 Subsystem : 3 +0x046 DllCharacteristics : 0x8140 +0x048 SizeOfStackReserve : 0x100000 +0x04c SizeOfStackCommit : 0x1000 +0x050 SizeOfHeapReserve : 0x100000 +0x054 SizeOfHeapCommit : 0x1000 +0x058 LoaderFlags : 0 +0x05c NumberOfRvaAndSizes : 0x10 +0x060 DataDirectory : [16] _IMAGE_DATA_DIRECTORY
0:001> ?? sizeof(IMAGE_NT_HEADERS) unsigned int 0xf8 0:001> ? 01230000 +0n224 + 0xf8 Evaluate expression: 19071448 = 012301d8这是起始地址
0:001> dt *!*IMAGE_SECTION* test1!IMAGE_SECTION_HEADER test1!PIMAGE_SECTION_HEADER test1!_IMAGE_SECTION_HEADER test1!_IMAGE_SECTION_HEADER test1!_IMAGE_SECTION_HEADER::<unnamed-type-Misc> MSVCR90D!IMAGE_SECTION_HEADER MSVCR90D!PIMAGE_SECTION_HEADER MSVCR90D!_IMAGE_SECTION_HEADER
0:001> dt IMAGE_SECTION_HEADER 012301d8 test1!IMAGE_SECTION_HEADER +0x000 Name : [8] ".textbss" +0x008 Misc : _IMAGE_SECTION_HEADER::<unnamed-type-Misc> +0x00c VirtualAddress : 0x1000 +0x010 SizeOfRawData : 0 +0x014 PointerToRawData : 0 +0x018 PointerToRelocations : 0 +0x01c PointerToLinenumbers : 0 +0x020 NumberOfRelocations : 0 +0x022 NumberOfLinenumbers : 0 +0x024 Characteristics : 0xe00000a0 0:001> ?? sizeof(IMAGE_SECTION_HEADER) unsigned int 0x28 0:001> dt IMAGE_SECTION_HEADER 012301d8+0x28 test1!IMAGE_SECTION_HEADER +0x000 Name : [8] ".text" +0x008 Misc : _IMAGE_SECTION_HEADER::<unnamed-type-Misc> +0x00c VirtualAddress : 0x11000 +0x010 SizeOfRawData : 0x3600 +0x014 PointerToRawData : 0x400 +0x018 PointerToRelocations : 0 +0x01c PointerToLinenumbers : 0 +0x020 NumberOfRelocations : 0 +0x022 NumberOfLinenumbers : 0 +0x024 Characteristics : 0x60000020 0:001> dt IMAGE_SECTION_HEADER 012301d8+0x28*2 test1!IMAGE_SECTION_HEADER +0x000 Name : [8] ".rdata" +0x008 Misc : _IMAGE_SECTION_HEADER::<unnamed-type-Misc> +0x00c VirtualAddress : 0x15000 +0x010 SizeOfRawData : 0x1e00 +0x014 PointerToRawData : 0x3a00 +0x018 PointerToRelocations : 0 +0x01c PointerToLinenumbers : 0 +0x020 NumberOfRelocations : 0 +0x022 NumberOfLinenumbers : 0 +0x024 Characteristics : 0x40000040 0:001> dt IMAGE_SECTION_HEADER 012301d8+0x28*3 test1!IMAGE_SECTION_HEADER +0x000 Name : [8] ".data" +0x008 Misc : _IMAGE_SECTION_HEADER::<unnamed-type-Misc> +0x00c VirtualAddress : 0x17000 +0x010 SizeOfRawData : 0x200 +0x014 PointerToRawData : 0x5800 +0x018 PointerToRelocations : 0 +0x01c PointerToLinenumbers : 0 +0x020 NumberOfRelocations : 0 +0x022 NumberOfLinenumbers : 0 +0x024 Characteristics : 0xc0000040 0:001> dt IMAGE_SECTION_HEADER 012301d8+0x28*4 test1!IMAGE_SECTION_HEADER +0x000 Name : [8] ".idata" +0x008 Misc : _IMAGE_SECTION_HEADER::<unnamed-type-Misc> +0x00c VirtualAddress : 0x18000 +0x010 SizeOfRawData : 0xa00 +0x014 PointerToRawData : 0x5a00 +0x018 PointerToRelocations : 0 +0x01c PointerToLinenumbers : 0 +0x020 NumberOfRelocations : 0 +0x022 NumberOfLinenumbers : 0 +0x024 Characteristics : 0xc0000040 0:001> dt IMAGE_SECTION_HEADER 012301d8+0x28*5 test1!IMAGE_SECTION_HEADER +0x000 Name : [8] ".rsrc" +0x008 Misc : _IMAGE_SECTION_HEADER::<unnamed-type-Misc> +0x00c VirtualAddress : 0x19000 +0x010 SizeOfRawData : 0xe00 +0x014 PointerToRawData : 0x6400 +0x018 PointerToRelocations : 0 +0x01c PointerToLinenumbers : 0 +0x020 NumberOfRelocations : 0 +0x022 NumberOfLinenumbers : 0 +0x024 Characteristics : 0x40000040 0:001> dt IMAGE_SECTION_HEADER 012301d8+0x28*6 test1!IMAGE_SECTION_HEADER +0x000 Name : [8] ".reloc" +0x008 Misc : _IMAGE_SECTION_HEADER::<unnamed-type-Misc> +0x00c VirtualAddress : 0x1a000 +0x010 SizeOfRawData : 0x600 +0x014 PointerToRawData : 0x7200 +0x018 PointerToRelocations : 0 +0x01c PointerToLinenumbers : 0 +0x020 NumberOfRelocations : 0 +0x022 NumberOfLinenumbers : 0 +0x024 Characteristics : 0x42000040 0:001> dt IMAGE_SECTION_HEADER 012301d8+0x28*7 test1!IMAGE_SECTION_HEADER +0x000 Name : [8] "" +0x008 Misc : _IMAGE_SECTION_HEADER::<unnamed-type-Misc> +0x00c VirtualAddress : 0 +0x010 SizeOfRawData : 0 +0x014 PointerToRawData : 0 +0x018 PointerToRelocations : 0 +0x01c PointerToLinenumbers : 0 +0x020 NumberOfRelocations : 0 +0x022 NumberOfLinenumbers : 0 +0x024 Characteristics : 0
0:001> dt _IMAGE_OPTIONAL_HEADER 01230000 +0n224+0x18 test1!_IMAGE_OPTIONAL_HEADER +0x058 LoaderFlags : 0 +0x05c NumberOfRvaAndSizes : 0x10 +0x060 DataDirectory : [16] _IMAGE_DATA_DIRECTORY 0:001> ?? sizeof(_IMAGE_DATA_DIRECTORY) unsigned int 8 0:001> dt _IMAGE_DATA_DIRECTORY 01230000 +0n224+0x18+0x68 test1!_IMAGE_DATA_DIRECTORY +0x000 VirtualAddress : 0x18000 +0x004 Size : 0x3c发现IMAGE_IMPORT_DESCRIPTOR dt不到
typedef struct _IMAGE_IMPORT_DESCRIPTOR { union { DWORD Characteristics; // 0 for terminating null import descriptor DWORD OriginalFirstThunk; // RVA to original unbound IAT (PIMAGE_THUNK_DATA) }; DWORD TimeDateStamp; // 0 if not bound, // -1 if bound, and real date\time stamp // in IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT (new BIND) // O.W. date/time stamp of DLL bound to (Old BIND) DWORD ForwarderChain; // -1 if no forwarders DWORD Name; DWORD FirstThunk; // RVA to IAT (if bound this IAT has actual addresses) } IMAGE_IMPORT_DESCRIPTOR;大小明显是20,那么我们用dd来划分吧:
0:001> dd 01230000 +0x18000 L5 01248000 0001803c 00000000 00000000 00018324 01248010 000181a8 0:001> da 00018324+01230000 01248324 "KERNEL32.dll" 0:001> dd 01230000 +0x18000+0n20 L5 01248014 000180e8 00000000 00000000 00018346 01248024 00018254 0:001> da 00018346+01230000 01248346 "MSVCR90D.dll" 0:001> dd 01230000 +0x18000+0n20*2 L5 01248028 00000000 00000000 00000000 00000000 01248038 00000000Name为0表示没有其他导入表了
0:001> dds 0x181a8+0x1230000 012481a8 76b63485 kernel32!CreateThread 012481ac 76b617e9 kernel32!GetCurrentProcess 012481b0 76b7d7d2 kernel32!TerminateProcess 012481b4 76b63478 kernel32!FreeLibrary 012481b8 76b64412 kernel32!VirtualQuery 012481bc 76b64908 kernel32!GetModuleFileNameW 012481c0 76b614c9 kernel32!GetProcessHeap 012481c4 77dfe046 ntdll!RtlAllocateHeap 012481c8 76b614a9 kernel32!HeapFree 012481cc 76b634b9 kernel32!GetSystemTimeAsFileTime 012481d0 76b611f8 kernel32!GetCurrentProcessId 012481d4 76b61430 kernel32!GetCurrentThreadId 012481d8 76b6110c kernel32!GetTickCount 012481dc 76b61705 kernel32!QueryPerformanceCounter 012481e0 76b68781 kernel32!SetUnhandledExceptionFilter 012481e4 76b6498f kernel32!LoadLibraryA 012481e8 76b61222 kernel32!GetProcAddress 012481ec 76b65a03 kernel32!lstrlen 012481f0 76b6190e kernel32!MultiByteToWideChar 012481f4 76b616ed kernel32!WideCharToMultiByte 012481f8 76be4755 kernel32!DebugBreak 012481fc 76b6585e kernel32!RaiseException 01248200 76b64a15 kernel32!IsDebuggerPresent 01248204 76b61464 kernel32!InterlockedCompareExchange 01248208 76b610ff kernel32!Sleep 0124820c 76b61442 kernel32!InterlockedExchange 01248210 76b876f7 kernel32!UnhandledExceptionFilter 01248214 00000000
0:001> dds 00018254+0x1230000 01248254 6a4df8d0 MSVCR90D!__dllonexit [f:\dd\vctools\crt_bld\self_x86\crt\src\onexit.c @ 267] 01248258 6a44d430 MSVCR90D!_lock [f:\dd\vctools\crt_bld\self_x86\crt\src\mlock.c @ 333] 0124825c 6a44d480 MSVCR90D!_unlock [f:\dd\vctools\crt_bld\self_x86\crt\src\mlock.c @ 371] 01248260 6a44e170 MSVCR90D!_decode_pointer [f:\dd\vctools\crt_bld\self_x86\crt\src\tidtable.c @ 161] 01248264 6a4eca80 MSVCR90D!_except_handler4_common 01248268 6a4ec880 MSVCR90D!_crt_debugger_hook [f:\dd\vctools\crt_bld\self_x86\crt\src\dbghook.c @ 62] 0124826c 6a4df460 MSVCR90D!_invoke_watson [f:\dd\vctools\crt_bld\self_x86\crt\src\invarg.c @ 137] 01248270 6a4fbc20 MSVCR90D!_controlfp_s 01248274 6a4c0280 MSVCR90D!terminate [f:\dd\vctools\crt_bld\self_x86\crt\prebuild\eh\hooks.cpp @ 95] 01248278 6a44c040 MSVCR90D!_initterm_e [f:\dd\vctools\crt_bld\self_x86\crt\src\crt0dat.c @ 938] 0124827c 6a44c010 MSVCR90D!_initterm [f:\dd\vctools\crt_bld\self_x86\crt\src\crt0dat.c @ 889] 01248280 6a4de7b0 MSVCR90D!_CrtDbgReportW [f:\dd\vctools\crt_bld\self_x86\crt\src\dbgrpt.c @ 252] 01248284 6a4e3010 MSVCR90D!_CrtSetCheckCount [f:\dd\vctools\crt_bld\self_x86\crt\src\dbgheap.c @ 3241] 01248288 6a525768 MSVCR90D!__winitenv 0124828c 6a44b9d0 MSVCR90D!exit [f:\dd\vctools\crt_bld\self_x86\crt\src\crt0dat.c @ 411] 01248290 6a44ba10 MSVCR90D!_cexit [f:\dd\vctools\crt_bld\self_x86\crt\src\crt0dat.c @ 426] 01248294 6a4e32e0 MSVCR90D!_XcptFilter [f:\dd\vctools\crt_bld\self_x86\crt\src\winxfltr.c @ 206] 01248298 6a44b9f0 MSVCR90D!_exit [f:\dd\vctools\crt_bld\self_x86\crt\src\crt0dat.c @ 419] 0124829c 6a44c600 MSVCR90D!__wgetmainargs [f:\dd\vctools\crt_bld\self_x86\crt\src\crtlib.c @ 98] 012482a0 6a44ba50 MSVCR90D!_amsg_exit [f:\dd\vctools\crt_bld\self_x86\crt\src\crt0dat.c @ 460] 012482a4 6a44ad60 MSVCR90D!__set_app_type [f:\dd\vctools\crt_bld\self_x86\crt\src\errmode.c @ 87] 012482a8 6a44e070 MSVCR90D!_encode_pointer [f:\dd\vctools\crt_bld\self_x86\crt\src\tidtable.c @ 86] 012482ac 6a44cf90 MSVCR90D!__p__fmode [f:\dd\vctools\crt_bld\self_x86\crt\src\crtlib.c @ 748] 012482b0 6a44cef0 MSVCR90D!__p__commode [f:\dd\vctools\crt_bld\self_x86\crt\src\crtlib.c @ 714] 012482b4 6a5266cc MSVCR90D!_adjust_fdiv 012482b8 6a44ada0 MSVCR90D!__setusermatherr 012482bc 6a4e6d80 MSVCR90D!_configthreadlocale [f:\dd\vctools\crt_bld\self_x86\crt\src\setlocal.c @ 420] 012482c0 6a4eb420 MSVCR90D!_CRT_RTC_INITW 012482c4 6a462450 MSVCR90D!getchar [f:\dd\vctools\crt_bld\self_x86\crt\src\fgetchar.c @ 45] 012482c8 6a46abb0 MSVCR90D!printf [f:\dd\vctools\crt_bld\self_x86\crt\src\printf.c @ 49] 012482cc 6a4df660 MSVCR90D!_onexit [f:\dd\vctools\crt_bld\self_x86\crt\src\onexit.c @ 85] 012482d0 6a4cd680 MSVCR90D!operator new [f:\dd\vctools\crt_bld\self_x86\crt\src\new.cpp @ 57]
OriginalFirstThunk来查找,先找到列表:1803c为Kernel32项第一个DWORD
typedef struct _IMAGE_THUNK_DATA32 { union { DWORD ForwarderString; // PBYTE 指向一个转向者字符串的RVA DWORD Function; // PDWORD被输入函数的内存地址 DWORD Ordinal; // 被输入的API序数号 DWORD AddressOfData; // PIMAGE_IMPORT_BY_NAME } u1; } IMAGE_THUNK_DATA32;这个函数同样在我的exe上没有找到,但很明显,这是一个4字节的数组
0:001> dd 0x1803c+0x1230000 0124803c 00018314 000186e4 000186d0 000186c2 0124804c 000186b2 0001869c 0001868a 0001867e 0124805c 00018672 00018658 00018642 0001862c 0124806c 0001861c 00018602 000185e4 000185d4 0124807c 000185c2 000185b6 000185a0 0001858a 0124808c 0001857c 0001856a 00018556 00018538 0124809c 00018530 0001851a 000186f8 00000000 012480ac 00000000 00000000 00000000 00000000
typedef struct _IMAGE_IMPORT_BY_NAME { WORD Hint; BYTE Name[1]; } IMAGE_IMPORT_BY_NAME, *PIMAGE_IMPORT_BY_NAME;所以有:
0:001> da 00018314+0x1230000+2 01248316 "CreateThread" 0:001> da 000186e4+0x1230000+2 012486e6 "GetCurrentProcess" ............................................................