ReactOS  0.4.12-dev-375-g61fed54
symdump.c
Go to the documentation of this file.
1 /*
2  * PE symbol dumper
3  *
4  * symdump.c
5  *
6  * Copyright (c) 2008 Timo Kreuzer <timo <dot> kreuzer <at> reactos <dot> org>
7  *
8  * This program is released under the terms of the GNU GPL.
9  *
10  * TODO:
11  * - fix GDILoObjType
12  * - fix UDTKind1
13  * - include the correct headers for some stuff
14  * - fix unions like LARGE_INTEGER
15  */
16 
17 #include <stdio.h>
18 #define _WINVER 0x501
19 #define SYMOPT_ALLOW_ABSOLUTE_SYMBOLS 0x00000800
20 #include <windows.h>
21 #include <shlwapi.h>
22 #include <dbghelp.h>
23 
26 
27 #define MAX_SYMBOL_NAME 1024
28 
29 #define CV_CALL_NEAR_C 0x00
30 #define CV_CALL_FAR_C 0x01
31 #define CV_CALL_NEAR_PASCAL 0x02
32 #define CV_CALL_FAR_PASCAL 0x03
33 #define CV_CALL_NEAR_FAST 0x04
34 #define CV_CALL_FAR_FAST 0x05
35 #define CV_CALL_SKIPPED 0x06
36 #define CV_CALL_NEAR_STD 0x07
37 #define CV_CALL_FAR_STD 0x08
38 #define CV_CALL_NEAR_SYS 0x09
39 #define CV_CALL_FAR_SYS 0x0a
40 #define CV_CALL_THISCALL 0x0b
41 #define CV_CALL_MIPSCALL 0x0c
42 #define CV_CALL_GENERIC 0x0d
43 #define CV_CALL_ALPHACALL 0x0e
44 #define CV_CALL_PPCCALL 0x0f
45 #define CV_CALL_SHCALL 0x10
46 #define CV_CALL_ARMCALL 0x11
47 #define CV_CALL_AM33CALL 0x12
48 #define CV_CALL_TRICALL 0x13
49 #define CV_CALL_SH5CALL 0x14
50 #define CV_CALL_M32RCALL 0x15
51 
53 {
86 };
87 
88 enum
89 {
91  UDTKind_Class = 1, /* ? */
93 };
94 
96 {
97  btNoType = 0,
98  btVoid = 1,
99  btChar = 2,
100  btWChar = 3,
101  btInt = 6,
102  btUInt = 7,
103  btFloat = 8,
104  btBCD = 9,
105  btBool = 10,
106  btLong = 13,
107  btULong = 14,
109  btDate = 26,
110  btVariant = 27,
111  btComplex = 28,
112  btBit = 29,
113  btBSTR = 30,
115 };
116 
117 typedef struct
118 {
123 } ENUMINFO, *PENUMINFO;
124 
125 VOID DumpType(DWORD dwTypeIndex, PENUMINFO pei, INT indent, BOOL bMembers);
126 
128 {
129  "SymTagNull",
130  "SymTagExe",
131  "SymTagCompiland",
132  "SymTagCompilandDetails",
133  "SymTagCompilandEnv",
134  "SymTagFunction",
135  "SymTagBlock",
136  "SymTagData",
137  "SymTagAnnotation",
138  "SymTagLabel",
139  "SymTagPublicSymbol",
140  "SymTagUDT",
141  "SymTagEnum",
142  "SymTagFunctionType",
143  "SymTagPointerType",
144  "SymTagArrayType",
145  "SymTagBaseType",
146  "SymTagTypedef",
147  "SymTagBaseClass",
148  "SymTagFriend",
149  "SymTagFunctionArgType",
150  "SymTagFuncDebugStart",
151  "SymTagFuncDebugEnd",
152  "SymTagUsingNamespace",
153  "SymTagVTableShape",
154  "SymTagVTable",
155  "SymTagCustom",
156  "SymTagThunk",
157  "SymTagCustomType",
158  "SymTagManagedType",
159  "SymTagDimension",
160  "SymTagMax"
161 };
162 
163 void
165 {
166  INT i;
167  for (i = 0; i < ind; i++)
168  {
169  printf(" ");
170  }
171 }
172 
173 #define printfi \
174  IndentPrint(indent); printf
175 
176 VOID
178 {
179  printf("Syntax:\n\n");
180  printf("dumpsym <file> [-sp=<symbolpath>] [-p] [<symname>]\n\n");
181  printf("<file> The PE file you want to dump the symbols of\n");
182  printf("-sp=<symbolpath> Path to your symbol files.\n");
183  printf(" Default is MS symbol server.\n");
184  printf("-p Enable struct positions.\n");
185  printf("<symname> A name of a Symbol, you want to dump\n");
186  printf(" Default is all symbols.\n");
187  printf("\n");
188 }
189 
191 {
192  if (!SymInitialize(hProcess, 0, FALSE))
193  return FALSE;
194 
197  SymSetSearchPath(hProcess, pszSymbolPath);
198  return TRUE;
199 }
200 
201 VOID
203 {
204  ULONG64 ulSize;
205  DWORD dwBaseType;
206 
207  SymGetTypeInfo(pei->hProcess, pei->dwModuleBase, dwTypeIndex, TI_GET_LENGTH, &ulSize);
208  SymGetTypeInfo(pei->hProcess, pei->dwModuleBase, dwTypeIndex, TI_GET_BASETYPE, &dwBaseType);
209 
210  switch (dwBaseType)
211  {
212  case btVoid:
213  printfi("VOID");
214  return;
215  case btChar:
216  printfi("CHAR");
217  return;
218  case btWChar:
219  printfi("WCHAR");
220  return;
221  case btInt:
222  switch (ulSize)
223  {
224  case 1:
225  printfi("CHAR");
226  return;
227  case 2:
228  printfi("SHORT");
229  return;
230  case 4:
231  printfi("INT");
232  return;
233  case 8:
234  printfi("INT64");
235  return;
236  default:
237  printfi("INT%ld", (ULONG)ulSize * 8);
238  return;
239  }
240  case btUInt:
241  switch (ulSize)
242  {
243  case 1:
244  printfi("UCHAR");
245  return;
246  case 2:
247  printfi("USHORT");
248  return;
249  case 4:
250  printfi("UINT");
251  return;
252  case 8:
253  printfi("UINT64");
254  return;
255  default:
256  printfi("UINT%ld", (ULONG)ulSize * 8);
257  return;
258  }
259  case btFloat:
260  switch (ulSize)
261  {
262  case 4:
263  printfi("FLOAT");
264  return;
265  case 8:
266  printfi("DOUBLE");
267  return;
268  default:
269  printfi("FLOAT%ld", (ULONG)ulSize * 8);
270  return;
271  }
272  case btBCD:
273  printfi("BCD%ld", (ULONG)ulSize * 8);
274  return;
275  case btBool:
276  switch (ulSize)
277  {
278  case 1:
279  printfi("BOOLEAN");
280  return;
281  case 4:
282  printfi("BOOL");
283  return;
284  default:
285  printfi("BOOL%ld", (ULONG)ulSize * 8);
286  return;
287  }
288  case btLong:
289  switch (ulSize)
290  {
291  case 1:
292  printfi("CHAR");
293  return;
294  case 2:
295  printfi("SHORT");
296  return;
297  case 4:
298  printfi("LONG");
299  return;
300  case 8:
301  printfi("LONGLONG");
302  return;
303  default:
304  printfi("LONG%ld", (ULONG)ulSize * 8);
305  return;
306  }
307  case btULong:
308  switch (ulSize)
309  {
310  case 1:
311  printfi("UCHAR");
312  return;
313  case 2:
314  printfi("USHORT");
315  return;
316  case 4:
317  printfi("ULONG");
318  return;
319  case 8:
320  printfi("ULONGLONG");
321  return;
322  default:
323  printfi("ULONG%ld", (ULONG)ulSize * 8);
324  return;
325  }
326  case btCurrency:
327  case btDate:
328  case btVariant:
329  case btComplex:
330  case btBit:
331  case btBSTR:
332  printfi("UNSUP_%ld_%ld", dwBaseType, (ULONG)ulSize);
333  return;
334  case btHresult:
335  if (ulSize == 4)
336  {
337  printfi("HRESULT");
338  return;
339  }
340  printfi("HRESULT%ld", (ULONG)ulSize);
341  return;
342  }
343 
344  printfi("UNKNBASETYPE");
345 }
346 
347 VOID
348 DumpArray(DWORD dwTypeIndex, PENUMINFO pei, INT indent)
349 {
350  DWORD dwTypeId;
351 
352  SymGetTypeInfo(pei->hProcess, pei->dwModuleBase, dwTypeIndex, TI_GET_TYPE, &dwTypeId);
353  DumpType(dwTypeId, pei, indent, FALSE);
354 }
355 
356 VOID
358 {
359  DWORD dwRefTypeId;
360  DWORD dwTag = 0;
361  ULONG64 ulSize;
362  DWORD dwBaseType;
363 
364  SymGetTypeInfo(pei->hProcess, pei->dwModuleBase, dwTypeIndex, TI_GET_TYPE, &dwRefTypeId);
365  SymGetTypeInfo(pei->hProcess, pei->dwModuleBase, dwRefTypeId, TI_GET_BASETYPE, &dwBaseType);
366  SymGetTypeInfo(pei->hProcess, pei->dwModuleBase, dwRefTypeId, TI_GET_LENGTH, &ulSize);
367  SymGetTypeInfo(pei->hProcess, pei->dwModuleBase, dwRefTypeId, TI_GET_SYMTAG, &dwTag);
368 
369  if (dwTag == SymTagFunctionType)
370  {
371  printfi("PPROC");
372  return;
373  }
374 
375  switch (dwBaseType)
376  {
377  case btVoid:
378  switch (ulSize)
379  {
380  case 0:
381  printfi("PVOID");
382  return;
383  }
384  break;
385 
386  case btChar:
387  switch (ulSize)
388  {
389  case 1:
390  printfi("PCHAR");
391  return;
392  }
393  break;
394  case btWChar:
395  switch (ulSize)
396  {
397  case 2:
398  printfi("PWCHAR");
399  return;
400  }
401  break;
402  case btInt:
403  switch (ulSize)
404  {
405  case 4:
406  printfi("PINT");
407  return;
408  }
409  break;
410  case btUInt:
411  switch (ulSize)
412  {
413  case 4:
414  printfi("PUINT");
415  return;
416  }
417  break;
418  case btFloat:
419  switch (ulSize)
420  {
421  case 4:
422  printfi("PFLOAT");
423  return;
424  case 8:
425  printfi("PDOUBLE");
426  return;
427  }
428  break;
429  case btBCD:
430  break;
431  case btBool:
432  switch (ulSize)
433  {
434  case 1:
435  printfi("PBOOLEAN");
436  return;
437  case 4:
438  printfi("PBOOL");
439  return;
440  }
441  break;
442  case btLong:
443  switch (ulSize)
444  {
445  case 4:
446  printfi("PLONG");
447  return;
448  case 8:
449  printfi("PLONGLONG");
450  return;
451  }
452  break;
453  case btULong:
454  switch (ulSize)
455  {
456  case 4:
457  printfi("PULONG");
458  return;
459  case 8:
460  printfi("PULONGLONG");
461  return;
462  }
463  break;
464  case btCurrency:
465  case btDate:
466  case btVariant:
467  case btComplex:
468  case btBit:
469  case btBSTR:
470  case btHresult:
471  break;
472  }
473 
474  DumpType(dwRefTypeId, pei, indent, FALSE);
475  printf("*");
476 }
477 
478 VOID
480 {
481 // printf("<vt%d>", v->n1.n2.vt);
482  switch (v->n1.n2.vt)
483  {
484  case VT_I1:
485  printf("%d", (INT)v->n1.n2.n3.cVal);
486  break;
487  case VT_UI1:
488  printf("0x%x", (UINT)v->n1.n2.n3.cVal);
489  break;
490  case VT_I2:
491  printf("%d", (UINT)v->n1.n2.n3.iVal);
492  break;
493  case VT_UI2:
494  printf("0x%x", (UINT)v->n1.n2.n3.iVal);
495  break;
496  case VT_INT:
497  case VT_I4:
498  printf("%d", (UINT)v->n1.n2.n3.lVal);
499  break;
500  case VT_UINT:
501  case VT_UI4:
502  printf("0x%x", (UINT)v->n1.n2.n3.lVal);
503  break;
504  }
505 }
506 
507 BOOL
508 IsUnnamed(WCHAR *pszName)
509 {
510  if ((StrStrW(pszName, L"__unnamed") != NULL) ||
511  (StrStrW(pszName, L"<unnamed-tag>") != NULL))
512  {
513  return TRUE;
514  }
515  return FALSE;
516 }
517 
518 VOID
519 DumpEnum(DWORD dwTypeIndex, PENUMINFO pei, INT indent, BOOL bMembers)
520 {
521  DWORD64 dwModuleBase = pei->dwModuleBase;
522  HANDLE hProcess = pei->hProcess;
523  INT i;
524  DWORD dwUDTKind;
525  WCHAR *pszName, *pszNameX;
526  struct
527  {
529  ULONG TypeIds[200];
530  } tfpex;
531  VARIANT v;
532 
533  SymGetTypeInfo(hProcess, dwModuleBase, dwTypeIndex, TI_GET_SYMNAME, &pszNameX);
534  SymGetTypeInfo(hProcess, dwModuleBase, dwTypeIndex, TI_GET_UDTKIND, &dwUDTKind);
535  pszName = pszNameX;
536  if (IsUnnamed(pszName))
537  {
538  if (bMembers)
539  {
540  LocalFree(pszNameX);
541  return;
542  }
543  bMembers = TRUE;
544  pszName = L"";
545  }
546  printfi("enum %ls", pszName);
547  LocalFree(pszNameX);
548 
549  if (bMembers)
550  {
551  printf(" /* %03x */", 0);
552  printfi("\n{\n");
553 
554  /* Get the children */
555  SymGetTypeInfo(hProcess, dwModuleBase, dwTypeIndex, TI_GET_CHILDRENCOUNT, &tfpex.tfp.Count);
556 
557  tfpex.tfp.Start = 0;
558  SymGetTypeInfo(hProcess, dwModuleBase, dwTypeIndex, TI_FINDCHILDREN, &tfpex.tfp);
559 
560  for (i = 0; i < tfpex.tfp.Count; i++)
561  {
562  pszName = L"";
563 
564  SymGetTypeInfo(hProcess, dwModuleBase, tfpex.tfp.ChildId[i], TI_GET_SYMNAME, &pszName);
565  SymGetTypeInfo(hProcess, dwModuleBase, tfpex.tfp.ChildId[i], TI_GET_VALUE, &v);
566 
567  indent++;
568  printfi("%ls = ", pszName);
569  PrintVariant(&v);
570  printf(",\n");
571  indent--;
572 
573  LocalFree(pszName);
574  }
575  printfi("}");
576  }
577 }
578 
579 VOID
580 DumpUDT(DWORD dwTypeIndex, PENUMINFO pei, INT indent, BOOL bMembers)
581 {
582  DWORD64 dwModuleBase = pei->dwModuleBase;
583  HANDLE hProcess = pei->hProcess;
584  INT i;
585  DWORD dwUDTKind;
586  WCHAR *pszName, *pszNameX;
587  struct
588  {
590  ULONG TypeIds[200];
591  } tfpex;
592 
593  DWORD dwDataKind;
594  DWORD dwTypeId;
595  DWORD dwCount;
596  WCHAR *pszTypeName;
597 
598  SymGetTypeInfo(hProcess, dwModuleBase, dwTypeIndex, TI_GET_SYMNAME, &pszNameX);
599  SymGetTypeInfo(hProcess, dwModuleBase, dwTypeIndex, TI_GET_UDTKIND, &dwUDTKind);
600 
601  pszName = pszNameX;
602  if (IsUnnamed(pszName))
603  {
604  if (bMembers)
605  {
606  LocalFree(pszNameX);
607  return;
608  }
609  bMembers = TRUE;
610  pszName = L"";
611  }
612  if (dwUDTKind == UDTKind_Struct)
613  {
614  printfi("struct %ls", pszName);
615  }
616  else if (dwUDTKind == UDTKind_Union)
617  {
618  printfi("union %ls", pszName);
619  }
620  else
621  {
622  printfi("UTDKind%ld %ls", dwUDTKind, pszName);
623  }
624  LocalFree(pszNameX);
625 
626  if (bMembers)
627  {
628  ULONG64 ulLength;
629 
630  printf("\n");
631  printfi("{\n");
632 
633  /* Get the children */
634  SymGetTypeInfo(hProcess, dwModuleBase, dwTypeIndex, TI_GET_CHILDRENCOUNT, &tfpex.tfp.Count);
635 
636  tfpex.tfp.Start = 0;
637  SymGetTypeInfo(hProcess, dwModuleBase, dwTypeIndex, TI_FINDCHILDREN, &tfpex.tfp);
638 
639  for (i = 0; i < tfpex.tfp.Count; i++)
640  {
641  DWORD dwChildTag;
642  DWORD dwOffset;
643 
644  pszName = L"";
645  pszTypeName = L"";
646 
647  SymGetTypeInfo(hProcess, dwModuleBase, tfpex.tfp.ChildId[i], TI_GET_SYMNAME, &pszName);
648  SymGetTypeInfo(hProcess, dwModuleBase, tfpex.tfp.ChildId[i], TI_GET_DATAKIND, &dwDataKind);
649  SymGetTypeInfo(hProcess, dwModuleBase, tfpex.tfp.ChildId[i], TI_GET_TYPE, &dwTypeId);
650  SymGetTypeInfo(hProcess, dwModuleBase, tfpex.tfp.ChildId[i], TI_GET_OFFSET, &dwOffset);
651  SymGetTypeInfo(hProcess, dwModuleBase, dwTypeId, TI_GET_SYMTAG, &dwChildTag);
652  SymGetTypeInfo(hProcess, dwModuleBase, dwTypeId, TI_GET_LENGTH, &ulLength);
653 
654  printf(" /* %03lx */", dwOffset);
655  DumpType(dwTypeId, pei, indent + 1, FALSE);
656  printf(" %ls", pszName);
657  if (dwChildTag == SymTagArrayType)
658  {
659  SymGetTypeInfo(hProcess, dwModuleBase, dwTypeId, TI_GET_COUNT, &dwCount);
660  printf("[%ld]", dwCount);
661  }
662  else
663  {
664  DWORD dwCurrentBitPos;
665  DWORD dwNextBitPos;
666 
667  SymGetTypeInfo(hProcess, dwModuleBase, tfpex.tfp.ChildId[i], TI_GET_BITPOSITION, &dwCurrentBitPos);
668  if (i < tfpex.tfp.Count - 1)
669  {
670  SymGetTypeInfo(hProcess, dwModuleBase, tfpex.tfp.ChildId[i+1], TI_GET_BITPOSITION, &dwNextBitPos);
671  }
672  else
673  {
674  dwNextBitPos = 0;
675  }
676 
677  if (dwNextBitPos == 0 && dwCurrentBitPos != 0)
678  {
679  dwNextBitPos = ulLength * 8;
680  }
681 
682  if (dwNextBitPos != dwCurrentBitPos)
683  {
684  printf(":%ld", dwNextBitPos - dwCurrentBitPos);
685  }
686  }
687  printf(";\n");
688  LocalFree(pszName);
689  }
690  printfi("}");
691  }
692 }
693 
694 VOID
695 DumpType(DWORD dwTypeIndex, PENUMINFO pei, INT indent, BOOL bMembers)
696 {
697  HANDLE hProcess = pei->hProcess;
698  DWORD64 dwModuleBase = pei->dwModuleBase;
699  DWORD dwTag = 0;
700 
701  SymGetTypeInfo(hProcess, dwModuleBase, dwTypeIndex, TI_GET_SYMTAG, &dwTag);
702 
703  switch (dwTag)
704  {
705  case SymTagEnum:
706  DumpEnum(dwTypeIndex, pei, indent, bMembers);
707  break;
708 
709  case SymTagUDT:
710  DumpUDT(dwTypeIndex, pei, indent, bMembers);
711  break;
712 
713  case SymTagPointerType:
714  DumpPointer(dwTypeIndex, pei, indent);
715  break;
716 
717  case SymTagBaseType:
718  DumpBaseType(dwTypeIndex, pei, indent);
719  break;
720 
721  case SymTagArrayType:
722  DumpArray(dwTypeIndex, pei, indent);
723  break;
724 
725  case SymTagFunctionType:
726  printfi("function");
727  break;
728 
729  default:
730  printfi("typeTag%ld", dwTag);
731  break;
732  }
733 
734 }
735 
736 
737 VOID
738 DumpCV(DWORD dwTypeIndex, PENUMINFO pei)
739 {
740  DWORD cv = 0x20;
741 
742  SymGetTypeInfo(pei->hProcess, pei->dwModuleBase, dwTypeIndex, TI_GET_CALLING_CONVENTION, &cv);
743  switch (cv)
744  {
745  case CV_CALL_NEAR_C:
746  printf("CDECL");
747  return;
748  case CV_CALL_FAR_C:
749  printf("FAR CDECL");
750  return;
751  case CV_CALL_NEAR_PASCAL:
752  printf("PASCAL");
753  return;
754  case CV_CALL_FAR_PASCAL:
755  printf("FAR PASCAL");
756  return;
757  case CV_CALL_NEAR_FAST:
758  printf("FASTCALL");
759  return;
760  case CV_CALL_FAR_FAST:
761  printf("FAR FASTCALL");
762  return;
763  case CV_CALL_SKIPPED:
764  printf("SKIPPED");
765  return;
766  case CV_CALL_NEAR_STD:
767  printf("STDCALL");
768  return;
769  case CV_CALL_FAR_STD:
770  printf("FAR STDCALL");
771  return;
772  case CV_CALL_NEAR_SYS:
773  case CV_CALL_FAR_SYS:
774  case CV_CALL_THISCALL:
775  printf("THISCALL");
776  return;
777  case CV_CALL_MIPSCALL:
778  printf("MIPSCALL");
779  return;
780  case CV_CALL_GENERIC:
781  case CV_CALL_ALPHACALL:
782  case CV_CALL_PPCCALL:
783  case CV_CALL_SHCALL:
784  case CV_CALL_ARMCALL:
785  case CV_CALL_AM33CALL:
786  case CV_CALL_TRICALL:
787  case CV_CALL_SH5CALL:
788  case CV_CALL_M32RCALL:
789  default:
790  printf("UNKNOWNCV");
791  }
792 
793 }
794 
797  PSYMBOL_INFO pSymInfo,
798  ULONG SymbolSize,
799  PVOID UserContext)
800 {
801  printf("x, ");
802  (*(INT*)UserContext)++;
803  return TRUE;
804 }
805 
806 VOID
808 {
810  BOOL bRet;
811  INT NumLocals = 0; // the number of local variables found
812 
813  sf.InstructionOffset = pSymInfo->Address;
814 
815  printf("(");
816  bRet = SymSetContext(pei->hProcess, &sf, 0);
817 
818  if (!bRet)
819  {
820  printf("\nError: SymSetContext() failed. Error code: %lu \n", GetLastError());
821  return;
822  }
823  printf("Address == 0x%x, ReturnOffset = 0x%x", (UINT)pSymInfo->Address, (UINT)sf.ReturnOffset);
824 
825  // Enumerate local variables
826 
827  bRet = SymEnumSymbols(pei->hProcess, 0, 0, EnumParamsProc, &NumLocals);
828 
829  if (!bRet)
830  {
831 // printf("Error: SymEnumSymbols() failed. Error code: %lu \n", GetLastError());
832  printf("?)");
833  return;
834  }
835 
836  if (NumLocals == 0)
837  {
838 // printf("The function does not have parameters and local variables.\n");
839  printf("void)");
840  }
841 
842  printf(")");
843 }
844 
845 VOID
847 {
848  DWORD dwTypeId;
849 
850 //printf("Name=%s, Size=%ld, TypeId=0x%ld\n", pSymInfo->Name, pSymInfo->Size, pSymInfo->TypeIndex);
851 
852  SymGetTypeInfo(pei->hProcess, pei->dwModuleBase, pSymInfo->TypeIndex, TI_GET_TYPEID, &dwTypeId);
853 
854 // DumpCV(pSymInfo->TypeIndex, pei);
855 // printf("\n");
856 // DumpType(pSymInfo->TypeIndex, pei, 0, FALSE);
857  printf("%s", pSymInfo->Name);
858  DumpParams(pSymInfo, pei);
859 }
860 
863  PSYMBOL_INFO pSymInfo,
864  ULONG SymbolSize,
865  PVOID UserContext)
866 {
867  PENUMINFO pei = (PENUMINFO)UserContext;
868 
869  if ((pei->pszSymbolName == NULL) ||
870  (strstr(pSymInfo->Name, pei->pszSymbolName) != 0))
871  {
872  if (pei->bType)
873  {
874  DumpType(pSymInfo->TypeIndex, pei, 0, TRUE);
875  printf("\n\n");
876  }
877  else
878  {
879 #if defined(__GNUC__) && \
880  (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__ < 40400)
881  printf("Symbol: %s, TypeIndex=%ld, Flags=%lx, Value=0x%llx\n",
882 #else
883  printf("Symbol: %s, TypeIndex=%ld, Flags=%lx, Value=0x%I64x\n",
884 #endif
885  pSymInfo->Name, pSymInfo->TypeIndex, pSymInfo->Flags, pSymInfo->Value);
886  //if (pSymInfo->Flags & SYMFLAG_FUNCTION)
887  {
888 // DumpFunction(pSymInfo, pei);
889 // printf("\n\n");
890  }
891  }
892  }
893  return TRUE;
894 }
895 
896 int main(int argc, char* argv[])
897 {
899  CHAR szFullFileName[MAX_PATH+1];
900  DWORD64 dwModuleBase;
901  BOOL bRet;
902  LPSTR pszSymbolPath, pszSymbolName;
903  INT i;
904  ENUMINFO enuminfo;
905 
906  printf("PE symbol dumper\n");
907  printf("Copyright (c) Timo Kreuzer 2008\n\n");
908 
909  if (argc < 2)
910  {
911  PrintUsage();
912  return 0;
913  }
914 
915  /* Get the full path name of the PE file from first argument */
916  GetFullPathName(argv[1], MAX_PATH, szFullFileName, NULL);
917 
918  /* Default Symbol Name (all) */
919  pszSymbolName = NULL;
920 
921  /* Default to ms symbol server */
922  pszSymbolPath = "srv**symbols*http://msdl.microsoft.com/download/symbols";
923 
924  /* Check other command line arguments */
925  for (i = 2; i < argc; i++)
926  {
927  if (*argv[i] == '-')
928  {
929  if (strncmp(argv[i], "-sp=", 4) == 0)
930  {
931  pszSymbolPath = argv[i] + 4;
932  }
933  else if (strcmp(argv[i], "-p") == 0)
934  {
935  g_bShowPos = 1;
936  }
937  else
938  {
939  printf("Invalid argument: %s\n", argv[i]);
940  PrintUsage();
941  return 0;
942  }
943  }
944  else
945  {
946  pszSymbolName = argv[i];
947  }
948  }
949 
951 
952  printf("Trying to get symbols from: %s\n", pszSymbolPath);
953 
954  if (!InitDbgHelp(hProcess, pszSymbolPath))
955  {
956  printf("SymInitialize() failed\n");
957  goto cleanup;
958  }
959 
960  printf("Loading symbols for %s, please wait...\n", szFullFileName);
961  dwModuleBase = SymLoadModule64(hProcess, 0, szFullFileName, 0, 0, 0);
962  if (dwModuleBase == 0)
963  {
964  printf("SymLoadModule64() failed: %ld\n", GetLastError());
965  goto cleanup;
966  }
967 
968  printf("\nSymbols:\n");
969  enuminfo.hProcess = hProcess;
970  enuminfo.pszSymbolName = pszSymbolName;
971  enuminfo.bType = FALSE;
973  bRet = SymEnumSymbols(hProcess, dwModuleBase, NULL, EnumSymbolsProc, &enuminfo);
974  if (!bRet)
975  {
976  printf("SymEnumSymbols failed: %ld\n", GetLastError());
977  }
978 
979  printf("\nTypes:\n");
980  enuminfo.bType = TRUE;
981  enuminfo.dwModuleBase = dwModuleBase;
983  bRet = SymEnumTypes(hProcess, dwModuleBase, EnumSymbolsProc, &enuminfo);
984  if (!bRet)
985  {
986  printf("SymEnumTypes failed: %ld\n", GetLastError());
987  }
988 
989 cleanup:
990 
991  return 0;
992 }
BasicType
Definition: compat.h:1249
BOOL CALLBACK EnumParamsProc(PSYMBOL_INFO pSymInfo, ULONG SymbolSize, PVOID UserContext)
Definition: symdump.c:796
VOID DumpUDT(DWORD dwTypeIndex, PENUMINFO pei, INT indent, BOOL bMembers)
Definition: symdump.c:580
#define CV_CALL_FAR_SYS
Definition: symdump.c:39
static int argc
Definition: ServiceArgs.c:12
CHAR Name[1]
Definition: compat.h:694
#define TRUE
Definition: types.h:120
Definition: compat.h:1932
static const WCHAR indent[]
Definition: object.c:1156
BOOL bType
Definition: symdump.c:122
#define ERROR_SUCCESS
Definition: deptool.c:10
Definition: compat.h:1944
DWORD WINAPI SymSetOptions(DWORD opts)
Definition: dbghelp.c:443
BOOL WINAPI SymGetTypeInfo(HANDLE hProcess, DWORD64 ModBase, ULONG TypeId, IMAGEHLP_SYMBOL_TYPE_INFO GetType, PVOID pInfo)
Definition: type.c:901
VOID DumpType(DWORD dwTypeIndex, PENUMINFO pei, INT indent, BOOL bMembers)
Definition: symdump.c:695
__wchar_t WCHAR
Definition: xmlstorage.h:180
#define CV_CALL_ALPHACALL
Definition: symdump.c:43
char * strstr(char *String1, char *String2)
Definition: utclib.c:653
char CHAR
Definition: xmlstorage.h:175
int main(int argc, char *argv[])
Definition: symdump.c:896
#define CALLBACK
Definition: compat.h:27
ULONG Flags
Definition: compat.h:686
BOOL InitDbgHelp(HANDLE hProcess, LPSTR pszSymbolPath)
Definition: symdump.c:190
ULONG TypeIndex
Definition: compat.h:681
#define CV_CALL_FAR_FAST
Definition: symdump.c:34
DWORD WINAPI GetLastError(VOID)
Definition: except.c:1059
_In_ BOOL _In_ HANDLE hProcess
Definition: mapping.h:70
ULONG64 Address
Definition: compat.h:688
#define argv
Definition: mplay32.c:18
char * LPSTR
Definition: xmlstorage.h:182
int32_t INT
Definition: typedefs.h:56
BOOL IsUnnamed(WCHAR *pszName)
Definition: symdump.c:508
#define CV_CALL_THISCALL
Definition: symdump.c:40
VOID DumpArray(DWORD dwTypeIndex, PENUMINFO pei, INT indent)
Definition: symdump.c:348
_In_ DWORD _In_ DWORD dwOffset
Definition: ntgdi.h:2032
#define SYMOPT_DEFERRED_LOADS
Definition: compat.h:638
BOOL WINAPI SymSetSearchPath(HANDLE hProcess, PCSTR searchPath)
Definition: dbghelp.c:199
struct ENUMINFO * PENUMINFO
#define CV_CALL_M32RCALL
Definition: symdump.c:50
VOID PrintUsage()
Definition: symdump.c:177
GLenum GLclampf GLint i
Definition: glfuncs.h:14
SymTagEnum
Definition: compat.h:1213
BOOL CALLBACK EnumSymbolsProc(PSYMBOL_INFO pSymInfo, ULONG SymbolSize, PVOID UserContext)
Definition: symdump.c:862
BOOL g_bShowPos
Definition: symdump.c:25
#define printfi
Definition: symdump.c:173
smooth NULL
Definition: ftsmooth.c:416
BOOL WINAPI SymInitialize(HANDLE hProcess, PCSTR UserSearchPath, BOOL fInvadeProcess)
Definition: dbghelp.c:393
LPSTR pszSymbolName
Definition: symdump.c:121
CHAR * SymTagString[]
Definition: symdump.c:127
#define CV_CALL_NEAR_STD
Definition: symdump.c:36
#define CV_CALL_AM33CALL
Definition: symdump.c:47
#define CV_CALL_FAR_PASCAL
Definition: symdump.c:32
#define SYMOPT_ALLOW_ABSOLUTE_SYMBOLS
Definition: symdump.c:19
DWORD64 WINAPI SymLoadModule64(HANDLE hProcess, HANDLE hFile, PCSTR ImageName, PCSTR ModuleName, DWORD64 BaseOfDll, DWORD SizeOfDll)
Definition: module.c:673
BOOL WINAPI SymEnumTypes(HANDLE hProcess, ULONG64 BaseOfDll, PSYM_ENUMERATESYMBOLS_CALLBACK EnumSymbolsCallback, PVOID UserContext)
Definition: type.c:449
unsigned int BOOL
Definition: ntddk_ex.h:94
#define CV_CALL_NEAR_FAST
Definition: symdump.c:33
#define CV_CALL_NEAR_C
Definition: symdump.c:29
Definition: symdump.c:112
HANDLE WINAPI GetCurrentProcess(VOID)
Definition: proc.c:1168
#define MAX_PATH
Definition: compat.h:26
unsigned int UINT
Definition: ndis.h:50
int strncmp(const char *String1, const char *String2, ACPI_SIZE Count)
Definition: utclib.c:534
unsigned long DWORD
Definition: ntddk_ex.h:95
Definition: symdump.c:104
#define SetLastError(x)
Definition: compat.h:409
HANDLE hCurrentProcess
Definition: symdump.c:24
#define CV_CALL_NEAR_PASCAL
Definition: symdump.c:31
Definition: symdump.c:98
unsigned __int64 ULONG64
Definition: imports.h:198
ULONG64 InstructionOffset
Definition: compat.h:1010
#define CV_CALL_PPCCALL
Definition: symdump.c:44
static const WCHAR L[]
Definition: oid.c:1087
BOOL WINAPI SymSetContext(HANDLE hProcess, PIMAGEHLP_STACK_FRAME StackFrame, PIMAGEHLP_CONTEXT Context)
Definition: dbghelp.c:478
VOID DumpCV(DWORD dwTypeIndex, PENUMINFO pei)
Definition: symdump.c:738
#define GetFullPathName
Definition: winbase.h:3635
Definition: symdump.c:99
VOID DumpParams(PSYMBOL_INFO pSymInfo, PENUMINFO pei)
Definition: symdump.c:807
LPWSTR WINAPI StrStrW(LPCWSTR lpszStr, LPCWSTR lpszSearch)
Definition: string.c:594
#define CV_CALL_FAR_C
Definition: symdump.c:30
uint64_t DWORD64
Definition: typedefs.h:65
const GLdouble * v
Definition: gl.h:2040
#define CV_CALL_FAR_STD
Definition: symdump.c:37
HANDLE hProcess
Definition: symdump.c:119
#define CV_CALL_SH5CALL
Definition: symdump.c:49
HLOCAL NTAPI LocalFree(HLOCAL hMem)
Definition: heapmem.c:1577
#define CV_CALL_NEAR_SYS
Definition: symdump.c:38
BOOL WINAPI SymEnumSymbols(HANDLE hProcess, ULONG64 BaseOfDll, PCSTR Mask, PSYM_ENUMERATESYMBOLS_CALLBACK EnumSymbolsCallback, PVOID UserContext)
Definition: symbol.c:1126
#define CV_CALL_SHCALL
Definition: symdump.c:45
VOID DumpEnum(DWORD dwTypeIndex, PENUMINFO pei, INT indent, BOOL bMembers)
Definition: symdump.c:519
#define CV_CALL_TRICALL
Definition: symdump.c:48
void IndentPrint(INT ind)
Definition: symdump.c:164
DWORD WINAPI SymGetOptions(void)
Definition: dbghelp.c:458
#define CV_CALL_ARMCALL
Definition: symdump.c:46
ULONG64 Value
Definition: compat.h:687
VOID PrintVariant(VARIANT *v)
Definition: symdump.c:479
unsigned int ULONG
Definition: retypes.h:1
int strcmp(const char *String1, const char *String2)
Definition: utclib.c:469
VOID DumpBaseType(DWORD dwTypeIndex, PENUMINFO pei, INT indent)
Definition: symdump.c:202
char * cleanup(char *str)
Definition: wpickclick.c:99
#define CV_CALL_SKIPPED
Definition: symdump.c:35
VOID DumpFunction(PSYMBOL_INFO pSymInfo, PENUMINFO pei)
Definition: symdump.c:846
#define CV_CALL_MIPSCALL
Definition: symdump.c:41
Definition: symdump.c:101
ULONG64 ReturnOffset
Definition: compat.h:1011
#define CV_CALL_GENERIC
Definition: symdump.c:42
SymTagEnum
Definition: symdump.c:52
VOID DumpPointer(DWORD dwTypeIndex, PENUMINFO pei, INT indent)
Definition: symdump.c:357
DWORD64 dwModuleBase
Definition: symdump.c:120
Definition: compat.h:1931
#define printf
Definition: config.h:203