Hello,
I'm developing an IDE for multiple programming languages, and have the need to create a .dbg file (using CoClassSymsDbgFile from Mar99hood (http://www.microsoft.com/msj/0399/hood/hood0399.aspx)).
To include only public symbols in my .dbg file, I need only to parse the .map file. To include public and private symbols, I need to 'parse' all .obj files used by the linker. All the info is stored in .map file: 0001:00000570 MyChildMenuDlgProc 00401570 Untitled 5.obj
0001:000007e0 OPENWINDOW 004017e0 ebstd:openwindow.obj
For sections with at least one public symbol I have no problem, because parsing the .map file (linker output) gives me the virtual addres for a symbol, which is converted to section virtual address, used to compute offsets to all non-public symbols in the same section, for currently scanned .obj file.
The problem is, when a section does not have public symbols (mostly .data or .bss). The following command generates all info I need in the relocations table:
link -dump /all program1.obj >program1_dump.txt
RELOCATIONS #1 (section .text)
Symbol Symbol
Offset Type Applied To Index Name
-------- ---------------- ----------------- -------- ------ // struct IMAGE_RELOCATION
000000CD DIR32 000000D0 13 .bss
0000010E DIR32 000000D0 13 .bss
00000160 DIR32 000000D0 13 .bss
COFF SYMBOL TABLE // struct IMAGE_SYMBOL
...
013 00000000 SECT3 notype Static | .bss
...
060 000000D0 SECT3 int Static | hMenu
For a reference I've picked the private hMenu symbol. Here is a question: how to compute 'Applied To' in relocations area? I'm asking, because IMAGE_RELOCATION does not include this field, it has only the offset in section, symbol index and relocation type, and I don't want to execute -dump for each object file.
The 000000D0 value (known as IMAGE_SYMBOL.Value) is referencing my hMenu symbol. Knowing how to compute it, I will be able to compute base (virtual) address of .bss section, then looping all symbols in .bss section I'll get the virtual addresses for all remaining symbols in .obj file.
EDIT: found it, the info I searched for is stored in .text section at offset section.relocation.offset
IDA: .text:000000CC mov eax, offset hMenu ; file offset=158h; first relocation for hMenu
FILE: B8 D0 00 00 00
Another question. Why sometimes the CoClassSymsDbgFile tool puts a huge empty space (zeros) to the .dbg file? Microsoft's debugger engine fails to load symbols if the dbg file has the empty space, only IDA works fine.
Quote from: akane
Another question. Why sometimes the CoClassSymsDbgFile tool puts a huge empty space (zeros) to the .dbg file? Microsoft's debugger engine fails to load symbols if the dbg file has the empty space, only IDA works fine.
I'd guess you'd need to analyse the code, vasts tract of zeros seems like a bug. Microsoft tools aren't usually very robust when handling data that is slightly odd, or corrupt.
-Clive
Edit: attaching a PE/COFF object dump/disassembler.
Clive, I have tried it. Failed when passing path to .dbg, but 'succeeded' with .exe path, displaying all bad informations and crashing at the end.
The command was peobj -sym edit.exe.
I do not have any debugging informations in .obj files, just a collection of symbols from .map, referenced .lib and .obj files, stored in .dbg file.
The exe after linking is modified, IMAGE_FILE_DEBUG_STRIPPED flag is added, IMAGE_DIRECTORY_ENTRY_DEBUG is initialzed to a special symbol with 256 bytes of space for three well known structures, and .dbg file name.
I've attached the test application for a day or two: exampleDbg.zip. You'll find an exe, dbg, the special "symbol" for debug structures - debug.asm, and the CoClassSymsDbgFile code, used in my compiler module.
The .dbg file contain empty space, but is still acceptable by dbgeng.dll.
EDIT: the empty space was generated just at the second linking. The original code was not adapted for multiple executions. To fix it, I just added "g_cbPublicSymbols = sizeof(OMFSymHash)" to the CoClassSymsBeginSymbolCallouts function.
DumpPE would be more appropriate for EXE/DBG files, PEObj is only for .OBJ files. I will look into it, I think I have a more recent build.
-Clive
PEObj edit.obj -disasm -sym >x
Machine 014C (Intel 386)
Sections 0004
Time Date Stamp 4BC355EF Mon Apr 12 12:18:39 2010
Symbol Table 00000380
Number of Symbols 00000018
Optional header size 0000
Characteristics 0000
Section Table
-------------
01 .drectve Virtual Address 00000000
Physical Address 00000000
Raw Data Offset 000000B4
Raw Data Size 00000031
Relocation Offset 00000000
Relocation Count 0000
Line Number Offset 00000000
Line Number Count 0000
Characteristics 00100A00
Comment
Remove
1 Byte Align
02 .debug$S Virtual Address 00000000
Physical Address 00000000
Raw Data Offset 000000E5
Raw Data Size 00000076
Relocation Offset 00000000
Relocation Count 0000
Line Number Offset 00000000
Line Number Count 0000
Characteristics 42100040
Initialized Data
1 Byte Align
Discardable
Readable
0036 - 0009 S_OBJNAME D:\Aurora\projects\aurora ide\Projects\edit.obj
00000000: 36 00 09 00 00 00 00 00 - 2F 44 3A 5C 41 75 72 6F 6......./D:\Auro
00000010: 72 61 5C 70 72 6F 6A 65 - 63 74 73 5C 61 75 72 6F ra\projects\auro
00000020: 72 61 20 69 64 65 5C 50 - 72 6F 6A 65 63 74 73 5C ra ide\Projects\
00000030: 65 64 69 74 2E 6F 62 6A edit.obj
0038 - 1013 S_COMPILE2_VS97
00000000: 38 00 13 10 00 02 00 00 - 07 00 0E 00 00 00 27 C6 8.............'.
00000010: 0E 00 00 00 27 C6 21 4D - 69 63 72 6F 73 6F 66 74 ....'.!Microsoft
00000020: 20 28 52 29 20 4F 70 74 - 69 6D 69 7A 69 6E 67 20 (R) Optimizing
00000030: 43 6F 6D 70 69 6C 65 72 - 00 00 Compiler..
03 .data Virtual Address 00000000
Physical Address 00000000
Raw Data Offset 0000015B
Raw Data Size 00000098
Relocation Offset 00000000
Relocation Count 0000
Line Number Offset 00000000
Line Number Count 0000
Characteristics C0400040
Initialized Data
8 Byte Align
Readable
Writeable
04 .text Virtual Address 00000000
Physical Address 00000000
Raw Data Offset 000001F3
Raw Data Size 00000101
Relocation Offset 000002F4
Relocation Count 000E
Line Number Offset 00000000
Line Number Count 0000
Characteristics 60500020
Code
16 Byte Align
Executable
Readable
00000009 00000008 0006 (DIR32 ) 3.00000000 $SG81556
00000015 00000011 0006 (DIR32 ) 0.00000000 __imp_FindWindowExW
00000025 00000009 0006 (DIR32 ) 3.00000010 $SG81559
0000005D 00000010 0006 (DIR32 ) 0.00000000 __imp_SendMessageW
00000065 0000000F 0006 (DIR32 ) 0.00000000 __imp_Sleep
0000006F 0000000E 0006 (DIR32 ) 0.00000000 __imp_MessageBeep
0000009E 00000017 0006 (DIR32 ) 0.00000000 __imp_RtlZeroMemory
000000BE 0000000A 0006 (DIR32 ) 3.00000080 $SG81570
000000C6 00000016 0006 (DIR32 ) 0.00000000 __imp_CreateProcessW
000000D2 00000015 0006 (DIR32 ) 0.00000000 __imp_WaitForInputIdle
000000D9 0000000D 0006 (DIR32 ) 4.00000000 EnumProc
000000E3 00000014 0006 (DIR32 ) 0.00000000 __imp_EnumThreadWindows
000000ED 00000013 0006 (DIR32 ) 0.00000000 __imp_CloseHandle
000000F7 00000013 0006 (DIR32 ) 0.00000000 __imp_CloseHandle
Symbol Table
0000 : Val 006DC627, Sec FFFFFFFF, Typ 0000, Sto 03, Aux 00 @comp.id
0001 : Val 00000001, Sec FFFFFFFF, Typ 0000, Sto 03, Aux 00 @feat.00
0002 : Val 00000000, Sec 0001, Typ 0000, Sto 03, Aux 01 .drectve
31 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00 1...............
00 00 ..
0004 : Val 00000000, Sec 0002, Typ 0000, Sto 03, Aux 01 .debug$S
76 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00 v...............
00 00 ..
0006 : Val 00000000, Sec 0003, Typ 0000, Sto 03, Aux 01 .data
98 00 00 00 00 00 00 00 - 08 F8 90 99 00 00 00 00 ................
00 00 ..
0008 : Val 00000000, Sec 0003, Typ 0000, Sto 03, Aux 00 $SG81556
0009 : Val 00000010, Sec 0003, Typ 0000, Sto 03, Aux 00 $SG81559
000A : Val 00000080, Sec 0003, Typ 0000, Sto 03, Aux 00 $SG81570
000B : Val 00000000, Sec 0004, Typ 0000, Sto 03, Aux 01 .text
01 01 00 00 0E 00 00 00 - F3 4A 6C 66 00 00 00 00 .........Jlf....
00 00 ..
000D : Val 00000000, Sec 0004, Typ 0020, Sto 02, Aux 00 EnumProc
000E : Val 00000000, Sec 0000, Typ 0000, Sto 02, Aux 00 __imp_MessageBeep
000F : Val 00000000, Sec 0000, Typ 0000, Sto 02, Aux 00 __imp_Sleep
0010 : Val 00000000, Sec 0000, Typ 0000, Sto 02, Aux 00 __imp_SendMessageW
0011 : Val 00000000, Sec 0000, Typ 0000, Sto 02, Aux 00 __imp_FindWindowExW
0012 : Val 00000090, Sec 0004, Typ 0020, Sto 02, Aux 00 main
0013 : Val 00000000, Sec 0000, Typ 0000, Sto 02, Aux 00 __imp_CloseHandle
0014 : Val 00000000, Sec 0000, Typ 0000, Sto 02, Aux 00 __imp_EnumThreadWindows
0015 : Val 00000000, Sec 0000, Typ 0000, Sto 02, Aux 00 __imp_WaitForInputIdle
0016 : Val 00000000, Sec 0000, Typ 0000, Sto 02, Aux 00 __imp_CreateProcessW
0017 : Val 00000000, Sec 0000, Typ 0000, Sto 02, Aux 00 __imp_RtlZeroMemory
Disassembly
00000040 $SG81556: ; Xref 000000E8
00000040 65006400690074000000 dw 'edit',000h
0000004A 00 00 00 00 00 00 ......
00000050 $SG81559: ; Xref 00000102
00000050 480057004E0044002000.. dw 'HWND hwndEdit = FindWindowEx(hwnd, 0, TEXT("edit"), 0);',000h
000000C0 $SG81570: ; Xref 0000019D
000000C0 6E006F00740065007000.. dw 'notepad.exe',000h
000000E0 EnumProc: ; Xref 000001B8
000000E0 55 push ebp
000000E1 8BEC mov ebp,esp
000000E3 83EC0C sub esp,0Ch
000000E6 6A00 push 0
000000E8 6840000000 push offset $SG81556 ; 'edit',000h
000000ED 6A00 push 0
000000EF 8B4508 mov eax,[ebp+8]
000000F2 50 push eax
000000F3 FF150000FFEF call dword ptr [__imp_FindWindowExW]
000000F9 8945FC mov [ebp-4],eax
000000FC 837DFC00 cmp dword ptr [ebp-4],0
00000100 7451 jz loc_00000153
00000102 C745F850000000 mov dword ptr [ebp-8],offset $SG81559 ; 'HWND hwndEdit = FindWindowEx(hwnd, 0, TEXT("edit"), 0);',000h
00000109 loc_00000109: ; Xref 00000149
00000109 8B4DF8 mov ecx,[ebp-8]
0000010C 0FB711 movzx edx,word ptr [ecx]
0000010F 85D2 test edx,edx
00000111 7438 jz loc_0000014B
00000113 8B45F8 mov eax,[ebp-8]
00000116 668B08 mov cx,[eax]
00000119 66894DF4 mov [ebp-0Ch],cx
0000011D 8B55F8 mov edx,[ebp-8]
00000120 83C202 add edx,2
00000123 8955F8 mov [ebp-8],edx
00000126 66C745F60000 mov word ptr [ebp-0Ah],0
0000012C 8D45F4 lea eax,[ebp-0Ch]
0000012F 50 push eax
00000130 6A01 push 1
00000132 68C2000000 push 0C2h
00000137 8B4DFC mov ecx,[ebp-4]
0000013A 51 push ecx
0000013B FF150000FEEF call dword ptr [__imp_SendMessageW]
00000141 6A64 push 64h
00000143 FF150000FDEF call dword ptr [__imp_Sleep]
00000149 EBBE jmp loc_00000109
0000014B loc_0000014B: ; Xref 00000111
0000014B 6A40 push 40h
0000014D FF150000FCEF call dword ptr [__imp_MessageBeep]
00000153 loc_00000153: ; Xref 00000100
00000153 33C0 xor eax,eax
00000155 837DFC00 cmp dword ptr [ebp-4],0
00000159 0F94C0 sete al
0000015C 8BE5 mov esp,ebp
0000015E 5D pop ebp
0000015F C20800 ret 8
00000162 CCCCCCCCCCCCCCCCCCCC.. db 14 dup (0CCh)
00000170 main:
00000170 55 push ebp
00000171 8BEC mov ebp,esp
00000173 83EC58 sub esp,58h
00000176 6A44 push 44h
00000178 8D45A8 lea eax,[ebp-58h]
0000017B 50 push eax
0000017C FF150000FBEF call dword ptr [__imp_RtlZeroMemory]
00000182 C745A844000000 mov dword ptr [ebp-58h],44h
00000189 8D4DF0 lea ecx,[ebp-10h]
0000018C 51 push ecx
0000018D 8D55A8 lea edx,[ebp-58h]
00000190 52 push edx
00000191 6A00 push 0
00000193 6A00 push 0
00000195 6A00 push 0
00000197 6A00 push 0
00000199 6A00 push 0
0000019B 6A00 push 0
0000019D 68C0000000 push offset $SG81570 ; 'notepad.exe',000h
000001A2 6A00 push 0
000001A4 FF150000FAEF call dword ptr [__imp_CreateProcessW]
000001AA 6AFF push 0FFFFFFFFh
000001AC 8B45F0 mov eax,[ebp-10h]
000001AF 50 push eax
000001B0 FF150000F9EF call dword ptr [__imp_WaitForInputIdle]
000001B6 6A00 push 0
000001B8 68E0000000 push offset EnumProc
000001BD 8B4DFC mov ecx,[ebp-4]
000001C0 51 push ecx
000001C1 FF150000F8EF call dword ptr [__imp_EnumThreadWindows]
000001C7 8B55F0 mov edx,[ebp-10h]
000001CA 52 push edx
000001CB FF150000F7EF call dword ptr [__imp_CloseHandle]
000001D1 8B45F4 mov eax,[ebp-0Ch]
000001D4 50 push eax
000001D5 FF150000F7EF call dword ptr [__imp_CloseHandle]
000001DB 33C0 xor eax,eax
000001DD 8BE5 mov esp,ebp
000001DF 5D pop ebp
000001E0 C3 ret