├── .gitignore
├── Callback.h
├── DIA2Dump.vcxproj
├── DIA2Dump.vcxproj.filters
├── DIA_SDK
├── bin
│ ├── amd64
│ │ └── msdia140.dll
│ ├── arm
│ │ └── msdia140.dll
│ └── msdia140.dll
├── idl
│ ├── Dia2Lib.dll
│ ├── dia2.h
│ ├── dia2.idl
│ ├── dia2.tlb
│ ├── dia2_i.c
│ ├── dia2_p.c
│ ├── dlldata.c
│ └── gen.cmd
├── include
│ ├── cvconst.h
│ ├── dia2.h
│ └── diacreate.h
└── lib
│ ├── amd64
│ └── diaguids.lib
│ ├── arm
│ └── diaguids.lib
│ └── diaguids.lib
├── PrintSymbol.cpp
├── PrintSymbol.h
├── README.md
├── dia2dump.cpp
├── dia2dump.h
├── regs.cpp
├── regs.h
├── stdafx.cpp
├── stdafx.h
├── x_common.h
├── x_cpp_enum.h
├── x_cpp_gen_file.h
├── x_cpp_proxy.h
├── x_meta.h
├── x_names.h
├── x_print.h
├── x_ripper.cpp
├── x_str.h
└── x_udt.h
/.gitignore:
--------------------------------------------------------------------------------
1 | _bin/
2 | _obj/
3 |
4 | .vs/
5 |
6 | *.sln
7 | *.suo
8 | *.sdf
9 | *.opensdf
10 | *.db
11 | *.opendb
12 | *.exe
13 | *.pdb
14 |
--------------------------------------------------------------------------------
/Callback.h:
--------------------------------------------------------------------------------
1 | #include "dia2.h"
2 |
3 | #pragma warning ( disable : 4100)
4 |
5 | class CCallback : public IDiaLoadCallback2{
6 | int m_nRefCount;
7 | public:
8 | CCallback() { m_nRefCount = 0; }
9 |
10 | //IUnknown
11 | ULONG STDMETHODCALLTYPE AddRef() {
12 | m_nRefCount++;
13 | return m_nRefCount;
14 | }
15 | ULONG STDMETHODCALLTYPE Release() {
16 | if ( (--m_nRefCount) == 0 )
17 | delete this;
18 | return m_nRefCount;
19 | }
20 | HRESULT STDMETHODCALLTYPE QueryInterface( REFIID rid, void **ppUnk ) {
21 | if ( ppUnk == NULL ) {
22 | return E_INVALIDARG;
23 | }
24 | if (rid == __uuidof( IDiaLoadCallback2 ) )
25 | *ppUnk = (IDiaLoadCallback2 *)this;
26 | else if (rid == __uuidof( IDiaLoadCallback ) )
27 | *ppUnk = (IDiaLoadCallback *)this;
28 | else if (rid == __uuidof( IUnknown ) )
29 | *ppUnk = (IUnknown *)this;
30 | else
31 | *ppUnk = NULL;
32 | if ( *ppUnk != NULL ) {
33 | AddRef();
34 | return S_OK;
35 | }
36 | return E_NOINTERFACE;
37 | }
38 |
39 | HRESULT STDMETHODCALLTYPE NotifyDebugDir(
40 | BOOL fExecutable,
41 | DWORD cbData,
42 | BYTE data[]) // really a const struct _IMAGE_DEBUG_DIRECTORY *
43 | {
44 | return S_OK;
45 | }
46 | HRESULT STDMETHODCALLTYPE NotifyOpenDBG(
47 | LPCOLESTR dbgPath,
48 | HRESULT resultCode)
49 | {
50 | // wprintf(L"opening %s...\n", dbgPath);
51 | return S_OK;
52 | }
53 |
54 | HRESULT STDMETHODCALLTYPE NotifyOpenPDB(
55 | LPCOLESTR pdbPath,
56 | HRESULT resultCode)
57 | {
58 | // wprintf(L"opening %s...\n", pdbPath);
59 | return S_OK;
60 | }
61 | HRESULT STDMETHODCALLTYPE RestrictRegistryAccess()
62 | {
63 | // return hr != S_OK to prevent querying the registry for symbol search paths
64 | return S_OK;
65 | }
66 | HRESULT STDMETHODCALLTYPE RestrictSymbolServerAccess()
67 | {
68 | // return hr != S_OK to prevent accessing a symbol server
69 | return S_OK;
70 | }
71 | HRESULT STDMETHODCALLTYPE RestrictOriginalPathAccess()
72 | {
73 | // return hr != S_OK to prevent querying the registry for symbol search paths
74 | return S_OK;
75 | }
76 | HRESULT STDMETHODCALLTYPE RestrictReferencePathAccess()
77 | {
78 | // return hr != S_OK to prevent accessing a symbol server
79 | return S_OK;
80 | }
81 | HRESULT STDMETHODCALLTYPE RestrictDBGAccess()
82 | {
83 | return S_OK;
84 | }
85 | HRESULT STDMETHODCALLTYPE RestrictSystemRootAccess()
86 | {
87 | return S_OK;
88 | }
89 | };
90 |
91 | #pragma warning ( default : 4100 )
92 |
--------------------------------------------------------------------------------
/DIA2Dump.vcxproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Debug
6 | x64
7 |
8 |
9 | Release
10 | x64
11 |
12 |
13 |
14 | {785BAA40-99C8-491E-B95B-A7EA0A8ABC78}
15 | Dia2Dump
16 | 10.0
17 |
18 |
19 |
20 | Application
21 | true
22 | v120
23 | Unicode
24 |
25 |
26 | Application
27 | false
28 | v120
29 | true
30 | Unicode
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 | $(VSInstallDir)\DIA SDK\include;$(IncludePath)
44 | $(VSInstallDir)\DIA SDK\lib;$(LibraryPath)
45 | $(SolutionDir)_bin\$(Platform)\$(Configuration)\
46 | $(SolutionDir)_obj\$(Platform)\$(Configuration)\
47 |
48 |
49 | $(VSInstallDir)\DIA SDK\include;$(IncludePath)
50 | $(VSInstallDir)\DIA SDK\lib;$(LibraryPath)
51 | $(SolutionDir)_bin\$(Platform)\$(Configuration)\
52 | $(SolutionDir)_obj\$(Platform)\$(Configuration)\
53 |
54 |
55 |
56 | Level3
57 | Disabled
58 | Use
59 | ProgramDatabase
60 | DIA_SDK\include\;%(AdditionalIncludeDirectories)
61 | false
62 | true
63 |
64 |
65 | true
66 | 10485760
67 | DIA_SDK\lib\amd64\;%(AdditionalLibraryDirectories)
68 |
69 |
70 |
71 |
72 | Level3
73 | MaxSpeed
74 | true
75 | false
76 | Use
77 | DIA_SDK\include\;%(AdditionalIncludeDirectories)
78 | ProgramDatabase
79 | AnySuitable
80 | MultiThreaded
81 | false
82 | true
83 |
84 |
85 | true
86 | true
87 | true
88 | DIA_SDK\lib\amd64\;%(AdditionalLibraryDirectories)
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
103 |
104 |
105 |
106 |
107 |
108 |
109 |
110 |
111 |
112 |
113 | Create
114 | Create
115 |
116 |
117 |
118 |
119 |
120 |
--------------------------------------------------------------------------------
/DIA2Dump.vcxproj.filters:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF}
6 | cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx
7 |
8 |
9 | {93995380-89BD-4b04-88EB-625FBE52EBFB}
10 | h;hpp;hxx;hm;inl;inc;xsd
11 |
12 |
13 | {67DA6AB6-F800-4c08-8B7A-83BB121AAD01}
14 | rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms
15 |
16 |
17 | {a117e75c-50ec-46bd-ae1e-4097d2f0f7ae}
18 |
19 |
20 |
21 |
22 | Header Files
23 |
24 |
25 | Header Files
26 |
27 |
28 | Header Files
29 |
30 |
31 | Header Files
32 |
33 |
34 | Header Files
35 |
36 |
37 | _custom
38 |
39 |
40 | _custom
41 |
42 |
43 | _custom
44 |
45 |
46 | _custom
47 |
48 |
49 | _custom
50 |
51 |
52 | _custom
53 |
54 |
55 | _custom
56 |
57 |
58 | _custom
59 |
60 |
61 | _custom
62 |
63 |
64 |
65 |
66 | Source Files
67 |
68 |
69 | Source Files
70 |
71 |
72 | Source Files
73 |
74 |
75 | Source Files
76 |
77 |
78 | _custom
79 |
80 |
81 |
--------------------------------------------------------------------------------
/DIA_SDK/bin/amd64/msdia140.dll:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wongfei/pdb-ripper/051982b24704cca88981cd0a5a12a37fc1506af0/DIA_SDK/bin/amd64/msdia140.dll
--------------------------------------------------------------------------------
/DIA_SDK/bin/arm/msdia140.dll:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wongfei/pdb-ripper/051982b24704cca88981cd0a5a12a37fc1506af0/DIA_SDK/bin/arm/msdia140.dll
--------------------------------------------------------------------------------
/DIA_SDK/bin/msdia140.dll:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wongfei/pdb-ripper/051982b24704cca88981cd0a5a12a37fc1506af0/DIA_SDK/bin/msdia140.dll
--------------------------------------------------------------------------------
/DIA_SDK/idl/Dia2Lib.dll:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wongfei/pdb-ripper/051982b24704cca88981cd0a5a12a37fc1506af0/DIA_SDK/idl/Dia2Lib.dll
--------------------------------------------------------------------------------
/DIA_SDK/idl/dia2.tlb:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wongfei/pdb-ripper/051982b24704cca88981cd0a5a12a37fc1506af0/DIA_SDK/idl/dia2.tlb
--------------------------------------------------------------------------------
/DIA_SDK/idl/dia2_i.c:
--------------------------------------------------------------------------------
1 |
2 |
3 | /* this ALWAYS GENERATED file contains the IIDs and CLSIDs */
4 |
5 | /* link this file in with the server and any clients */
6 |
7 |
8 | /* File created by MIDL compiler version 8.01.0622 */
9 | /* at Tue Jan 19 05:14:07 2038
10 | */
11 | /* Compiler settings for C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\\DIA SDK\idl\dia2.idl:
12 | Oicf, W1, Zp8, env=Win32 (32b run), target_arch=X86 8.01.0622
13 | protocol : dce , ms_ext, c_ext, robust
14 | error checks: allocation ref bounds_check enum stub_data
15 | VC __declspec() decoration level:
16 | __declspec(uuid()), __declspec(selectany), __declspec(novtable)
17 | DECLSPEC_UUID(), MIDL_INTERFACE()
18 | */
19 | /* @@MIDL_FILE_HEADING( ) */
20 |
21 | #pragma warning( disable: 4049 ) /* more than 64k source lines */
22 |
23 |
24 | #ifdef __cplusplus
25 | extern "C"{
26 | #endif
27 |
28 |
29 | #include
30 | #include
31 |
32 | #ifdef _MIDL_USE_GUIDDEF_
33 |
34 | #ifndef INITGUID
35 | #define INITGUID
36 | #include
37 | #undef INITGUID
38 | #else
39 | #include
40 | #endif
41 |
42 | #define MIDL_DEFINE_GUID(type,name,l,w1,w2,b1,b2,b3,b4,b5,b6,b7,b8) \
43 | DEFINE_GUID(name,l,w1,w2,b1,b2,b3,b4,b5,b6,b7,b8)
44 |
45 | #else // !_MIDL_USE_GUIDDEF_
46 |
47 | #ifndef __IID_DEFINED__
48 | #define __IID_DEFINED__
49 |
50 | typedef struct _IID
51 | {
52 | unsigned long x;
53 | unsigned short s1;
54 | unsigned short s2;
55 | unsigned char c[8];
56 | } IID;
57 |
58 | #endif // __IID_DEFINED__
59 |
60 | #ifndef CLSID_DEFINED
61 | #define CLSID_DEFINED
62 | typedef IID CLSID;
63 | #endif // CLSID_DEFINED
64 |
65 | #define MIDL_DEFINE_GUID(type,name,l,w1,w2,b1,b2,b3,b4,b5,b6,b7,b8) \
66 | EXTERN_C __declspec(selectany) const type name = {l,w1,w2,{b1,b2,b3,b4,b5,b6,b7,b8}}
67 |
68 | #endif // !_MIDL_USE_GUIDDEF_
69 |
70 | MIDL_DEFINE_GUID(IID, IID_IDiaLoadCallback,0xC32ADB82,0x73F4,0x421b,0x95,0xD5,0xA4,0x70,0x6E,0xDF,0x5D,0xBE);
71 |
72 |
73 | MIDL_DEFINE_GUID(IID, IID_IDiaLoadCallback2,0x4688a074,0x5a4d,0x4486,0xae,0xa8,0x7b,0x90,0x71,0x1d,0x9f,0x7c);
74 |
75 |
76 | MIDL_DEFINE_GUID(IID, IID_IDiaReadExeAtOffsetCallback,0x587A461C,0xB80B,0x4f54,0x91,0x94,0x50,0x32,0x58,0x9A,0x63,0x19);
77 |
78 |
79 | MIDL_DEFINE_GUID(IID, IID_IDiaReadExeAtRVACallback,0x8E3F80CA,0x7517,0x432a,0xBA,0x07,0x28,0x51,0x34,0xAA,0xEA,0x8E);
80 |
81 |
82 | MIDL_DEFINE_GUID(IID, IID_IDiaDataSource,0x79F1BB5F,0xB66E,0x48e5,0xB6,0xA9,0x15,0x45,0xC3,0x23,0xCA,0x3D);
83 |
84 |
85 | MIDL_DEFINE_GUID(IID, IID_IDiaEnumSymbols,0xCAB72C48,0x443B,0x48f5,0x9B,0x0B,0x42,0xF0,0x82,0x0A,0xB2,0x9A);
86 |
87 |
88 | MIDL_DEFINE_GUID(IID, IID_IDiaEnumSymbolsByAddr,0x624B7D9C,0x24EA,0x4421,0x9D,0x06,0x3B,0x57,0x74,0x71,0xC1,0xFA);
89 |
90 |
91 | MIDL_DEFINE_GUID(IID, IID_IDiaEnumSourceFiles,0x10F3DBD9,0x664F,0x4469,0xB8,0x08,0x94,0x71,0xC7,0xA5,0x05,0x38);
92 |
93 |
94 | MIDL_DEFINE_GUID(IID, IID_IDiaEnumInputAssemblyFiles,0x1C7FF653,0x51F7,0x457E,0x84,0x19,0xB2,0x0F,0x57,0xEF,0x7E,0x4D);
95 |
96 |
97 | MIDL_DEFINE_GUID(IID, IID_IDiaEnumLineNumbers,0xFE30E878,0x54AC,0x44f1,0x81,0xBA,0x39,0xDE,0x94,0x0F,0x60,0x52);
98 |
99 |
100 | MIDL_DEFINE_GUID(IID, IID_IDiaEnumInjectedSources,0xD5612573,0x6925,0x4468,0x88,0x83,0x98,0xCD,0xEC,0x8C,0x38,0x4A);
101 |
102 |
103 | MIDL_DEFINE_GUID(IID, IID_IDiaEnumSegments,0xE8368CA9,0x01D1,0x419d,0xAC,0x0C,0xE3,0x12,0x35,0xDB,0xDA,0x9F);
104 |
105 |
106 | MIDL_DEFINE_GUID(IID, IID_IDiaEnumSectionContribs,0x1994DEB2,0x2C82,0x4b1d,0xA5,0x7F,0xAF,0xF4,0x24,0xD5,0x4A,0x68);
107 |
108 |
109 | MIDL_DEFINE_GUID(IID, IID_IDiaEnumFrameData,0x9FC77A4B,0x3C1C,0x44ed,0xA7,0x98,0x6C,0x1D,0xEE,0xA5,0x3E,0x1F);
110 |
111 |
112 | MIDL_DEFINE_GUID(IID, IID_IDiaEnumDebugStreamData,0x486943E8,0xD187,0x4a6b,0xA3,0xC4,0x29,0x12,0x59,0xFF,0xF6,0x0D);
113 |
114 |
115 | MIDL_DEFINE_GUID(IID, IID_IDiaEnumDebugStreams,0x08CBB41E,0x47A6,0x4f87,0x92,0xF1,0x1C,0x9C,0x87,0xCE,0xD0,0x44);
116 |
117 |
118 | MIDL_DEFINE_GUID(IID, IID_IDiaAddressMap,0xB62A2E7A,0x067A,0x4ea3,0xB5,0x98,0x04,0xC0,0x97,0x17,0x50,0x2C);
119 |
120 |
121 | MIDL_DEFINE_GUID(IID, IID_IDiaSession,0x2F609EE1,0xD1C8,0x4E24,0x82,0x88,0x33,0x26,0xBA,0xDC,0xD2,0x11);
122 |
123 |
124 | MIDL_DEFINE_GUID(IID, IID_IDiaSymbol,0xcb787b2f,0xbd6c,0x4635,0xba,0x52,0x93,0x31,0x26,0xbd,0x2d,0xcd);
125 |
126 |
127 | MIDL_DEFINE_GUID(IID, IID_IDiaSymbol2,0x611e86cd,0xb7d1,0x4546,0x8a,0x15,0x07,0x0e,0x2b,0x07,0xa4,0x27);
128 |
129 |
130 | MIDL_DEFINE_GUID(IID, IID_IDiaSymbol3,0x99b665f7,0xc1b2,0x49d3,0x89,0xb2,0xa3,0x84,0x36,0x1a,0xca,0xb5);
131 |
132 |
133 | MIDL_DEFINE_GUID(IID, IID_IDiaSymbol4,0xbf6c88a7,0xe9d6,0x4346,0x99,0xa1,0xd0,0x53,0xde,0x5a,0x78,0x08);
134 |
135 |
136 | MIDL_DEFINE_GUID(IID, IID_IDiaSymbol5,0xabe2de00,0xdc2d,0x4793,0xaf,0x9a,0xef,0x1d,0x90,0x83,0x26,0x44);
137 |
138 |
139 | MIDL_DEFINE_GUID(IID, IID_IDiaSymbol6,0x8133dad3,0x75fe,0x4234,0xac,0x7e,0xf8,0xe7,0xa1,0xd3,0xcb,0xb3);
140 |
141 |
142 | MIDL_DEFINE_GUID(IID, IID_IDiaSymbol7,0x64ce6cd5,0x7315,0x4328,0x86,0xd6,0x10,0xe3,0x03,0xe0,0x10,0xb4);
143 |
144 |
145 | MIDL_DEFINE_GUID(IID, IID_IDiaSymbol8,0x7f2e041f,0x1294,0x41bd,0xb8,0x3a,0xe7,0x15,0x97,0x2d,0x2c,0xe3);
146 |
147 |
148 | MIDL_DEFINE_GUID(IID, IID_IDiaSourceFile,0xA2EF5353,0xF5A8,0x4eb3,0x90,0xD2,0xCB,0x52,0x6A,0xCB,0x3C,0xDD);
149 |
150 |
151 | MIDL_DEFINE_GUID(IID, IID_IDiaInputAssemblyFile,0x3BFE56B0,0x390C,0x4863,0x94,0x30,0x1F,0x3D,0x08,0x3B,0x76,0x84);
152 |
153 |
154 | MIDL_DEFINE_GUID(IID, IID_IDiaLineNumber,0xB388EB14,0xBE4D,0x421d,0xA8,0xA1,0x6C,0xF7,0xAB,0x05,0x70,0x86);
155 |
156 |
157 | MIDL_DEFINE_GUID(IID, IID_IDiaSectionContrib,0x0CF4B60E,0x35B1,0x4c6c,0xBD,0xD8,0x85,0x4B,0x9C,0x8E,0x38,0x57);
158 |
159 |
160 | MIDL_DEFINE_GUID(IID, IID_IDiaSegment,0x0775B784,0xC75B,0x4449,0x84,0x8B,0xB7,0xBD,0x31,0x59,0x54,0x5B);
161 |
162 |
163 | MIDL_DEFINE_GUID(IID, IID_IDiaInjectedSource,0xAE605CDC,0x8105,0x4a23,0xB7,0x10,0x32,0x59,0xF1,0xE2,0x61,0x12);
164 |
165 |
166 | MIDL_DEFINE_GUID(IID, IID_IDiaStackWalkFrame,0x07C590C1,0x438D,0x4F47,0xBD,0xCD,0x43,0x97,0xBC,0x81,0xAD,0x75);
167 |
168 |
169 | MIDL_DEFINE_GUID(IID, IID_IDiaFrameData,0xA39184B7,0x6A36,0x42de,0x8E,0xEC,0x7D,0xF9,0xF3,0xF5,0x9F,0x33);
170 |
171 |
172 | MIDL_DEFINE_GUID(IID, IID_IDiaImageData,0xC8E40ED2,0xA1D9,0x4221,0x86,0x92,0x3C,0xE6,0x61,0x18,0x4B,0x44);
173 |
174 |
175 | MIDL_DEFINE_GUID(IID, IID_IDiaTable,0x4A59FB77,0xABAC,0x469b,0xA3,0x0B,0x9E,0xCC,0x85,0xBF,0xEF,0x14);
176 |
177 |
178 | MIDL_DEFINE_GUID(IID, IID_IDiaEnumTables,0xC65C2B0A,0x1150,0x4d7a,0xAF,0xCC,0xE0,0x5B,0xF3,0xDE,0xE8,0x1E);
179 |
180 |
181 | MIDL_DEFINE_GUID(IID, LIBID_Dia2Lib,0x106173A0,0x0173,0x4e5c,0x84,0xE7,0xE9,0x15,0x42,0x2B,0xE9,0x97);
182 |
183 |
184 | MIDL_DEFINE_GUID(CLSID, CLSID_DiaSource,0xe6756135,0x1e65,0x4d17,0x85,0x76,0x61,0x07,0x61,0x39,0x8c,0x3c);
185 |
186 |
187 | MIDL_DEFINE_GUID(CLSID, CLSID_DiaSourceAlt,0x91904831,0x49ca,0x4766,0xb9,0x5c,0x25,0x39,0x7e,0x2d,0xd6,0xdc);
188 |
189 |
190 | MIDL_DEFINE_GUID(CLSID, CLSID_DiaStackWalker,0xce4a85db,0x5768,0x475b,0xa4,0xe1,0xc0,0xbc,0xa2,0x11,0x2a,0x6b);
191 |
192 |
193 | MIDL_DEFINE_GUID(IID, IID_IDiaPropertyStorage,0x9d416f9c,0xe184,0x45b2,0xa4,0xf0,0xce,0x51,0x7f,0x71,0x9e,0x9b);
194 |
195 |
196 | MIDL_DEFINE_GUID(IID, IID_IDiaStackFrame,0x5edbc96d,0xcdd6,0x4792,0xaf,0xbe,0xcc,0x89,0x00,0x7d,0x96,0x10);
197 |
198 |
199 | MIDL_DEFINE_GUID(IID, IID_IDiaEnumStackFrames,0xec9d461d,0xce74,0x4711,0xa0,0x20,0x7d,0x8f,0x9a,0x1d,0xd2,0x55);
200 |
201 |
202 | MIDL_DEFINE_GUID(IID, IID_IDiaStackWalkHelper,0x21F81B1B,0xC5BB,0x42A3,0xBC,0x4F,0xCC,0xBA,0xA7,0x5B,0x9F,0x19);
203 |
204 |
205 | MIDL_DEFINE_GUID(IID, IID_IDiaStackWalker,0x5485216b,0xa54c,0x469f,0x96,0x70,0x52,0xb2,0x4d,0x52,0x29,0xbb);
206 |
207 |
208 | MIDL_DEFINE_GUID(IID, IID_IDiaStackWalkHelper2,0x8222c490,0x507b,0x4bef,0xb3,0xbd,0x41,0xdc,0xa7,0xb5,0x93,0x4c);
209 |
210 |
211 | MIDL_DEFINE_GUID(IID, IID_IDiaStackWalker2,0x7c185885,0xa015,0x4cac,0x94,0x11,0x0f,0x4f,0xb3,0x9b,0x1f,0x3a);
212 |
213 | #undef MIDL_DEFINE_GUID
214 |
215 | #ifdef __cplusplus
216 | }
217 | #endif
218 |
219 |
220 |
221 |
--------------------------------------------------------------------------------
/DIA_SDK/idl/dia2_p.c:
--------------------------------------------------------------------------------
1 |
2 |
3 | /* this ALWAYS GENERATED file contains the proxy stub code */
4 |
5 |
6 | /* File created by MIDL compiler version 8.01.0622 */
7 | /* at Tue Jan 19 05:14:07 2038
8 | */
9 | /* Compiler settings for C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\\DIA SDK\idl\dia2.idl:
10 | Oicf, W1, Zp8, env=Win32 (32b run), target_arch=X86 8.01.0622
11 | protocol : dce , ms_ext, c_ext, robust
12 | error checks: allocation ref bounds_check enum stub_data
13 | VC __declspec() decoration level:
14 | __declspec(uuid()), __declspec(selectany), __declspec(novtable)
15 | DECLSPEC_UUID(), MIDL_INTERFACE()
16 | */
17 | /* @@MIDL_FILE_HEADING( ) */
18 |
19 | #if !defined(_M_IA64) && !defined(_M_AMD64) && !defined(_ARM_)
20 |
21 |
22 | #pragma warning( disable: 4049 ) /* more than 64k source lines */
23 | #if _MSC_VER >= 1200
24 | #pragma warning(push)
25 | #endif
26 |
27 | #pragma warning( disable: 4211 ) /* redefine extern to static */
28 | #pragma warning( disable: 4232 ) /* dllimport identity*/
29 | #pragma warning( disable: 4024 ) /* array to pointer mapping*/
30 | #pragma warning( disable: 4152 ) /* function/data pointer conversion in expression */
31 | #pragma warning( disable: 4100 ) /* unreferenced arguments in x86 call */
32 |
33 | #pragma optimize("", off )
34 |
35 | #define USE_STUBLESS_PROXY
36 |
37 |
38 | /* verify that the version is high enough to compile this file*/
39 | #ifndef __REDQ_RPCPROXY_H_VERSION__
40 | #define __REQUIRED_RPCPROXY_H_VERSION__ 475
41 | #endif
42 |
43 |
44 | #include "rpcproxy.h"
45 | #ifndef __RPCPROXY_H_VERSION__
46 | #error this stub requires an updated version of
47 | #endif /* __RPCPROXY_H_VERSION__ */
48 |
49 |
50 | #include "dia2.h"
51 |
52 | #define TYPE_FORMAT_STRING_SIZE 3
53 | #define PROC_FORMAT_STRING_SIZE 1
54 | #define EXPR_FORMAT_STRING_SIZE 1
55 | #define TRANSMIT_AS_TABLE_SIZE 0
56 | #define WIRE_MARSHAL_TABLE_SIZE 0
57 |
58 | typedef struct _dia2_MIDL_TYPE_FORMAT_STRING
59 | {
60 | short Pad;
61 | unsigned char Format[ TYPE_FORMAT_STRING_SIZE ];
62 | } dia2_MIDL_TYPE_FORMAT_STRING;
63 |
64 | typedef struct _dia2_MIDL_PROC_FORMAT_STRING
65 | {
66 | short Pad;
67 | unsigned char Format[ PROC_FORMAT_STRING_SIZE ];
68 | } dia2_MIDL_PROC_FORMAT_STRING;
69 |
70 | typedef struct _dia2_MIDL_EXPR_FORMAT_STRING
71 | {
72 | long Pad;
73 | unsigned char Format[ EXPR_FORMAT_STRING_SIZE ];
74 | } dia2_MIDL_EXPR_FORMAT_STRING;
75 |
76 |
77 | static const RPC_SYNTAX_IDENTIFIER _RpcTransferSyntax =
78 | {{0x8A885D04,0x1CEB,0x11C9,{0x9F,0xE8,0x08,0x00,0x2B,0x10,0x48,0x60}},{2,0}};
79 |
80 |
81 | extern const dia2_MIDL_TYPE_FORMAT_STRING dia2__MIDL_TypeFormatString;
82 | extern const dia2_MIDL_PROC_FORMAT_STRING dia2__MIDL_ProcFormatString;
83 | extern const dia2_MIDL_EXPR_FORMAT_STRING dia2__MIDL_ExprFormatString;
84 |
85 |
86 |
87 | #if !defined(__RPC_WIN32__)
88 | #error Invalid build platform for this stub.
89 | #endif
90 |
91 | #if !(TARGET_IS_NT50_OR_LATER)
92 | #error You need Windows 2000 or later to run this stub because it uses these features:
93 | #error /robust command line switch.
94 | #error However, your C/C++ compilation flags indicate you intend to run this app on earlier systems.
95 | #error This app will fail with the RPC_X_WRONG_STUB_VERSION error.
96 | #endif
97 |
98 |
99 | static const dia2_MIDL_PROC_FORMAT_STRING dia2__MIDL_ProcFormatString =
100 | {
101 | 0,
102 | {
103 |
104 | 0x0
105 | }
106 | };
107 |
108 | static const dia2_MIDL_TYPE_FORMAT_STRING dia2__MIDL_TypeFormatString =
109 | {
110 | 0,
111 | {
112 | NdrFcShort( 0x0 ), /* 0 */
113 |
114 | 0x0
115 | }
116 | };
117 |
118 |
119 | /* Standard interface: __MIDL_itf_dia2_0000_0000, ver. 0.0,
120 | GUID={0x00000000,0x0000,0x0000,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}} */
121 |
122 |
123 | /* Object interface: IUnknown, ver. 0.0,
124 | GUID={0x00000000,0x0000,0x0000,{0xC0,0x00,0x00,0x00,0x00,0x00,0x00,0x46}} */
125 |
126 |
127 | /* Object interface: IDiaLoadCallback, ver. 0.0,
128 | GUID={0xC32ADB82,0x73F4,0x421b,{0x95,0xD5,0xA4,0x70,0x6E,0xDF,0x5D,0xBE}} */
129 |
130 |
131 | /* Object interface: IDiaLoadCallback2, ver. 0.0,
132 | GUID={0x4688a074,0x5a4d,0x4486,{0xae,0xa8,0x7b,0x90,0x71,0x1d,0x9f,0x7c}} */
133 |
134 |
135 | /* Object interface: IDiaReadExeAtOffsetCallback, ver. 0.0,
136 | GUID={0x587A461C,0xB80B,0x4f54,{0x91,0x94,0x50,0x32,0x58,0x9A,0x63,0x19}} */
137 |
138 |
139 | /* Object interface: IDiaReadExeAtRVACallback, ver. 0.0,
140 | GUID={0x8E3F80CA,0x7517,0x432a,{0xBA,0x07,0x28,0x51,0x34,0xAA,0xEA,0x8E}} */
141 |
142 |
143 | /* Object interface: IDiaDataSource, ver. 0.0,
144 | GUID={0x79F1BB5F,0xB66E,0x48e5,{0xB6,0xA9,0x15,0x45,0xC3,0x23,0xCA,0x3D}} */
145 |
146 |
147 | /* Object interface: IDiaEnumSymbols, ver. 0.0,
148 | GUID={0xCAB72C48,0x443B,0x48f5,{0x9B,0x0B,0x42,0xF0,0x82,0x0A,0xB2,0x9A}} */
149 |
150 |
151 | /* Object interface: IDiaEnumSymbolsByAddr, ver. 0.0,
152 | GUID={0x624B7D9C,0x24EA,0x4421,{0x9D,0x06,0x3B,0x57,0x74,0x71,0xC1,0xFA}} */
153 |
154 |
155 | /* Object interface: IDiaEnumSourceFiles, ver. 0.0,
156 | GUID={0x10F3DBD9,0x664F,0x4469,{0xB8,0x08,0x94,0x71,0xC7,0xA5,0x05,0x38}} */
157 |
158 |
159 | /* Object interface: IDiaEnumInputAssemblyFiles, ver. 0.0,
160 | GUID={0x1C7FF653,0x51F7,0x457E,{0x84,0x19,0xB2,0x0F,0x57,0xEF,0x7E,0x4D}} */
161 |
162 |
163 | /* Object interface: IDiaEnumLineNumbers, ver. 0.0,
164 | GUID={0xFE30E878,0x54AC,0x44f1,{0x81,0xBA,0x39,0xDE,0x94,0x0F,0x60,0x52}} */
165 |
166 |
167 | /* Object interface: IDiaEnumInjectedSources, ver. 0.0,
168 | GUID={0xD5612573,0x6925,0x4468,{0x88,0x83,0x98,0xCD,0xEC,0x8C,0x38,0x4A}} */
169 |
170 |
171 | /* Object interface: IDiaEnumSegments, ver. 0.0,
172 | GUID={0xE8368CA9,0x01D1,0x419d,{0xAC,0x0C,0xE3,0x12,0x35,0xDB,0xDA,0x9F}} */
173 |
174 |
175 | /* Object interface: IDiaEnumSectionContribs, ver. 0.0,
176 | GUID={0x1994DEB2,0x2C82,0x4b1d,{0xA5,0x7F,0xAF,0xF4,0x24,0xD5,0x4A,0x68}} */
177 |
178 |
179 | /* Object interface: IDiaEnumFrameData, ver. 0.0,
180 | GUID={0x9FC77A4B,0x3C1C,0x44ed,{0xA7,0x98,0x6C,0x1D,0xEE,0xA5,0x3E,0x1F}} */
181 |
182 |
183 | /* Object interface: IDiaEnumDebugStreamData, ver. 0.0,
184 | GUID={0x486943E8,0xD187,0x4a6b,{0xA3,0xC4,0x29,0x12,0x59,0xFF,0xF6,0x0D}} */
185 |
186 |
187 | /* Object interface: IDiaEnumDebugStreams, ver. 0.0,
188 | GUID={0x08CBB41E,0x47A6,0x4f87,{0x92,0xF1,0x1C,0x9C,0x87,0xCE,0xD0,0x44}} */
189 |
190 |
191 | /* Standard interface: __MIDL_itf_dia2_0000_0016, ver. 0.0,
192 | GUID={0x00000000,0x0000,0x0000,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}} */
193 |
194 |
195 | /* Object interface: IDiaAddressMap, ver. 0.0,
196 | GUID={0xB62A2E7A,0x067A,0x4ea3,{0xB5,0x98,0x04,0xC0,0x97,0x17,0x50,0x2C}} */
197 |
198 |
199 | /* Object interface: IDiaSession, ver. 0.0,
200 | GUID={0x2F609EE1,0xD1C8,0x4E24,{0x82,0x88,0x33,0x26,0xBA,0xDC,0xD2,0x11}} */
201 |
202 |
203 | /* Object interface: IDiaSymbol, ver. 0.0,
204 | GUID={0xcb787b2f,0xbd6c,0x4635,{0xba,0x52,0x93,0x31,0x26,0xbd,0x2d,0xcd}} */
205 |
206 |
207 | /* Object interface: IDiaSymbol2, ver. 0.0,
208 | GUID={0x611e86cd,0xb7d1,0x4546,{0x8a,0x15,0x07,0x0e,0x2b,0x07,0xa4,0x27}} */
209 |
210 |
211 | /* Object interface: IDiaSymbol3, ver. 0.0,
212 | GUID={0x99b665f7,0xc1b2,0x49d3,{0x89,0xb2,0xa3,0x84,0x36,0x1a,0xca,0xb5}} */
213 |
214 |
215 | /* Object interface: IDiaSymbol4, ver. 0.0,
216 | GUID={0xbf6c88a7,0xe9d6,0x4346,{0x99,0xa1,0xd0,0x53,0xde,0x5a,0x78,0x08}} */
217 |
218 |
219 | /* Object interface: IDiaSymbol5, ver. 0.0,
220 | GUID={0xabe2de00,0xdc2d,0x4793,{0xaf,0x9a,0xef,0x1d,0x90,0x83,0x26,0x44}} */
221 |
222 |
223 | /* Object interface: IDiaSymbol6, ver. 0.0,
224 | GUID={0x8133dad3,0x75fe,0x4234,{0xac,0x7e,0xf8,0xe7,0xa1,0xd3,0xcb,0xb3}} */
225 |
226 |
227 | /* Object interface: IDiaSymbol7, ver. 0.0,
228 | GUID={0x64ce6cd5,0x7315,0x4328,{0x86,0xd6,0x10,0xe3,0x03,0xe0,0x10,0xb4}} */
229 |
230 |
231 | /* Object interface: IDiaSymbol8, ver. 0.0,
232 | GUID={0x7f2e041f,0x1294,0x41bd,{0xb8,0x3a,0xe7,0x15,0x97,0x2d,0x2c,0xe3}} */
233 |
234 |
235 | /* Object interface: IDiaSourceFile, ver. 0.0,
236 | GUID={0xA2EF5353,0xF5A8,0x4eb3,{0x90,0xD2,0xCB,0x52,0x6A,0xCB,0x3C,0xDD}} */
237 |
238 |
239 | /* Object interface: IDiaInputAssemblyFile, ver. 0.0,
240 | GUID={0x3BFE56B0,0x390C,0x4863,{0x94,0x30,0x1F,0x3D,0x08,0x3B,0x76,0x84}} */
241 |
242 |
243 | /* Object interface: IDiaLineNumber, ver. 0.0,
244 | GUID={0xB388EB14,0xBE4D,0x421d,{0xA8,0xA1,0x6C,0xF7,0xAB,0x05,0x70,0x86}} */
245 |
246 |
247 | /* Object interface: IDiaSectionContrib, ver. 0.0,
248 | GUID={0x0CF4B60E,0x35B1,0x4c6c,{0xBD,0xD8,0x85,0x4B,0x9C,0x8E,0x38,0x57}} */
249 |
250 |
251 | /* Object interface: IDiaSegment, ver. 0.0,
252 | GUID={0x0775B784,0xC75B,0x4449,{0x84,0x8B,0xB7,0xBD,0x31,0x59,0x54,0x5B}} */
253 |
254 |
255 | /* Object interface: IDiaInjectedSource, ver. 0.0,
256 | GUID={0xAE605CDC,0x8105,0x4a23,{0xB7,0x10,0x32,0x59,0xF1,0xE2,0x61,0x12}} */
257 |
258 |
259 | /* Standard interface: __MIDL_itf_dia2_0000_0032, ver. 0.0,
260 | GUID={0x00000000,0x0000,0x0000,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}} */
261 |
262 |
263 | /* Object interface: IDiaStackWalkFrame, ver. 0.0,
264 | GUID={0x07C590C1,0x438D,0x4F47,{0xBD,0xCD,0x43,0x97,0xBC,0x81,0xAD,0x75}} */
265 |
266 |
267 | /* Object interface: IDiaFrameData, ver. 0.0,
268 | GUID={0xA39184B7,0x6A36,0x42de,{0x8E,0xEC,0x7D,0xF9,0xF3,0xF5,0x9F,0x33}} */
269 |
270 |
271 | /* Object interface: IDiaImageData, ver. 0.0,
272 | GUID={0xC8E40ED2,0xA1D9,0x4221,{0x86,0x92,0x3C,0xE6,0x61,0x18,0x4B,0x44}} */
273 |
274 |
275 | /* Object interface: IEnumUnknown, ver. 0.0,
276 | GUID={0x00000100,0x0000,0x0000,{0xC0,0x00,0x00,0x00,0x00,0x00,0x00,0x46}} */
277 |
278 |
279 | /* Object interface: IDiaTable, ver. 0.0,
280 | GUID={0x4A59FB77,0xABAC,0x469b,{0xA3,0x0B,0x9E,0xCC,0x85,0xBF,0xEF,0x14}} */
281 |
282 |
283 | /* Object interface: IDiaEnumTables, ver. 0.0,
284 | GUID={0xC65C2B0A,0x1150,0x4d7a,{0xAF,0xCC,0xE0,0x5B,0xF3,0xDE,0xE8,0x1E}} */
285 |
286 |
287 | /* Standard interface: __MIDL_itf_dia2_0000_0038, ver. 0.0,
288 | GUID={0x00000000,0x0000,0x0000,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}} */
289 |
290 |
291 | /* Object interface: IDiaPropertyStorage, ver. 0.0,
292 | GUID={0x9d416f9c,0xe184,0x45b2,{0xa4,0xf0,0xce,0x51,0x7f,0x71,0x9e,0x9b}} */
293 |
294 |
295 | /* Object interface: IDiaStackFrame, ver. 0.0,
296 | GUID={0x5edbc96d,0xcdd6,0x4792,{0xaf,0xbe,0xcc,0x89,0x00,0x7d,0x96,0x10}} */
297 |
298 |
299 | /* Object interface: IDiaEnumStackFrames, ver. 0.0,
300 | GUID={0xec9d461d,0xce74,0x4711,{0xa0,0x20,0x7d,0x8f,0x9a,0x1d,0xd2,0x55}} */
301 |
302 |
303 | /* Standard interface: __MIDL_itf_dia2_0000_0041, ver. 0.0,
304 | GUID={0x00000000,0x0000,0x0000,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}} */
305 |
306 |
307 | /* Object interface: IDiaStackWalkHelper, ver. 0.0,
308 | GUID={0x21F81B1B,0xC5BB,0x42A3,{0xBC,0x4F,0xCC,0xBA,0xA7,0x5B,0x9F,0x19}} */
309 |
310 |
311 | /* Object interface: IDiaStackWalker, ver. 0.0,
312 | GUID={0x5485216b,0xa54c,0x469f,{0x96,0x70,0x52,0xb2,0x4d,0x52,0x29,0xbb}} */
313 |
314 |
315 | /* Object interface: IDiaStackWalkHelper2, ver. 0.0,
316 | GUID={0x8222c490,0x507b,0x4bef,{0xb3,0xbd,0x41,0xdc,0xa7,0xb5,0x93,0x4c}} */
317 |
318 |
319 | /* Object interface: IDiaStackWalker2, ver. 0.0,
320 | GUID={0x7c185885,0xa015,0x4cac,{0x94,0x11,0x0f,0x4f,0xb3,0x9b,0x1f,0x3a}} */
321 |
322 | static const MIDL_STUB_DESC Object_StubDesc =
323 | {
324 | 0,
325 | NdrOleAllocate,
326 | NdrOleFree,
327 | 0,
328 | 0,
329 | 0,
330 | 0,
331 | 0,
332 | dia2__MIDL_TypeFormatString.Format,
333 | 1, /* -error bounds_check flag */
334 | 0x50002, /* Ndr library version */
335 | 0,
336 | 0x801026e, /* MIDL Version 8.1.622 */
337 | 0,
338 | 0,
339 | 0, /* notify & notify_flag routine table */
340 | 0x1, /* MIDL flag */
341 | 0, /* cs routines */
342 | 0, /* proxy/server info */
343 | 0
344 | };
345 |
346 | const CInterfaceProxyVtbl * const _dia2_ProxyVtblList[] =
347 | {
348 | 0
349 | };
350 |
351 | const CInterfaceStubVtbl * const _dia2_StubVtblList[] =
352 | {
353 | 0
354 | };
355 |
356 | PCInterfaceName const _dia2_InterfaceNamesList[] =
357 | {
358 | 0
359 | };
360 |
361 |
362 | #define _dia2_CHECK_IID(n) IID_GENERIC_CHECK_IID( _dia2, pIID, n)
363 |
364 | int __stdcall _dia2_IID_Lookup( const IID * pIID, int * pIndex )
365 | {
366 | UNREFERENCED_PARAMETER(pIID);
367 | UNREFERENCED_PARAMETER(pIndex);
368 | return 0;
369 | }
370 |
371 | const ExtendedProxyFileInfo dia2_ProxyFileInfo =
372 | {
373 | (PCInterfaceProxyVtblList *) & _dia2_ProxyVtblList,
374 | (PCInterfaceStubVtblList *) & _dia2_StubVtblList,
375 | (const PCInterfaceName * ) & _dia2_InterfaceNamesList,
376 | 0, /* no delegation */
377 | & _dia2_IID_Lookup,
378 | 0,
379 | 2,
380 | 0, /* table of [async_uuid] interfaces */
381 | 0, /* Filler1 */
382 | 0, /* Filler2 */
383 | 0 /* Filler3 */
384 | };
385 | #if _MSC_VER >= 1200
386 | #pragma warning(pop)
387 | #endif
388 |
389 |
390 | #endif /* !defined(_M_IA64) && !defined(_M_AMD64) && !defined(_ARM_) */
391 |
392 |
--------------------------------------------------------------------------------
/DIA_SDK/idl/dlldata.c:
--------------------------------------------------------------------------------
1 | /*********************************************************
2 | DllData file -- generated by MIDL compiler
3 |
4 | DO NOT ALTER THIS FILE
5 |
6 | This file is regenerated by MIDL on every IDL file compile.
7 |
8 | To completely reconstruct this file, delete it and rerun MIDL
9 | on all the IDL files in this DLL, specifying this file for the
10 | /dlldata command line option
11 |
12 | *********************************************************/
13 |
14 |
15 | #include
16 |
17 | #ifdef __cplusplus
18 | extern "C" {
19 | #endif
20 |
21 | EXTERN_PROXY_FILE( dia2 )
22 |
23 |
24 | PROXYFILE_LIST_START
25 | /* Start of list */
26 | REFERENCE_PROXY_FILE( dia2 ),
27 | /* End of list */
28 | PROXYFILE_LIST_END
29 |
30 |
31 | DLLDATA_ROUTINES( aProxyFileList, GET_DLL_CLSID )
32 |
33 | #ifdef __cplusplus
34 | } /*extern "C" */
35 | #endif
36 |
37 | /* end of generated dlldata file */
38 |
--------------------------------------------------------------------------------
/DIA_SDK/idl/gen.cmd:
--------------------------------------------------------------------------------
1 | midl /I "%VSINSTALLDIR%\DIA SDK\include" "%VSINSTALLDIR%\DIA SDK\idl\dia2.idl" /tlb dia2.tlb
2 | tlbimp dia2.tlb
3 | pause
4 |
--------------------------------------------------------------------------------
/DIA_SDK/include/diacreate.h:
--------------------------------------------------------------------------------
1 | // diacreate.h - creation helper functions for DIA initialization
2 | //-----------------------------------------------------------------
3 | //
4 | // Copyright Microsoft Corporation. All Rights Reserved.
5 | //
6 | //---------------------------------------------------------------
7 | #ifndef _DIACREATE_H_
8 | #define _DIACREATE_H_
9 |
10 | //
11 | // Create a dia data source object from the dia dll (by dll name - does not access the registry).
12 | //
13 |
14 | HRESULT STDMETHODCALLTYPE NoRegCoCreate( const __wchar_t *dllName,
15 | REFCLSID rclsid,
16 | REFIID riid,
17 | void **ppv);
18 |
19 | #ifndef _NATIVE_WCHAR_T_DEFINED
20 | #ifdef __cplusplus
21 |
22 | HRESULT STDMETHODCALLTYPE NoRegCoCreate( const wchar_t *dllName,
23 | REFCLSID rclsid,
24 | REFIID riid,
25 | void **ppv)
26 | {
27 | return NoRegCoCreate( (const __wchar_t *)dllName, rclsid, riid, ppv );
28 | }
29 |
30 | #endif
31 | #endif
32 |
33 |
34 |
35 | //
36 | // Create a dia data source object from the dia dll (looks up the class id in the registry).
37 | //
38 | HRESULT STDMETHODCALLTYPE NoOleCoCreate( REFCLSID rclsid,
39 | REFIID riid,
40 | void **ppv);
41 |
42 | #endif
43 |
--------------------------------------------------------------------------------
/DIA_SDK/lib/amd64/diaguids.lib:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wongfei/pdb-ripper/051982b24704cca88981cd0a5a12a37fc1506af0/DIA_SDK/lib/amd64/diaguids.lib
--------------------------------------------------------------------------------
/DIA_SDK/lib/arm/diaguids.lib:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wongfei/pdb-ripper/051982b24704cca88981cd0a5a12a37fc1506af0/DIA_SDK/lib/arm/diaguids.lib
--------------------------------------------------------------------------------
/DIA_SDK/lib/diaguids.lib:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wongfei/pdb-ripper/051982b24704cca88981cd0a5a12a37fc1506af0/DIA_SDK/lib/diaguids.lib
--------------------------------------------------------------------------------
/PrintSymbol.h:
--------------------------------------------------------------------------------
1 | inline int myDebugBreak( int ){
2 | DebugBreak();
3 | return 0;
4 | }
5 | #define MAXELEMS(x) (sizeof(x)/sizeof(x[0]))
6 | #define SafeDRef(a, i) ((i < MAXELEMS(a)) ? a[i] : a[myDebugBreak(i)])
7 |
8 | #define MAX_TYPE_IN_DETAIL 5
9 | #define MAX_RVA_LINES_BYTES_RANGE 0x100
10 |
11 | extern const wchar_t * const rgBaseType[];
12 | extern const wchar_t * const rgTags[];
13 | extern const wchar_t * const rgFloatPackageStrings[];
14 | extern const wchar_t * const rgProcessorStrings[];
15 | extern const wchar_t * const rgDataKind[];
16 | extern const wchar_t * const rgUdtKind[];
17 | extern const wchar_t * const rgAccess[];
18 | extern const wchar_t * const rgCallingConvention[];
19 | extern const wchar_t * const rgLanguage[];
20 | extern const wchar_t * const rgLocationTypeString[];
21 |
22 | void PrintPublicSymbol( IDiaSymbol* );
23 | void PrintGlobalSymbol( IDiaSymbol* );
24 | void PrintSymbol( IDiaSymbol* , DWORD );
25 | void PrintSymTag( DWORD );
26 | void PrintName( IDiaSymbol* );
27 | void PrintUndName( IDiaSymbol* );
28 | void PrintThunk( IDiaSymbol* );
29 | void PrintCompilandDetails( IDiaSymbol* );
30 | void PrintCompilandEnv( IDiaSymbol* );
31 | void PrintLocation( IDiaSymbol* );
32 | void PrintConst( IDiaSymbol* );
33 | void PrintUDT( IDiaSymbol* );
34 | void PrintSymbolType( IDiaSymbol* );
35 | void PrintType( IDiaSymbol* );
36 | void PrintBound( IDiaSymbol* );
37 | void PrintData( IDiaSymbol* );
38 | void PrintVariant( VARIANT );
39 | void PrintUdtKind( IDiaSymbol* );
40 | void PrintTypeInDetail( IDiaSymbol* , DWORD );
41 | void PrintFunctionType( IDiaSymbol* );
42 | void PrintSourceFile( IDiaSourceFile* );
43 | void PrintLines( IDiaSession* , IDiaSymbol* );
44 | void PrintLines( IDiaEnumLineNumbers* );
45 | void PrintSource( IDiaSourceFile* );
46 | void PrintSecContribs( IDiaSectionContrib* );
47 | void PrintStreamData( IDiaEnumDebugStreamData* );
48 | void PrintFrameData( IDiaFrameData* );
49 |
50 | void PrintPropertyStorage( IDiaPropertyStorage* );
51 |
52 | template void PrintGeneric( T t ){
53 | IDiaPropertyStorage* pPropertyStorage;
54 |
55 | if(t->QueryInterface( __uuidof(IDiaPropertyStorage), (void **)&pPropertyStorage ) == S_OK){
56 | PrintPropertyStorage(pPropertyStorage);
57 | pPropertyStorage->Release();
58 | }
59 | }
60 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # pdb ripper
2 |
3 | Extracts UserDefinedTypes from pdb file and generates cpp code
4 |
5 | ## Usage
6 |
7 | ```
8 | Dia2Dump.exe -rip [flags] ...
9 | -printNamesOnly
10 | -printCppProxy
11 | -genCppFiles
12 | -ii : include internals
13 | -it : include templates
14 | -s : generate symbol information
15 | -m : generate meta information
16 | -d : include deps
17 | -rd : resolve/sort deps
18 | -names : select specific UDTs (-names "nameA;nameB;-excludeC")
19 | ```
20 |
21 | ## How it works
22 |
23 | Imagine some code compiled into test.exe / test.pdb
24 |
25 | ```cpp
26 | class Shape {
27 | public:
28 | Shape(int newx, int newy);
29 | virtual ~Shape();
30 | int getX();
31 | int getY();
32 | void setX(int newx);
33 | void setY(int newy);
34 | void moveTo(int newx, int newy);
35 | void rMoveTo(int deltax, int deltay);
36 | virtual void draw();
37 | private:
38 | int x;
39 | int y;
40 | };
41 |
42 | Shape::Shape(int newx, int newy) { moveTo(newx, newy); }
43 | Shape::~Shape() {}
44 | int Shape::getX() { return x; }
45 | int Shape::getY() { return y; }
46 | void Shape::setX(int newx) { x = newx; }
47 | void Shape::setY(int newy) { y = newy; }
48 | void Shape::moveTo(int newx, int newy) { setX(newx); setY(newy); }
49 | void Shape::rMoveTo(int deltax, int deltay) { moveTo(getX() + deltax, getY() + deltay); }
50 | void Shape::draw() {}
51 |
52 | class Rectangle: public Shape {
53 | public:
54 | Rectangle(int newx, int newy, int newwidth, int newheight);
55 | int getWidth();
56 | int getHeight();
57 | void setWidth(int newwidth);
58 | void setHeight(int newheight);
59 | void draw();
60 | private:
61 | int width;
62 | int height;
63 | };
64 |
65 | Rectangle::Rectangle(int newx, int newy, int newwidth, int newheight): Shape(newx, newy) { setWidth(newwidth); setHeight(newheight); }
66 | int Rectangle::getWidth() { return width; }
67 | int Rectangle::getHeight() { return height; }
68 | void Rectangle::setWidth(int newwidth) { width = newwidth; }
69 | void Rectangle::setHeight(int newheight) { height = newheight; }
70 | void Rectangle::draw() { printf("Rectangle %d %d %d %d\n", getX(), getY(), getWidth(), getHeight()); }
71 |
72 | class Circle: public Shape {
73 | public:
74 | Circle(int newx, int newy, int newradius);
75 | int getRadius();
76 | void setRadius(int newradius);
77 | void draw();
78 | private:
79 | int radius;
80 | };
81 |
82 | Circle::Circle(int newx, int newy, int newradius): Shape(newx, newy) { setRadius(newradius); }
83 | int Circle::getRadius() { return radius; }
84 | void Circle::setRadius(int newradius) { radius = newradius; }
85 | void Circle::draw() { printf("Circle %d %d %d\n", getX(), getY(), getRadius()); }
86 | ```
87 |
88 | Invite the ripper to do some work:
89 |
90 | `Dia2Dump.exe -rip -printCppProxy -s -m -d -rd -names "Rectangle;Circle" test.pdb > gen.h`
91 |
92 | Generated file:
93 |
94 | ```cpp
95 | //UDT: class Shape @len=16 @vfcount=2
96 | //_VTable:
97 | //_Func: public void Shape(Shape & _arg0); @loc=optimized @len=0 @rva=0
98 | //_Func: public void Shape(int newx, int newy); @loc=static @len=62 @rva=6768
99 | //_Func: public void ~Shape(); @intro @virtual vtpo=0 vfid=0 @loc=static @len=21 @rva=7664
100 | //_Func: public int getX(); @loc=static @len=14 @rva=14208
101 | //_Func: public int getY(); @loc=static @len=14 @rva=14224
102 | //_Func: public void setX(int newx); @loc=static @len=22 @rva=14960
103 | //_Func: public void setY(int newy); @loc=static @len=22 @rva=14992
104 | //_Func: public void moveTo(int newx, int newy); @loc=static @len=51 @rva=14720
105 | //_Func: public void rMoveTo(int deltax, int deltay); @loc=static @len=74 @rva=14784
106 | //_Func: public void draw(); @intro @virtual vtpo=0 vfid=1 @loc=static @len=6 @rva=13808
107 | //_Data: this+0x8, Member, Type: int, x
108 | //_Data: this+0xC, Member, Type: int, y
109 | //_Func: public Shape & operator=(Shape & _arg0); @loc=optimized @len=0 @rva=0
110 | //_Func: public void * __vecDelDtor(unsigned int _arg0); @intro @virtual vtpo=0 vfid=0 @loc=optimized @len=0 @rva=0
111 | //UDT;
112 |
113 | class Shape {
114 | public:
115 | int x;
116 | int y;
117 | inline Shape() { }
118 | inline void ctor(int newx, int newy) { typedef void (*_fpt)(Shape *pthis, int, int); _fpt _f=(_fpt)_drva(6768); _f(this, newx, newy); }
119 | virtual ~Shape();
120 | inline void dtor() { typedef void (*_fpt)(Shape *pthis); _fpt _f=(_fpt)_drva(7664); _f(this); }
121 | inline int getX() { typedef int (*_fpt)(Shape *pthis); _fpt _f=(_fpt)_drva(14208); return _f(this); }
122 | inline int getY() { typedef int (*_fpt)(Shape *pthis); _fpt _f=(_fpt)_drva(14224); return _f(this); }
123 | inline void setX(int newx) { typedef void (*_fpt)(Shape *pthis, int); _fpt _f=(_fpt)_drva(14960); return _f(this, newx); }
124 | inline void setY(int newy) { typedef void (*_fpt)(Shape *pthis, int); _fpt _f=(_fpt)_drva(14992); return _f(this, newy); }
125 | inline void moveTo(int newx, int newy) { typedef void (*_fpt)(Shape *pthis, int, int); _fpt _f=(_fpt)_drva(14720); return _f(this, newx, newy); }
126 | inline void rMoveTo(int deltax, int deltay) { typedef void (*_fpt)(Shape *pthis, int, int); _fpt _f=(_fpt)_drva(14784); return _f(this, deltax, deltay); }
127 | virtual void draw_vf1();
128 | inline void draw_impl() { typedef void (*_fpt)(Shape *pthis); _fpt _f=(_fpt)_drva(13808); return _f(this); }
129 | inline void draw() { return draw_vf1(); }
130 | };
131 |
132 | //UDT: class Rectangle @len=24 @vfcount=2
133 | //_Base: class Shape @off=0 @len=16
134 | //_Func: public void Rectangle(Rectangle * _arg0); @loc=optimized @len=0 @rva=0
135 | //_Func: public void Rectangle(Rectangle & _arg0); @loc=optimized @len=0 @rva=0
136 | //_Func: public void Rectangle(int newx, int newy, int newwidth, int newheight); @loc=static @len=106 @rva=6656
137 | //_Func: public int getWidth(); @loc=static @len=14 @rva=14192
138 | //_Func: public int getHeight(); @loc=static @len=14 @rva=14160
139 | //_Func: public void setWidth(int newwidth); @loc=static @len=22 @rva=14928
140 | //_Func: public void setHeight(int newheight); @loc=static @len=22 @rva=14864
141 | //_Func: public void draw(); @virtual vtpo=0 vfid=1 @loc=static @len=102 @rva=13696
142 | //_Data: this+0x10, Member, Type: int, width
143 | //_Data: this+0x14, Member, Type: int, height
144 | //_Func: public void ~Rectangle(); @virtual vtpo=0 vfid=0 @loc=static @len=24 @rva=7632
145 | //_Func: public Rectangle & operator=(Rectangle * _arg0); @loc=optimized @len=0 @rva=0
146 | //_Func: public Rectangle & operator=(Rectangle & _arg0); @loc=optimized @len=0 @rva=0
147 | //_Func: public void * __vecDelDtor(unsigned int _arg0); @intro @virtual vtpo=0 vfid=0 @loc=optimized @len=0 @rva=0
148 | //UDT;
149 |
150 | class Rectangle : public Shape {
151 | public:
152 | int width;
153 | int height;
154 | inline Rectangle() { }
155 | inline void ctor(int newx, int newy, int newwidth, int newheight) { typedef void (*_fpt)(Rectangle *pthis, int, int, int, int); _fpt _f=(_fpt)_drva(6656); _f(this, newx, newy, newwidth, newheight); }
156 | inline int getWidth() { typedef int (*_fpt)(Rectangle *pthis); _fpt _f=(_fpt)_drva(14192); return _f(this); }
157 | inline int getHeight() { typedef int (*_fpt)(Rectangle *pthis); _fpt _f=(_fpt)_drva(14160); return _f(this); }
158 | inline void setWidth(int newwidth) { typedef void (*_fpt)(Rectangle *pthis, int); _fpt _f=(_fpt)_drva(14928); return _f(this, newwidth); }
159 | inline void setHeight(int newheight) { typedef void (*_fpt)(Rectangle *pthis, int); _fpt _f=(_fpt)_drva(14864); return _f(this, newheight); }
160 | virtual void draw_vf1();
161 | inline void draw_impl() { typedef void (*_fpt)(Rectangle *pthis); _fpt _f=(_fpt)_drva(13696); return _f(this); }
162 | inline void draw() { return draw_vf1(); }
163 | virtual ~Rectangle();
164 | inline void dtor() { typedef void (*_fpt)(Rectangle *pthis); _fpt _f=(_fpt)_drva(7632); _f(this); }
165 | };
166 |
167 | //UDT: class Circle @len=24 @vfcount=2
168 | //_Base: class Shape @off=0 @len=16
169 | //_Func: public void Circle(Circle * _arg0); @loc=optimized @len=0 @rva=0
170 | //_Func: public void Circle(Circle & _arg0); @loc=optimized @len=0 @rva=0
171 | //_Func: public void Circle(int newx, int newy, int newradius); @loc=static @len=92 @rva=5856
172 | //_Func: public int getRadius(); @loc=static @len=14 @rva=14176
173 | //_Func: public void setRadius(int newradius); @loc=static @len=22 @rva=14896
174 | //_Func: public void draw(); @virtual vtpo=0 vfid=1 @loc=static @len=80 @rva=13616
175 | //_Data: this+0x10, Member, Type: int, radius
176 | //_Func: public void ~Circle(); @virtual vtpo=0 vfid=0 @loc=static @len=24 @rva=7152
177 | //_Func: public Circle & operator=(Circle * _arg0); @loc=optimized @len=0 @rva=0
178 | //_Func: public Circle & operator=(Circle & _arg0); @loc=optimized @len=0 @rva=0
179 | //_Func: public void * __vecDelDtor(unsigned int _arg0); @intro @virtual vtpo=0 vfid=0 @loc=optimized @len=0 @rva=0
180 | //UDT;
181 |
182 | class Circle : public Shape {
183 | public:
184 | int radius;
185 | inline Circle() { }
186 | inline void ctor(int newx, int newy, int newradius) { typedef void (*_fpt)(Circle *pthis, int, int, int); _fpt _f=(_fpt)_drva(5856); _f(this, newx, newy, newradius); }
187 | inline int getRadius() { typedef int (*_fpt)(Circle *pthis); _fpt _f=(_fpt)_drva(14176); return _f(this); }
188 | inline void setRadius(int newradius) { typedef void (*_fpt)(Circle *pthis, int); _fpt _f=(_fpt)_drva(14896); return _f(this, newradius); }
189 | virtual void draw_vf1();
190 | inline void draw_impl() { typedef void (*_fpt)(Circle *pthis); _fpt _f=(_fpt)_drva(13616); return _f(this); }
191 | inline void draw() { return draw_vf1(); }
192 | virtual ~Circle();
193 | inline void dtor() { typedef void (*_fpt)(Circle *pthis); _fpt _f=(_fpt)_drva(7152); _f(this); }
194 | };
195 | ```
196 |
197 | Inject into test.exe and do some manipulations:
198 |
199 | ```cpp
200 | template
201 | static inline T* new_udt(Args&&... params) {
202 | T* obj = (T*)malloc(sizeof(T));
203 | obj->ctor(std::forward(params)...);
204 | return obj;
205 | }
206 |
207 | Circle* obj = new_udt(0, 0, 10);
208 | obj->draw();
209 | ```
210 |
--------------------------------------------------------------------------------
/dia2dump.cpp:
--------------------------------------------------------------------------------
1 | // Dia2Dump.cpp : Defines the entry point for the console application.
2 | //
3 | // This is a part of the Debug Interface Access SDK
4 | // Copyright (c) Microsoft Corporation. All rights reserved.
5 | //
6 | // This source code is only intended as a supplement to the
7 | // Debug Interface Access SDK and related electronic documentation
8 | // provided with the library.
9 | // See these sources for detailed information regarding the
10 | // Debug Interface Access SDK API.
11 | //
12 |
13 | #include "stdafx.h"
14 | #include "Dia2Dump.h"
15 | #include "PrintSymbol.h"
16 |
17 | #include "Callback.h"
18 |
19 | #pragma warning (disable : 4100)
20 |
21 | const wchar_t *g_szFilename;
22 | IDiaDataSource *g_pDiaDataSource;
23 | IDiaSession *g_pDiaSession;
24 | IDiaSymbol *g_pGlobalSymbol;
25 | DWORD g_dwMachineType = CV_CFL_80386;
26 |
27 | extern void RipPdb(IDiaSymbol *pGlobal, int argc, wchar_t *argv[]);
28 |
29 | ////////////////////////////////////////////////////////////
30 | //
31 | int wmain(int argc, wchar_t *argv[])
32 | {
33 | FILE *pFile;
34 |
35 | if (argc < 2) {
36 | PrintHelpOptions();
37 | return -1;
38 | }
39 |
40 | if (_wfopen_s(&pFile, argv[argc - 1], L"r") || !pFile) {
41 | // invalid file name or file does not exist
42 |
43 | PrintHelpOptions();
44 | return -1;
45 | }
46 |
47 | fclose(pFile);
48 |
49 | g_szFilename = argv[argc - 1];
50 |
51 | // CoCreate() and initialize COM objects
52 |
53 | if (!LoadDataFromPdb(g_szFilename, &g_pDiaDataSource, &g_pDiaSession, &g_pGlobalSymbol)) {
54 | return -1;
55 | }
56 |
57 | if (argc == 2) {
58 | // no options passed; print all pdb info
59 |
60 | DumpAllPdbInfo(g_pDiaSession, g_pGlobalSymbol);
61 | }
62 |
63 | else if (!_wcsicmp(argv[1], L"-all")) {
64 | DumpAllPdbInfo(g_pDiaSession, g_pGlobalSymbol);
65 | }
66 |
67 | else if (!_wcsicmp(argv[1], L"-rip")) {
68 | RipPdb(g_pGlobalSymbol, argc, argv);
69 | }
70 |
71 | else if (!ParseArg(argc-2, &argv[1])) {
72 | Cleanup();
73 |
74 | return -1;
75 | }
76 |
77 | // release COM objects and CoUninitialize()
78 |
79 | Cleanup();
80 |
81 | return 0;
82 | }
83 |
84 | ////////////////////////////////////////////////////////////
85 | // Create an IDiaData source and open a PDB file
86 | //
87 | bool LoadDataFromPdb(
88 | const wchar_t *szFilename,
89 | IDiaDataSource **ppSource,
90 | IDiaSession **ppSession,
91 | IDiaSymbol **ppGlobal)
92 | {
93 | wchar_t wszExt[MAX_PATH];
94 | wchar_t *wszSearchPath = L"SRV**\\\\symbols\\symbols"; // Alternate path to search for debug data
95 | DWORD dwMachType = 0;
96 |
97 | HRESULT hr = CoInitialize(NULL);
98 |
99 | // Obtain access to the provider
100 |
101 | hr = CoCreateInstance(__uuidof(DiaSource),
102 | NULL,
103 | CLSCTX_INPROC_SERVER,
104 | __uuidof(IDiaDataSource),
105 | (void **) ppSource);
106 |
107 | if (FAILED(hr)) {
108 | wprintf(L"CoCreateInstance failed - HRESULT = %08X\n", hr);
109 |
110 | return false;
111 | }
112 |
113 | _wsplitpath_s(szFilename, NULL, 0, NULL, 0, NULL, 0, wszExt, MAX_PATH);
114 |
115 | if (!_wcsicmp(wszExt, L".pdb")) {
116 | // Open and prepare a program database (.pdb) file as a debug data source
117 |
118 | hr = (*ppSource)->loadDataFromPdb(szFilename);
119 |
120 | if (FAILED(hr)) {
121 | wprintf(L"loadDataFromPdb failed - HRESULT = %08X\n", hr);
122 |
123 | return false;
124 | }
125 | }
126 |
127 | else {
128 | CCallback callback; // Receives callbacks from the DIA symbol locating procedure,
129 | // thus enabling a user interface to report on the progress of
130 | // the location attempt. The client application may optionally
131 | // provide a reference to its own implementation of this
132 | // virtual base class to the IDiaDataSource::loadDataForExe method.
133 | callback.AddRef();
134 |
135 | // Open and prepare the debug data associated with the executable
136 |
137 | hr = (*ppSource)->loadDataForExe(szFilename, wszSearchPath, &callback);
138 |
139 | if (FAILED(hr)) {
140 | wprintf(L"loadDataForExe failed - HRESULT = %08X\n", hr);
141 |
142 | return false;
143 | }
144 | }
145 |
146 | // Open a session for querying symbols
147 |
148 | hr = (*ppSource)->openSession(ppSession);
149 |
150 | if (FAILED(hr)) {
151 | wprintf(L"openSession failed - HRESULT = %08X\n", hr);
152 |
153 | return false;
154 | }
155 |
156 | // Retrieve a reference to the global scope
157 |
158 | hr = (*ppSession)->get_globalScope(ppGlobal);
159 |
160 | if (hr != S_OK) {
161 | wprintf(L"get_globalScope failed\n");
162 |
163 | return false;
164 | }
165 |
166 | // Set Machine type for getting correct register names
167 |
168 | if ((*ppGlobal)->get_machineType(&dwMachType) == S_OK) {
169 | switch (dwMachType) {
170 | case IMAGE_FILE_MACHINE_I386 : g_dwMachineType = CV_CFL_80386; break;
171 | case IMAGE_FILE_MACHINE_IA64 : g_dwMachineType = CV_CFL_IA64; break;
172 | case IMAGE_FILE_MACHINE_AMD64 : g_dwMachineType = CV_CFL_AMD64; break;
173 | }
174 | }
175 |
176 | return true;
177 | }
178 |
179 | ////////////////////////////////////////////////////////////
180 | // Release DIA objects and CoUninitialize
181 | //
182 | void Cleanup()
183 | {
184 | if (g_pGlobalSymbol) {
185 | g_pGlobalSymbol->Release();
186 | g_pGlobalSymbol = NULL;
187 | }
188 |
189 | if (g_pDiaSession) {
190 | g_pDiaSession->Release();
191 | g_pDiaSession = NULL;
192 | }
193 |
194 | CoUninitialize();
195 | }
196 |
197 | ////////////////////////////////////////////////////////////
198 | // Parse the arguments of the program
199 | //
200 | bool ParseArg(int argc, wchar_t *argv[])
201 | {
202 | int iCount = 0;
203 | bool bReturn = true;
204 |
205 | if (!argc) {
206 | return true;
207 | }
208 |
209 | if (!_wcsicmp(argv[0], L"-?")) {
210 | PrintHelpOptions();
211 |
212 | return true;
213 | }
214 |
215 | else if (!_wcsicmp(argv[0], L"-help")) {
216 | PrintHelpOptions();
217 |
218 | return true;
219 | }
220 |
221 | else if (!_wcsicmp(argv[0], L"-m")) {
222 | // -m : print all the mods
223 |
224 | iCount = 1;
225 | bReturn = bReturn && DumpAllMods(g_pGlobalSymbol);
226 | argc -= iCount;
227 | bReturn = bReturn && ParseArg(argc, &argv[iCount]);
228 | }
229 |
230 | else if (!_wcsicmp(argv[0], L"-p")) {
231 | // -p : print all the publics
232 |
233 | iCount = 1;
234 | bReturn = bReturn && DumpAllPublics(g_pGlobalSymbol);
235 | argc -= iCount;
236 | bReturn = bReturn && ParseArg(argc, &argv[iCount]);
237 | }
238 |
239 | else if (!_wcsicmp(argv[0], L"-s")) {
240 | // -s : print symbols
241 |
242 | iCount = 1;
243 | bReturn = bReturn && DumpAllSymbols(g_pGlobalSymbol);
244 | argc -= iCount;
245 | bReturn = bReturn && ParseArg(argc, &argv[iCount]);
246 | }
247 |
248 | else if (!_wcsicmp(argv[0], L"-g")) {
249 | // -g : print all the globals
250 |
251 | iCount = 1;
252 | bReturn = bReturn && DumpAllGlobals(g_pGlobalSymbol);
253 | argc -= iCount;
254 | bReturn = bReturn && ParseArg(argc, &argv[iCount]);
255 | }
256 |
257 | else if (!_wcsicmp(argv[0], L"-t")) {
258 | // -t : print all the types
259 |
260 | iCount = 1;
261 | bReturn = bReturn && DumpAllTypes(g_pGlobalSymbol);
262 | argc -= iCount;
263 | bReturn = bReturn && ParseArg(argc, &argv[iCount]);
264 | }
265 |
266 | else if (!_wcsicmp(argv[0], L"-f")) {
267 | // -f : print all the files
268 |
269 | iCount = 1;
270 | bReturn = bReturn && DumpAllFiles(g_pDiaSession, g_pGlobalSymbol);
271 | argc -= iCount;
272 | bReturn = bReturn && ParseArg(argc, &argv[iCount]);
273 | }
274 |
275 | else if (!_wcsicmp(argv[0], L"-l")) {
276 | if (argc > 1 && *argv[1] != L'-') {
277 | // -l RVA [bytes] : print line number info at RVA address in the bytes range
278 |
279 | DWORD dwRVA = 0;
280 | DWORD dwRange = MAX_RVA_LINES_BYTES_RANGE;
281 |
282 | swscanf_s(argv[1], L"%x", &dwRVA);
283 | if (argc > 2 && *argv[2] != L'-') {
284 | swscanf_s(argv[2], L"%d", &dwRange);
285 | iCount = 3;
286 | }
287 |
288 | else {
289 | iCount = 2;
290 | }
291 |
292 | bReturn = bReturn && DumpAllLines(g_pDiaSession, dwRVA, dwRange);
293 | }
294 |
295 | else {
296 | // -l : print line number info
297 |
298 | bReturn = bReturn && DumpAllLines(g_pDiaSession, g_pGlobalSymbol);
299 | iCount = 1;
300 | }
301 |
302 | argc -= iCount;
303 | bReturn = bReturn && ParseArg(argc, &argv[iCount]);
304 | }
305 |
306 | else if (!_wcsicmp(argv[0], L"-c")) {
307 | // -c : print section contribution info
308 |
309 | iCount = 1;
310 | bReturn = bReturn && DumpAllSecContribs(g_pDiaSession);
311 | argc -= iCount;
312 | bReturn = bReturn && ParseArg(argc, &argv[iCount]);
313 | }
314 |
315 | else if (!_wcsicmp(argv[0], L"-dbg")) {
316 | // -dbg : dump debug streams
317 |
318 | iCount = 1;
319 | bReturn = bReturn && DumpAllDebugStreams(g_pDiaSession);
320 | argc -= iCount;
321 | bReturn = bReturn && ParseArg(argc, &argv[iCount]);
322 | }
323 |
324 | else if (!_wcsicmp(argv[0], L"-injsrc")) {
325 | if (argc > 1 && *argv[1] != L'-') {
326 | // -injsrc filename : dump injected source filename
327 |
328 | bReturn = bReturn && DumpInjectedSource(g_pDiaSession, argv[1]);
329 | iCount = 2;
330 | }
331 |
332 | else {
333 | // -injsrc : dump all injected source
334 |
335 | bReturn = bReturn && DumpAllInjectedSources(g_pDiaSession);
336 | iCount = 1;
337 | }
338 |
339 | argc -= iCount;
340 | bReturn = bReturn && ParseArg(argc, &argv[iCount]);
341 | }
342 |
343 | else if (!_wcsicmp(argv[0], L"-sf")) {
344 | // -sf : dump all source files
345 |
346 | iCount = 1;
347 | bReturn = bReturn && DumpAllSourceFiles(g_pDiaSession, g_pGlobalSymbol);
348 | argc -= iCount;
349 | bReturn = bReturn && ParseArg(argc, &argv[iCount]);
350 | }
351 |
352 | else if (!_wcsicmp(argv[0], L"-oem")) {
353 | // -oem : dump all OEM specific types
354 |
355 | iCount = 1;
356 | bReturn = bReturn && DumpAllOEMs(g_pGlobalSymbol);
357 | argc -= iCount;
358 | bReturn = bReturn && ParseArg(argc, &argv[iCount]);
359 | }
360 |
361 | else if (!_wcsicmp(argv[0], L"-fpo")) {
362 | if (argc > 1 && *argv[1] != L'-') {
363 | DWORD dwRVA = 0;
364 |
365 | if (iswdigit(*argv[1])) {
366 | // -fpo [RVA] : dump frame pointer omission information for a function address
367 |
368 | swscanf_s(argv[1], L"%x", &dwRVA);
369 | bReturn = bReturn && DumpFPO(g_pDiaSession, dwRVA);
370 | }
371 |
372 | else {
373 | // -fpo [symbolname] : dump frame pointer omission information for a function symbol
374 |
375 | bReturn = bReturn && DumpFPO(g_pDiaSession, g_pGlobalSymbol, argv[1]);
376 | }
377 |
378 | iCount = 2;
379 | }
380 |
381 | else {
382 | bReturn = bReturn && DumpAllFPO(g_pDiaSession);
383 | iCount = 1;
384 | }
385 |
386 | argc -= iCount;
387 | bReturn = bReturn && ParseArg(argc, &argv[iCount]);
388 | }
389 |
390 | else if (!_wcsicmp(argv[0], L"-compiland")) {
391 | if ((argc > 1) && (*argv[1] != L'-')) {
392 | // -compiland [name] : dump symbols for this compiland
393 |
394 | bReturn = bReturn && DumpCompiland(g_pGlobalSymbol, argv[1]);
395 | argc -= 2;
396 | }
397 |
398 | else {
399 | wprintf(L"ERROR - ParseArg(): missing argument for option '-line'");
400 |
401 | return false;
402 | }
403 |
404 | argc -= iCount;
405 | bReturn = bReturn && ParseArg(argc, &argv[iCount]);
406 | }
407 |
408 | else if (!_wcsicmp(argv[0], L"-lines")) {
409 | if ((argc > 1) && (*argv[1] != L'-')) {
410 | DWORD dwRVA = 0;
411 |
412 | if (iswdigit(*argv[1])) {
413 | // -lines : dump line numbers for this address\n"
414 |
415 | swscanf_s(argv[1], L"%x", &dwRVA);
416 | bReturn = bReturn && DumpLines(g_pDiaSession, dwRVA);
417 | }
418 |
419 | else {
420 | // -lines : dump line numbers for this function
421 |
422 | bReturn = bReturn && DumpLines(g_pDiaSession, g_pGlobalSymbol, argv[1]);
423 | }
424 |
425 | iCount = 2;
426 | }
427 |
428 | else {
429 | wprintf(L"ERROR - ParseArg(): missing argument for option '-compiland'");
430 |
431 | return false;
432 | }
433 |
434 | argc -= iCount;
435 | bReturn = bReturn && ParseArg(argc, &argv[iCount]);
436 | }
437 |
438 | else if (!_wcsicmp(argv[0], L"-type")) {
439 | // -type : dump this type in detail
440 |
441 | if ((argc > 1) && (*argv[1] != L'-')) {
442 | bReturn = bReturn && DumpType(g_pGlobalSymbol, argv[1]);
443 | iCount = 2;
444 | }
445 |
446 | else {
447 | wprintf(L"ERROR - ParseArg(): missing argument for option '-type'");
448 |
449 | return false;
450 | }
451 |
452 | argc -= iCount;
453 | bReturn = bReturn && ParseArg(argc, &argv[iCount]);
454 | }
455 |
456 | else if (!_wcsicmp(argv[0], L"-label")) {
457 | // -label : dump label at RVA
458 | if ((argc > 1) && (*argv[1] != L'-')) {
459 | DWORD dwRVA = 0;
460 |
461 | swscanf_s(argv[1], L"%x", &dwRVA);
462 | bReturn = bReturn && DumpLabel(g_pDiaSession, dwRVA);
463 | iCount = 2;
464 | }
465 |
466 | else {
467 | wprintf(L"ERROR - ParseArg(): missing argument for option '-label'");
468 |
469 | return false;
470 | }
471 |
472 | argc -= iCount;
473 | bReturn = bReturn && ParseArg(argc, &argv[iCount]);
474 | }
475 |
476 | else if (!_wcsicmp(argv[0], L"-sym")) {
477 | if ((argc > 1) && (*argv[1] != L'-')) {
478 | DWORD dwRVA = 0;
479 | const wchar_t *szChildname = NULL;
480 |
481 | iCount = 2;
482 |
483 | if (argc > 2 && *argv[2] != L'-') {
484 | szChildname = argv[2];
485 | iCount = 3;
486 | }
487 |
488 | if (iswdigit(*argv[1])) {
489 | // -sym [childname] : dump child information of symbol at this address
490 |
491 | swscanf_s(argv[1], L"%x", &dwRVA);
492 | bReturn = bReturn && DumpSymbolWithRVA(g_pDiaSession, dwRVA, szChildname);
493 | }
494 |
495 | else {
496 | // -sym [childname] : dump child information of this symbol
497 |
498 | bReturn = bReturn && DumpSymbolsWithRegEx(g_pGlobalSymbol, argv[1], szChildname);
499 | }
500 | }
501 |
502 | else {
503 | wprintf(L"ERROR - ParseArg(): missing argument for option '-sym'");
504 |
505 | return false;
506 | }
507 |
508 | argc -= iCount;
509 | bReturn = bReturn && ParseArg(argc, &argv[iCount]);
510 | }
511 |
512 | else if (!_wcsicmp(argv[0], L"-lsrc")) {
513 | // -lsrc [line] : dump line numbers for this source file
514 |
515 | if ((argc > 1) && (*argv[1] != L'-')) {
516 | DWORD dwLine = 0;
517 |
518 | iCount = 2;
519 | if (argc > 2 && *argv[2] != L'-') {
520 | swscanf_s(argv[1], L"%d", &dwLine);
521 | iCount = 3;
522 | }
523 |
524 | bReturn = bReturn && DumpLinesForSourceFile(g_pDiaSession, argv[1], dwLine);
525 | }
526 |
527 | else {
528 | wprintf(L"ERROR - ParseArg(): missing argument for option '-lsrc'");
529 |
530 | return false;
531 | }
532 |
533 | argc -= iCount;
534 | bReturn = bReturn && ParseArg(argc, &argv[iCount]);
535 | }
536 |
537 | else if (!_wcsicmp(argv[0], L"-ps")) {
538 | // -ps [-n ] : dump symbols after this address, default 16
539 |
540 | if ((argc > 1) && (*argv[1] != L'-')) {
541 | DWORD dwRVA = 0;
542 | DWORD dwRange;
543 |
544 | swscanf_s(argv[1], L"%x", &dwRVA);
545 | if (argc > 3 && !_wcsicmp(argv[2], L"-n")) {
546 | swscanf_s(argv[3], L"%d", &dwRange);
547 | iCount = 4;
548 | }
549 |
550 | else {
551 | dwRange = 16;
552 | iCount = 2;
553 | }
554 |
555 | bReturn = bReturn && DumpPublicSymbolsSorted(g_pDiaSession, dwRVA, dwRange, true);
556 | }
557 |
558 | else {
559 | wprintf(L"ERROR - ParseArg(): missing argument for option '-ps'");
560 |
561 | return false;
562 | }
563 |
564 | argc -= iCount;
565 | bReturn = bReturn && ParseArg(argc, &argv[iCount]);
566 | }
567 |
568 | else if (!_wcsicmp(argv[0], L"-psr")) {
569 | // -psr [-n ] : dump symbols before this address, default 16
570 |
571 | if ((argc > 1) && (*argv[1] != L'-')) {
572 | DWORD dwRVA = 0;
573 | DWORD dwRange;
574 |
575 | swscanf_s(argv[1], L"%x", &dwRVA);
576 |
577 | if (argc > 3 && !_wcsicmp(argv[2], L"-n")) {
578 | swscanf_s(argv[3], L"%d", &dwRange);
579 | iCount = 4;
580 | }
581 |
582 | else {
583 | dwRange = 16;
584 | iCount = 2;
585 | }
586 |
587 | bReturn = bReturn && DumpPublicSymbolsSorted(g_pDiaSession, dwRVA, dwRange, false);
588 | }
589 |
590 | else {
591 | wprintf(L"ERROR - ParseArg(): missing argument for option '-psr'");
592 |
593 | return false;
594 | }
595 |
596 | argc -= iCount;
597 | bReturn = bReturn && ParseArg(argc, &argv[iCount]);
598 | }
599 |
600 | else if (!_wcsicmp(argv[0], L"-annotations")) {
601 | // -annotations : dump annotation symbol for this RVA
602 |
603 | if ((argc > 1) && (*argv[1] != L'-')) {
604 | DWORD dwRVA = 0;
605 |
606 | swscanf_s(argv[1], L"%x", &dwRVA);
607 | bReturn = bReturn && DumpAnnotations(g_pDiaSession, dwRVA);
608 | iCount = 2;
609 | }
610 |
611 | else {
612 | wprintf(L"ERROR - ParseArg(): missing argument for option '-maptosrc'");
613 |
614 | return false;
615 | }
616 |
617 | argc -= iCount;
618 | bReturn = bReturn && ParseArg(argc, &argv[iCount]);
619 | }
620 |
621 | else if (!_wcsicmp(argv[0], L"-maptosrc")) {
622 | // -maptosrc : dump src RVA for this image RVA
623 |
624 | if ((argc > 1) && (*argv[1] != L'-')) {
625 | DWORD dwRVA = 0;
626 |
627 | swscanf_s(argv[1], L"%x", &dwRVA);
628 | bReturn = bReturn && DumpMapToSrc(g_pDiaSession, dwRVA);
629 | iCount = 2;
630 | }
631 |
632 | else {
633 | wprintf(L"ERROR - ParseArg(): missing argument for option '-maptosrc'");
634 |
635 | return false;
636 | }
637 |
638 | argc -= iCount;
639 | bReturn = bReturn && ParseArg(argc, &argv[iCount]);
640 | }
641 |
642 | else if (!_wcsicmp(argv[0], L"-mapfromsrc")) {
643 | // -mapfromsrc : dump image RVA for src RVA
644 |
645 | if ((argc > 1) && (*argv[1] != L'-')) {
646 | DWORD dwRVA = 0;
647 |
648 | swscanf_s(argv[1], L"%x", &dwRVA);
649 | bReturn = bReturn && DumpMapFromSrc(g_pDiaSession, dwRVA);
650 | iCount = 2;
651 | }
652 |
653 | else {
654 | wprintf(L"ERROR - ParseArg(): missing argument for option '-mapfromsrc'");
655 |
656 | return false;
657 | }
658 |
659 | argc -= iCount;
660 | bReturn = bReturn && ParseArg(argc, &argv[iCount]);
661 | }
662 |
663 | else {
664 | wprintf(L"ERROR - unknown option %s\n", argv[0]);
665 |
666 | PrintHelpOptions();
667 |
668 | return false;
669 | }
670 |
671 | return bReturn;
672 | }
673 |
674 | ////////////////////////////////////////////////////////////
675 | // Display the usage
676 | //
677 | void PrintHelpOptions()
678 | {
679 | static const wchar_t * const helpString = L"usage: Dia2Dump.exe [ options ] \n"
680 | L" -? : print this help\n"
681 | L" -all : print all the debug info\n"
682 | L" -m : print all the mods\n"
683 | L" -p : print all the publics\n"
684 | L" -g : print all the globals\n"
685 | L" -t : print all the types\n"
686 | L" -f : print all the files\n"
687 | L" -s : print symbols\n"
688 | L" -l [RVA [bytes]] : print line number info at RVA address in the bytes range\n"
689 | L" -c : print section contribution info\n"
690 | L" -dbg : dump debug streams\n"
691 | L" -injsrc [file] : dump injected source\n"
692 | L" -sf : dump all source files\n"
693 | L" -oem : dump all OEM specific types\n"
694 | L" -fpo [RVA] : dump frame pointer omission information for a func addr\n"
695 | L" -fpo [symbolname] : dump frame pointer omission information for a func symbol\n"
696 | L" -compiland [name] : dump symbols for this compiland\n"
697 | L" -lines : dump line numbers for this function\n"
698 | L" -lines : dump line numbers for this address\n"
699 | L" -type : dump this type in detail\n"
700 | L" -label : dump label at RVA\n"
701 | L" -sym [childname] : dump child information of this symbol\n"
702 | L" -sym [childname] : dump child information of symbol at this addr\n"
703 | L" -lsrc [line] : dump line numbers for this source file\n"
704 | L" -ps [-n ] : dump symbols after this address, default 16\n"
705 | L" -psr [-n ] : dump symbols before this address, default 16\n"
706 | L" -annotations : dump annotation symbol for this RVA\n"
707 | L" -maptosrc : dump src RVA for this image RVA\n"
708 | L" -mapfromsrc : dump image RVA for src RVA\n";
709 |
710 | wprintf(helpString);
711 | }
712 |
713 | ////////////////////////////////////////////////////////////
714 | // Dump all the data stored in a PDB
715 | //
716 | void DumpAllPdbInfo(IDiaSession *pSession, IDiaSymbol *pGlobal)
717 | {
718 | DumpAllMods(pGlobal);
719 | DumpAllPublics(pGlobal);
720 | DumpAllSymbols(pGlobal);
721 | DumpAllGlobals(pGlobal);
722 | DumpAllTypes(pGlobal);
723 | DumpAllFiles(pSession, pGlobal);
724 | DumpAllLines(pSession, pGlobal);
725 | DumpAllSecContribs(pSession);
726 | DumpAllDebugStreams(pSession);
727 | DumpAllInjectedSources(pSession);
728 | DumpAllFPO(pSession);
729 | DumpAllOEMs(pGlobal);
730 | }
731 |
732 | ////////////////////////////////////////////////////////////
733 | // Dump all the modules information
734 | //
735 | bool DumpAllMods(IDiaSymbol *pGlobal)
736 | {
737 | wprintf(L"\n\n*** MODULES\n\n");
738 |
739 | // Retrieve all the compiland symbols
740 |
741 | IDiaEnumSymbols *pEnumSymbols;
742 |
743 | if (FAILED(pGlobal->findChildren(SymTagCompiland, NULL, nsNone, &pEnumSymbols))) {
744 | return false;
745 | }
746 |
747 | IDiaSymbol *pCompiland;
748 | ULONG celt = 0;
749 | ULONG iMod = 1;
750 |
751 | while (SUCCEEDED(pEnumSymbols->Next(1, &pCompiland, &celt)) && (celt == 1)) {
752 | BSTR bstrName;
753 |
754 | if (pCompiland->get_name(&bstrName) != S_OK) {
755 | wprintf(L"ERROR - Failed to get the compiland's name\n");
756 |
757 | pCompiland->Release();
758 | pEnumSymbols->Release();
759 |
760 | return false;
761 | }
762 |
763 | wprintf(L"%04X %s\n", iMod++, bstrName);
764 |
765 | // Deallocate the string allocated previously by the call to get_name
766 |
767 | SysFreeString(bstrName);
768 |
769 | pCompiland->Release();
770 | }
771 |
772 | pEnumSymbols->Release();
773 |
774 | putwchar(L'\n');
775 |
776 | return true;
777 | }
778 |
779 | ////////////////////////////////////////////////////////////
780 | // Dump all the public symbols - SymTagPublicSymbol
781 | //
782 | bool DumpAllPublics(IDiaSymbol *pGlobal)
783 | {
784 | wprintf(L"\n\n*** PUBLICS\n\n");
785 |
786 | // Retrieve all the public symbols
787 |
788 | IDiaEnumSymbols *pEnumSymbols;
789 |
790 | if (FAILED(pGlobal->findChildren(SymTagPublicSymbol, NULL, nsNone, &pEnumSymbols))) {
791 | return false;
792 | }
793 |
794 | IDiaSymbol *pSymbol;
795 | ULONG celt = 0;
796 |
797 | while (SUCCEEDED(pEnumSymbols->Next(1, &pSymbol, &celt)) && (celt == 1)) {
798 | PrintPublicSymbol(pSymbol);
799 |
800 | pSymbol->Release();
801 | }
802 |
803 | pEnumSymbols->Release();
804 |
805 | putwchar(L'\n');
806 |
807 | return true;
808 | }
809 |
810 | ////////////////////////////////////////////////////////////
811 | // Dump all the symbol information stored in the compilands
812 | //
813 | bool DumpAllSymbols(IDiaSymbol *pGlobal)
814 | {
815 | wprintf(L"\n\n*** SYMBOLS\n\n\n");
816 |
817 | // Retrieve the compilands first
818 |
819 | IDiaEnumSymbols *pEnumSymbols;
820 |
821 | if (FAILED(pGlobal->findChildren(SymTagCompiland, NULL, nsNone, &pEnumSymbols))) {
822 | return false;
823 | }
824 |
825 | IDiaSymbol *pCompiland;
826 | ULONG celt = 0;
827 |
828 | while (SUCCEEDED(pEnumSymbols->Next(1, &pCompiland, &celt)) && (celt == 1)) {
829 | wprintf(L"\n** Module: ");
830 |
831 | // Retrieve the name of the module
832 |
833 | BSTR bstrName;
834 |
835 | if (pCompiland->get_name(&bstrName) != S_OK) {
836 | wprintf(L"(???)\n\n");
837 | }
838 |
839 | else {
840 | wprintf(L"%s\n\n", bstrName);
841 |
842 | SysFreeString(bstrName);
843 | }
844 |
845 | // Find all the symbols defined in this compiland and print their info
846 |
847 | IDiaEnumSymbols *pEnumChildren;
848 |
849 | if (SUCCEEDED(pCompiland->findChildren(SymTagNull, NULL, nsNone, &pEnumChildren))) {
850 | IDiaSymbol *pSymbol;
851 | ULONG celtChildren = 0;
852 |
853 | while (SUCCEEDED(pEnumChildren->Next(1, &pSymbol, &celtChildren)) && (celtChildren == 1)) {
854 | PrintSymbol(pSymbol, 0);
855 | pSymbol->Release();
856 | }
857 |
858 | pEnumChildren->Release();
859 | }
860 |
861 | pCompiland->Release();
862 | }
863 |
864 | pEnumSymbols->Release();
865 |
866 | putwchar(L'\n');
867 |
868 | return true;
869 | }
870 |
871 | ////////////////////////////////////////////////////////////
872 | // Dump all the global symbols - SymTagFunction,
873 | // SymTagThunk and SymTagData
874 | //
875 | bool DumpAllGlobals(IDiaSymbol *pGlobal)
876 | {
877 | IDiaEnumSymbols *pEnumSymbols;
878 | IDiaSymbol *pSymbol;
879 | enum SymTagEnum dwSymTags[] = { SymTagFunction, SymTagThunk, SymTagData };
880 | ULONG celt = 0;
881 |
882 | wprintf(L"\n\n*** GLOBALS\n\n");
883 |
884 | for (size_t i = 0; i < _countof(dwSymTags); i++, pEnumSymbols = NULL) {
885 | if (SUCCEEDED(pGlobal->findChildren(dwSymTags[i], NULL, nsNone, &pEnumSymbols))) {
886 | while (SUCCEEDED(pEnumSymbols->Next(1, &pSymbol, &celt)) && (celt == 1)) {
887 | PrintGlobalSymbol(pSymbol);
888 |
889 | pSymbol->Release();
890 | }
891 |
892 | pEnumSymbols->Release();
893 | }
894 |
895 | else {
896 | wprintf(L"ERROR - DumpAllGlobals() returned no symbols\n");
897 |
898 | return false;
899 | }
900 | }
901 |
902 | putwchar(L'\n');
903 |
904 | return true;
905 | }
906 |
907 | ////////////////////////////////////////////////////////////
908 | // Dump all the types information
909 | // (type symbols can be UDTs, enums or typedefs)
910 | //
911 | bool DumpAllTypes(IDiaSymbol *pGlobal)
912 | {
913 | wprintf(L"\n\n*** TYPES\n");
914 |
915 | bool f1 = DumpAllUDTs(pGlobal);
916 | bool f2 = DumpAllEnums(pGlobal);
917 | bool f3 = DumpAllTypedefs(pGlobal);
918 |
919 | return f1 && f2 && f3;
920 | }
921 |
922 | ////////////////////////////////////////////////////////////
923 | // Dump all the user defined types (UDT)
924 | //
925 | bool DumpAllUDTs(IDiaSymbol *pGlobal)
926 | {
927 | wprintf(L"\n\n** User Defined Types\n\n");
928 |
929 | IDiaEnumSymbols *pEnumSymbols;
930 |
931 | if (FAILED(pGlobal->findChildren(SymTagUDT, NULL, nsNone, &pEnumSymbols))) {
932 | wprintf(L"ERROR - DumpAllUDTs() returned no symbols\n");
933 |
934 | return false;
935 | }
936 |
937 | IDiaSymbol *pSymbol;
938 | ULONG celt = 0;
939 |
940 | while (SUCCEEDED(pEnumSymbols->Next(1, &pSymbol, &celt)) && (celt == 1)) {
941 | PrintTypeInDetail(pSymbol, 0);
942 |
943 | pSymbol->Release();
944 | }
945 |
946 | pEnumSymbols->Release();
947 |
948 | putwchar(L'\n');
949 |
950 | return true;
951 | }
952 |
953 | ////////////////////////////////////////////////////////////
954 | // Dump all the enum types from the pdb
955 | //
956 | bool DumpAllEnums(IDiaSymbol *pGlobal)
957 | {
958 | wprintf(L"\n\n** ENUMS\n\n");
959 |
960 | IDiaEnumSymbols *pEnumSymbols;
961 |
962 | if (FAILED(pGlobal->findChildren(SymTagEnum, NULL, nsNone, &pEnumSymbols))) {
963 | wprintf(L"ERROR - DumpAllEnums() returned no symbols\n");
964 |
965 | return false;
966 | }
967 |
968 | IDiaSymbol *pSymbol;
969 | ULONG celt = 0;
970 |
971 | while (SUCCEEDED(pEnumSymbols->Next(1, &pSymbol, &celt)) && (celt == 1)) {
972 | PrintTypeInDetail(pSymbol, 0);
973 |
974 | pSymbol->Release();
975 | }
976 |
977 | pEnumSymbols->Release();
978 |
979 | putwchar(L'\n');
980 |
981 | return true;
982 | }
983 |
984 | ////////////////////////////////////////////////////////////
985 | // Dump all the typedef types from the pdb
986 | //
987 | bool DumpAllTypedefs(IDiaSymbol *pGlobal)
988 | {
989 | wprintf(L"\n\n** TYPEDEFS\n\n");
990 |
991 | IDiaEnumSymbols *pEnumSymbols;
992 |
993 | if (FAILED(pGlobal->findChildren(SymTagTypedef, NULL, nsNone, &pEnumSymbols))) {
994 | wprintf(L"ERROR - DumpAllTypedefs() returned no symbols\n");
995 |
996 | return false;
997 | }
998 |
999 | IDiaSymbol *pSymbol;
1000 | ULONG celt = 0;
1001 |
1002 | while (SUCCEEDED(pEnumSymbols->Next(1, &pSymbol, &celt)) && (celt == 1)) {
1003 | PrintTypeInDetail(pSymbol, 0);
1004 |
1005 | pSymbol->Release();
1006 | }
1007 |
1008 | pEnumSymbols->Release();
1009 |
1010 | putwchar(L'\n');
1011 |
1012 | return true;
1013 | }
1014 |
1015 | ////////////////////////////////////////////////////////////
1016 | // Dump OEM specific types
1017 | //
1018 | bool DumpAllOEMs(IDiaSymbol *pGlobal)
1019 | {
1020 | wprintf(L"\n\n*** OEM Specific types\n\n");
1021 |
1022 | IDiaEnumSymbols *pEnumSymbols;
1023 |
1024 | if (FAILED(pGlobal->findChildren(SymTagCustomType, NULL, nsNone, &pEnumSymbols))) {
1025 | wprintf(L"ERROR - DumpAllOEMs() returned no symbols\n");
1026 |
1027 | return false;
1028 | }
1029 |
1030 | IDiaSymbol *pSymbol;
1031 | ULONG celt = 0;
1032 |
1033 | while (SUCCEEDED(pEnumSymbols->Next(1, &pSymbol, &celt)) && (celt == 1)) {
1034 | PrintTypeInDetail(pSymbol, 0);
1035 |
1036 | pSymbol->Release();
1037 | }
1038 |
1039 | pEnumSymbols->Release();
1040 |
1041 | putwchar(L'\n');
1042 |
1043 | return true;
1044 | }
1045 |
1046 | ////////////////////////////////////////////////////////////
1047 | // For each compiland in the PDB dump all the source files
1048 | //
1049 | bool DumpAllFiles(IDiaSession *pSession, IDiaSymbol *pGlobal)
1050 | {
1051 | wprintf(L"\n\n*** FILES\n\n");
1052 |
1053 | // In order to find the source files, we have to look at the image's compilands/modules
1054 |
1055 | IDiaEnumSymbols *pEnumSymbols;
1056 |
1057 | if (FAILED(pGlobal->findChildren(SymTagCompiland, NULL, nsNone, &pEnumSymbols))) {
1058 | return false;
1059 | }
1060 |
1061 | IDiaSymbol *pCompiland;
1062 | ULONG celt = 0;
1063 |
1064 | while (SUCCEEDED(pEnumSymbols->Next(1, &pCompiland, &celt)) && (celt == 1)) {
1065 | BSTR bstrName;
1066 |
1067 | if (pCompiland->get_name(&bstrName) == S_OK) {
1068 | wprintf(L"\nCompiland = %s\n\n", bstrName);
1069 |
1070 | SysFreeString(bstrName);
1071 | }
1072 |
1073 | // Every compiland could contain multiple references to the source files which were used to build it
1074 | // Retrieve all source files by compiland by passing NULL for the name of the source file
1075 |
1076 | IDiaEnumSourceFiles *pEnumSourceFiles;
1077 |
1078 | if (SUCCEEDED(pSession->findFile(pCompiland, NULL, nsNone, &pEnumSourceFiles))) {
1079 | IDiaSourceFile *pSourceFile;
1080 |
1081 | while (SUCCEEDED(pEnumSourceFiles->Next(1, &pSourceFile, &celt)) && (celt == 1)) {
1082 | PrintSourceFile(pSourceFile);
1083 | putwchar(L'\n');
1084 |
1085 | pSourceFile->Release();
1086 | }
1087 |
1088 | pEnumSourceFiles->Release();
1089 | }
1090 |
1091 | putwchar(L'\n');
1092 |
1093 | pCompiland->Release();
1094 | }
1095 |
1096 | pEnumSymbols->Release();
1097 |
1098 | return true;
1099 | }
1100 |
1101 | ////////////////////////////////////////////////////////////
1102 | // Dump all the line numbering information contained in the PDB
1103 | // Only function symbols have corresponding line numbering information
1104 | bool DumpAllLines(IDiaSession *pSession, IDiaSymbol *pGlobal)
1105 | {
1106 | wprintf(L"\n\n*** LINES\n\n");
1107 |
1108 | // First retrieve the compilands/modules
1109 |
1110 | IDiaEnumSymbols *pEnumSymbols;
1111 |
1112 | if (FAILED(pGlobal->findChildren(SymTagCompiland, NULL, nsNone, &pEnumSymbols))) {
1113 | return false;
1114 | }
1115 |
1116 | IDiaSymbol *pCompiland;
1117 | ULONG celt = 0;
1118 |
1119 | while (SUCCEEDED(pEnumSymbols->Next(1, &pCompiland, &celt)) && (celt == 1)) {
1120 | IDiaEnumSymbols *pEnumFunction;
1121 |
1122 | // For every function symbol defined in the compiland, retrieve and print the line numbering info
1123 |
1124 | if (SUCCEEDED(pCompiland->findChildren(SymTagFunction, NULL, nsNone, &pEnumFunction))) {
1125 | IDiaSymbol *pFunction;
1126 |
1127 | while (SUCCEEDED(pEnumFunction->Next(1, &pFunction, &celt)) && (celt == 1)) {
1128 | PrintLines(pSession, pFunction);
1129 |
1130 | pFunction->Release();
1131 | }
1132 |
1133 | pEnumFunction->Release();
1134 | }
1135 |
1136 | pCompiland->Release();
1137 | }
1138 |
1139 | pEnumSymbols->Release();
1140 |
1141 | putwchar(L'\n');
1142 |
1143 | return true;
1144 | }
1145 |
1146 | ////////////////////////////////////////////////////////////
1147 | // Dump all the line numbering information for a given RVA
1148 | // and a given range
1149 | //
1150 | bool DumpAllLines(IDiaSession *pSession, DWORD dwRVA, DWORD dwRange)
1151 | {
1152 | // Retrieve and print the lines that corresponds to a specified RVA
1153 |
1154 | IDiaEnumLineNumbers *pLines;
1155 |
1156 | if (FAILED(pSession->findLinesByRVA(dwRVA, dwRange, &pLines))) {
1157 | return false;
1158 | }
1159 |
1160 | PrintLines(pLines);
1161 |
1162 | pLines->Release();
1163 |
1164 | putwchar(L'\n');
1165 |
1166 | return true;
1167 | }
1168 |
1169 | ////////////////////////////////////////////////////////////
1170 | // Dump all the section contributions from the PDB
1171 | //
1172 | // Section contributions are stored in a table which will
1173 | // be retrieved via IDiaSession->getEnumTables through
1174 | // QueryInterface()using the REFIID of the IDiaEnumSectionContribs
1175 | //
1176 | bool DumpAllSecContribs(IDiaSession *pSession)
1177 | {
1178 | wprintf(L"\n\n*** SECTION CONTRIBUTION\n\n");
1179 |
1180 | IDiaEnumSectionContribs *pEnumSecContribs;
1181 |
1182 | if (FAILED(GetTable(pSession, __uuidof(IDiaEnumSectionContribs), (void **) &pEnumSecContribs))) {
1183 | return false;
1184 | }
1185 |
1186 | wprintf(L" RVA Address Size Module\n");
1187 |
1188 | IDiaSectionContrib *pSecContrib;
1189 | ULONG celt = 0;
1190 |
1191 | while (SUCCEEDED(pEnumSecContribs->Next(1, &pSecContrib, &celt)) && (celt == 1)) {
1192 | PrintSecContribs(pSecContrib);
1193 |
1194 | pSecContrib->Release();
1195 | }
1196 |
1197 | pEnumSecContribs->Release();
1198 |
1199 | putwchar(L'\n');
1200 |
1201 | return true;
1202 | }
1203 |
1204 | ////////////////////////////////////////////////////////////
1205 | // Dump all debug data streams contained in the PDB
1206 | //
1207 | bool DumpAllDebugStreams(IDiaSession *pSession)
1208 | {
1209 | IDiaEnumDebugStreams *pEnumStreams;
1210 |
1211 | wprintf(L"\n\n*** DEBUG STREAMS\n\n");
1212 |
1213 | // Retrieve an enumerated sequence of debug data streams
1214 |
1215 | if (FAILED(pSession->getEnumDebugStreams(&pEnumStreams))) {
1216 | return false;
1217 | }
1218 |
1219 | IDiaEnumDebugStreamData *pStream;
1220 | ULONG celt = 0;
1221 |
1222 | for (; SUCCEEDED(pEnumStreams->Next(1, &pStream, &celt)) && (celt == 1); pStream = NULL) {
1223 | PrintStreamData(pStream);
1224 |
1225 | pStream->Release();
1226 | }
1227 |
1228 | pEnumStreams->Release();
1229 |
1230 | putwchar(L'\n');
1231 |
1232 | return true;
1233 | }
1234 |
1235 | ////////////////////////////////////////////////////////////
1236 | // Dump all the injected source from the PDB
1237 | //
1238 | // Injected sources data is stored in a table which will
1239 | // be retrieved via IDiaSession->getEnumTables through
1240 | // QueryInterface()using the REFIID of the IDiaEnumSectionContribs
1241 | //
1242 | bool DumpAllInjectedSources(IDiaSession *pSession)
1243 | {
1244 | wprintf(L"\n\n*** INJECTED SOURCES TABLE\n\n");
1245 |
1246 | IDiaEnumInjectedSources *pEnumInjSources = NULL;
1247 |
1248 | if (SUCCEEDED(GetTable(pSession, __uuidof(IDiaEnumInjectedSources), (void **) &pEnumInjSources))) {
1249 | return false;
1250 | }
1251 |
1252 | IDiaInjectedSource *pInjSource;
1253 | ULONG celt = 0;
1254 |
1255 | while (SUCCEEDED(pEnumInjSources->Next(1, &pInjSource, &celt)) && (celt == 1)) {
1256 | PrintGeneric(pInjSource);
1257 |
1258 | pInjSource->Release();
1259 | }
1260 |
1261 | pEnumInjSources->Release();
1262 |
1263 | putwchar(L'\n');
1264 |
1265 | return true;
1266 | }
1267 |
1268 | ////////////////////////////////////////////////////////////
1269 | // Dump info corresponing to a given injected source filename
1270 | //
1271 | bool DumpInjectedSource(IDiaSession *pSession, const wchar_t *szName)
1272 | {
1273 | // Retrieve a source that has been placed into the symbol store by attribute providers or
1274 | // other components of the compilation process
1275 |
1276 | IDiaEnumInjectedSources *pEnumInjSources;
1277 |
1278 | if (FAILED(pSession->findInjectedSource(szName, &pEnumInjSources))) {
1279 | wprintf(L"ERROR - DumpInjectedSources() could not find %s\n", szName);
1280 |
1281 | return false;
1282 | }
1283 |
1284 | IDiaInjectedSource *pInjSource;
1285 | ULONG celt = 0;
1286 |
1287 | while (SUCCEEDED(pEnumInjSources->Next(1, &pInjSource, &celt)) && (celt == 1)) {
1288 | PrintGeneric(pInjSource);
1289 |
1290 | pInjSource->Release();
1291 | }
1292 |
1293 | pEnumInjSources->Release();
1294 |
1295 | return true;
1296 | }
1297 |
1298 | ////////////////////////////////////////////////////////////
1299 | // Dump all the source file information stored in the PDB
1300 | // We have to go through every compiland in order to retrieve
1301 | // all the information otherwise checksums for instance
1302 | // will not be available
1303 | // Compilands can have multiple source files with the same
1304 | // name but different content which produces diffrent
1305 | // checksums
1306 | //
1307 | bool DumpAllSourceFiles(IDiaSession *pSession, IDiaSymbol *pGlobal)
1308 | {
1309 | wprintf(L"\n\n*** SOURCE FILES\n\n");
1310 |
1311 | // To get the complete source file info we must go through the compiland first
1312 | // by passing NULL instead all the source file names only will be retrieved
1313 |
1314 | IDiaEnumSymbols *pEnumSymbols;
1315 |
1316 | if (FAILED(pGlobal->findChildren(SymTagCompiland, NULL, nsNone, &pEnumSymbols))) {
1317 | return false;
1318 | }
1319 |
1320 | IDiaSymbol *pCompiland;
1321 | ULONG celt = 0;
1322 |
1323 | while (SUCCEEDED(pEnumSymbols->Next(1, &pCompiland, &celt)) && (celt == 1)) {
1324 | BSTR bstrName;
1325 |
1326 | if (pCompiland->get_name(&bstrName) == S_OK) {
1327 | wprintf(L"\nCompiland = %s\n\n", bstrName);
1328 |
1329 | SysFreeString(bstrName);
1330 | }
1331 |
1332 | // Every compiland could contain multiple references to the source files which were used to build it
1333 | // Retrieve all source files by compiland by passing NULL for the name of the source file
1334 |
1335 | IDiaEnumSourceFiles *pEnumSourceFiles;
1336 |
1337 | if (SUCCEEDED(pSession->findFile(pCompiland, NULL, nsNone, &pEnumSourceFiles))) {
1338 | IDiaSourceFile *pSourceFile;
1339 |
1340 | while (SUCCEEDED(pEnumSourceFiles->Next(1, &pSourceFile, &celt)) && (celt == 1)) {
1341 | PrintSourceFile(pSourceFile);
1342 | putwchar(L'\n');
1343 |
1344 | pSourceFile->Release();
1345 | }
1346 |
1347 | pEnumSourceFiles->Release();
1348 | }
1349 |
1350 | putwchar(L'\n');
1351 |
1352 | pCompiland->Release();
1353 | }
1354 |
1355 | pEnumSymbols->Release();
1356 |
1357 | return true;
1358 | }
1359 |
1360 | ////////////////////////////////////////////////////////////
1361 | // Dump all the FPO info
1362 | //
1363 | // FPO data stored in a table which will be retrieved via
1364 | // IDiaSession->getEnumTables through QueryInterface()
1365 | // using the REFIID of the IDiaEnumFrameData
1366 | //
1367 | bool DumpAllFPO(IDiaSession *pSession)
1368 | {
1369 | IDiaEnumFrameData *pEnumFrameData;
1370 |
1371 | wprintf(L"\n\n*** FPO\n\n");
1372 |
1373 | if (FAILED(GetTable(pSession, __uuidof(IDiaEnumFrameData), (void **) &pEnumFrameData))) {
1374 | return false;
1375 | }
1376 |
1377 | IDiaFrameData *pFrameData;
1378 | ULONG celt = 0;
1379 |
1380 | while (SUCCEEDED(pEnumFrameData->Next(1, &pFrameData, &celt)) && (celt == 1)) {
1381 | PrintFrameData(pFrameData);
1382 |
1383 | pFrameData->Release();
1384 | }
1385 |
1386 | pEnumFrameData->Release();
1387 |
1388 | putwchar(L'\n');
1389 |
1390 | return true;
1391 | }
1392 |
1393 | ////////////////////////////////////////////////////////////
1394 | // Dump FPO info for a function at the specified RVA
1395 | //
1396 | bool DumpFPO(IDiaSession *pSession, DWORD dwRVA)
1397 | {
1398 | IDiaEnumFrameData *pEnumFrameData;
1399 |
1400 | // Retrieve first the table holding all the FPO info
1401 |
1402 | if ((dwRVA != 0) && SUCCEEDED(GetTable(pSession, __uuidof(IDiaEnumFrameData), (void **) &pEnumFrameData))) {
1403 | IDiaFrameData *pFrameData;
1404 |
1405 | // Retrieve the frame data corresponding to the given RVA
1406 |
1407 | if (SUCCEEDED(pEnumFrameData->frameByRVA(dwRVA, &pFrameData))) {
1408 | PrintGeneric(pFrameData);
1409 |
1410 | pFrameData->Release();
1411 | }
1412 |
1413 | else {
1414 | // Some function might not have FPO data available (see ASM funcs like strcpy)
1415 |
1416 | wprintf(L"ERROR - DumpFPO() frameByRVA invalid RVA: 0x%08X\n", dwRVA);
1417 |
1418 | pEnumFrameData->Release();
1419 |
1420 | return false;
1421 | }
1422 |
1423 | pEnumFrameData->Release();
1424 | }
1425 |
1426 | else {
1427 | wprintf(L"ERROR - DumpFPO() GetTable\n");
1428 |
1429 | return false;
1430 | }
1431 |
1432 | putwchar(L'\n');
1433 |
1434 | return true;
1435 | }
1436 |
1437 | ////////////////////////////////////////////////////////////
1438 | // Dump FPO info for a specified function symbol using its
1439 | // name (a regular expression string is used for the search)
1440 | //
1441 | bool DumpFPO(IDiaSession *pSession, IDiaSymbol *pGlobal, const wchar_t *szSymbolName)
1442 | {
1443 | IDiaEnumSymbols *pEnumSymbols;
1444 | IDiaSymbol *pSymbol;
1445 | ULONG celt = 0;
1446 | DWORD dwRVA;
1447 |
1448 | // Find first all the function symbols that their names matches the search criteria
1449 |
1450 | if (FAILED(pGlobal->findChildren(SymTagFunction, szSymbolName, nsRegularExpression, &pEnumSymbols))) {
1451 | wprintf(L"ERROR - DumpFPO() findChildren could not find symol %s\n", szSymbolName);
1452 |
1453 | return false;
1454 | }
1455 |
1456 | while (SUCCEEDED(pEnumSymbols->Next(1, &pSymbol, &celt)) && (celt == 1)) {
1457 | if (pSymbol->get_relativeVirtualAddress(&dwRVA) == S_OK) {
1458 | PrintPublicSymbol(pSymbol);
1459 |
1460 | DumpFPO(pSession, dwRVA);
1461 | }
1462 |
1463 | pSymbol->Release();
1464 | }
1465 |
1466 | pEnumSymbols->Release();
1467 |
1468 | putwchar(L'\n');
1469 |
1470 | return true;
1471 | }
1472 |
1473 | ////////////////////////////////////////////////////////////
1474 | // Dump a specified compiland and all the symbols defined in it
1475 | //
1476 | bool DumpCompiland(IDiaSymbol *pGlobal, const wchar_t *szCompName)
1477 | {
1478 | IDiaEnumSymbols *pEnumSymbols;
1479 |
1480 | if (FAILED(pGlobal->findChildren(SymTagCompiland, szCompName, nsCaseInsensitive, &pEnumSymbols))) {
1481 | return false;
1482 | }
1483 |
1484 | IDiaSymbol *pCompiland;
1485 | ULONG celt = 0;
1486 |
1487 | while (SUCCEEDED(pEnumSymbols->Next(1, &pCompiland, &celt)) && (celt == 1)) {
1488 | wprintf(L"\n** Module: ");
1489 |
1490 | // Retrieve the name of the module
1491 |
1492 | BSTR bstrName;
1493 |
1494 | if (pCompiland->get_name(&bstrName) != S_OK) {
1495 | wprintf(L"(???)\n\n");
1496 | }
1497 |
1498 | else {
1499 | wprintf(L"%s\n\n", bstrName);
1500 |
1501 | SysFreeString(bstrName);
1502 | }
1503 |
1504 | IDiaEnumSymbols *pEnumChildren;
1505 |
1506 | if (SUCCEEDED(pCompiland->findChildren(SymTagNull, NULL, nsNone, &pEnumChildren))) {
1507 | IDiaSymbol *pSymbol;
1508 | ULONG celt_ = 0;
1509 |
1510 | while (SUCCEEDED(pEnumChildren->Next(1, &pSymbol, &celt_)) && (celt_ == 1)) {
1511 | PrintSymbol(pSymbol, 0);
1512 |
1513 | pSymbol->Release();
1514 | }
1515 |
1516 | pEnumChildren->Release();
1517 | }
1518 |
1519 | pCompiland->Release();
1520 | }
1521 |
1522 | pEnumSymbols->Release();
1523 |
1524 | return true;
1525 | }
1526 |
1527 | ////////////////////////////////////////////////////////////
1528 | // Dump the line numbering information for a specified RVA
1529 | //
1530 | bool DumpLines(IDiaSession *pSession, DWORD dwRVA)
1531 | {
1532 | IDiaEnumLineNumbers *pLines;
1533 |
1534 | if (FAILED(pSession->findLinesByRVA(dwRVA, MAX_RVA_LINES_BYTES_RANGE, &pLines))) {
1535 | return false;
1536 | }
1537 |
1538 | PrintLines(pLines);
1539 |
1540 | pLines->Release();
1541 |
1542 | return true;
1543 | }
1544 |
1545 | ////////////////////////////////////////////////////////////
1546 | // Dump the all line numbering information for a specified
1547 | // function symbol name (as a regular expression string)
1548 | //
1549 | bool DumpLines(IDiaSession *pSession, IDiaSymbol *pGlobal, const wchar_t *szFuncName)
1550 | {
1551 | IDiaEnumSymbols *pEnumSymbols;
1552 |
1553 | if (FAILED(pGlobal->findChildren(SymTagFunction, szFuncName, nsRegularExpression, &pEnumSymbols))) {
1554 | return false;
1555 | }
1556 |
1557 | IDiaSymbol *pFunction;
1558 | ULONG celt = 0;
1559 |
1560 | while (SUCCEEDED(pEnumSymbols->Next(1, &pFunction, &celt)) && (celt == 1)) {
1561 | PrintLines(pSession, pFunction);
1562 |
1563 | pFunction->Release();
1564 | }
1565 |
1566 | pEnumSymbols->Release();
1567 |
1568 | return true;
1569 | }
1570 |
1571 | ////////////////////////////////////////////////////////////
1572 | // Dump the symbol information corresponding to a specified RVA
1573 | //
1574 | bool DumpSymbolWithRVA(IDiaSession *pSession, DWORD dwRVA, const wchar_t *szChildname)
1575 | {
1576 | IDiaSymbol *pSymbol;
1577 | LONG lDisplacement;
1578 |
1579 | if (FAILED(pSession->findSymbolByRVAEx(dwRVA, SymTagNull, &pSymbol, &lDisplacement))) {
1580 | return false;
1581 | }
1582 |
1583 | wprintf(L"Displacement = 0x%X\n", lDisplacement);
1584 |
1585 | PrintGeneric(pSymbol);
1586 |
1587 | DumpSymbolWithChildren(pSymbol, szChildname);
1588 |
1589 | while (pSymbol != NULL) {
1590 | IDiaSymbol *pParent;
1591 |
1592 | if ((pSymbol->get_lexicalParent(&pParent) == S_OK) && pParent) {
1593 | wprintf(L"\nParent\n");
1594 |
1595 | PrintSymbol(pParent, 0);
1596 |
1597 | pSymbol->Release();
1598 |
1599 | pSymbol = pParent;
1600 | }
1601 |
1602 | else {
1603 | pSymbol->Release();
1604 | break;
1605 | }
1606 | }
1607 |
1608 | return true;
1609 | }
1610 |
1611 | ////////////////////////////////////////////////////////////
1612 | // Dump the symbols information where their names matches a
1613 | // specified regular expression string
1614 | //
1615 | bool DumpSymbolsWithRegEx(IDiaSymbol *pGlobal, const wchar_t *szRegEx, const wchar_t *szChildname)
1616 | {
1617 | IDiaEnumSymbols *pEnumSymbols;
1618 |
1619 | if (FAILED(pGlobal->findChildren(SymTagNull, szRegEx, nsRegularExpression, &pEnumSymbols))) {
1620 | return false;
1621 | }
1622 |
1623 | bool bReturn = true;
1624 |
1625 | IDiaSymbol *pSymbol;
1626 | ULONG celt = 0;
1627 |
1628 | while (SUCCEEDED(pEnumSymbols->Next(1, &pSymbol, &celt)) && (celt == 1)) {
1629 | PrintGeneric(pSymbol);
1630 |
1631 | bReturn = DumpSymbolWithChildren(pSymbol, szChildname);
1632 |
1633 | pSymbol->Release();
1634 | }
1635 |
1636 | pEnumSymbols->Release();
1637 |
1638 | return bReturn;
1639 | }
1640 |
1641 | ////////////////////////////////////////////////////////////
1642 | // Dump the information corresponding to a symbol name which
1643 | // is a children of the specified parent symbol
1644 | //
1645 | bool DumpSymbolWithChildren(IDiaSymbol *pSymbol, const wchar_t *szChildname)
1646 | {
1647 | if (szChildname != NULL) {
1648 | IDiaEnumSymbols *pEnumSyms;
1649 |
1650 | if (FAILED(pSymbol->findChildren(SymTagNull, szChildname, nsRegularExpression, &pEnumSyms))) {
1651 | return false;
1652 | }
1653 |
1654 | IDiaSymbol *pChild;
1655 | DWORD celt = 1;
1656 |
1657 | while (SUCCEEDED(pEnumSyms->Next(celt, &pChild, &celt)) && (celt == 1)) {
1658 | PrintGeneric(pChild);
1659 | PrintSymbol(pChild, 0);
1660 |
1661 | pChild->Release();
1662 | }
1663 |
1664 | pEnumSyms->Release();
1665 | }
1666 |
1667 | else {
1668 | // If the specified name is NULL then only the parent symbol data is displayed
1669 |
1670 | DWORD dwSymTag;
1671 |
1672 | if ((pSymbol->get_symTag(&dwSymTag) == S_OK) && (dwSymTag == SymTagPublicSymbol)) {
1673 | PrintPublicSymbol(pSymbol);
1674 | }
1675 |
1676 | else {
1677 | PrintSymbol(pSymbol, 0);
1678 | }
1679 | }
1680 |
1681 | return true;
1682 | }
1683 |
1684 | ////////////////////////////////////////////////////////////
1685 | // Dump all the type symbols information that matches their
1686 | // names to a specified regular expression string
1687 | //
1688 | bool DumpType(IDiaSymbol *pGlobal, const wchar_t *szRegEx)
1689 | {
1690 | IDiaEnumSymbols *pEnumSymbols;
1691 |
1692 | if (FAILED(pGlobal->findChildren(SymTagUDT, szRegEx, nsRegularExpression, &pEnumSymbols))) {
1693 | return false;
1694 | }
1695 |
1696 | IDiaSymbol *pSymbol;
1697 | ULONG celt = 0;
1698 |
1699 | while (SUCCEEDED(pEnumSymbols->Next(1, &pSymbol, &celt)) && (celt == 1)) {
1700 | PrintTypeInDetail(pSymbol, 0);
1701 |
1702 | pSymbol->Release();
1703 | }
1704 |
1705 | pEnumSymbols->Release();
1706 |
1707 | return true;
1708 | }
1709 |
1710 | ////////////////////////////////////////////////////////////
1711 | // Dump line numbering information for a given file name and
1712 | // an optional line number
1713 | //
1714 | bool DumpLinesForSourceFile(IDiaSession *pSession, const wchar_t *szFileName, DWORD dwLine)
1715 | {
1716 | IDiaEnumSourceFiles *pEnumSrcFiles;
1717 |
1718 | if (FAILED(pSession->findFile(NULL, szFileName, nsFNameExt, &pEnumSrcFiles))) {
1719 | return false;
1720 | }
1721 |
1722 | IDiaSourceFile *pSrcFile;
1723 | ULONG celt = 0;
1724 |
1725 | while (SUCCEEDED(pEnumSrcFiles->Next(1, &pSrcFile, &celt)) && (celt == 1)) {
1726 | IDiaEnumSymbols *pEnumCompilands;
1727 |
1728 | if (pSrcFile->get_compilands(&pEnumCompilands) == S_OK) {
1729 | IDiaSymbol *pCompiland;
1730 |
1731 | celt = 0;
1732 | while (SUCCEEDED(pEnumCompilands->Next(1, &pCompiland, &celt)) && (celt == 1)) {
1733 | BSTR bstrName;
1734 |
1735 | if (pCompiland->get_name(&bstrName) == S_OK) {
1736 | wprintf(L"Compiland = %s\n", bstrName);
1737 |
1738 | SysFreeString(bstrName);
1739 | }
1740 |
1741 | else {
1742 | wprintf(L"Compiland = (???)\n");
1743 | }
1744 |
1745 | IDiaEnumLineNumbers *pLines;
1746 |
1747 | if (dwLine != 0) {
1748 | if (SUCCEEDED(pSession->findLinesByLinenum(pCompiland, pSrcFile, dwLine, 0, &pLines))) {
1749 | PrintLines(pLines);
1750 |
1751 | pLines->Release();
1752 | }
1753 | }
1754 |
1755 | else {
1756 | if (SUCCEEDED(pSession->findLines(pCompiland, pSrcFile, &pLines))) {
1757 | PrintLines(pLines);
1758 |
1759 | pLines->Release();
1760 | }
1761 | }
1762 |
1763 | pCompiland->Release();
1764 | }
1765 |
1766 | pEnumCompilands->Release();
1767 | }
1768 |
1769 | pSrcFile->Release();
1770 | }
1771 |
1772 | pEnumSrcFiles->Release();
1773 |
1774 | return true;
1775 | }
1776 |
1777 | ////////////////////////////////////////////////////////////
1778 | // Dump public symbol information for a given number of
1779 | // symbols around a given RVA address
1780 | //
1781 | bool DumpPublicSymbolsSorted(IDiaSession *pSession, DWORD dwRVA, DWORD dwRange, bool bReverse)
1782 | {
1783 | IDiaEnumSymbolsByAddr *pEnumSymsByAddr;
1784 |
1785 | if (FAILED(pSession->getSymbolsByAddr(&pEnumSymsByAddr))) {
1786 | return false;
1787 | }
1788 |
1789 | IDiaSymbol *pSymbol;
1790 |
1791 | if (SUCCEEDED(pEnumSymsByAddr->symbolByRVA(dwRVA, &pSymbol))) {
1792 | if (dwRange == 0) {
1793 | PrintPublicSymbol(pSymbol);
1794 | }
1795 |
1796 | ULONG celt;
1797 | ULONG i;
1798 |
1799 | if (bReverse) {
1800 | pSymbol->Release();
1801 |
1802 | i = 0;
1803 |
1804 | for (pSymbol = NULL; (i < dwRange) && SUCCEEDED(pEnumSymsByAddr->Next(1, &pSymbol, &celt)) && (celt == 1); i++) {
1805 | PrintPublicSymbol(pSymbol);
1806 |
1807 | pSymbol->Release();
1808 | }
1809 | }
1810 |
1811 | else {
1812 | PrintPublicSymbol(pSymbol);
1813 |
1814 | pSymbol->Release();
1815 |
1816 | i = 1;
1817 |
1818 | for (pSymbol = NULL; (i < dwRange) && SUCCEEDED(pEnumSymsByAddr->Prev(1, &pSymbol, &celt)) && (celt == 1); i++) {
1819 | PrintPublicSymbol(pSymbol);
1820 | }
1821 | }
1822 | }
1823 |
1824 | pEnumSymsByAddr->Release();
1825 |
1826 | return true;
1827 | }
1828 |
1829 | ////////////////////////////////////////////////////////////
1830 | // Dump label symbol information at a given RVA
1831 | //
1832 | bool DumpLabel(IDiaSession *pSession, DWORD dwRVA)
1833 | {
1834 | IDiaSymbol *pSymbol;
1835 | LONG lDisplacement;
1836 |
1837 | if (FAILED(pSession->findSymbolByRVAEx(dwRVA, SymTagLabel, &pSymbol, &lDisplacement)) || (pSymbol == NULL)) {
1838 | return false;
1839 | }
1840 |
1841 | wprintf(L"Displacement = 0x%X\n", lDisplacement);
1842 |
1843 | PrintGeneric(pSymbol);
1844 |
1845 | pSymbol->Release();
1846 |
1847 | return true;
1848 | }
1849 |
1850 | ////////////////////////////////////////////////////////////
1851 | // Dump annotation symbol information at a given RVA
1852 | //
1853 | bool DumpAnnotations(IDiaSession *pSession, DWORD dwRVA)
1854 | {
1855 | IDiaSymbol *pSymbol;
1856 | LONG lDisplacement;
1857 |
1858 | if (FAILED(pSession->findSymbolByRVAEx(dwRVA, SymTagAnnotation, &pSymbol, &lDisplacement)) || (pSymbol == NULL)) {
1859 | return false;
1860 | }
1861 |
1862 | wprintf(L"Displacement = 0x%X\n", lDisplacement);
1863 |
1864 | PrintGeneric(pSymbol);
1865 |
1866 | pSymbol->Release();
1867 |
1868 | return true;
1869 | }
1870 |
1871 | struct OMAP_DATA
1872 | {
1873 | DWORD dwRVA;
1874 | DWORD dwRVATo;
1875 | };
1876 |
1877 | ////////////////////////////////////////////////////////////
1878 | //
1879 | bool DumpMapToSrc(IDiaSession *pSession, DWORD dwRVA)
1880 | {
1881 | IDiaEnumDebugStreams *pEnumStreams;
1882 | IDiaEnumDebugStreamData *pStream;
1883 | ULONG celt;
1884 |
1885 | if (FAILED(pSession->getEnumDebugStreams(&pEnumStreams))) {
1886 | return false;
1887 | }
1888 |
1889 | celt = 0;
1890 |
1891 | for (; SUCCEEDED(pEnumStreams->Next(1, &pStream, &celt)) && (celt == 1); pStream = NULL) {
1892 | BSTR bstrName;
1893 |
1894 | if (pStream->get_name(&bstrName) != S_OK) {
1895 | bstrName = NULL;
1896 | }
1897 |
1898 | if (bstrName && wcscmp(bstrName, L"OMAPTO") == 0) {
1899 | OMAP_DATA data, datasav;
1900 | DWORD cbData;
1901 | DWORD dwRVATo = 0;
1902 | unsigned int i;
1903 |
1904 | datasav.dwRVATo = 0;
1905 | datasav.dwRVA = 0;
1906 |
1907 | while (SUCCEEDED(pStream->Next(1, sizeof(data), &cbData, (BYTE*) &data, &celt)) && (celt == 1)) {
1908 | if (dwRVA > data.dwRVA) {
1909 | datasav = data;
1910 | continue;
1911 | }
1912 |
1913 | else if (dwRVA == data.dwRVA) {
1914 | dwRVATo = data.dwRVATo;
1915 | }
1916 |
1917 | else if (datasav.dwRVATo) {
1918 | dwRVATo = datasav.dwRVATo + (dwRVA - datasav.dwRVA);
1919 | }
1920 | break;
1921 | }
1922 |
1923 | wprintf(L"image rva = %08X ==> source rva = %08X\n\nRelated OMAP entries:\n", dwRVA, dwRVATo);
1924 | wprintf(L"image rva ==> source rva\n");
1925 | wprintf(L"%08X ==> %08X\n", datasav.dwRVA, datasav.dwRVATo);
1926 |
1927 | i = 0;
1928 |
1929 | do {
1930 | wprintf(L"%08X ==> %08X\n", data.dwRVA, data.dwRVATo);
1931 | }
1932 | while ((++i) < 5 && SUCCEEDED(pStream->Next(1, sizeof(data), &cbData, (BYTE*) &data, &celt)) && (celt == 1));
1933 | }
1934 |
1935 | if (bstrName != NULL) {
1936 | SysFreeString(bstrName);
1937 | }
1938 |
1939 | pStream->Release();
1940 | }
1941 |
1942 | pEnumStreams->Release();
1943 |
1944 | return true;
1945 | }
1946 |
1947 | ////////////////////////////////////////////////////////////
1948 | //
1949 | bool DumpMapFromSrc(IDiaSession *pSession, DWORD dwRVA)
1950 | {
1951 | IDiaEnumDebugStreams *pEnumStreams;
1952 |
1953 | if (FAILED(pSession->getEnumDebugStreams(&pEnumStreams))) {
1954 | return false;
1955 | }
1956 |
1957 | IDiaEnumDebugStreamData *pStream;
1958 | ULONG celt = 0;
1959 |
1960 | for (; SUCCEEDED(pEnumStreams->Next(1, &pStream, &celt)) && (celt == 1); pStream = NULL) {
1961 | BSTR bstrName;
1962 |
1963 | if (pStream->get_name(&bstrName) != S_OK) {
1964 | bstrName = NULL;
1965 | }
1966 |
1967 | if (bstrName && wcscmp(bstrName, L"OMAPFROM") == 0) {
1968 | OMAP_DATA data;
1969 | OMAP_DATA datasav;
1970 | DWORD cbData;
1971 | DWORD dwRVATo = 0;
1972 | unsigned int i;
1973 |
1974 | datasav.dwRVATo = 0;
1975 | datasav.dwRVA = 0;
1976 |
1977 | while (SUCCEEDED(pStream->Next(1, sizeof(data), &cbData, (BYTE*) &data, &celt)) && (celt == 1)) {
1978 | if (dwRVA > data.dwRVA) {
1979 | datasav = data;
1980 | continue;
1981 | }
1982 |
1983 | else if (dwRVA == data.dwRVA) {
1984 | dwRVATo = data.dwRVATo;
1985 | }
1986 |
1987 | else if (datasav.dwRVATo) {
1988 | dwRVATo = datasav.dwRVATo + (dwRVA - datasav.dwRVA);
1989 | }
1990 | break;
1991 | }
1992 |
1993 | wprintf(L"source rva = %08X ==> image rva = %08X\n\nRelated OMAP entries:\n", dwRVA, dwRVATo);
1994 | wprintf(L"source rva ==> image rva\n");
1995 | wprintf(L"%08X ==> %08X\n", datasav.dwRVA, datasav.dwRVATo);
1996 |
1997 | i = 0;
1998 |
1999 | do {
2000 | wprintf(L"%08X ==> %08X\n", data.dwRVA, data.dwRVATo);
2001 | }
2002 | while ((++i) < 5 && SUCCEEDED(pStream->Next(1, sizeof(data), &cbData, (BYTE*) &data, &celt)) && (celt == 1));
2003 | }
2004 |
2005 | if (bstrName != NULL) {
2006 | SysFreeString(bstrName);
2007 | }
2008 |
2009 | pStream->Release();
2010 | }
2011 |
2012 | pEnumStreams->Release();
2013 |
2014 | return true;
2015 | }
2016 |
2017 | ////////////////////////////////////////////////////////////
2018 | // Retreive the table that matches the given iid
2019 | //
2020 | // A PDB table could store the section contributions, the frame data,
2021 | // the injected sources
2022 | //
2023 | HRESULT GetTable(IDiaSession *pSession, REFIID iid, void **ppUnk)
2024 | {
2025 | IDiaEnumTables *pEnumTables;
2026 |
2027 | if (FAILED(pSession->getEnumTables(&pEnumTables))) {
2028 | wprintf(L"ERROR - GetTable() getEnumTables\n");
2029 |
2030 | return E_FAIL;
2031 | }
2032 |
2033 | IDiaTable *pTable;
2034 | ULONG celt = 0;
2035 |
2036 | while (SUCCEEDED(pEnumTables->Next(1, &pTable, &celt)) && (celt == 1)) {
2037 | // There's only one table that matches the given IID
2038 |
2039 | if (SUCCEEDED(pTable->QueryInterface(iid, (void **) ppUnk))) {
2040 | pTable->Release();
2041 | pEnumTables->Release();
2042 |
2043 | return S_OK;
2044 | }
2045 |
2046 | pTable->Release();
2047 | }
2048 |
2049 | pEnumTables->Release();
2050 |
2051 | return E_FAIL;
2052 | }
2053 |
--------------------------------------------------------------------------------
/dia2dump.h:
--------------------------------------------------------------------------------
1 | #include "dia2.h"
2 |
3 | extern const wchar_t *g_szFilename;
4 | extern IDiaDataSource *g_pDiaDataSource;
5 | extern IDiaSession *g_pDiaSession;
6 | extern IDiaSymbol *g_pGlobalSymbol;
7 | extern DWORD g_dwMachineType;
8 |
9 | void PrintHelpOptions();
10 | bool ParseArg(int , wchar_t *[]);
11 |
12 | void Cleanup();
13 | bool LoadDataFromPdb(const wchar_t *, IDiaDataSource **, IDiaSession **, IDiaSymbol **);
14 |
15 | void DumpAllPdbInfo(IDiaSession *, IDiaSymbol *);
16 | bool DumpAllMods(IDiaSymbol *);
17 | bool DumpAllPublics(IDiaSymbol *);
18 | bool DumpCompiland(IDiaSymbol *, const wchar_t *);
19 | bool DumpAllSymbols(IDiaSymbol *);
20 | bool DumpAllGlobals(IDiaSymbol *);
21 | bool DumpAllTypes(IDiaSymbol *);
22 | bool DumpAllUDTs(IDiaSymbol *);
23 | bool DumpAllEnums(IDiaSymbol *);
24 | bool DumpAllTypedefs(IDiaSymbol *);
25 | bool DumpAllOEMs(IDiaSymbol *);
26 | bool DumpAllFiles(IDiaSession *, IDiaSymbol *);
27 | bool DumpAllLines(IDiaSession *, IDiaSymbol *);
28 | bool DumpAllLines(IDiaSession *, DWORD, DWORD);
29 | bool DumpAllSecContribs(IDiaSession *);
30 | bool DumpAllDebugStreams(IDiaSession *);
31 | bool DumpAllInjectedSources(IDiaSession *);
32 | bool DumpInjectedSource(IDiaSession *, const wchar_t *);
33 | bool DumpAllSourceFiles(IDiaSession *, IDiaSymbol *);
34 | bool DumpAllFPO(IDiaSession *);
35 | bool DumpFPO(IDiaSession *, DWORD);
36 | bool DumpFPO(IDiaSession *, IDiaSymbol *, const wchar_t *);
37 | bool DumpSymbolWithRVA(IDiaSession *, DWORD, const wchar_t *);
38 | bool DumpSymbolsWithRegEx(IDiaSymbol *, const wchar_t *, const wchar_t *);
39 | bool DumpSymbolWithChildren(IDiaSymbol *, const wchar_t *);
40 | bool DumpLines(IDiaSession *, DWORD);
41 | bool DumpLines(IDiaSession *, IDiaSymbol *, const wchar_t *);
42 | bool DumpType(IDiaSymbol *, const wchar_t *);
43 | bool DumpLinesForSourceFile(IDiaSession *, const wchar_t *, DWORD);
44 | bool DumpPublicSymbolsSorted(IDiaSession *, DWORD, DWORD, bool);
45 | bool DumpLabel(IDiaSession *, DWORD);
46 | bool DumpAnnotations(IDiaSession *, DWORD);
47 | bool DumpMapToSrc(IDiaSession *, DWORD);
48 | bool DumpMapFromSrc(IDiaSession *, DWORD);
49 |
50 | HRESULT GetTable(IDiaSession *, REFIID, void **);
51 |
52 | ///////////////////////////////////////////////////////////////////
53 | // Functions defined in regs.cpp
54 | const wchar_t *SzNameC7Reg(USHORT, DWORD);
55 | const wchar_t *SzNameC7Reg(USHORT);
56 |
--------------------------------------------------------------------------------
/regs.h:
--------------------------------------------------------------------------------
1 | extern const wchar_t * const rgRegX86[];
2 | extern const wchar_t * const rgRegAMD64[];
3 | extern const wchar_t * const rgRegMips[];
4 | extern const wchar_t * const rgReg68k[];
5 | extern const wchar_t * const rgRegAlpha[];
6 | extern const wchar_t * const rgRegPpc[];
7 | extern const wchar_t * const rgRegSh[];
8 | extern const wchar_t * const rgRegArm[];
9 |
10 | typedef struct MapIa64Reg{
11 | CV_HREG_e iCvReg;
12 | const wchar_t* wszRegName;
13 | }MapIa64Reg;
14 | extern const MapIa64Reg mpIa64regSz[];
15 | int cmpIa64regSz( const void* , const void* );
16 |
17 | extern DWORD g_dwMachineType;
18 | const wchar_t* SzNameC7Reg( USHORT , DWORD );
19 | const wchar_t* SzNameC7Reg( USHORT );
20 |
--------------------------------------------------------------------------------
/stdafx.cpp:
--------------------------------------------------------------------------------
1 | // stdafx.cpp : source file that includes just the standard includes
2 | // Dia2Dump.pch will be the pre-compiled header
3 | // stdafx.obj will contain the pre-compiled type information
4 |
5 | #include "stdafx.h"
6 |
7 | // TODO: reference any additional headers you need in STDAFX.H
8 | // and not in this file
9 |
--------------------------------------------------------------------------------
/stdafx.h:
--------------------------------------------------------------------------------
1 | // stdafx.h : include file for standard system include files,
2 | // or project specific include files that are used frequently, but
3 | // are changed infrequently
4 | //
5 |
6 | #pragma once
7 |
8 |
9 | #define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers
10 | #include
11 | #include
12 | #include
13 |
14 |
15 |
16 | // TODO: reference additional headers your program requires here
17 | #include "dia2.h"
18 |
19 |
--------------------------------------------------------------------------------
/x_common.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | static const wchar_t* rgCallConv[] =
4 | {
5 | L"", // CV_CALL_NEAR_C (__cdecl)
6 | L"__fastcall", // CV_CALL_NEAR_FAST
7 | L"__stdcall" // CV_CALL_NEAR_STD
8 | L"__syscall", // CV_CALL_NEAR_SYS
9 | L"__thoscall", // CV_CALL_THISCALL
10 | L"__clrcall" // CV_CALL_CLRCALL
11 | };
12 |
13 | class Bstr
14 | {
15 | public:
16 | BSTR _str;
17 |
18 | inline Bstr() : _str(NULL) {}
19 | inline Bstr(BSTR str) : _str(str) {}
20 |
21 | inline BSTR* operator &() { Release(); return &_str; }
22 | inline BSTR operator *() { return _str; }
23 |
24 | inline void Release() { if (_str) { SysFreeString(_str); _str = NULL; } }
25 | inline ~Bstr() { Release(); }
26 | };
27 |
28 | template
29 | class ComRef
30 | {
31 | public:
32 | T* _ptr;
33 |
34 | inline ComRef() : _ptr(NULL) {}
35 | inline ComRef(T* ptr) : _ptr(ptr) {}
36 | inline ComRef(const ComRef& other) { _ptr = other._ptr; if (_ptr) { _ptr->AddRef(); } }
37 | inline ComRef& operator=(const ComRef& other) { Release(); _ptr = other._ptr; if (_ptr) { _ptr->AddRef(); } return *this; }
38 |
39 | inline T** operator &() { Release(); return &_ptr; }
40 | inline T* operator *() { return _ptr; }
41 | inline T* operator ->() { return _ptr; }
42 |
43 | inline void Release() { if (_ptr) { _ptr->Release(); _ptr = NULL; } }
44 | inline ~ComRef() { Release(); }
45 | };
46 |
47 | class SymbolEnumerator
48 | {
49 | public:
50 | ComRef _enumerator;
51 | ComRef _sym;
52 |
53 | inline SymbolEnumerator() {}
54 |
55 | inline bool Find(IDiaSymbol* parent, enum SymTagEnum tagType, const wchar_t* filter = NULL, NameSearchOptions opt = nsNone) {
56 | return (SUCCEEDED(parent->findChildren(tagType, filter, opt, &_enumerator)));
57 | }
58 |
59 | inline bool Next() {
60 | ULONG celt = 0;
61 | return (SUCCEEDED(_enumerator->Next(1, &_sym, &celt)) && (celt == 1));
62 | }
63 |
64 | inline IDiaSymbol* operator *() { return _sym._ptr; }
65 | inline IDiaSymbol* operator ->() { return _sym._ptr; }
66 | inline ComRef& ref() { return _sym; }
67 | };
68 |
69 | static ComRef FindSymbol(IDiaSymbol* parent, enum SymTagEnum tagType, const wchar_t* filter = NULL)
70 | {
71 | ComRef enumerator;
72 | if (SUCCEEDED(parent->findChildren(tagType, filter, nsNone, &enumerator))) {
73 | IDiaSymbol* child = NULL;
74 | ULONG celt = 0;
75 | if (SUCCEEDED(enumerator->Next(1, &child, &celt)) && (celt == 1)) {
76 | return ComRef(child);
77 | }
78 | }
79 | return ComRef();
80 | }
81 |
--------------------------------------------------------------------------------
/x_cpp_enum.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | static void CppPrintEnum(IDiaSymbol *pGlobal, const wchar_t* filter, FILE* fd = stdout)
4 | {
5 | SymbolEnumerator symbol;
6 | if (symbol.Find(pGlobal, SymTagEnum, filter)) {
7 | while (symbol.Next()) {
8 |
9 | Bstr name;
10 | symbol->get_name(&name);
11 | if (!IsAllowedName(*name)) return;
12 |
13 | std::wstring nameFixed(fixEnumName(*name));
14 | fwprintf(fd, L"enum class %s {\n", nameFixed.c_str());
15 |
16 | SymbolEnumerator data;
17 | if (data.Find(*symbol, SymTagData, NULL)) {
18 | while (data.Next()) {
19 |
20 | DWORD dwDataKind = 0;
21 | data->get_dataKind(&dwDataKind);
22 |
23 | if (dwDataKind == DataIsConstant)
24 | {
25 | Bstr dataName;
26 | data->get_name(&dataName);
27 |
28 | fwprintf(fd, L"\t");
29 | fwprintf(fd, L"%s =", *dataName);
30 |
31 | VARIANT vt = { VT_EMPTY };
32 | if (data->get_value(&vt) == S_OK) {
33 |
34 | std::wstring valStr;
35 | PrintVariantX(vt, &valStr);
36 | fwprintf(fd, L"%s", valStr.c_str());
37 |
38 | VariantClear((VARIANTARG *)&vt);
39 | }
40 |
41 | fwprintf(fd, L",\n");
42 | }
43 | }
44 | }
45 |
46 | fwprintf(fd, L"};\n");
47 | }
48 | }
49 | }
50 |
51 | static void CppPrintEnums(IDiaSymbol *global, ResolvedUdtGraphPtr graph, FILE* fd = stdout)
52 | {
53 | std::unordered_set uniqEnums;
54 |
55 | for (auto& node : graph->nodes) {
56 | for (auto& idep : node->dep_s) {
57 | if (*idep.second) {
58 |
59 | DWORD tag;
60 | idep.second->get_symTag(&tag);
61 |
62 | if (tag == SymTagEnum) {
63 | if (uniqEnums.find(idep.first) == uniqEnums.end()) {
64 |
65 | uniqEnums.insert(idep.first);
66 | CppPrintEnum(global, idep.first.c_str(), fd);
67 | fwprintf(fd, L"\n");
68 | }
69 | }
70 | }
71 | }
72 | }
73 | }
74 |
--------------------------------------------------------------------------------
/x_cpp_gen_file.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | static void CppGenEnums(IDiaSymbol *global, ResolvedUdtGraphPtr graph)
4 | {
5 | std::unordered_set uniqEnums;
6 |
7 | for (auto& node : graph->nodes) {
8 | for (auto& idep : node->dep_s) {
9 | if (*idep.second) {
10 |
11 | DWORD tag;
12 | idep.second->get_symTag(&tag);
13 |
14 | if (tag == SymTagEnum) {
15 |
16 | std::wstring nameFixed(fixEnumName(idep.first));
17 | std::wstring fileName(nameFixed + L".h");
18 |
19 | if (uniqEnums.find(nameFixed) == uniqEnums.end()) {
20 | uniqEnums.insert(nameFixed);
21 |
22 | FILE* fd = NULL;
23 | _wfopen_s(&fd, fileName.c_str(), L"wt");
24 | if (fd)
25 | {
26 | fwprintf(fd, L"#pragma once\n\n");
27 | CppPrintEnum(global, idep.first.c_str(), fd);
28 | fclose(fd);
29 | }
30 | }
31 | }
32 | }
33 | else {
34 | //wprintf(L"%s is null\n", idep.first.c_str());
35 | }
36 | }
37 | }
38 | }
39 |
40 | static void CppGenClass(IDiaSymbol *pGlobal, IDiaSymbol *pUDT, UdtNodePtr& node, ResolvedUdtGraphPtr& resolved, UdtGraphPtr& graph)
41 | {
42 | DWORD symTag;
43 | if (pUDT->get_symTag(&symTag) != S_OK) return;
44 | if (symTag != SymTagUDT) return;
45 |
46 | DWORD kind = 0;
47 | pUDT->get_udtKind(&kind);
48 | if (!(kind == UdtStruct || kind == UdtClass))
49 | {
50 | return;
51 | }
52 |
53 | Bstr name;
54 | if (pUDT->get_name(&name) != S_OK) {
55 | return;
56 | }
57 |
58 | std::wstring uname(*name);
59 | std::wstring nameFixed(fixName(uname));
60 | std::wstring namePrefix;
61 | std::wstring nameInner;
62 | {
63 | size_t pos = uname.find_last_of(L"::");
64 | if (pos != std::string::npos)
65 | {
66 | namePrefix.assign(uname.substr(0, pos - 1));
67 | nameInner.assign(uname.substr(pos + 1));
68 | }
69 | else
70 | {
71 | namePrefix.clear();
72 | nameInner.assign(uname);
73 | }
74 | }
75 |
76 | std::wstring fileName(nameFixed + L".h");
77 | FILE* fd = NULL;
78 | _wfopen_s(&fd, fileName.c_str(), L"wt");
79 | if (!fd) return;
80 |
81 | struct ScopedFile {
82 | FILE* _fd;
83 | ScopedFile(FILE* fd) : _fd(fd) {}
84 | ScopedFile() { if (_fd) { fclose(_fd); } }
85 | };
86 | ScopedFile sfd(fd);
87 |
88 | fwprintf(fd, L"#pragma once\n\n");
89 |
90 | // deps
91 | {
92 | std::unordered_set uniq;
93 | int count = 0;
94 |
95 | for (auto& idep : node->dep_s) {
96 |
97 | if (!endsWith(idep.first, L'*') && IsAllowedName(idep.first.c_str()) && !startsWith(idep.first, L"void")) {
98 |
99 | std::wstring name(idep.first);
100 | trim(name);
101 |
102 | auto inode = graph->nodes.find(name);
103 | if (inode != graph->nodes.end()) {
104 |
105 | auto className(fixName(name));
106 |
107 | if (IsTemplateClass(idep.first.c_str()))
108 | {
109 | size_t inner = className.find_first_of(L'<');
110 | auto templName(className.substr(0, inner));
111 |
112 | if (!templName.empty() && uniq.find(templName) == uniq.end()) {
113 | uniq.insert(templName);
114 |
115 | fwprintf(fd, L"#include \"%s.h\"\n", templName.c_str());
116 | ++count;
117 | }
118 | }
119 | else
120 | {
121 | if (!className.empty() && uniq.find(className) == uniq.end()) {
122 | uniq.insert(className);
123 |
124 | fwprintf(fd, L"#include \"%s.h\"\n", className.c_str());
125 | ++count;
126 | }
127 | }
128 | }
129 | else {
130 | auto depSym = FindSymbol(pGlobal, SymTagEnum, name.c_str());
131 | if (*depSym)
132 | {
133 | DWORD depTag = 0;
134 | depSym->get_symTag(&depTag);
135 | if (depTag == SymTagEnum)
136 | {
137 | auto enumName(fixEnumName(name));
138 |
139 | if (!enumName.empty() && uniq.find(enumName) == uniq.end()) {
140 | uniq.insert(enumName);
141 | fwprintf(fd, L"#include \"%s.h\"\n", enumName.c_str());
142 | ++count;
143 | }
144 | }
145 | }
146 | }
147 | }
148 | }
149 | if (count) {
150 | fwprintf(fd, L"\n");
151 | }
152 | }
153 |
154 | // forward decls
155 | {
156 | std::unordered_set uniq;
157 | int count = 0;
158 | for (auto& idep : node->dep_s) {
159 |
160 | if (endsWith(idep.first, L'*') && IsAllowedName(idep.first.c_str()) && !startsWith(idep.first, L"void")) {
161 |
162 | std::wstring name(idep.first);
163 | replace(name, L"*", L"");
164 | trim(name);
165 |
166 | auto inode = graph->nodes.find(name);
167 | if (inode != graph->nodes.end()) {
168 |
169 | auto fixedName(fixName(name));
170 | if (!fixedName.empty() && uniq.find(fixedName) == uniq.end()) {
171 | uniq.insert(fixedName);
172 |
173 | DWORD kind;
174 | inode->second->symbol->get_udtKind(&kind);
175 | fwprintf(fd, L"%s %s;\n", rgUdtKind[kind], fixedName.c_str());
176 | ++count;
177 | }
178 | }
179 | }
180 | }
181 | if (count) {
182 | fwprintf(fd, L"\n");
183 | }
184 | }
185 |
186 | // enums
187 | {
188 | #if 0
189 | for (auto& idep : node->dep_s) {
190 | if (*idep.second) {
191 |
192 | DWORD tag;
193 | idep.second->get_symTag(&tag)
194 |
195 | if (tag == SymTagEnum) {
196 | if (uniqEnums.find(idep.first) == uniqEnums.end()) {
197 |
198 | uniqEnums.insert(idep.first);
199 | CppPrintEnum(pGlobal, idep.first.c_str(), fd);
200 | }
201 | }
202 | }
203 | }
204 | #endif
205 | }
206 |
207 | // class
208 | fwprintf(fd, L"%s %s", rgUdtKind[kind], nameFixed.c_str());
209 |
210 | // base class
211 | {
212 | int baseId = 0;
213 | SymbolEnumerator symbol;
214 | if (symbol.Find(pUDT, SymTagBaseClass, NULL)) {
215 | while (symbol.Next()) {
216 |
217 | if (!baseId) fwprintf(fd, L" : ");
218 | else fwprintf(fd, L", ");
219 | fwprintf(fd, L"public ");
220 |
221 | Bstr baseName;
222 | symbol->get_name(&baseName);
223 |
224 | std::wstring baseNameFixed(fixName(*baseName));
225 | fwprintf(fd, L"%s", baseNameFixed.c_str());
226 | baseId++;
227 | }
228 | }
229 | }
230 |
231 | // body
232 | fwprintf(fd, L" {\n");
233 | fwprintf(fd, L"public:\n");
234 |
235 | // data
236 | {
237 | SymbolEnumerator symbol;
238 | if (symbol.Find(pUDT, SymTagData, NULL)) {
239 | while (symbol.Next()) {
240 |
241 | DWORD dwDataKind;
242 | symbol->get_dataKind(&dwDataKind);
243 |
244 | if (dwDataKind == DataIsMember)
245 | {
246 | Bstr fieldName;
247 | symbol->get_name(&fieldName);
248 |
249 | ComRef fieldType;
250 | symbol->get_type(&fieldType);
251 |
252 | DWORD fieldTypeTag;
253 | fieldType->get_symTag(&fieldTypeTag);
254 |
255 | fwprintf(fd, L"\t");
256 |
257 | if (fieldTypeTag == SymTagPointerType)
258 | {
259 | }
260 |
261 | std::wstring fieldTypeStr;
262 | PrintTypeX(*fieldType, &fieldTypeStr);
263 | fwprintf(fd, L"%s", fieldTypeStr.c_str());
264 |
265 | fwprintf(fd, L" %s", *fieldName);
266 |
267 | if (fieldTypeTag == SymTagArrayType)
268 | {
269 | std::wstring arrTypeStr;
270 | PrintArraySizeX(*fieldType, &arrTypeStr);
271 | fwprintf(fd, L"%s", arrTypeStr.c_str());
272 | }
273 |
274 | fwprintf(fd, L";\n");
275 | }
276 | }
277 | }
278 | }
279 |
280 | // stubs
281 | {
282 | int funcLineId = 0;
283 | SymbolEnumerator symbol;
284 | if (symbol.Find(pUDT, SymTagFunction, NULL)) {
285 | while (symbol.Next()) {
286 |
287 | DWORD funcId;
288 | symbol->get_symIndexId(&funcId);
289 |
290 | Bstr funcName;
291 | symbol->get_name(&funcName);
292 | if (wcsstr(*funcName, L"__vecDelDtor")) continue;
293 | if (wcsstr(*funcName, L"__local_vftable_ctor_closure")) continue;
294 |
295 | BOOL isPure = FALSE;
296 | symbol->get_pure(&isPure);
297 |
298 | BOOL isVirtual = FALSE;
299 | symbol->get_virtual(&isVirtual);
300 |
301 | if (isPure && !isVirtual) continue;
302 |
303 | ULONGLONG len = 0;
304 | DWORD dwLocType = 0, dwRVA = 0, dwSect = 0, dwOff = 0;
305 | symbol->get_length(&len);
306 | symbol->get_locationType(&dwLocType);
307 | symbol->get_relativeVirtualAddress(&dwRVA);
308 | symbol->get_addressSection(&dwSect);
309 | symbol->get_addressOffset(&dwOff);
310 |
311 | BOOL isOptimized = (dwLocType == 0);
312 | //if (isOptimized && !isVirtual) continue;
313 |
314 | DWORD vtpo = 0; // virtual table pointer offset
315 | DWORD vfid = 0; // virtual function id in VT
316 | if (isVirtual) {
317 | GetVirtualFuncInfo(pUDT, *symbol, vtpo, vfid);
318 | }
319 |
320 | DWORD callConv = 0;
321 | symbol->get_callingConvention(&callConv);
322 |
323 | ComRef funcType;
324 | symbol->get_type(&funcType);
325 |
326 | ComRef returnType;
327 | funcType->get_type(&returnType);
328 |
329 | BOOL isDtor = (wcsstr(*funcName, L"~") ? TRUE : FALSE);
330 | BOOL isCtor = (wcscmp(*funcName, nameInner.c_str()) == 0);
331 | BOOL isFunc = !(isCtor || isDtor);
332 |
333 | // skip non virtual dtors
334 | if (!isVirtual && isDtor) continue;
335 |
336 | if (!funcLineId++) {
337 | fwprintf(fd, L"\n");
338 | }
339 |
340 | if (!isVirtual) {
341 |
342 | fwprintf(fd, L"\t");
343 | if (isDtor) {
344 | //fwprintf(fd, L"~%s", nameFixed.c_str());
345 | }
346 | else if (isCtor) {
347 | fwprintf(fd, L"%s", nameFixed.c_str());
348 | }
349 | else {
350 | std::wstring returnTypeStr;
351 | PrintTypeX(*returnType, &returnTypeStr);
352 | fwprintf(fd, L"%s", returnTypeStr.c_str());
353 |
354 | fwprintf(fd, L" ");
355 |
356 | if (callConv > 0) {
357 | fwprintf(fd, L"%s ", rgCallConv[callConv]); // not __cdecl
358 | }
359 |
360 | if (isVirtual) {
361 | fwprintf(fd, L"%s_impl", *funcName);
362 | }
363 | else {
364 | fwprintf(fd, L"%s", *funcName);
365 | }
366 | }
367 | fwprintf(fd, L"(");
368 | std::wstring funcArgsStr;
369 | PrintFunctionArgsX(*symbol, TRUE, TRUE, NULL, &funcArgsStr);
370 | fwprintf(fd, L"%s", funcArgsStr.c_str());
371 | fwprintf(fd, L")");
372 |
373 | fwprintf(fd, L" {} ");
374 | fwprintf(fd, L"\n");
375 | }
376 |
377 | if (isVirtual) {
378 | if (isDtor) {
379 | fwprintf(fd, L"\tvirtual ~%s()", nameFixed.c_str());
380 | }
381 | else {
382 | fwprintf(fd, L"\tvirtual ");
383 |
384 | std::wstring returnTypeStr;
385 | PrintTypeX(*returnType, &returnTypeStr);
386 | fwprintf(fd, L"%s", returnTypeStr.c_str());
387 |
388 | fwprintf(fd, L" ");
389 | if (callConv > 0) {
390 | fwprintf(fd, L"%s ", rgCallConv[callConv]);
391 | }
392 | fwprintf(fd, L"%s(", *funcName);
393 |
394 | std::wstring funcArgsStr;
395 | PrintFunctionArgsX(*symbol, TRUE, TRUE, NULL, &funcArgsStr);
396 | fwprintf(fd, L"%s", funcArgsStr.c_str());
397 |
398 | fwprintf(fd, L")");
399 | }
400 | if (isPure) {
401 | fwprintf(fd, L" = 0;");
402 | }
403 | else {
404 | fwprintf(fd, L" {}");
405 | }
406 | fwprintf(fd, L" // vf%u", (unsigned int)vfid);
407 | fwprintf(fd, L"\n");
408 | }
409 | }
410 | }
411 | }
412 |
413 | fwprintf(fd, L"};\n"); // end UDT
414 | fwprintf(fd, L"\n");
415 | }
416 |
--------------------------------------------------------------------------------
/x_cpp_proxy.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | static void CppProxyPrintForwardDecl(IDiaSymbol *global, ResolvedUdtGraphPtr resolved, UdtGraphPtr graph)
4 | {
5 | std::unordered_set uniq;
6 |
7 | int count = 0;
8 | for (auto& node : resolved->nodes) {
9 | for (auto& idep : node->dep_s) {
10 |
11 | if (endsWith(idep.first, L'*') && IsAllowedName(idep.first.c_str()) && !startsWith(idep.first, L"void")) {
12 |
13 | std::wstring name(idep.first);
14 | replace(name, L"*", L"");
15 | trim(name);
16 |
17 | auto inode = graph->nodes.find(name);
18 | if (inode != graph->nodes.end()) {
19 |
20 | auto fixedName(fixName(name));
21 | if (!fixedName.empty() && uniq.find(fixedName) == uniq.end()) {
22 | uniq.insert(fixedName);
23 |
24 | DWORD kind;
25 | inode->second->symbol->get_udtKind(&kind);
26 |
27 | wprintf(L"%s %s;\n", rgUdtKind[kind], fixedName.c_str());
28 | ++count;
29 | }
30 | }
31 | }
32 | }
33 | }
34 | if (count) {
35 | wprintf(L"\n");
36 | }
37 | }
38 |
39 | static void CppProxyPrintUDT(IDiaSymbol *pUDT, BOOL bGuardObject = FALSE, BOOL bZeroInitialize = FALSE)
40 | {
41 | // https://github.com/MicrosoftDocs/visualstudio-docs/blob/master/docs/debugger/debug-interface-access/lexical-hierarchy-of-symbol-types.md
42 | // https://github.com/MicrosoftDocs/visualstudio-docs/blob/master/docs/debugger/debug-interface-access/class-hierarchy-of-symbol-types.md
43 | // https://github.com/MicrosoftDocs/visualstudio-docs/blob/master/docs/debugger/debug-interface-access/udt.md
44 |
45 | DWORD symTag;
46 | if (pUDT->get_symTag(&symTag) != S_OK) return;
47 | if (symTag != SymTagUDT) return;
48 |
49 | DWORD kind = 0;
50 | pUDT->get_udtKind(&kind);
51 | if (!(kind == UdtStruct || kind == UdtClass))
52 | {
53 | return;
54 | }
55 |
56 | Bstr name;
57 | if (pUDT->get_name(&name) != S_OK) {
58 | return;
59 | }
60 |
61 | // class
62 | std::wstring uname(*name);
63 | std::wstring nameFixed(fixName(uname));
64 | std::wstring namePrefix;
65 | std::wstring nameInner;
66 | {
67 | size_t pos = uname.find_last_of(L"::");
68 | if (pos != std::string::npos)
69 | {
70 | namePrefix.assign(uname.substr(0, pos - 1));
71 | nameInner.assign(uname.substr(pos + 1));
72 | }
73 | else
74 | {
75 | namePrefix.clear();
76 | nameInner.assign(uname);
77 | }
78 | }
79 |
80 | wprintf(L"%s %s", rgUdtKind[kind], nameFixed.c_str());
81 |
82 | // base class
83 | {
84 | int baseId = 0;
85 | SymbolEnumerator symbol;
86 | if (symbol.Find(pUDT, SymTagBaseClass, NULL)) {
87 | while (symbol.Next()) {
88 |
89 | if (!baseId) wprintf(L" : ");
90 | else wprintf(L", ");
91 | wprintf(L"public ");
92 |
93 | Bstr baseName;
94 | symbol->get_name(&baseName);
95 |
96 | std::wstring baseNameFixed(fixName(*baseName));
97 | wprintf(L"%s", baseNameFixed.c_str());
98 | baseId++;
99 | }
100 | }
101 | }
102 |
103 | // body
104 | wprintf(L" {\n");
105 | wprintf(L"public:\n");
106 |
107 | BOOL addFakeVtp = FALSE;
108 |
109 | // virtual table ptr
110 | {
111 | BOOL hasIntroVf = FALSE;
112 | BOOL hasOverVf = FALSE;
113 |
114 | SymbolEnumerator symbol;
115 | if (symbol.Find(pUDT, SymTagFunction, NULL)) {
116 | while (symbol.Next()) {
117 |
118 | Bstr funcName;
119 | symbol->get_name(&funcName);
120 |
121 | BOOL isVirtual = FALSE;
122 | symbol->get_virtual(&isVirtual);
123 |
124 | if (isVirtual) {
125 | BOOL isIntro = FALSE;
126 | symbol->get_intro(&isIntro);
127 |
128 | if (isIntro)
129 | hasIntroVf = TRUE;
130 | else
131 | hasOverVf = TRUE;
132 | }
133 | }
134 | }
135 |
136 | if (hasIntroVf && !hasOverVf)
137 | {
138 | addFakeVtp = TRUE;
139 | wprintf(L"\tvoid* _vtable;\n");
140 | }
141 | }
142 |
143 | // data
144 | {
145 | SymbolEnumerator symbol;
146 | if (symbol.Find(pUDT, SymTagData, NULL)) {
147 | while (symbol.Next()) {
148 |
149 | DWORD dwDataKind;
150 | symbol->get_dataKind(&dwDataKind);
151 |
152 | if (dwDataKind == DataIsMember)
153 | {
154 | Bstr fieldName;
155 | symbol->get_name(&fieldName);
156 |
157 | ComRef fieldType;
158 | symbol->get_type(&fieldType);
159 |
160 | DWORD fieldTypeTag;
161 | fieldType->get_symTag(&fieldTypeTag);
162 |
163 | BOOL isRef = FALSE;
164 | fieldType->get_reference(&isRef);
165 |
166 | wprintf(L"\t");
167 | if (!isRef) {
168 | PrintTypeX(*fieldType);
169 | }
170 | else {
171 | PrintPointerTypeX(*fieldType, NULL, TRUE);
172 | }
173 | wprintf(L" %s", *fieldName);
174 |
175 | if (fieldTypeTag == SymTagArrayType)
176 | {
177 | PrintArraySizeX(*fieldType);
178 | }
179 |
180 | // default zero initialization
181 | if (bZeroInitialize && (fieldTypeTag == SymTagBaseType || fieldTypeTag == SymTagPointerType || fieldTypeTag == SymTagEnum || fieldTypeTag == SymTagArrayType))
182 | {
183 | if (!isRef)
184 | {
185 | if (fieldTypeTag == SymTagEnum)
186 | {
187 | // SomeEnum e = {} crashes the compiler LOL
188 | wprintf(L" = (");
189 | PrintTypeX(*fieldType);
190 | wprintf(L")(0)");
191 | }
192 | else if (fieldTypeTag == SymTagArrayType)
193 | {
194 | ComRef arrType;
195 | fieldType->get_type(&arrType);
196 |
197 | DWORD arrTypeTag;
198 | arrType->get_symTag(&arrTypeTag);
199 |
200 | if (arrTypeTag == SymTagBaseType || arrTypeTag == SymTagPointerType)
201 | {
202 | wprintf(L" = {}");
203 | }
204 | }
205 | else
206 | wprintf(L" = 0");
207 | }
208 | }
209 |
210 | wprintf(L";\n");
211 | }
212 | }
213 | }
214 | }
215 |
216 | // methods
217 | {
218 | BOOL hasDefConstructor = FALSE;
219 | BOOL hasCtor = FALSE;
220 | BOOL hasDtor = FALSE;
221 |
222 | std::wstring ctorPrefix;
223 | ctorPrefix.assign(L"__cdecl ");
224 | ctorPrefix.assign(nameInner);
225 | ctorPrefix.append(L"::");
226 | ctorPrefix.append(nameInner);
227 | ctorPrefix.append(L"(");
228 |
229 | std::wstring fixedFuncName;
230 | fixedFuncName.reserve(1024);
231 |
232 | std::wstring funcNamespace(*name);
233 | funcNamespace.append(L"::");
234 |
235 | SymbolEnumerator symbol;
236 | if (symbol.Find(pUDT, SymTagFunction, NULL)) {
237 | while (symbol.Next()) {
238 |
239 | DWORD funcId;
240 | symbol->get_symIndexId(&funcId);
241 |
242 | Bstr funcName;
243 | symbol->get_name(&funcName);
244 | if (wcsstr(*funcName, L"__vecDelDtor")) continue;
245 |
246 | fixedFuncName.assign(*funcName);
247 | replace(fixedFuncName, funcNamespace, L"");
248 |
249 | Bstr undecName;
250 | symbol->get_undecoratedName(&undecName);
251 |
252 | BOOL isDtor = (wcsstr(*funcName, L"~") ? TRUE : FALSE);
253 | BOOL isCtor = (wcscmp(*funcName, nameInner.c_str()) == 0);
254 |
255 | // HACK for newer msdia
256 | if (wcsstr(*undecName, ctorPrefix.c_str()))
257 | {
258 | isCtor = TRUE;
259 | }
260 |
261 | BOOL isFunc = !(isCtor || isDtor);
262 |
263 | BOOL isPure = FALSE;
264 | symbol->get_pure(&isPure);
265 |
266 | BOOL isVirtual = FALSE;
267 | symbol->get_virtual(&isVirtual);
268 |
269 | BOOL isStatic = FALSE;
270 | symbol->get_isStatic(&isStatic);
271 |
272 | ULONGLONG len = 0;
273 | DWORD dwLocType = 0, dwRVA = 0, dwSect = 0, dwOff = 0;
274 | symbol->get_length(&len);
275 | symbol->get_locationType(&dwLocType);
276 | symbol->get_relativeVirtualAddress(&dwRVA);
277 | symbol->get_addressSection(&dwSect);
278 | symbol->get_addressOffset(&dwOff);
279 | BOOL isOptimized = (dwLocType == 0);
280 |
281 | // HACK for newer msdia
282 | if (isFunc && dwLocType == LocIsStatic && dwRVA && isPure && !isVirtual)
283 | {
284 | isStatic = TRUE;
285 | }
286 |
287 | BOOL isValidVirtual = FALSE;
288 | DWORD vtpo = 0; // virtual table pointer offset
289 | DWORD vfid = 0; // virtual function id in VT
290 |
291 | if (isVirtual) {
292 | isValidVirtual = GetVirtualFuncInfo(pUDT, *symbol, vtpo, vfid);
293 | if (!isValidVirtual) {
294 | wprintf(L"\t#error INVALID VFID %s::%s\n", nameFixed.c_str(), *funcName);
295 | }
296 | }
297 |
298 | DWORD callConv = 0;
299 | symbol->get_callingConvention(&callConv); // rgCallConv[callConv]
300 |
301 | ComRef funcType;
302 | symbol->get_type(&funcType);
303 |
304 | ComRef returnType;
305 | funcType->get_type(&returnType);
306 |
307 | // UDT ctor/dtor
308 |
309 | if (isCtor && !isOptimized) {
310 | hasCtor = TRUE;
311 | wprintf(L"\tinline %s * ctor(", nameFixed.c_str());
312 | PrintFunctionArgsX(*symbol, TRUE, TRUE);
313 | wprintf(L") {");
314 |
315 | wprintf(L" typedef ");
316 | wprintf(L"%s *", nameFixed.c_str());
317 | wprintf(L" (%s::*_fpt)(", nameFixed.c_str());
318 | PrintFunctionArgsX(*symbol, TRUE, FALSE);
319 | wprintf(L");");
320 |
321 | wprintf(L" auto _f=xcast<_fpt>(_drva(%u));", (unsigned int)dwRVA);
322 | wprintf(L" return (this->*_f)(");
323 | PrintFunctionArgsX(*symbol, FALSE, TRUE);
324 | wprintf(L");");
325 |
326 | wprintf(L" }\n");
327 | }
328 |
329 | if (isDtor && (!isOptimized || (isVirtual && isValidVirtual))) {
330 | hasDtor = TRUE;
331 | wprintf(L"\tinline void dtor() {");
332 |
333 | wprintf(L" typedef ");
334 | PrintTypeX(*returnType);
335 | wprintf(L" (%s::*_fpt)(", nameFixed.c_str());
336 | PrintFunctionArgsX(*symbol, TRUE, FALSE);
337 | wprintf(L");");
338 |
339 | if (isVirtual) {
340 | wprintf(L" auto _f=xcast<_fpt>(get_vfp(this, %u));", (unsigned int)vfid);
341 | }
342 | else {
343 | wprintf(L" auto _f=xcast<_fpt>(_drva(%u));", (unsigned int)dwRVA);
344 | }
345 | wprintf(L" (this->*_f)();");
346 |
347 | wprintf(L" }\n");
348 | }
349 |
350 | // direct rva calls
351 |
352 | if (isFunc && !isOptimized) {
353 |
354 | wprintf(L"\tinline ");
355 | if (isStatic) {
356 | wprintf(L"static ");
357 | }
358 | PrintTypeX(*returnType);
359 | wprintf(L" ");
360 | if (callConv > 0) {
361 | wprintf(L"%s ", rgCallConv[callConv]);
362 | }
363 | if (isVirtual) {
364 | wprintf(L"%s_impl", fixedFuncName.c_str()); // funcName
365 | }
366 | else {
367 | wprintf(L"%s", fixedFuncName.c_str()); // funcName
368 | }
369 | wprintf(L"(");
370 | PrintFunctionArgsX(*symbol, TRUE, TRUE);
371 | wprintf(L")");
372 |
373 | // body
374 | wprintf(L" { ");
375 |
376 | wprintf(L"typedef ");
377 | PrintTypeX(*returnType);
378 | wprintf(L" (");
379 | if (callConv > 0) {
380 | wprintf(L"%s ", rgCallConv[callConv]);
381 | }
382 | if (!isStatic) {
383 | wprintf(L"%s::", nameFixed.c_str());
384 | }
385 | wprintf(L"*_fpt)(");
386 | if (isStatic) {
387 | PrintFunctionArgsX(*symbol, TRUE, FALSE);
388 | }
389 | else {
390 | PrintFunctionArgsX(*symbol, TRUE, FALSE);
391 | }
392 | wprintf(L");");
393 |
394 | if (isStatic) {
395 | wprintf(L" auto _f=(_fpt)_drva(%u);", (unsigned int)dwRVA);
396 | }
397 | else {
398 | wprintf(L" auto _f=xcast<_fpt>(_drva(%u));", (unsigned int)dwRVA);
399 | }
400 |
401 | if (isStatic) {
402 | wprintf(L" return _f(");
403 | }
404 | else {
405 | wprintf(L" return (this->*_f)(");
406 | }
407 | if (isStatic) {
408 | PrintFunctionArgsX(*symbol, FALSE, TRUE);
409 | }
410 | else {
411 | PrintFunctionArgsX(*symbol, FALSE, TRUE);
412 | }
413 | wprintf(L");");
414 |
415 | wprintf(L" }");
416 | wprintf(L"\n");
417 | }
418 |
419 | // virtual redirectors
420 |
421 | #if defined(GEN_VFUNC_REDIR)
422 | if (isVirtual && isFunc) {
423 | wprintf(L"\tinline ");
424 | PrintTypeX(*returnType);
425 | wprintf(L" %s(", fixedFuncName.c_str()); // *funcName
426 | PrintFunctionArgsX(*symbol, TRUE, TRUE);
427 | wprintf(L") {");
428 |
429 | wprintf(L" typedef ");
430 | PrintTypeX(*returnType);
431 | wprintf(L" (%s::*_fpt)(", nameFixed.c_str());
432 | PrintFunctionArgsX(*symbol, TRUE, FALSE);
433 | wprintf(L");");
434 | wprintf(L" auto _f=xcast<_fpt>(get_vfp(this, %u));", (unsigned int)vfid);
435 | wprintf(L" return (this->*_f)(");
436 | PrintFunctionArgsX(*symbol, FALSE, TRUE);
437 | wprintf(L");");
438 |
439 | wprintf(L" }\n");
440 | }
441 | #endif
442 | }
443 | }
444 |
445 | if (!hasCtor) {
446 | wprintf(L"\tinline %s * ctor() { return this; }\n", nameFixed.c_str());
447 | }
448 |
449 | if (!hasDtor) {
450 | wprintf(L"\tinline void dtor() {}\n");
451 | }
452 | }
453 |
454 | // guard
455 | if (bGuardObject)
456 | {
457 | ULONGLONG len = 0;
458 | pUDT->get_length(&len);
459 |
460 | wprintf(L"\tinline void _guard_obj() {\n");
461 | wprintf(L"\t\tstatic_assert((sizeof(%s)==%u),\"bad size\");\n", nameFixed.c_str(), (unsigned int)len);
462 |
463 | SymbolEnumerator symbol;
464 | if (symbol.Find(pUDT, SymTagData, NULL)) {
465 | while (symbol.Next()) {
466 |
467 | DWORD dwDataKind;
468 | symbol->get_dataKind(&dwDataKind);
469 | if (dwDataKind == DataIsMember)
470 | {
471 | DWORD locType = 0;
472 | symbol->get_locationType(&locType);
473 | if (locType == LocIsThisRel)
474 | {
475 | LONG off = 0;
476 | if (symbol->get_offset(&off) == S_OK)
477 | {
478 | ComRef fieldType;
479 | symbol->get_type(&fieldType);
480 | BOOL isRef = FALSE;
481 | fieldType->get_reference(&isRef);
482 |
483 | if (!isRef) {
484 | Bstr fieldName;
485 | symbol->get_name(&fieldName);
486 | wprintf(L"\t\tstatic_assert((offsetof(%s,%s)==0x%X),\"bad off\");\n", nameFixed.c_str(), *fieldName, (unsigned int)off);
487 | }
488 | }
489 | }
490 | }
491 | }
492 | }
493 | wprintf(L"\t};\n");
494 | }
495 |
496 | wprintf(L"};\n"); // end UDT
497 | wprintf(L"\n");
498 | }
499 |
--------------------------------------------------------------------------------
/x_meta.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | static std::wstring GetUniqFunctionName(IDiaSymbol *pFunc, BOOL bWithArgs = TRUE)
4 | {
5 | std::wstring result;
6 |
7 | Bstr name;
8 | pFunc->get_name(&name);
9 | result.assign(*name);
10 |
11 | if (bWithArgs)
12 | {
13 | result.append(L"(");
14 | PrintFunctionArgsX(pFunc, TRUE, FALSE, NULL, &result);
15 | result.append(L")");
16 | }
17 |
18 | return result;
19 | }
20 |
21 | static IDiaSymbol* FindIntroVirtual(IDiaSymbol* pObj, const std::wstring& funcName, DWORD* pBaseOffset, BOOL bWithArgs = TRUE)
22 | {
23 | ComRef enumerator;
24 | ComRef sym;
25 |
26 | if (SUCCEEDED(pObj->findChildren(SymTagFunction, NULL, nsNone, &enumerator)))
27 | {
28 | ULONG celt = 0;
29 | while (SUCCEEDED(enumerator->Next(1, &sym, &celt)) && (celt == 1))
30 | {
31 | auto name = GetUniqFunctionName(*sym, bWithArgs);
32 |
33 | if (
34 | (wcscmp(funcName.c_str(), name.c_str()) == 0)
35 | || ((funcName)[0] == L'~' && (name)[0] == L'~'))
36 | {
37 | BOOL isVirtual = FALSE;
38 | sym->get_virtual(&isVirtual);
39 |
40 | BOOL isIntro = FALSE;
41 | sym->get_intro(&isIntro);
42 |
43 | if (isVirtual && isIntro)
44 | {
45 | IDiaSymbol* res = *sym;
46 | sym._ptr = NULL;
47 | return res;
48 | }
49 | }
50 | }
51 | }
52 |
53 | if (SUCCEEDED(pObj->findChildren(SymTagBaseClass, NULL, nsNone, &enumerator)))
54 | {
55 | ULONG celt = 0;
56 | while (SUCCEEDED(enumerator->Next(1, &sym, &celt)) && (celt == 1))
57 | {
58 | IDiaSymbol* res = FindIntroVirtual(*sym, funcName, pBaseOffset, bWithArgs);
59 | if (res)
60 | {
61 | LONG offset;
62 | if (sym->get_offset(&offset) == S_OK) {
63 | *pBaseOffset += offset;
64 | }
65 |
66 | return res;
67 | }
68 | }
69 | }
70 |
71 | return NULL;
72 | }
73 |
74 | static BOOL GetVirtualFuncInfo(IDiaSymbol* pThis, IDiaSymbol* pFunc, DWORD& vtpo, DWORD& vfid)
75 | {
76 | BOOL res = FALSE;
77 |
78 | vtpo = 0; // virtual table pointer offset
79 | vfid = 0; // virtual function id in VT
80 |
81 | BOOL isVirtual = FALSE;
82 | pFunc->get_virtual(&isVirtual);
83 |
84 | if (isVirtual)
85 | {
86 | DWORD off = 0;
87 | res = (S_OK == pFunc->get_virtualBaseOffset(&off));
88 |
89 | BOOL isIntro = FALSE;
90 | pFunc->get_intro(&isIntro);
91 |
92 | if (off == 0 && !isIntro)
93 | {
94 | Bstr udtName;
95 | pThis->get_name(&udtName);
96 |
97 | std::wstring udtPrefix(*udtName);
98 | udtPrefix.append(L"::");
99 |
100 | Bstr symName;
101 | pFunc->get_name(&symName);
102 |
103 | auto funcName = GetUniqFunctionName(pFunc);
104 |
105 | // HACK: on win10 have to remove UDT name prefix
106 | removePrefix(funcName, udtPrefix);
107 |
108 | ComRef intro(FindIntroVirtual(pThis, funcName, &vtpo));
109 | if (!(*intro))
110 | {
111 | // HACK: find by function by name without args
112 | funcName = *symName;
113 | removePrefix(funcName, udtPrefix);
114 | intro = FindIntroVirtual(pThis, funcName, &vtpo, FALSE);
115 | }
116 |
117 | if (*intro)
118 | {
119 | res = (S_OK == intro->get_virtualBaseOffset(&off));
120 | }
121 | else
122 | {
123 | res = FALSE;
124 | }
125 | }
126 |
127 | vfid = off / sizeof(void*);
128 | }
129 |
130 | return res;
131 | }
132 |
133 | static void PrintMetaSym(IDiaSymbol *pSymbol, std::unordered_set& uniq, int depth = 0)
134 | {
135 | // sym
136 |
137 | DWORD symId = 0;
138 | pSymbol->get_symIndexId(&symId);
139 |
140 | if (uniq.find(symId) != uniq.end()) return;
141 | uniq.insert(symId);
142 |
143 | DWORD symTag = 0;
144 | pSymbol->get_symTag(&symTag);
145 |
146 | Bstr symName;
147 | pSymbol->get_name(&symName);
148 |
149 | // type
150 |
151 | DWORD typeId = 0;
152 | DWORD typeTag = 0;
153 | Bstr typeName;
154 |
155 | ComRef type;
156 | if (pSymbol->get_type(&type) == S_OK)
157 | {
158 | type->get_symIndexId(&typeId);
159 | type->get_symTag(&typeTag);
160 | type->get_name(&typeName);
161 | }
162 |
163 | // print
164 |
165 | for (int i = 0; i < depth; ++i) putwchar(L' ');
166 | wprintf(L"//SYM: %u %s \"%s\" # Type: %u %s \"%s\"\n",
167 | (unsigned int)symId, rgTags[symTag], *symName,
168 | (unsigned int)typeId, rgTags[typeTag], *typeName
169 | );
170 |
171 | if (typeTag == SymTagPointerType)
172 | {
173 | ComRef ptrType;
174 | if (type->get_type(&ptrType) == S_OK)
175 | {
176 | DWORD ptrId = 0;
177 | ptrType->get_symIndexId(&ptrId);
178 |
179 | DWORD ptrTag = 0;
180 | ptrType->get_symTag(&ptrTag);
181 |
182 | Bstr ptrName;
183 | ptrType->get_name(&ptrName);
184 |
185 | for (int i = 0; i < depth; ++i) putwchar(L' ');
186 | wprintf(L" //PTR: %u %s \"%s\"\n", (unsigned int)ptrId, rgTags[ptrTag], *ptrName);
187 | }
188 | }
189 |
190 | // children
191 |
192 | #if 0
193 | for (int i = 0; i < depth; ++i) putwchar(L' ');
194 | wprintf(L" //C\n");
195 | #endif
196 |
197 | SymbolEnumerator iter;
198 | if (iter.Find(pSymbol, SymTagNull, NULL)) {
199 | while (iter.Next()) {
200 | PrintMetaSym(*iter, uniq, depth + 1);
201 | }
202 | }
203 |
204 | // type children
205 |
206 | #if 0
207 | for (int i = 0; i < depth; ++i) putwchar(L' ');
208 | wprintf(L" //T\n");
209 | #endif
210 |
211 | if (*type)
212 | {
213 | if (iter.Find(*type, SymTagNull, NULL)) {
214 | while (iter.Next()) {
215 | PrintMetaSym(*iter, uniq, depth + 1);
216 | }
217 | }
218 | }
219 |
220 | if (depth == 0)
221 | {
222 | wprintf(L"\n");
223 | }
224 | }
225 |
226 | static void PrintMetaBaseClass(Bstr& udtName, IDiaSymbol *pSymbol)
227 | {
228 | // https://github.com/MicrosoftDocs/visualstudio-docs/blob/master/docs/debugger/debug-interface-access/baseclass.md
229 |
230 | DWORD baseKind = 0;
231 | pSymbol->get_udtKind(&baseKind);
232 | wprintf(L"%s ", rgUdtKind[baseKind]);
233 |
234 | PrintName(pSymbol);
235 |
236 | BOOL flag;
237 | DWORD dispIndex;
238 | LONG ptrOffset;
239 | ComRef vbTableType;
240 |
241 | if ((pSymbol->get_virtualBaseClass(&flag) == S_OK) && flag) {
242 | if ((pSymbol->get_virtualBaseDispIndex(&dispIndex) == S_OK) &&
243 | (pSymbol->get_virtualBasePointerOffset(&ptrOffset) == S_OK)) {
244 |
245 | wprintf(L" @vbc @vbdi=0x%X @vbpo=%ld @vbtt=", dispIndex, ptrOffset);
246 | if (pSymbol->get_virtualBaseTableType(&vbTableType) == S_OK) {
247 | PrintTypeX(*vbTableType);
248 | }
249 | else {
250 | wprintf(L"?");
251 | }
252 | }
253 | }
254 | else {
255 | LONG offset;
256 | if (pSymbol->get_offset(&offset) == S_OK) {
257 | wprintf(L" @off=%u", (unsigned int)offset);
258 | }
259 | }
260 |
261 | ULONGLONG len;
262 | if (pSymbol->get_length(&len) == S_OK) {
263 | wprintf(L" @len=%u", (unsigned int)len);
264 | }
265 |
266 | putwchar(L'\n');
267 | }
268 |
269 | static void PrintMetaField(Bstr& udtName, IDiaSymbol *pSymbol)
270 | {
271 | PrintLocation(pSymbol);
272 |
273 | DWORD dwDataKind;
274 | pSymbol->get_dataKind(&dwDataKind);
275 |
276 | wprintf(L", %s", rgDataKind[dwDataKind]);
277 | PrintSymbolType(pSymbol);
278 |
279 | wprintf(L", ");
280 | PrintName(pSymbol);
281 |
282 | putwchar(L'\n');
283 | }
284 |
285 | static void PrintMetaFunction(Bstr& udtName, IDiaSymbol* pUDT, IDiaSymbol *pSymbol)
286 | {
287 | // https://github.com/MicrosoftDocs/visualstudio-docs/blob/master/docs/debugger/debug-interface-access/function-debug-interface-access-sdk.md
288 |
289 | DWORD symId;
290 | pSymbol->get_symIndexId(&symId);
291 |
292 | Bstr name;
293 | pSymbol->get_name(&name);
294 |
295 | BOOL isStatic = FALSE;
296 | pSymbol->get_isStatic(&isStatic);
297 |
298 | BOOL isVirtual = FALSE;
299 | pSymbol->get_virtual(&isVirtual);
300 |
301 | BOOL isPure = FALSE;
302 | pSymbol->get_pure(&isPure);
303 |
304 | BOOL isIntro = FALSE;
305 | pSymbol->get_intro(&isIntro);
306 |
307 | DWORD access = 0;
308 | pSymbol->get_access(&access);
309 |
310 | DWORD callConv = 0;
311 | pSymbol->get_callingConvention(&callConv);
312 |
313 | ULONGLONG len = 0;
314 | pSymbol->get_length(&len);
315 |
316 | DWORD dwLocType = 0;
317 | DWORD dwRVA = 0, dwSect = 0, dwOff = 0;
318 | if (pSymbol->get_locationType(&dwLocType) == S_OK) {
319 | if ((pSymbol->get_relativeVirtualAddress(&dwRVA) == S_OK) &&
320 | (pSymbol->get_addressSection(&dwSect) == S_OK) &&
321 | (pSymbol->get_addressOffset(&dwOff) == S_OK)) {
322 | }
323 | }
324 |
325 | DWORD vtpo = 0; // virtual table pointer offset
326 | DWORD vfid = 0; // virtual function id in VT
327 | if (isVirtual) {
328 | GetVirtualFuncInfo(pUDT, pSymbol, vtpo, vfid);
329 | }
330 |
331 | ComRef funcType;
332 | pSymbol->get_type(&funcType);
333 |
334 | ComRef returnType;
335 | funcType->get_type(&returnType);
336 |
337 | wprintf(L"%s ", rgAccess[access]);
338 | PrintTypeX(*returnType);
339 | wprintf(L" %s(", *name);
340 | PrintFunctionArgsX(pSymbol, TRUE, TRUE);
341 | wprintf(L");");
342 |
343 | if (isIntro) {
344 | wprintf(L" @intro");
345 | }
346 | if (isPure) {
347 | wprintf(L" @pure");
348 | }
349 | if (isVirtual) {
350 | wprintf(L" @virtual vtpo=%u vfid=%u", (unsigned int)vtpo, (unsigned int)vfid);
351 | }
352 |
353 | wprintf(L" @loc=%s", (dwLocType > 0 ? rgLocationTypeString[dwLocType] : L"optimized"));
354 |
355 | wprintf(L" @len=%u @rva=%u @symid=%u", (unsigned int)len, (unsigned int)dwRVA, (unsigned int)symId);
356 |
357 | //std::wstring uniq = GetUniqFunctionName(pSymbol);
358 | //wprintf(L" @uniq \"%s\"", uniq.c_str());
359 |
360 | putwchar(L'\n');
361 | }
362 |
363 | static void PrintMetaUDT(IDiaSymbol *pUDT)
364 | {
365 | // https://github.com/MicrosoftDocs/visualstudio-docs/blob/master/docs/debugger/debug-interface-access/udt.md
366 |
367 | DWORD symTag;
368 | if (pUDT->get_symTag(&symTag) != S_OK) return;
369 |
370 | if (symTag != SymTagUDT)
371 | {
372 | DWORD symId;
373 | pUDT->get_symIndexId(&symId);
374 |
375 | Bstr name;
376 | pUDT->get_name(&name);
377 |
378 | wprintf(L"//Tag: %u %s \"%s\"\n", (unsigned int)symId, rgTags[symTag], *name);
379 |
380 | ComRef type;
381 | if (pUDT->get_type(&type) == S_OK)
382 | {
383 | DWORD typeTag;
384 | type->get_symTag(&typeTag);
385 | type->get_symIndexId(&symId);
386 | type->get_name(&name);
387 |
388 | wprintf(L"\t//type %u %s \"%s\"\n", (unsigned int)symId, rgTags[typeTag], *name);
389 | }
390 |
391 | return;
392 | }
393 |
394 | DWORD kind = 0;
395 | pUDT->get_udtKind(&kind);
396 | if (!(kind == UdtStruct || kind == UdtClass))
397 | {
398 | return;
399 | }
400 |
401 | Bstr name;
402 | if (pUDT->get_name(&name) != S_OK) {
403 | return;
404 | }
405 |
406 | wprintf(L"//UDT: ");
407 | wprintf(L"%s", rgUdtKind[kind]);
408 | wprintf(L" %s", *name);
409 |
410 | ULONGLONG len;
411 | if (pUDT->get_length(&len) == S_OK) {
412 | wprintf(L" @len=%u", (unsigned int)len);
413 | }
414 |
415 | BOOL aligned = FALSE;
416 | pUDT->get_isDataAligned(&aligned);
417 | if (aligned) {
418 | wprintf(L" @aligned");
419 | }
420 |
421 | ComRef enumerator;
422 | ComRef symbol;
423 | DWORD baseCount = 0;
424 | if (SUCCEEDED(pUDT->findChildren(SymTagBaseClass, NULL, nsNone, &enumerator)))
425 | {
426 | ULONG celt = 0;
427 | while (SUCCEEDED(enumerator->Next(1, &symbol, &celt)) && (celt == 1)) { baseCount++; }
428 | }
429 | if (baseCount > 1)
430 | {
431 | wprintf(L" @multibase=%u", (unsigned int)baseCount);
432 | }
433 | else
434 | {
435 | ComRef vtShape;
436 | if (pUDT->get_virtualTableShape(&vtShape) == S_OK)
437 | {
438 | DWORD vfCount = 0;
439 | vtShape->get_count(&vfCount);
440 | if (vfCount) {
441 | wprintf(L" @vfcount=%u", (unsigned int)vfCount);
442 | }
443 | }
444 | }
445 |
446 | putwchar(L'\n');
447 |
448 | // print tags
449 | DWORD dataOff = 0;
450 | if (SUCCEEDED(pUDT->findChildren(SymTagNull, NULL, nsNone, &enumerator))) {
451 | ULONG celt = 0;
452 | while (SUCCEEDED(enumerator->Next(1, &symbol, &celt)) && (celt == 1)) {
453 |
454 | DWORD tag;
455 | symbol->get_symTag(&tag);
456 | switch (tag)
457 | {
458 | case SymTagBaseClass:
459 | {
460 | LONG baseOff = 0;
461 | ULONGLONG baseLen = 0;
462 | if (symbol->get_offset(&baseOff) == S_OK) {
463 | if (symbol->get_length(&baseLen) == S_OK) {
464 | DWORD val = (DWORD)(baseOff + baseLen);
465 | if (dataOff < val) {
466 | dataOff = val;
467 | }
468 | }
469 | }
470 | wprintf(L"\t//_Base: ");
471 | PrintMetaBaseClass(name, *symbol);
472 | break;
473 | }
474 |
475 | case SymTagVTable:
476 | {
477 | // https://github.com/MicrosoftDocs/visualstudio-docs/blob/master/docs/debugger/debug-interface-access/vtable.md
478 | wprintf(L"\t//_VTable: ");
479 | putwchar(L'\n');
480 | break;
481 | }
482 |
483 | case SymTagFunction:
484 | {
485 | wprintf(L"\t//_Func: ");
486 | PrintMetaFunction(name, pUDT, *symbol);
487 | break;
488 | }
489 |
490 | case SymTagData:
491 | {
492 | wprintf(L"\t//_Data: ");
493 | PrintMetaField(name, *symbol);
494 | break;
495 | }
496 |
497 | default:
498 | {
499 | wprintf(L"\t//_Tag %u\n", (unsigned int)tag);
500 | break;
501 | }
502 | }
503 | }
504 | }
505 |
506 | wprintf(L"//UDT;\n\n");
507 | }
508 |
--------------------------------------------------------------------------------
/x_names.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | static bool IsCompilerNamespace(const wchar_t* name)
4 | {
5 | bool res =
6 | startsWith(name, L"std::") ||
7 | startsWith(name, L"boost::") ||
8 | startsWith(name, L"Concurrency::") ||
9 | startsWith(name, L"DirectX::")
10 | ;
11 | return res;
12 | }
13 |
14 | static bool IsCompilerPrefix(const wchar_t* name)
15 | {
16 | bool res =
17 | startsWith(name, L"_") ||
18 | startsWith(name, L"$") ||
19 | startsWith(name, L"_std") ||
20 | startsWith(name, L"_vc_") ||
21 | startsWith(name, L"_crt") ||
22 | startsWith(name, L"_vcrt") ||
23 | startsWith(name, L"_RTTI")
24 | ;
25 | return res;
26 | }
27 |
28 | static bool IsAllowedName(const wchar_t* name)
29 | {
30 | bool bad =
31 | IsCompilerNamespace(name)
32 | || IsCompilerPrefix(name)
33 | || startsWith(name, L"DXGI")
34 | || startsWith(name, L"IDXGI")
35 | || startsWith(name, L"D2D1")
36 | || startsWith(name, L"D3D1")
37 | || startsWith(name, L"D3DX")
38 | || startsWith(name, L"ID3D")
39 | || startsWith(name, L"CD3D")
40 | || startsWith(name, L"D3D_")
41 | || startsWith(name, L"IDirectInput")
42 | || startsWith(name, L"IDWrite")
43 | || startsWith(name, L"DWRITE")
44 | || startsWith(name, L"FMOD")
45 | || wcsstr(name, L"unnamed-tag")
46 | || wcsstr(name, L"unnamed-type")
47 | || wcsstr(name, L"unnamed-enum")
48 | || wcsstr(name, L"lambda_")
49 | ;
50 | return !bad;
51 | }
52 |
53 | static bool IsTemplateClass(const wchar_t* name)
54 | {
55 | return wcsstr(name, L"<") ? true : false;
56 | }
57 |
58 | inline std::wstring fixEnumName(const std::wstring& name)
59 | {
60 | std::wstring fixed(name);
61 | replaceAll(fixed, L"::", L"_");
62 | return fixed;
63 | }
64 |
65 | inline std::wstring fixName(const std::wstring& name)
66 | {
67 | // TODO: THIS IS SPARTA!!!
68 | std::wstring fixed(name);
69 | replaceAll(fixed, L"std::", L"stdXX");
70 | replaceAll(fixed, L"Concurrency::", L"ConcurrencyXX");
71 | replaceAll(fixed, L"DirectX::", L"DirectXXX");
72 | replaceAll(fixed, L"::", L"_");
73 | replaceAll(fixed, L"stdXX", L"std::");
74 | replaceAll(fixed, L"ConcurrencyXX", L"Concurrency::");
75 | replaceAll(fixed, L"DirectXXX", L"DirectX::");
76 | return fixed;
77 | }
78 |
--------------------------------------------------------------------------------
/x_print.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | // forward decl
4 | static void PrintTypeX(IDiaSymbol *pSymbol, std::wstring* dst = NULL);
5 |
6 | static void wprintfX(std::wstring* dst, const wchar_t* format, ...)
7 | {
8 | wchar_t buf[1024] = { 0 };
9 | va_list args;
10 | va_start(args, format);
11 | const int count = _vsnwprintf_s(buf, _countof(buf) - 1, _TRUNCATE, format, args);
12 | va_end(args);
13 |
14 | if (count > 0)
15 | {
16 | if (dst) dst->append(buf);
17 | else wprintf(L"%s", buf);
18 | }
19 | }
20 |
21 | static void PrintVariantX(VARIANT var, std::wstring* dst = NULL)
22 | {
23 | switch (var.vt) {
24 | case VT_UI1:
25 | case VT_I1:
26 | wprintfX(dst, L" 0x%X", var.bVal);
27 | break;
28 |
29 | case VT_I2:
30 | case VT_UI2:
31 | case VT_BOOL:
32 | wprintfX(dst, L" 0x%X", var.iVal);
33 | break;
34 |
35 | case VT_I4:
36 | case VT_UI4:
37 | case VT_INT:
38 | case VT_UINT:
39 | case VT_ERROR:
40 | wprintfX(dst, L" 0x%X", var.lVal);
41 | break;
42 |
43 | case VT_R4:
44 | wprintfX(dst, L" %g", var.fltVal);
45 | break;
46 |
47 | case VT_R8:
48 | wprintfX(dst, L" %g", var.dblVal);
49 | break;
50 |
51 | case VT_BSTR:
52 | wprintfX(dst, L" \"%s\"", var.bstrVal);
53 | break;
54 |
55 | default:
56 | wprintfX(dst, L" ??");
57 | }
58 | }
59 |
60 | static void PrintNameX(IDiaSymbol *pSymbol, std::wstring* dst = NULL)
61 | {
62 | BSTR bstrName;
63 | BSTR bstrUndName;
64 |
65 | if (pSymbol->get_name(&bstrName) != S_OK) {
66 | wprintfX(dst, L"(none)");
67 | return;
68 | }
69 |
70 | if (pSymbol->get_undecoratedName(&bstrUndName) == S_OK) {
71 | if (wcscmp(bstrName, bstrUndName) == 0) {
72 | wprintfX(dst, L"%s", bstrName);
73 | }
74 | else {
75 | wprintfX(dst, L"%s(%s)", bstrUndName, bstrName);
76 | }
77 | SysFreeString(bstrUndName);
78 | }
79 | else {
80 | wprintfX(dst, L"%s", bstrName);
81 | }
82 |
83 | SysFreeString(bstrName);
84 | }
85 |
86 | static void PrintBaseTypeX(IDiaSymbol *pSymbol, std::wstring* dst = NULL)
87 | {
88 | DWORD dwInfo;
89 | if (pSymbol->get_baseType(&dwInfo) != S_OK) return;
90 |
91 | ULONGLONG ulLen = 0;
92 | pSymbol->get_length(&ulLen);
93 |
94 | switch (dwInfo) {
95 | case btUInt:
96 | wprintfX(dst, L"unsigned ");
97 | // fall through
98 |
99 | case btInt:
100 | switch (ulLen) {
101 | case 1:
102 | if (dwInfo == btInt) {
103 | wprintfX(dst, L"signed ");
104 | }
105 | wprintfX(dst, L"char");
106 | break;
107 |
108 | case 2:
109 | wprintfX(dst, L"short");
110 | break;
111 |
112 | case 4:
113 | wprintfX(dst, L"int");
114 | break;
115 |
116 | case 8:
117 | wprintfX(dst, L"__int64");
118 | break;
119 | }
120 | dwInfo = 0xFFFFFFFF;
121 | break;
122 |
123 | case btFloat:
124 | switch (ulLen) {
125 | case 4:
126 | wprintfX(dst, L"float");
127 | break;
128 | case 8:
129 | wprintfX(dst, L"double");
130 | break;
131 | }
132 | dwInfo = 0xFFFFFFFF;
133 | break;
134 | }
135 |
136 | if (dwInfo != 0xFFFFFFFF) {
137 | wprintfX(dst, L"%s", rgBaseType[dwInfo]);
138 | }
139 | }
140 |
141 | static void PrintLocationX(IDiaSymbol *pSymbol, std::wstring* dst = NULL)
142 | {
143 | DWORD dwLocType;
144 | DWORD dwRVA, dwSect, dwOff, dwReg, dwBitPos, dwSlot;
145 | LONG lOffset;
146 | ULONGLONG ulLen;
147 | VARIANT vt = { VT_EMPTY };
148 |
149 | if (pSymbol->get_locationType(&dwLocType) != S_OK) {
150 | wprintfX(dst, L"optmized");
151 | return;
152 | }
153 |
154 | switch (dwLocType) {
155 | case LocIsStatic:
156 | if ((pSymbol->get_relativeVirtualAddress(&dwRVA) == S_OK) &&
157 | (pSymbol->get_addressSection(&dwSect) == S_OK) &&
158 | (pSymbol->get_addressOffset(&dwOff) == S_OK)) {
159 | wprintfX(dst, L"%s, [%08X][%04X:%08X]", (rgLocationTypeString, dwLocType), dwRVA, dwSect, dwOff);
160 | }
161 | break;
162 |
163 | case LocIsTLS:
164 | case LocInMetaData:
165 | case LocIsIlRel:
166 | if ((pSymbol->get_relativeVirtualAddress(&dwRVA) == S_OK) &&
167 | (pSymbol->get_addressSection(&dwSect) == S_OK) &&
168 | (pSymbol->get_addressOffset(&dwOff) == S_OK)) {
169 | wprintfX(dst, L"%s, [%08X][%04X:%08X]", (rgLocationTypeString, dwLocType), dwRVA, dwSect, dwOff);
170 | }
171 | break;
172 |
173 | case LocIsRegRel:
174 | if ((pSymbol->get_registerId(&dwReg) == S_OK) &&
175 | (pSymbol->get_offset(&lOffset) == S_OK)) {
176 | wprintfX(dst, L"%s Relative, [%08X]", SzNameC7Reg((USHORT)dwReg), lOffset);
177 | }
178 | break;
179 |
180 | case LocIsThisRel:
181 | if (pSymbol->get_offset(&lOffset) == S_OK) {
182 | wprintfX(dst, L"this+0x%X", lOffset);
183 | }
184 | break;
185 |
186 | case LocIsBitField:
187 | if ((pSymbol->get_offset(&lOffset) == S_OK) &&
188 | (pSymbol->get_bitPosition(&dwBitPos) == S_OK) &&
189 | (pSymbol->get_length(&ulLen) == S_OK)) {
190 | wprintfX(dst, L"this(bf)+0x%X:0x%X len(0x%X)", lOffset, dwBitPos, (ULONG)ulLen);
191 | }
192 | break;
193 |
194 | case LocIsEnregistered:
195 | if (pSymbol->get_registerId(&dwReg) == S_OK) {
196 | wprintfX(dst, L"enregistered %s", SzNameC7Reg((USHORT)dwReg));
197 | }
198 | break;
199 |
200 | case LocIsSlot:
201 | if (pSymbol->get_slot(&dwSlot) == S_OK) {
202 | wprintfX(dst, L"%s, [%08X]", (rgLocationTypeString, dwLocType), dwSlot);
203 | }
204 | break;
205 |
206 | case LocIsConstant:
207 | wprintfX(dst, L"constant");
208 |
209 | if (pSymbol->get_value(&vt) == S_OK) {
210 | PrintVariantX(vt, dst);
211 | VariantClear((VARIANTARG *)&vt);
212 | }
213 | break;
214 |
215 | case LocIsNull:
216 | break;
217 |
218 | default:
219 | wprintfX(dst, L"Error - invalid location type: 0x%X", dwLocType);
220 | break;
221 | }
222 | }
223 |
224 | static void PrintPointerTypeX(IDiaSymbol *pSymbol, std::wstring* dst = NULL, BOOL replaceRefWithPtr = FALSE)
225 | {
226 | ComRef pBaseType;
227 | if (pSymbol->get_type(&pBaseType) != S_OK) return;
228 |
229 | Bstr name;
230 | pSymbol->get_name(&name);
231 |
232 | BOOL isRef = FALSE;
233 | pSymbol->get_reference(&isRef);
234 |
235 | BOOL isConst = FALSE;
236 | pSymbol->get_constType(&isConst);
237 |
238 | DWORD baseTypeTag = 0;
239 | pBaseType->get_symTag(&baseTypeTag);
240 |
241 | BOOL isBaseConst = FALSE;
242 | pBaseType->get_constType(&isBaseConst);
243 |
244 | #if 0
245 | if (baseTypeTag == SymTagUDT && !isRef)
246 | {
247 | DWORD kind = 0;
248 | pBaseType->get_udtKind(&kind);
249 | wprintfX(dst, L"%s ", rgUdtKind[kind]);
250 | }
251 | #endif
252 |
253 | if (isBaseConst) {
254 | wprintfX(dst, L"const ");
255 | }
256 |
257 | if (baseTypeTag == SymTagFunctionType)
258 | {
259 | wprintfX(dst, L"void");
260 | }
261 | else
262 | {
263 | PrintTypeX(*pBaseType, dst);
264 | }
265 |
266 | if (isRef) {
267 | if (replaceRefWithPtr)
268 | wprintfX(dst, L" *");
269 | else
270 | wprintfX(dst, L" &");
271 | }
272 | else {
273 | wprintfX(dst, L" *");
274 | }
275 |
276 | #if 0
277 | BOOL bSet;
278 | if ((pSymbol->get_constType(&bSet) == S_OK) && bSet) {
279 | wprintfX(dst, L" const");
280 | }
281 |
282 | if ((pSymbol->get_volatileType(&bSet) == S_OK) && bSet) {
283 | wprintfX(dst, L" volatile");
284 | }
285 |
286 | if ((pSymbol->get_unalignedType(&bSet) == S_OK) && bSet) {
287 | wprintfX(dst, L" __unaligned");
288 | }
289 | #endif
290 | }
291 |
292 | static void PrintBoundX(IDiaSymbol *pSymbol, std::wstring* dst = NULL)
293 | {
294 | DWORD dwTag = 0;
295 | DWORD dwKind;
296 |
297 | if (pSymbol->get_symTag(&dwTag) != S_OK) {
298 | wprintfX(dst, L"ERROR - PrintBound() get_symTag");
299 | return;
300 | }
301 |
302 | if (pSymbol->get_locationType(&dwKind) != S_OK) {
303 | wprintfX(dst, L"ERROR - PrintBound() get_locationType");
304 | return;
305 | }
306 |
307 | if (dwTag == SymTagData && dwKind == LocIsConstant) {
308 | VARIANT v = { VT_EMPTY };
309 | if (pSymbol->get_value(&v) == S_OK) {
310 | PrintVariantX(v, dst);
311 | VariantClear((VARIANTARG *)&v);
312 | }
313 | }
314 | else {
315 | PrintNameX(pSymbol, dst);
316 | }
317 | }
318 |
319 | static void PrintArraySizeX(IDiaSymbol *pSymbol, std::wstring* dst = NULL)
320 | {
321 | DWORD symTag;
322 | pSymbol->get_symTag(&symTag);
323 | if (symTag != SymTagArrayType) {
324 | return;
325 | }
326 |
327 | ComRef baseType;
328 | if (pSymbol->get_type(&baseType) != S_OK) {
329 | return;
330 | }
331 |
332 | PrintArraySizeX(*baseType, dst);
333 |
334 | SymbolEnumerator child;
335 | DWORD dwRank;
336 | LONG count;
337 |
338 | if (pSymbol->get_rank(&dwRank) == S_OK) {
339 | if (child.Find(pSymbol, SymTagDimension, NULL)) {
340 | while (child.Next()) {
341 |
342 | wprintfX(dst, L"[");
343 | ComRef bound;
344 | if (child->get_lowerBound(&bound) == S_OK) {
345 | PrintBoundX(*bound, dst);
346 | wprintfX(dst, L"..");
347 | }
348 |
349 | if (child->get_upperBound(&bound) == S_OK) {
350 | PrintBoundX(*bound, dst);
351 | }
352 | wprintfX(dst, L"]");
353 | }
354 | }
355 | }
356 | else if (child.Find(pSymbol, SymTagCustomType, NULL) && (child._enumerator->get_Count(&count) == S_OK) && (count > 0)) {
357 | while (child.Next()) {
358 |
359 | wprintfX(dst, L"[");
360 | PrintTypeX(*child, dst);
361 | wprintfX(dst, L"]");
362 | }
363 | }
364 | else {
365 | DWORD dwCountElems = 0;
366 | ULONGLONG ulLenArray = 0;
367 | ULONGLONG ulLenElem = 0;
368 |
369 | if (pSymbol->get_count(&dwCountElems) == S_OK) {
370 | wprintfX(dst, L"[%u]", (unsigned int)dwCountElems);
371 | }
372 | else if ((pSymbol->get_length(&ulLenArray) == S_OK) && (baseType->get_length(&ulLenElem) == S_OK)) {
373 | if (ulLenElem == 0) {
374 | wprintfX(dst, L"[%u]", (unsigned int)ulLenArray);
375 | }
376 | else {
377 | wprintfX(dst, L"[%u]", (unsigned int)ulLenArray / (unsigned int)ulLenElem);
378 | }
379 | }
380 | }
381 | }
382 |
383 | static void PrintCustomTypeX(IDiaSymbol *pSymbol, std::wstring* dst = NULL)
384 | {
385 | DWORD idOEM, idOEMSym;
386 | DWORD cbData = 0;
387 | DWORD count;
388 |
389 | if (pSymbol->get_oemId(&idOEM) == S_OK) {
390 | wprintfX(dst, L"OEMId = %X, ", idOEM);
391 | }
392 |
393 | if (pSymbol->get_oemSymbolId(&idOEMSym) == S_OK) {
394 | wprintfX(dst, L"SymbolId = %X, ", idOEMSym);
395 | }
396 |
397 | if (pSymbol->get_types(0, &count, NULL) == S_OK) {
398 | IDiaSymbol** rgpDiaSymbols = (IDiaSymbol**)_alloca(sizeof(IDiaSymbol *) * count);
399 |
400 | if (pSymbol->get_types(count, &count, rgpDiaSymbols) == S_OK) {
401 | for (ULONG i = 0; i < count; i++) {
402 |
403 | PrintTypeX(rgpDiaSymbols[i], dst);
404 | rgpDiaSymbols[i]->Release();
405 | }
406 | }
407 | }
408 |
409 | if ((pSymbol->get_dataBytes(cbData, &cbData, NULL) == S_OK) && (cbData != 0)) {
410 |
411 | wprintfX(dst, L", Data: ");
412 |
413 | BYTE *pbData = new BYTE[cbData];
414 | pSymbol->get_dataBytes(cbData, &cbData, pbData);
415 |
416 | for (ULONG i = 0; i < cbData; i++) {
417 | wprintfX(dst, L"0x%02X ", pbData[i]);
418 | }
419 |
420 | delete[] pbData;
421 | }
422 | }
423 |
424 | static void PrintFunctionArgsX(IDiaSymbol *pFunc, BOOL genArgTypes = TRUE, BOOL genArgNames = FALSE, const wchar_t* pthisType = NULL, std::wstring* dst = NULL)
425 | {
426 | if (!genArgTypes && !genArgNames) return;
427 |
428 | int argId = 0;
429 |
430 | if (pthisType) {
431 | if (genArgTypes) {
432 | wprintfX(dst, L"%s *pthis", pthisType);
433 | }
434 | else {
435 | wprintfX(dst, L"this");
436 | }
437 | argId++;
438 | }
439 |
440 | int dataCount = 0;
441 | ComRef children;
442 | if (SUCCEEDED(pFunc->findChildren(SymTagData, NULL, nsNone, &children))) {
443 | ComRef child;
444 | ULONG celt = 0;
445 | while (SUCCEEDED(children->Next(1, &child, &celt)) && (celt == 1)) {
446 |
447 | DWORD argKind = 0;
448 | child->get_dataKind(&argKind);
449 | if (argKind == DataIsParam) {
450 |
451 | ComRef childType;
452 | if (child->get_type(&childType) == S_OK) {
453 |
454 | if (argId) {
455 | wprintfX(dst, L", ");
456 | }
457 | if (genArgTypes) {
458 | PrintTypeX(*childType, dst);
459 | }
460 | if (genArgNames) {
461 | if (genArgTypes) {
462 | wprintfX(dst, L" ");
463 | }
464 | Bstr name;
465 | child->get_name(&name);
466 | wprintfX(dst, L"%s", *name);
467 | }
468 | argId++;
469 | }
470 | dataCount++;
471 | }
472 | }
473 | }
474 |
475 | if (!dataCount) {
476 | ComRef funcType;
477 | pFunc->get_type(&funcType);
478 |
479 | if (SUCCEEDED(funcType->findChildren(SymTagFunctionArgType, NULL, nsNone, &children))) {
480 | ComRef child;
481 | ULONG celt = 0;
482 | while (SUCCEEDED(children->Next(1, &child, &celt)) && (celt == 1)) {
483 |
484 | ComRef childType;
485 | if (child->get_type(&childType) == S_OK) {
486 | if (argId) {
487 | wprintfX(dst, L", ");
488 | }
489 | if (genArgTypes) {
490 | PrintTypeX(*childType, dst);
491 | }
492 | if (genArgNames) {
493 | if (genArgTypes) {
494 | //wprintfX(dst, L" ");
495 | }
496 | wprintfX(dst, L" _arg%d", argId);
497 | }
498 | argId++;
499 | }
500 | }
501 | }
502 | }
503 | }
504 |
505 | static void PrintTypeX(IDiaSymbol *pSymbol, std::wstring* dst)
506 | {
507 | DWORD dwTag;
508 | if (pSymbol->get_symTag(&dwTag) != S_OK) return;
509 |
510 | #if 0
511 | if (dwTag != SymTagPointerType)
512 | {
513 | BOOL bSet;
514 | if ((pSymbol->get_constType(&bSet) == S_OK) && bSet) {
515 | wprintfX(dst, L"const ");
516 | }
517 | if ((pSymbol->get_volatileType(&bSet) == S_OK) && bSet) {
518 | wprintfX(dst, L"volatile ");
519 | }
520 | if ((pSymbol->get_unalignedType(&bSet) == S_OK) && bSet) {
521 | wprintfX(dst, L"__unaligned ");
522 | }
523 | }
524 | #endif
525 |
526 | switch (dwTag)
527 | {
528 | case SymTagUDT:
529 | {
530 | Bstr symName;
531 | pSymbol->get_name(&symName);
532 | std::wstring fixedName(fixName(*symName));
533 |
534 | wprintfX(dst, L"%s", fixedName.c_str());
535 | break;
536 | }
537 |
538 | case SymTagEnum:
539 | {
540 | Bstr symName;
541 | pSymbol->get_name(&symName);
542 | std::wstring fixedName(fixEnumName(*symName));
543 |
544 | wprintfX(dst, L"%s", fixedName.c_str());
545 | break;
546 | }
547 |
548 | case SymTagBaseType:
549 | {
550 | PrintBaseTypeX(pSymbol, dst);
551 | break;
552 | }
553 |
554 | case SymTagPointerType:
555 | {
556 | PrintPointerTypeX(pSymbol, dst);
557 | break;
558 | }
559 |
560 | case SymTagArrayType:
561 | {
562 | ComRef baseType;
563 | pSymbol->get_type(&baseType);
564 |
565 | PrintTypeX(*baseType, dst);
566 | break;
567 | }
568 |
569 | case SymTagCustomType:
570 | {
571 | PrintCustomTypeX(pSymbol, dst);
572 | break;
573 | }
574 |
575 | case SymTagTypedef:
576 | {
577 | PrintNameX(pSymbol, dst);
578 | break;
579 | }
580 |
581 | case SymTagData:
582 | {
583 | PrintLocationX(pSymbol, dst);
584 | break;
585 | }
586 | }
587 | }
588 |
589 | static void PrintFakeRefsX(IDiaSymbol *pUDT, std::wstring* dst = NULL)
590 | {
591 | int count = 0;
592 | SymbolEnumerator symbol;
593 | if (symbol.Find(pUDT, SymTagData, NULL)) {
594 | while (symbol.Next()) {
595 |
596 | DWORD dwDataKind;
597 | symbol->get_dataKind(&dwDataKind);
598 |
599 | if (dwDataKind == DataIsMember)
600 | {
601 | ComRef fieldType;
602 | symbol->get_type(&fieldType);
603 |
604 | BOOL isRef = FALSE;
605 | fieldType->get_reference(&isRef);
606 |
607 | if (isRef) {
608 |
609 | if (!count) wprintfX(dst, L" : ");
610 | else wprintfX(dst, L", ");
611 |
612 | Bstr fieldName;
613 | symbol->get_name(&fieldName);
614 | wprintfX(dst, L"%s(*((", *fieldName);
615 |
616 | ComRef baseType;
617 | fieldType->get_type(&baseType);
618 | Bstr baseName;
619 | baseType->get_name(&baseName);
620 |
621 | PrintTypeX(*baseType);
622 | wprintfX(dst, L"*)NULL))");
623 |
624 | ++count;
625 | }
626 | }
627 | }
628 | }
629 | }
630 |
--------------------------------------------------------------------------------
/x_ripper.cpp:
--------------------------------------------------------------------------------
1 | //
2 | // ACHTUNG!!! COMPLETELY BRAINDAMAGED SHITCODE!!!
3 | //
4 |
5 | #include "stdafx.h"
6 | #include
7 | #include
8 |
9 | #include
10 | #include
11 | #include
12 | #include
13 | #include
14 | #include
15 | #include