I have been scouring the web trying to find an answer to this question, but it seems to be eluding me. I have consulting the following sources before asking this question.
http://www.csn.ul.ie/~caolan/publink/winresdump/winresdump/doc/pefile.html
http://msdn.microsoft.com/en-us/magazine/cc301805.aspx
I understand the PE format (or at least I think I do). Using the command-line debugger (cdb), I would like to be able to disassemble the address where the RVA is to see what the first call is. For a native application (like Notepad), I would expect to see notepad!WinMainCRTStartup, and for a .NET application, I would expect to see a jmp command to the CLR.
Using Notepad as an example, I executed dumpbin /headers on it, and got a value of 3570 for the entry point. When I execute cdb notepad and perform this command - u [base address in memory]+0x3570 - I do not get the WinMainCRTStartup call.
Am I misinterpreting the PE output from dumpbin? How can I know exactly where to look in memory for the starting function of an application?
Edit (1/7/13): I forgot to mention that I am running this on 64-bit Windows 7. If I try to use cdb in Windows XP Mode (to get results from a 32-bit OS), disassembling the AddressOfEntryPoint that I get from an analysis of the PE file gets me the call to WinMainCRTStartup as I would expect. In other words, the exact address I am told to look at contains what I think it should in a 32-bit OS. Does running the application on a 64-bit machine truly make that much of a difference?
Just to add complexity, if I do a !dh on the ImageBaseAddress in the 64-bit OS in cdb, I get the EXACT AddressOfEntryPoint that I need to use.
Use the Microsoft Symbol Server to obtain symbol debugging information. http://support.microsoft.com/kb/311503/en-us
0:001> !dh -a notepad
....
3689 address of entry point
...
00ac0000 image base
...
0:001> u ac3689
notepad!WinMainCRTStartup:
Edit: add dumpbin output (entry point the same offset, image base may be different because ASLR works when image loads in memory):
Microsoft (R) COFF/PE Dumper Version 11.00.50727.1
Copyright (C) Microsoft Corporation. All rights reserved.
Dump of file c:\windows\notepad.exe
PE signature found
File Type: EXECUTABLE IMAGE
FILE HEADER VALUES
14C machine (x86)
4 number of sections
4A5BC60F time date stamp Tue Jul 14 03:41:03 2009
0 file pointer to symbol table
0 number of symbols
E0 size of optional header
102 characteristics
Executable
32 bit word machine
OPTIONAL HEADER VALUES
10B magic # (PE32)
9.00 linker version
A800 size of code
22400 size of initialized data
0 size of uninitialized data
3689 entry point (01003689) _WinMainCRTStartup
Edit 2 add output for x64
dumpbin:
Microsoft (R) COFF/PE Dumper Version 10.00.30319.01
Copyright (C) Microsoft Corporation. All rights reserved.
Dump of file c:\windows\notepad.exe
PE signature found
File Type: EXECUTABLE IMAGE
FILE HEADER VALUES
8664 machine (x64)
6 number of sections
4A5BC9B3 time date stamp Tue Jul 14 03:56:35 2009
0 file pointer to symbol table
0 number of symbols
F0 size of optional header
22 characteristics
Executable
Application can handle large (>2GB) addresses
OPTIONAL HEADER VALUES
20B magic # (PE32+)
9.00 linker version
A800 size of code
25800 size of initialized data
0 size of uninitialized data
3570 entry point (0000000100003570) WinMainCRTStartup
windbg:
0:000> !dh -a notepad
File Type: EXECUTABLE IMAGE
FILE HEADER VALUES
8664 machine (X64)
...
1000 base of code
----- new -----
00000000ff0c0000 image base
...
0:000> u ff0c0000+3570
notepad!WinMainCRTStartup:
Related
I'm building zlib from source using Visual Studio 2012. Note, I didn't tag zlib here simply because I don't think the question is specific to any given project.
The build succeeds but when I use dumpbin /EXPORTS the output looks like this:
C:\Source\zlib>dumpbin /EXPORTS ./zlib1.dll
Microsoft (R) COFF/PE Dumper Version 11.00.61232.400
Copyright (C) Microsoft Corporation. All rights reserved.
Dump of file ./zlib1.dll
File Type: DLL
Section contains the following exports for zlib1.dll
00000000 characteristics
5DD6A00D time date stamp Thu Nov 21 08:32:45 2019
0.00 version
1 ordinal base
165 number of functions
119 number of names
ordinal hint RVA name
1 1 00001000 adler32
140 2 00001340 adler32_combine
2 3 00001410 compress
39 4 00001360 compress2
46 5 00001430 compressBound
However, when I examine a version someone else built (using VC6 - not sure if that matters), the output looks like:
C:\Source\zlib-1.2.7-win32>dumpbin /EXPORTS ./zlib1.dll
Microsoft (R) COFF/PE Dumper Version 11.00.61232.400
Copyright (C) Microsoft Corporation. All rights reserved.
Dump of file ./zlib1.dll
File Type: DLL
Section contains the following exports for zlib1.dll
00000000 characteristics
509EFCCB time date stamp Sat Nov 10 19:18:03 2012
0.00 version
1 ordinal base
76 number of functions
76 number of names
ordinal hint RVA name
1 0 00001000 adler32 = _adler32
2 1 00001270 adler32_combine = _adler32_combine
3 2 00001340 adler32_combine64 = _adler32_combine64
4 3 00001400 compress = _compress
5 4 00001360 compress2 = _compress2
6 5 00001420 compressBound = _compressBound
I'm having problems finding the visual studio setting that changes this output type. Next I tried just changing the .def file from
LIBRARY
; zlib data compression and ZIP file I/O library
VERSION 1.2
EXPORTS
adler32 #1
to
LIBRARY
; zlib data compression and ZIP file I/O library
VERSION 1.2
EXPORTS
_adler32=adler32 #1
But that appears to simply rename the export so instead of getting:
ordinal hint RVA name
1 0 00001000 adler32 = _adler32
I get:
ordinal hint RVA name
1 0 00001000 _adler32
and if you switch them around in the .def file, the project doesn't build/link correctly(makes sense).
So is there a setting in newer (than VC6) versions of VS that give /EXPORTS in the format somefunc=_somefunc?
According to this answer (C++ DLL Export: Decorated/Mangled names), they must have used Generate Debug Info = Yes
I have a few Windows 7 machines that I am not able to read their memory dumps. I found something that I suspect may be related, but am not positive:
https://twitter.com/aionescu/status/634028737458114560
I also found this: http://support.microsoft.com/kb/2528507
However, the scenario message regarding wow64exts given in the doc is not seen in any of my dumps. I also cannot apply that hotfix at this time to test it. So I'm just looking for some more information or opinions.
I'm able to open any other OS dump as well as my own system's Windows 7 dump, but there are 2 other machines that run Win 7 and it's telling me I have the wrong kernel symbols.
I have tried clearing out my symbol cache, reinstalled the Windows SDK, and also tried to open the dumps on two other machines with the same result. If it matters, the crash is manually created using the scroll lock method.
Symbol path: SRV*c:\symbols*http://msdl.microsoft.com/download/symbols;
Seeing these errors: followed by "Type referenced: nt!_KPRCB"
Does anyone know about the issue mentioned by Alex in the twitter link and if it's possibly related to what I'm seeing?
Update 2015-10-22:
With the Microsoft patch day (2015-10-13) and KB3088195, symbols are available again.
However, symbols for the broken version have not been provided, so below may still be useful.
Microsoft has already published "good" symbols for ntdll in the past, containing type information like _TEB or _KPRCB. Starting from mid of July 2015, Microsoft has still published symbols for ntdll, but not containing that information.
So it depends on the version of ntdll whether you get type information or not. Old dumps referencing an old version of ntdll will download old PDBs containing type information while new dumps reference new versions of ntdll and WinDbg (or any other debugger) downloads PDBs without type information.
Could Microsoft remove type information of "good" symbols retroactively, thus making them "bad"?
Yes. As described in this answer, there is a tool to remove type information from existing PDBs. Doing that and replacing the PDB would result in such an effect.
Can Microsoft publish the "good" version of those PDBs which are currently "bad"?
That's hard to tell, since we don't know whether Microsoft has kept a copy of the "good" version so they could replace the "bad" version on the symbol server with the "good" one. Rebuilding ntdll from the same source code and thus creating new PDBs sounds possible, but the PDB gets a new time stamp and checksum. This can potentially be corrected manually, especially be Microsoft, since they should have the knowledge about the PDB internal format, but IMHO it's unlikely they'll do that. Things may go wrong and MS will hardly have tests to guarantee the correctness of such a thing.
So what can I do?
IMHO you can do nothing to really correct the situation.
You could assume that the types in ntdll have not changed so much. This would allow you to take an older version of wntdll.pdb and the new version of ntdll.dll and apply ChkMatch -m to it. This will copy the timestamp and checksum from the DLL to the PDB. After you did that (in an empty folder), replace the existing wntdll.pdb in your symbols directory with the hacked one.
WinDbg walkthrough (with output shortened to relevant things). I am using the latest version of wntdll.pdb I could find on my PC.
WARNING: doing the following may fix the type information but will likely destroy the correctness of the callstacks. Since any changes in the implementation (which are likely for security fixes) will change the method offsets.
0:005> dt nt!_PEB
*************************************************************************
*** ***
*** Either you specified an unqualified symbol, or your debugger ***
...
*** Type referenced: nt!_PEB ***
*** ***
*************************************************************************
Symbol nt!_PEB not found.
0:005> lm m ntdll
start end module name
773f0000 77570000 ntdll (pdb symbols) e:\debug\symbols\wntdll.pdb\FA9C48F9C11D4E0894B8970DECD92C972\wntdll.pdb
0:005> .shell cmd /c copy C:\Windows\SysWOW64\ntdll.dll e:\debug\temp\ntdllhack\ntdll.dll
1 file(s) copied.
0:005> .shell cmd /c copy "E:\Windows SDk\8.0\Debuggers\x86\sym\wntdll.pdb\B081677DFC724CC4AC53992627BEEA242\wntdll.pdb" e:\debug\temp\ntdllhack\wntdll.pdb
1 file(s) copied.
0:005> .shell cmd /c E:\debug\temp\ntdllhack\chkmatch.exe -m E:\debug\temp\ntdllhack\ntdll.dll E:\debug\temp\ntdllhack\wntdll.pdb
...
Executable: E:\debug\temp\ntdllhack\ntdll.dll
Debug info file: E:\debug\temp\ntdllhack\wntdll.pdb
Executable:
TimeDateStamp: 55a69e20
Debug info: 2 ( CodeView )
TimeStamp: 55a68c18 Characteristics: 0 MajorVer: 0 MinorVer: 0
Size: 35 RVA: 000e63e0 FileOffset: 000d67e0
CodeView format: RSDS
Signature: {fa9c48f9-c11d-4e08-94b8-970decd92c97} Age: 2
PdbFile: wntdll.pdb
Debug info: 10 ( Unknown )
TimeStamp: 55a68c18 Characteristics: 0 MajorVer: 565 MinorVer: 6526
Size: 4 RVA: 000e63dc FileOffset: 000d67dc
Debug information file:
Format: PDB 7.00
Signature: {b081677d-fc72-4cc4-ac53-992627beea24} Age: 4
Writing to the debug information file...
Result: Success.
0:005> .shell cmd /c copy E:\debug\temp\ntdllhack\wntdll.pdb E:\debug\symbols\wntdll.pdb\FA9C48F9C11D4E0894B8970DECD92C972\wntdll.pdb
1 file(s) copied.
0:005> .reload
Reloading current modules
.............................
0:005> dt nt!_PEB
ntdll!_PEB
+0x000 InheritedAddressSpace : UChar
+0x001 ReadImageFileExecOptions : UChar
...
0:005> !heap -s
LFH Key : 0x219ab08b
Termination on corruption : DISABLED
Heap Flags Reserv Commit Virt Free List UCR Virt Lock Fast
(k) (k) (k) (k) length blocks cont. heap
-----------------------------------------------------------------------------
Virtual block: 00920000 - 00920000 (size 00000000)
Virtual block: 02c60000 - 02c60000 (size 00000000)
Virtual block: 02e10000 - 02e10000 (size 00000000)
...
Note: using ChkMatch like this has the benefit that you do not need to turn on .symopt- 100, since that option would affect all PDB files, and you would not find potential other symbol issues. If you don't mind using .symopt, you could simply copy an old wntdll.PDB over the new one.
The issue is now fixed according to Microsoft and Microsoft told me that you should clear your symbol cache to get the new PDBs, otherwise Windbg would use the old Symbols which miss the information.
Is it possible to examine a dll, not installed in the registry, to see if it an ActiveX, the public methods, if it supports COM, etc. Is there some other tool with which to analyze a dll?
That's a very generic question, but you can analyze a dll's exported methods and ASM code using some decompiler/debugger like OllyDbg. Of course you need to have a good understanding of ASM and Windows inner workings.
http://www.ollydbg.de/version2.html
if you have Visual Studio and just want to know if the dll contains a COM component, you can open the visual studio command prompt, and use:
dumpbin /exports filename.dll
to show the dll's exported functions. If the dll exports DllGetClassObject, DllRegisterServer and DllUnregisterServer, it contains a COM component.
Example:
C:\Program Files (x86)\Microsoft Visual Studio 10.0\VC>dumpbin /exports c:\windows\system32\quartz.dll
Microsoft (R) COFF/PE Dumper Version 10.00.40219.01
Copyright (C) Microsoft Corporation. All rights reserved.
Dump of file c:\windows\system32\quartz.dll
File Type: DLL
Section contains the following exports for QUARTZ.dll
00000000 characteristics
5215E909 time date stamp Thu Aug 22 12:33:45 2013
0.00 version
1 ordinal base
8 number of functions
8 number of names
ordinal hint RVA name
1 0 0003B34C AMGetErrorTextA
2 1 0003B41C AMGetErrorTextW
3 2 0003B2C8 AmpFactorToDB
4 3 0003B314 DBToAmpFactor
5 4 00002848 DllCanUnloadNow
6 5 000032E0 DllGetClassObject
7 6 0003AFA0 DllRegisterServer
8 7 0003B2A0 DllUnregisterServer
Summary
36000 .data
4000 .idata
F000 .pdata
4000 .reloc
B000 .rsrc
157000 .text
1000 RT_CODE
here is what I'm trying to solve. I have a crash dump from Google Chrome.
I open windbg and say File -> Symbol File Path:
"SRV*c:\code\symbols*http://msdl.microsoft.com/download/symbols;SRV*c:\code\symbols*https://chromium-browser-symsrv.commondatastorage.googleapis.com"
I guess this looks for the debugging symbols from let to right and should finally grab them from google then. I copied that from http://www.chromium.org/developers/how-tos/debugging.
I drag and drop the crash dump into windbg
And then...
Microsoft (R) Windows Debugger Version 6.2.8400.0 AMD64
Copyright (c) Microsoft Corporation. All rights reserved.
Loading Dump File [C:\Users\cburgdorf\Desktop\Chrome-last.dmp]
User Mini Dump File: Only registers, stack and portions of memory are available
Symbol search path is: SRV*c:\code\symbols*http://msdl.microsoft.com/download/symbols;SRV*c:\code\symbols*https://chromium-browser-symsrv.commondatastorage.googleapis.com
Executable search path is:
Windows 7 Version 7601 (Service Pack 1) MP (8 procs) Free x86 compatible
Product: WinNt, suite: SingleUserTS
Machine Name:
Debug session time: Wed May 16 16:25:24.000 2012 (UTC + 2:00)
System Uptime: not available
Process Uptime: 0 days 0:01:39.000
.........................................
This dump file has a breakpoint exception stored in it.
The stored exception information can be accessed via .ecxr.
eax=00000000 ebx=0038e1f8 ecx=00000001 edx=0012df58 esi=00000002 edi=0038e218
eip=776e013d esp=0038e1a8 ebp=0038e244 iopl=0 nv up ei pl zr na pe nc
cs=0023 ss=002b ds=002b es=002b fs=0053 gs=002b efl=00200246
ntdll!NtWaitForMultipleObjects+0x15:
776e013d 83c404 add esp,4
0:000> .excr
^ Syntax error in '.excr'
You see that it says "The stored exception information can be accessed via .ecxr" but once I insert that it tells me that I have a syntax error.
Does anyone know what I'm doing wrong?
You've got a typo, it's .ecxr :) In the meantime, another easy way to get information out of a crash dump without needing too much WinDbg-fu, is:
.symfix; .reload
!analyze -v
And if this is a .NET App (Chromium isn't but just for extra info), add these three lines
.loadby sos clr
!pe
~*e !clrstack
Does anyone know whether the 'import address table' in the PE executable format on Windows is 'per dll' or 'per exe'?
Any PE can have an import address table, so both DLLs and EXEs can have them. This makes sense since both can have dependencies (imports) on other binaries. Unless you're doing dynamic loading (LoadLibrary/GetProcAddress), you'll have an import address table when calling into another module.
You can use the dumpbin utility with Visual Studio to see the imports of a PE:
An example on user32.dll:
C:\Windows\System32> dumpbin /imports
user32.dll
Microsoft (R) COFF/PE
Dumper Version 10.00.30319.01
Copyright (C) Microsoft Corporation.
All rights reserved.
Dump of file user32.dll
File Type: DLL
Section contains the following
imports:
ntdll.dll
7DC60000 Import Address Table
7DCCACEC Import Name Table
0 time date stamp
0 Index of first forwarder reference
15A NtOpenKey
7A9 wcscat_s
7AD wcscpy_s
...
...and for notepad.exe...
C:\Windows\System32> dumpbin /imports
notepad.exe
Microsoft (R) COFF/PE
Dumper Version 10.00.30319.01
Copyright (C) Microsoft Corporation.
All rights reserved.
Dump of file notepad.exe
File Type: EXECUTABLE IMAGE
Section contains the following
imports:
ADVAPI32.dll
1001000 Import Address Table
100A234 Import Name Table
FFFFFFFF time date stamp
FFFFFFFF Index of first forwarder reference
77C71C82 27E RegSetValueExW
77C7BCD5 26E RegQueryValueExW
77C7BED4 230 RegCloseKey
...
Short answer:
IAT(Import Address Table) is per PE file(dll and exe).
Long answer:
When the loader load exe file its copy each section of the PE to the process memory, unless IMAGE_SCN_MEM_DISCARDABLE is set for this sections. The IAT is in the .idata section (msdn):
The PE file's .idata section contains the information necessary for the loader to determine the addresses of the target functions and patch them into the executable image. The .idata section (or import table, as I prefer to call it) ...
IMAGE_SCN_MEM_DISCARDABLE is not set for idata section. Therefore- idata section copied to memory, and both exe and dll have this section- meaning IAT is per PE.
I wrote a simple dll loader here, if it help you understand.