From e9f18efcfc4c59e3b5b4d1000fef16fbb579030b Mon Sep 17 00:00:00 2001 From: Timo Kreuzer Date: Thu, 14 Aug 2008 21:35:52 +0000 Subject: [PATCH] PE symbol dumper. It's not finished, functions don't work and the type output doesn't always look 100% correct. But it does it's job. You need dbghelp.dll and symsrv.dll from windbg. svn path=/trunk/; revision=35346 --- .../applications/devutils/directory.rbuild | 4 + .../applications/devutils/symdump/symdump.c | 985 ++++++++++++++++++ .../devutils/symdump/symdump.rbuild | 9 + 3 files changed, 998 insertions(+) create mode 100644 rosapps/applications/devutils/symdump/symdump.c create mode 100644 rosapps/applications/devutils/symdump/symdump.rbuild diff --git a/rosapps/applications/devutils/directory.rbuild b/rosapps/applications/devutils/directory.rbuild index 071248a4102..1f981be4285 100644 --- a/rosapps/applications/devutils/directory.rbuild +++ b/rosapps/applications/devutils/directory.rbuild @@ -20,6 +20,10 @@ + + + + diff --git a/rosapps/applications/devutils/symdump/symdump.c b/rosapps/applications/devutils/symdump/symdump.c new file mode 100644 index 00000000000..28b9e2ba51c --- /dev/null +++ b/rosapps/applications/devutils/symdump/symdump.c @@ -0,0 +1,985 @@ +/* + * PE symbol dumper + * + * symdump.c + * + * Copyright (c) 2008 Timo Kreuzer kreuzer reactos org> + * + * This program is released under the terms of the GNU GPL. + * + * TODO: + * - fix GDILoObjType + * - fix UDTKind1 + * - include the correct headers for some stuff + * - fix unions like LARGE_INTEGER + */ + +#include +#define _WINVER 0x501 +#include +#include +#include + +HANDLE hCurrentProcess; +BOOL g_bShowPos = 0; + +#define MAX_SYMBOL_NAME 1024 + +#define CV_CALL_NEAR_C 0x00 +#define CV_CALL_FAR_C 0x01 +#define CV_CALL_NEAR_PASCAL 0x02 +#define CV_CALL_FAR_PASCAL 0x03 +#define CV_CALL_NEAR_FAST 0x04 +#define CV_CALL_FAR_FAST 0x05 +#define CV_CALL_SKIPPED 0x06 +#define CV_CALL_NEAR_STD 0x07 +#define CV_CALL_FAR_STD 0x08 +#define CV_CALL_NEAR_SYS 0x09 +#define CV_CALL_FAR_SYS 0x0a +#define CV_CALL_THISCALL 0x0b +#define CV_CALL_MIPSCALL 0x0c +#define CV_CALL_GENERIC 0x0d +#define CV_CALL_ALPHACALL 0x0e +#define CV_CALL_PPCCALL 0x0f +#define CV_CALL_SHCALL 0x10 +#define CV_CALL_ARMCALL 0x11 +#define CV_CALL_AM33CALL 0x12 +#define CV_CALL_TRICALL 0x13 +#define CV_CALL_SH5CALL 0x14 +#define CV_CALL_M32RCALL 0x15 + +enum SymTagEnum +{ + SymTagNull, + SymTagExe, + SymTagCompiland, + SymTagCompilandDetails, + SymTagCompilandEnv, + SymTagFunction, + SymTagBlock, + SymTagData, + SymTagAnnotation, + SymTagLabel, + SymTagPublicSymbol, + SymTagUDT, + SymTagEnum, + SymTagFunctionType, + SymTagPointerType, + SymTagArrayType, + SymTagBaseType, + SymTagTypedef, + SymTagBaseClass, + SymTagFriend, + SymTagFunctionArgType, + SymTagFuncDebugStart, + SymTagFuncDebugEnd, + SymTagUsingNamespace, + SymTagVTableShape, + SymTagVTable, + SymTagCustom, + SymTagThunk, + SymTagCustomType, + SymTagManagedType, + SymTagDimension, + SymTagMax +}; + +enum +{ + UDTKind_Struct = 0, + UDTKind_Class = 1, /* ? */ + UDTKind_Union = 2, +}; + +enum BasicType +{ + btNoType = 0, + btVoid = 1, + btChar = 2, + btWChar = 3, + btInt = 6, + btUInt = 7, + btFloat = 8, + btBCD = 9, + btBool = 10, + btLong = 13, + btULong = 14, + btCurrency = 25, + btDate = 26, + btVariant = 27, + btComplex = 28, + btBit = 29, + btBSTR = 30, + btHresult = 31 +}; + +typedef struct +{ + HANDLE hProcess; + DWORD64 dwModuleBase; + LPSTR pszSymbolName; + BOOL bType; +} ENUMINFO, *PENUMINFO; + +VOID DumpType(DWORD dwTypeIndex, PENUMINFO pei, INT indent, BOOL bMembers); + +CHAR *SymTagString[] = +{ + "SymTagNull", + "SymTagExe", + "SymTagCompiland", + "SymTagCompilandDetails", + "SymTagCompilandEnv", + "SymTagFunction", + "SymTagBlock", + "SymTagData", + "SymTagAnnotation", + "SymTagLabel", + "SymTagPublicSymbol", + "SymTagUDT", + "SymTagEnum", + "SymTagFunctionType", + "SymTagPointerType", + "SymTagArrayType", + "SymTagBaseType", + "SymTagTypedef", + "SymTagBaseClass", + "SymTagFriend", + "SymTagFunctionArgType", + "SymTagFuncDebugStart", + "SymTagFuncDebugEnd", + "SymTagUsingNamespace", + "SymTagVTableShape", + "SymTagVTable", + "SymTagCustom", + "SymTagThunk", + "SymTagCustomType", + "SymTagManagedType", + "SymTagDimension", + "SymTagMax" +}; + +void +IndentPrint(INT ind) +{ + INT i; + for (i = 0; i < ind; i++) + { + printf(" "); + } +} + +#define printfi \ + IndentPrint(indent); printf + +VOID +PrintUsage() +{ + printf("Syntax:\n\n"); + printf("dumpsym [-sp=] [-p] []\n\n"); + printf(" The PE file you want to dump the symbols of\n"); + printf("-sp= Path to your symbol files.\n"); + printf(" Default is MS symbol server.\n"); + printf("-p Enable struct positions.\n"); + printf(" A name of a Symbol, you want to dump\n"); + printf(" Default is all symbols.\n"); + printf("\n"); +} + +BOOL InitDbgHelp(HANDLE hProcess, LPSTR pszSymbolPath) +{ + if (!SymInitialize(hProcess, 0, FALSE)) + return FALSE; + + SymSetOptions(SymGetOptions() | SYMOPT_ALLOW_ABSOLUTE_SYMBOLS); + SymSetOptions(SymGetOptions() & (~SYMOPT_DEFERRED_LOADS)); + SymSetSearchPath(hProcess, pszSymbolPath); + return TRUE; +} + +VOID +DumpBaseType(DWORD dwTypeIndex, PENUMINFO pei, INT indent) +{ + ULONG64 ulSize; + DWORD dwBaseType; + + SymGetTypeInfo(pei->hProcess, pei->dwModuleBase, dwTypeIndex, TI_GET_LENGTH, &ulSize); + SymGetTypeInfo(pei->hProcess, pei->dwModuleBase, dwTypeIndex, TI_GET_BASETYPE, &dwBaseType); + + switch (dwBaseType) + { + case btVoid: + printfi("VOID"); + return; + case btChar: + printfi("CHAR"); + return; + case btWChar: + printfi("WCHAR"); + return; + case btInt: + switch (ulSize) + { + case 1: + printfi("CHAR"); + return; + case 2: + printfi("SHORT"); + return; + case 4: + printfi("INT"); + return; + case 8: + printfi("INT64"); + return; + default: + printfi("INT%ld", (ULONG)ulSize * 8); + return; + } + case btUInt: + switch (ulSize) + { + case 1: + printfi("UCHAR"); + return; + case 2: + printfi("USHORT"); + return; + case 4: + printfi("UINT"); + return; + case 8: + printfi("UINT64"); + return; + default: + printfi("UINT%ld", (ULONG)ulSize * 8); + return; + } + case btFloat: + switch (ulSize) + { + case 4: + printfi("FLOAT"); + return; + case 8: + printfi("DOUBLE"); + return; + default: + printfi("FLOAT%ld", (ULONG)ulSize * 8); + return; + } + case btBCD: + printfi("BCD%ld", (ULONG)ulSize * 8); + return; + case btBool: + switch (ulSize) + { + case 1: + printfi("BOOLEAN"); + return; + case 4: + printfi("BOOL"); + return; + default: + printfi("BOOL%ld", (ULONG)ulSize * 8); + return; + } + case btLong: + switch (ulSize) + { + case 1: + printfi("CHAR"); + return; + case 2: + printfi("SHORT"); + return; + case 4: + printfi("LONG"); + return; + case 8: + printfi("LONGLONG"); + return; + default: + printfi("LONG%ld", (ULONG)ulSize * 8); + return; + } + case btULong: + switch (ulSize) + { + case 1: + printfi("UCHAR"); + return; + case 2: + printfi("USHORT"); + return; + case 4: + printfi("ULONG"); + return; + case 8: + printfi("ULONGLONG"); + return; + default: + printfi("ULONG%ld", (ULONG)ulSize * 8); + return; + } + case btCurrency: + case btDate: + case btVariant: + case btComplex: + case btBit: + case btBSTR: + printfi("UNSUP_%ld_%ld", dwBaseType, (ULONG)ulSize); + return; + case btHresult: + if (ulSize == 4) + { + printfi("HRESULT"); + return; + } + printfi("HRESULT%ld", (ULONG)ulSize); + return; + } + + printfi("UNKNBASETYPE"); +} + +VOID +DumpArray(DWORD dwTypeIndex, PENUMINFO pei, INT indent) +{ + DWORD dwTypeId; + + SymGetTypeInfo(pei->hProcess, pei->dwModuleBase, dwTypeIndex, TI_GET_TYPE, &dwTypeId); + DumpType(dwTypeId, pei, indent, FALSE); +} + +VOID +DumpPointer(DWORD dwTypeIndex, PENUMINFO pei, INT indent) +{ + DWORD dwRefTypeId; + DWORD dwTag = 0; + ULONG64 ulSize; + DWORD dwBaseType; + + SymGetTypeInfo(pei->hProcess, pei->dwModuleBase, dwTypeIndex, TI_GET_TYPE, &dwRefTypeId); + SymGetTypeInfo(pei->hProcess, pei->dwModuleBase, dwRefTypeId, TI_GET_BASETYPE, &dwBaseType); + SymGetTypeInfo(pei->hProcess, pei->dwModuleBase, dwRefTypeId, TI_GET_LENGTH, &ulSize); + SymGetTypeInfo(pei->hProcess, pei->dwModuleBase, dwRefTypeId, TI_GET_SYMTAG, &dwTag); + + if (dwTag == SymTagFunctionType) + { + printfi("PPROC"); + return; + } + + switch (dwBaseType) + { + case btVoid: + switch (ulSize) + { + case 0: + printfi("PVOID"); + return; + } + break; + + case btChar: + switch (ulSize) + { + case 1: + printfi("PCHAR"); + return; + } + break; + case btWChar: + switch (ulSize) + { + case 2: + printfi("PWCHAR"); + return; + } + break; + case btInt: + switch (ulSize) + { + case 4: + printfi("PINT"); + return; + } + break; + case btUInt: + switch (ulSize) + { + case 4: + printfi("PUINT"); + return; + } + break; + case btFloat: + switch (ulSize) + { + case 4: + printfi("PFLOAT"); + return; + case 8: + printfi("PDOUBLE"); + return; + } + break; + case btBCD: + break; + case btBool: + switch (ulSize) + { + case 1: + printfi("PBOOLEAN"); + return; + case 4: + printfi("PBOOL"); + return; + } + break; + case btLong: + switch (ulSize) + { + case 4: + printfi("PLONG"); + return; + case 8: + printfi("PLONGLONG"); + return; + } + break; + case btULong: + switch (ulSize) + { + case 4: + printfi("PULONG"); + return; + case 8: + printfi("PULONGLONG"); + return; + } + break; + case btCurrency: + case btDate: + case btVariant: + case btComplex: + case btBit: + case btBSTR: + case btHresult: + break; + } + + DumpType(dwRefTypeId, pei, indent, FALSE); + printf("*"); +} + +VOID +PrintVariant(VARIANT *v) +{ +// printf("", v->n1.n2.vt); + switch (v->n1.n2.vt) + { + case VT_I1: + printf("%d", (INT)v->n1.n2.n3.cVal); + break; + case VT_UI1: + printf("0x%x", (UINT)v->n1.n2.n3.cVal); + break; + case VT_I2: + printf("%d", (UINT)v->n1.n2.n3.iVal); + break; + case VT_UI2: + printf("0x%x", (UINT)v->n1.n2.n3.iVal); + break; + case VT_INT: + case VT_I4: + printf("%d", (UINT)v->n1.n2.n3.lVal); + break; + case VT_UINT: + case VT_UI4: + printf("0x%x", (UINT)v->n1.n2.n3.lVal); + break; + } +} + +BOOL +IsUnnamed(WCHAR *pszName) +{ + if ((StrStrW(pszName, L"__unnamed") != NULL) || + (StrStrW(pszName, L"") != NULL)) + { + return TRUE; + } + return FALSE; +} + +VOID +DumpEnum(DWORD dwTypeIndex, PENUMINFO pei, INT indent, BOOL bMembers) +{ + DWORD64 dwModuleBase = pei->dwModuleBase; + HANDLE hProcess = pei->hProcess; + INT i; + DWORD dwUDTKind; + WCHAR *pszName, *pszNameX; + struct + { + TI_FINDCHILDREN_PARAMS tfp; + ULONG TypeIds[200]; + } tfpex; + VARIANT v; + + SymGetTypeInfo(hProcess, dwModuleBase, dwTypeIndex, TI_GET_SYMNAME, &pszNameX); + SymGetTypeInfo(hProcess, dwModuleBase, dwTypeIndex, TI_GET_UDTKIND, &dwUDTKind); + pszName = pszNameX; + if (IsUnnamed(pszName)) + { + if (bMembers) + { + LocalFree(pszNameX); + return; + } + bMembers = TRUE; + pszName = L""; + } + printfi("enum %ls", pszName); + LocalFree(pszNameX); + + if (bMembers) + { + printf(" /* %03x */", 0); + printfi("\n{\n"); + + /* Get the children */ + SymGetTypeInfo(hProcess, dwModuleBase, dwTypeIndex, TI_GET_CHILDRENCOUNT, &tfpex.tfp.Count); + + tfpex.tfp.Start = 0; + SymGetTypeInfo(hProcess, dwModuleBase, dwTypeIndex, TI_FINDCHILDREN, &tfpex.tfp); + + for (i = 0; i < tfpex.tfp.Count; i++) + { + pszName = L""; + + SymGetTypeInfo(hProcess, dwModuleBase, tfpex.tfp.ChildId[i], TI_GET_SYMNAME, &pszName); + SymGetTypeInfo(hProcess, dwModuleBase, tfpex.tfp.ChildId[i], TI_GET_VALUE, &v); + + indent++; + printfi("%ls = ", pszName); + PrintVariant(&v); + printf(",\n"); + indent--; + + LocalFree(pszName); + } + printfi("}"); + } +} + +VOID +DumpUDT(DWORD dwTypeIndex, PENUMINFO pei, INT indent, BOOL bMembers) +{ + DWORD64 dwModuleBase = pei->dwModuleBase; + HANDLE hProcess = pei->hProcess; + INT i; + DWORD dwUDTKind; + WCHAR *pszName, *pszNameX; + struct + { + TI_FINDCHILDREN_PARAMS tfp; + ULONG TypeIds[200]; + } tfpex; + + DWORD dwDataKind; + DWORD dwTypeId; + DWORD dwCount; + WCHAR *pszTypeName; + + SymGetTypeInfo(hProcess, dwModuleBase, dwTypeIndex, TI_GET_SYMNAME, &pszNameX); + SymGetTypeInfo(hProcess, dwModuleBase, dwTypeIndex, TI_GET_UDTKIND, &dwUDTKind); + + pszName = pszNameX; + if (IsUnnamed(pszName)) + { + if (bMembers) + { + LocalFree(pszNameX); + return; + } + bMembers = TRUE; + pszName = L""; + } + if (dwUDTKind == UDTKind_Struct) + { + printfi("struct %ls", pszName); + } + else if (dwUDTKind == UDTKind_Union) + { + printfi("union %ls", pszName); + } + else + { + printfi("UTDKind%ld %ls", dwUDTKind, pszName); + } + LocalFree(pszNameX); + + if (bMembers) + { + ULONG64 ulLength; + + printf("\n"); + printfi("{\n"); + + /* Get the children */ + SymGetTypeInfo(hProcess, dwModuleBase, dwTypeIndex, TI_GET_CHILDRENCOUNT, &tfpex.tfp.Count); + + tfpex.tfp.Start = 0; + SymGetTypeInfo(hProcess, dwModuleBase, dwTypeIndex, TI_FINDCHILDREN, &tfpex.tfp); + + for (i = 0; i < tfpex.tfp.Count; i++) + { + DWORD dwChildTag; + DWORD dwOffset; + + pszName = L""; + pszTypeName = L""; + + SymGetTypeInfo(hProcess, dwModuleBase, tfpex.tfp.ChildId[i], TI_GET_SYMNAME, &pszName); + SymGetTypeInfo(hProcess, dwModuleBase, tfpex.tfp.ChildId[i], TI_GET_DATAKIND, &dwDataKind); + SymGetTypeInfo(hProcess, dwModuleBase, tfpex.tfp.ChildId[i], TI_GET_TYPE, &dwTypeId); + SymGetTypeInfo(hProcess, dwModuleBase, tfpex.tfp.ChildId[i], TI_GET_OFFSET, &dwOffset); + SymGetTypeInfo(hProcess, dwModuleBase, dwTypeId, TI_GET_SYMTAG, &dwChildTag); + SymGetTypeInfo(hProcess, dwModuleBase, dwTypeId, TI_GET_LENGTH, &ulLength); + + printf(" /* %03lx */", dwOffset); + DumpType(dwTypeId, pei, indent + 1, FALSE); + printf(" %ls", pszName); + if (dwChildTag == SymTagArrayType) + { + SymGetTypeInfo(hProcess, dwModuleBase, dwTypeId, TI_GET_COUNT, &dwCount); + printf("[%ld]", dwCount); + } + else + { + DWORD dwCurrentBitPos; + DWORD dwNextBitPos; + + SymGetTypeInfo(hProcess, dwModuleBase, tfpex.tfp.ChildId[i], TI_GET_BITPOSITION, &dwCurrentBitPos); + if (i < tfpex.tfp.Count - 1) + { + SymGetTypeInfo(hProcess, dwModuleBase, tfpex.tfp.ChildId[i+1], TI_GET_BITPOSITION, &dwNextBitPos); + } + else + { + dwNextBitPos = 0; + } + + if (dwNextBitPos == 0 && dwCurrentBitPos != 0) + { + dwNextBitPos = ulLength * 8; + } + + if (dwNextBitPos != dwCurrentBitPos) + { + printf(":%ld", dwNextBitPos - dwCurrentBitPos); + } + } + printf(";\n"); + LocalFree(pszName); + } + printfi("}"); + } +} + +VOID +DumpType(DWORD dwTypeIndex, PENUMINFO pei, INT indent, BOOL bMembers) +{ + HANDLE hProcess = pei->hProcess; + DWORD64 dwModuleBase = pei->dwModuleBase; + DWORD dwTag = 0; + + SymGetTypeInfo(hProcess, dwModuleBase, dwTypeIndex, TI_GET_SYMTAG, &dwTag); + + switch (dwTag) + { + case SymTagEnum: + DumpEnum(dwTypeIndex, pei, indent, bMembers); + break; + + case SymTagUDT: + DumpUDT(dwTypeIndex, pei, indent, bMembers); + break; + + case SymTagPointerType: + DumpPointer(dwTypeIndex, pei, indent); + break; + + case SymTagBaseType: + DumpBaseType(dwTypeIndex, pei, indent); + break; + + case SymTagArrayType: + DumpArray(dwTypeIndex, pei, indent); + break; + + case SymTagFunctionType: + printfi("function"); + break; + + default: + printfi("typeTag%ld", dwTag); + break; + } + +} + + +VOID +DumpCV(DWORD dwTypeIndex, PENUMINFO pei) +{ + DWORD cv = 0x20; + + SymGetTypeInfo(pei->hProcess, pei->dwModuleBase, dwTypeIndex, TI_GET_CALLING_CONVENTION, &cv); + switch (cv) + { + case CV_CALL_NEAR_C: + printf("CDECL"); + return; + case CV_CALL_FAR_C: + printf("FAR CDECL"); + return; + case CV_CALL_NEAR_PASCAL: + printf("PASCAL"); + return; + case CV_CALL_FAR_PASCAL: + printf("FAR PASCAL"); + return; + case CV_CALL_NEAR_FAST: + printf("FASTCALL"); + return; + case CV_CALL_FAR_FAST: + printf("FAR FASTCALL"); + return; + case CV_CALL_SKIPPED: + printf("SKIPPED"); + return; + case CV_CALL_NEAR_STD: + printf("STDCALL"); + return; + case CV_CALL_FAR_STD: + printf("FAR STDCALL"); + return; + case CV_CALL_NEAR_SYS: + case CV_CALL_FAR_SYS: + case CV_CALL_THISCALL: + printf("THISCALL"); + return; + case CV_CALL_MIPSCALL: + printf("MIPSCALL"); + return; + case CV_CALL_GENERIC: + case CV_CALL_ALPHACALL: + case CV_CALL_PPCCALL: + case CV_CALL_SHCALL: + case CV_CALL_ARMCALL: + case CV_CALL_AM33CALL: + case CV_CALL_TRICALL: + case CV_CALL_SH5CALL: + case CV_CALL_M32RCALL: + default: + printf("UNKNOWNCV"); + } + +} + +BOOL CALLBACK +EnumParamsProc( + PSYMBOL_INFO pSymInfo, + ULONG SymbolSize, + PVOID UserContext) +{ + printf("x, "); + (*(INT*)UserContext)++; + return TRUE; +} + +VOID +DumpParams(PSYMBOL_INFO pSymInfo, PENUMINFO pei) +{ + IMAGEHLP_STACK_FRAME sf; + BOOL bRet; + + sf.InstructionOffset = pSymInfo->Address; + + printf("("); + bRet = SymSetContext(pei->hProcess, &sf, 0); + + if (!bRet) + { + printf("\nError: SymSetContext() failed. Error code: %lu \n", GetLastError()); + return; + } + printf("Address == 0x%x, ReturnOffset = 0x%x", (UINT)pSymInfo->Address, (UINT)sf.ReturnOffset); + + // Enumerate local variables + + INT NumLocals = 0; // the number of local variables found + + bRet = SymEnumSymbols(pei->hProcess, 0, 0, EnumParamsProc, &NumLocals); + + if (!bRet) + { +// printf("Error: SymEnumSymbols() failed. Error code: %lu \n", GetLastError()); + printf("?)"); + return; + } + + if (NumLocals == 0) + { +// printf("The function does not have parameters and local variables.\n"); + printf("void)"); + } + + printf(")"); +} + +VOID +DumpFunction(PSYMBOL_INFO pSymInfo, PENUMINFO pei) +{ + DWORD dwTypeId; + +//printf("Name=%s, Size=%ld, TypeId=0x%ld\n", pSymInfo->Name, pSymInfo->Size, pSymInfo->TypeIndex); + + SymGetTypeInfo(pei->hProcess, pei->dwModuleBase, pSymInfo->TypeIndex, TI_GET_TYPEID, &dwTypeId); + +// DumpCV(pSymInfo->TypeIndex, pei); +// printf("\n"); +// DumpType(pSymInfo->TypeIndex, pei, 0, FALSE); + printf("%s", pSymInfo->Name); + DumpParams(pSymInfo, pei); +} + +BOOL CALLBACK +EnumSymbolsProc( + PSYMBOL_INFO pSymInfo, + ULONG SymbolSize, + PVOID UserContext) +{ + PENUMINFO pei = (PENUMINFO)UserContext; + + if ((pei->pszSymbolName == NULL) || + (strstr(pSymInfo->Name, pei->pszSymbolName) != 0)) + { + if (pei->bType) + { + DumpType(pSymInfo->TypeIndex, pei, 0, TRUE); + printf("\n\n"); + } + else + { + //if (pSymInfo->Flags & SYMFLAG_FUNCTION) + { +// DumpFunction(pSymInfo, pei); +// printf("\n\n"); + } + } + } + return TRUE; +} + +int main(int argc, char* argv[]) +{ + HANDLE hProcess; + CHAR szFullFileName[MAX_PATH+1]; + DWORD64 dwModuleBase; + BOOL bRet; + LPSTR pszSymbolPath, pszSymbolName; + INT i; + ENUMINFO enuminfo; + + printf("PE symbol dumper\n"); + printf("Copyright (c) Timo Kreuzer 2008\n\n"); + + if (argc < 2) + { + PrintUsage(); + return 0; + } + + /* Get the full path name of the PE file from first argument */ + GetFullPathName(argv[1], MAX_PATH, szFullFileName, NULL); + + /* Default Symbol Name (all) */ + pszSymbolName = NULL; + + /* Default to ms symbol server */ + pszSymbolPath = "srv**symbols*http://msdl.microsoft.com/download/symbols"; + + /* Check other command line arguments */ + for (i = 2; i < argc; i++) + { + if (*argv[i] == '-') + { + if (strncmp(argv[i], "-sp=", 4) == 0) + { + pszSymbolPath = argv[i] + 4; + } + else if (strcmp(argv[i], "-p") == 0) + { + g_bShowPos = 1; + } + else + { + printf("Invalid argument: %s\n", argv[i]); + PrintUsage(); + return 0; + } + } + else + { + pszSymbolName = argv[i]; + } + } + + hProcess = GetCurrentProcess(); + + printf("Trying to get symbols from: %s\n", pszSymbolPath); + + if (!InitDbgHelp(hProcess, pszSymbolPath)) + { + printf("SymInitialize() failed\n"); + goto cleanup; + } + + printf("Loading symbols for %s, please wait...\n", szFullFileName); + dwModuleBase = SymLoadModule64(hProcess, 0, szFullFileName, 0, 0, 0); + if (dwModuleBase == 0) + { + printf("SymLoadModule64() failed: %ld\n", GetLastError()); + goto cleanup; + } + + printf("\nSymbols:\n"); + enuminfo.hProcess = hProcess; + enuminfo.pszSymbolName = pszSymbolName; + enuminfo.bType = FALSE; + SetLastError(ERROR_SUCCESS); + bRet = SymEnumSymbols(hProcess, dwModuleBase, NULL, EnumSymbolsProc, &enuminfo); + if (!bRet) + { + printf("SymEnumSymbols failed: %ld\n", GetLastError()); + } + + printf("\nTypes:\n"); + enuminfo.bType = TRUE; + enuminfo.dwModuleBase = dwModuleBase; + SetLastError(ERROR_SUCCESS); + bRet = SymEnumTypes(hProcess, dwModuleBase, EnumSymbolsProc, &enuminfo); + if (!bRet) + { + printf("SymEnumTypes failed: %ld\n", GetLastError()); + } + +cleanup: + + return 0; +} diff --git a/rosapps/applications/devutils/symdump/symdump.rbuild b/rosapps/applications/devutils/symdump/symdump.rbuild new file mode 100644 index 00000000000..a02bddd0fb0 --- /dev/null +++ b/rosapps/applications/devutils/symdump/symdump.rbuild @@ -0,0 +1,9 @@ + + . + 0x0501 + 0x0501 + dbghelp + shlwapi + kernel32 + symdump.c +