DBG: undecorate import/export names
This commit is contained in:
parent
c11659da23
commit
144dbd4c2f
|
@ -12,6 +12,7 @@
|
||||||
#include "console.h"
|
#include "console.h"
|
||||||
#include "debugger.h"
|
#include "debugger.h"
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
#include "symbolundecorator.h"
|
||||||
|
|
||||||
std::map<Range, std::unique_ptr<MODINFO>, RangeCompare> modinfo;
|
std::map<Range, std::unique_ptr<MODINFO>, RangeCompare> modinfo;
|
||||||
std::unordered_map<duint, std::string> hashNameMap;
|
std::unordered_map<duint, std::string> hashNameMap;
|
||||||
|
@ -156,6 +157,13 @@ static void ReadExportDirectory(MODINFO & Info, ULONG_PTR FileMapVA)
|
||||||
{
|
{
|
||||||
return Info.exports.at(a).rva < Info.exports.at(b).rva;
|
return Info.exports.at(a).rva < Info.exports.at(b).rva;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// undecorate names
|
||||||
|
for(auto & x : Info.exports)
|
||||||
|
{
|
||||||
|
if(!x.name.empty())
|
||||||
|
undecorateName(x.name, x.undecoratedName);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void ReadImportDirectory(MODINFO & Info, ULONG_PTR FileMapVA)
|
static void ReadImportDirectory(MODINFO & Info, ULONG_PTR FileMapVA)
|
||||||
|
@ -237,6 +245,10 @@ static void ReadImportDirectory(MODINFO & Info, ULONG_PTR FileMapVA)
|
||||||
{
|
{
|
||||||
return Info.imports[a].iatRva < Info.imports[b].iatRva;
|
return Info.imports[a].iatRva < Info.imports[b].iatRva;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// undecorate names
|
||||||
|
for(auto & i : Info.imports)
|
||||||
|
undecorateName(i.name, i.undecoratedName);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void ReadTlsCallbacks(MODINFO & Info, ULONG_PTR FileMapVA)
|
static void ReadTlsCallbacks(MODINFO & Info, ULONG_PTR FileMapVA)
|
||||||
|
@ -617,7 +629,6 @@ void GetModuleInfo(MODINFO & Info, ULONG_PTR FileMapVA)
|
||||||
|
|
||||||
ReadExportDirectory(Info, FileMapVA);
|
ReadExportDirectory(Info, FileMapVA);
|
||||||
ReadImportDirectory(Info, FileMapVA);
|
ReadImportDirectory(Info, FileMapVA);
|
||||||
dprintf("[%s%s] read %d imports and %d exports\n", Info.name, Info.extension, Info.imports.size(), Info.exports.size());
|
|
||||||
ReadTlsCallbacks(Info, FileMapVA);
|
ReadTlsCallbacks(Info, FileMapVA);
|
||||||
ReadBaseRelocationTable(Info, FileMapVA);
|
ReadBaseRelocationTable(Info, FileMapVA);
|
||||||
ReadDebugDirectory(Info, FileMapVA);
|
ReadDebugDirectory(Info, FileMapVA);
|
||||||
|
@ -1166,7 +1177,7 @@ void MODIMPORT::convertToGuiSymbol(duint base, SYMBOLINFO* info) const
|
||||||
info->addr = base + iatRva;
|
info->addr = base + iatRva;
|
||||||
info->type = sym_import;
|
info->type = sym_import;
|
||||||
info->decoratedSymbol = (char*)name.c_str();
|
info->decoratedSymbol = (char*)name.c_str();
|
||||||
info->undecoratedSymbol = "";
|
info->undecoratedSymbol = (char*)undecoratedName.c_str();
|
||||||
info->freeDecorated = info->freeUndecorated = false;
|
info->freeDecorated = info->freeUndecorated = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1175,6 +1186,6 @@ void MODEXPORT::convertToGuiSymbol(duint base, SYMBOLINFO* info) const
|
||||||
info->addr = base + rva;
|
info->addr = base + rva;
|
||||||
info->type = sym_export;
|
info->type = sym_export;
|
||||||
info->decoratedSymbol = (char*)name.c_str();
|
info->decoratedSymbol = (char*)name.c_str();
|
||||||
info->undecoratedSymbol = "";
|
info->undecoratedSymbol = (char*)undecoratedName.c_str();
|
||||||
info->freeDecorated = info->freeUndecorated = false;
|
info->freeDecorated = info->freeUndecorated = false;
|
||||||
}
|
}
|
||||||
|
|
|
@ -57,6 +57,7 @@ struct MODEXPORT : SymbolInfoGui
|
||||||
bool forwarded = false;
|
bool forwarded = false;
|
||||||
String forwardName;
|
String forwardName;
|
||||||
String name;
|
String name;
|
||||||
|
String undecoratedName;
|
||||||
|
|
||||||
virtual void convertToGuiSymbol(duint base, SYMBOLINFO* info) const override;
|
virtual void convertToGuiSymbol(duint base, SYMBOLINFO* info) const override;
|
||||||
};
|
};
|
||||||
|
@ -67,6 +68,7 @@ struct MODIMPORT : SymbolInfoGui
|
||||||
DWORD iatRva;
|
DWORD iatRva;
|
||||||
duint ordinal; //equal to -1 if imported by name
|
duint ordinal; //equal to -1 if imported by name
|
||||||
String name;
|
String name;
|
||||||
|
String undecoratedName;
|
||||||
|
|
||||||
virtual void convertToGuiSymbol(duint base, SYMBOLINFO* info) const override;
|
virtual void convertToGuiSymbol(duint base, SYMBOLINFO* info) const override;
|
||||||
};
|
};
|
||||||
|
|
|
@ -13,6 +13,7 @@
|
||||||
#include "pdbdiafile.h"
|
#include "pdbdiafile.h"
|
||||||
#include "stringutils.h"
|
#include "stringutils.h"
|
||||||
#include "console.h"
|
#include "console.h"
|
||||||
|
#include "symbolundecorator.h"
|
||||||
|
|
||||||
//Taken from: https://msdn.microsoft.com/en-us/library/ms752876(v=vs.85).aspx
|
//Taken from: https://msdn.microsoft.com/en-us/library/ms752876(v=vs.85).aspx
|
||||||
class FileStream : public IStream
|
class FileStream : public IStream
|
||||||
|
@ -973,50 +974,6 @@ bool PDBDiaFile::resolveSymbolSize(IDiaSymbol* symbol, uint64_t & size, uint32_t
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
typedef char* pchar_t;
|
|
||||||
typedef const char* pcchar_t;
|
|
||||||
typedef char* (*GetParameter_t)(long n);
|
|
||||||
using Alloc_t = decltype(malloc);
|
|
||||||
using Free_t = decltype(free);
|
|
||||||
|
|
||||||
enum
|
|
||||||
{
|
|
||||||
UNDNAME_COMPLETE = 0x0, //Enables full undecoration.
|
|
||||||
UNDNAME_NO_LEADING_UNDERSCORES = 0x1, //Removes leading underscores from Microsoft extended keywords.
|
|
||||||
UNDNAME_NO_MS_KEYWORDS = 0x2, //Disables expansion of Microsoft extended keywords.
|
|
||||||
UNDNAME_NO_FUNCTION_RETURNS = 0x4, //Disables expansion of return type for primary declaration.
|
|
||||||
UNDNAME_NO_ALLOCATION_MODEL = 0x8, //Disables expansion of the declaration model.
|
|
||||||
UNDNAME_NO_ALLOCATION_LANGUAGE = 0x10, //Disables expansion of the declaration language specifier.
|
|
||||||
UNDNAME_NO_MS_THISTYPE = 0x20, //NYI Disable expansion of MS keywords on the 'this' type for primary declaration.
|
|
||||||
UNDNAME_NO_CV_THISTYPE = 0x40, //NYI Disable expansion of CV modifiers on the 'this' type for primary declaration/
|
|
||||||
UNDNAME_NO_THISTYPE = 0x60, //Disables all modifiers on the this type.
|
|
||||||
UNDNAME_NO_ACCESS_SPECIFIERS = 0x80, //Disables expansion of access specifiers for members.
|
|
||||||
UNDNAME_NO_THROW_SIGNATURES = 0x100, //Disables expansion of "throw-signatures" for functions and pointers to functions.
|
|
||||||
UNDNAME_NO_MEMBER_TYPE = 0x200, //Disables expansion of static or virtual members.
|
|
||||||
UNDNAME_NO_RETURN_UDT_MODEL = 0x400, //Disables expansion of the Microsoft model for UDT returns.
|
|
||||||
UNDNAME_32_BIT_DECODE = 0x800, //Undecorates 32-bit decorated names.
|
|
||||||
UNDNAME_NAME_ONLY = 0x1000, //Gets only the name for primary declaration; returns just [scope::]name. Expands template params.
|
|
||||||
UNDNAME_TYPE_ONLY = 0x2000, //Input is just a type encoding; composes an abstract declarator.
|
|
||||||
UNDNAME_HAVE_PARAMETERS = 0x4000, //The real template parameters are available.
|
|
||||||
UNDNAME_NO_ECSU = 0x8000, //Suppresses enum/class/struct/union.
|
|
||||||
UNDNAME_NO_IDENT_CHAR_CHECK = 0x10000, //Suppresses check for valid identifier characters.
|
|
||||||
UNDNAME_NO_PTR64 = 0x20000, //Does not include ptr64 in output.
|
|
||||||
};
|
|
||||||
|
|
||||||
#if _MSC_VER != 1800
|
|
||||||
#error unDNameEx is undocumented and possibly unsupported on your runtime! Uncomment this line if you understand the risks and want continue regardless...
|
|
||||||
#endif //_MSC_VER
|
|
||||||
|
|
||||||
//undname.cxx
|
|
||||||
extern "C" pchar_t __cdecl __unDNameEx(_Out_opt_z_cap_(maxStringLength) pchar_t outputString,
|
|
||||||
pcchar_t name,
|
|
||||||
int maxStringLength, // Note, COMMA is leading following optional arguments
|
|
||||||
Alloc_t pAlloc,
|
|
||||||
Free_t pFree,
|
|
||||||
GetParameter_t pGetParameter,
|
|
||||||
unsigned long disableFlags
|
|
||||||
);
|
|
||||||
|
|
||||||
bool PDBDiaFile::convertSymbolInfo(IDiaSymbol* symbol, DiaSymbol_t & symbolInfo, InternalQueryContext_t & context)
|
bool PDBDiaFile::convertSymbolInfo(IDiaSymbol* symbol, DiaSymbol_t & symbolInfo, InternalQueryContext_t & context)
|
||||||
{
|
{
|
||||||
HRESULT hr;
|
HRESULT hr;
|
||||||
|
@ -1042,36 +999,7 @@ bool PDBDiaFile::convertSymbolInfo(IDiaSymbol* symbol, DiaSymbol_t & symbolInfo,
|
||||||
|
|
||||||
if(context.collectUndecoratedNames && !symbolInfo.name.empty() && symbolInfo.name.at(0) == '?')
|
if(context.collectUndecoratedNames && !symbolInfo.name.empty() && symbolInfo.name.at(0) == '?')
|
||||||
{
|
{
|
||||||
//TODO: undocumented hack to have some kind of performance while undecorating names
|
undecorateName(symbolInfo.name, symbolInfo.undecoratedName);
|
||||||
auto mymalloc = [](size_t size) { return emalloc(size, "convertSymbolInfo::undecoratedName"); };
|
|
||||||
auto myfree = [](void* ptr) { return efree(ptr, "convertSymbolInfo::undecoratedName"); };
|
|
||||||
symbolInfo.undecoratedName.resize(max(512, symbolInfo.name.length() * 2));
|
|
||||||
if(!__unDNameEx((char*)symbolInfo.undecoratedName.data(),
|
|
||||||
symbolInfo.name.c_str(),
|
|
||||||
symbolInfo.undecoratedName.size(),
|
|
||||||
mymalloc,
|
|
||||||
myfree,
|
|
||||||
nullptr,
|
|
||||||
UNDNAME_COMPLETE))
|
|
||||||
{
|
|
||||||
symbolInfo.undecoratedName.clear();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
symbolInfo.undecoratedName.resize(strlen(symbolInfo.undecoratedName.c_str()));
|
|
||||||
if(symbolInfo.name == symbolInfo.undecoratedName)
|
|
||||||
symbolInfo.undecoratedName = ""; //https://stackoverflow.com/a/18299315
|
|
||||||
/*auto test = getSymbolUndecoratedNameString(symbol); //TODO: this does not appear to work very well
|
|
||||||
if(!symbolInfo.undecoratedName.empty())
|
|
||||||
{
|
|
||||||
if(test != symbolInfo.undecoratedName)
|
|
||||||
{
|
|
||||||
GuiSymbolLogAdd(StringUtils::sprintf("undecoration mismatch, msvcrt: \"%s\", DIA: \"%s\"\n",
|
|
||||||
symbolInfo.undecoratedName.c_str(),
|
|
||||||
test.c_str()).c_str());
|
|
||||||
}
|
|
||||||
}*/
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
|
@ -0,0 +1,76 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
typedef char* pchar_t;
|
||||||
|
typedef const char* pcchar_t;
|
||||||
|
typedef char* (*GetParameter_t)(long n);
|
||||||
|
using Alloc_t = decltype(malloc);
|
||||||
|
using Free_t = decltype(free);
|
||||||
|
|
||||||
|
enum
|
||||||
|
{
|
||||||
|
X_UNDNAME_COMPLETE = 0x0, //Enables full undecoration.
|
||||||
|
X_UNDNAME_NO_LEADING_UNDERSCORES = 0x1, //Removes leading underscores from Microsoft extended keywords.
|
||||||
|
X_UNDNAME_NO_MS_KEYWORDS = 0x2, //Disables expansion of Microsoft extended keywords.
|
||||||
|
X_UNDNAME_NO_FUNCTION_RETURNS = 0x4, //Disables expansion of return type for primary declaration.
|
||||||
|
X_UNDNAME_NO_ALLOCATION_MODEL = 0x8, //Disables expansion of the declaration model.
|
||||||
|
X_UNDNAME_NO_ALLOCATION_LANGUAGE = 0x10, //Disables expansion of the declaration language specifier.
|
||||||
|
X_UNDNAME_NO_MS_THISTYPE = 0x20, //NYI Disable expansion of MS keywords on the 'this' type for primary declaration.
|
||||||
|
X_UNDNAME_NO_CV_THISTYPE = 0x40, //NYI Disable expansion of CV modifiers on the 'this' type for primary declaration/
|
||||||
|
X_UNDNAME_NO_THISTYPE = 0x60, //Disables all modifiers on the this type.
|
||||||
|
X_UNDNAME_NO_ACCESS_SPECIFIERS = 0x80, //Disables expansion of access specifiers for members.
|
||||||
|
X_UNDNAME_NO_THROW_SIGNATURES = 0x100, //Disables expansion of "throw-signatures" for functions and pointers to functions.
|
||||||
|
X_UNDNAME_NO_MEMBER_TYPE = 0x200, //Disables expansion of static or virtual members.
|
||||||
|
X_UNDNAME_NO_RETURN_UDT_MODEL = 0x400, //Disables expansion of the Microsoft model for UDT returns.
|
||||||
|
X_UNDNAME_32_BIT_DECODE = 0x800, //Undecorates 32-bit decorated names.
|
||||||
|
X_UNDNAME_NAME_ONLY = 0x1000, //Gets only the name for primary declaration; returns just [scope::]name. Expands template params.
|
||||||
|
X_UNDNAME_TYPE_ONLY = 0x2000, //Input is just a type encoding; composes an abstract declarator.
|
||||||
|
X_UNDNAME_HAVE_PARAMETERS = 0x4000, //The real template parameters are available.
|
||||||
|
X_UNDNAME_NO_ECSU = 0x8000, //Suppresses enum/class/struct/union.
|
||||||
|
X_UNDNAME_NO_IDENT_CHAR_CHECK = 0x10000, //Suppresses check for valid identifier characters.
|
||||||
|
X_UNDNAME_NO_PTR64 = 0x20000, //Does not include ptr64 in output.
|
||||||
|
};
|
||||||
|
|
||||||
|
#if _MSC_VER != 1800
|
||||||
|
#error unDNameEx is undocumented and possibly unsupported on your runtime! Uncomment this line if you understand the risks and want continue regardless...
|
||||||
|
#endif //_MSC_VER
|
||||||
|
|
||||||
|
//undname.cxx
|
||||||
|
extern "C" pchar_t __cdecl __unDNameEx(_Out_opt_z_cap_(maxStringLength) pchar_t outputString,
|
||||||
|
pcchar_t name,
|
||||||
|
int maxStringLength, // Note, COMMA is leading following optional arguments
|
||||||
|
Alloc_t pAlloc,
|
||||||
|
Free_t pFree,
|
||||||
|
GetParameter_t pGetParameter,
|
||||||
|
unsigned long disableFlags
|
||||||
|
);
|
||||||
|
|
||||||
|
template<size_t MaxSize = 512>
|
||||||
|
inline bool undecorateName(const std::string & decoratedName, std::string & undecoratedName)
|
||||||
|
{
|
||||||
|
//TODO: undocumented hack to have some kind of performance while undecorating names
|
||||||
|
auto mymalloc = [](size_t size) { return emalloc(size, "symbolundecorator::undecoratedName"); };
|
||||||
|
auto myfree = [](void* ptr) { return efree(ptr, "symbolundecorator::undecoratedName"); };
|
||||||
|
|
||||||
|
undecoratedName.resize(max(MaxSize, decoratedName.length() * 2));
|
||||||
|
if(!__unDNameEx((char*)undecoratedName.data(),
|
||||||
|
decoratedName.c_str(),
|
||||||
|
(int)undecoratedName.size(),
|
||||||
|
mymalloc,
|
||||||
|
myfree,
|
||||||
|
nullptr,
|
||||||
|
X_UNDNAME_COMPLETE))
|
||||||
|
{
|
||||||
|
undecoratedName.clear();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
undecoratedName.resize(strlen(undecoratedName.c_str()));
|
||||||
|
if(decoratedName == undecoratedName)
|
||||||
|
undecoratedName = ""; //https://stackoverflow.com/a/18299315
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
|
@ -238,6 +238,7 @@
|
||||||
<ClInclude Include="sortedlru.h" />
|
<ClInclude Include="sortedlru.h" />
|
||||||
<ClInclude Include="symbolsourcebase.h" />
|
<ClInclude Include="symbolsourcebase.h" />
|
||||||
<ClInclude Include="symbolsourcedia.h" />
|
<ClInclude Include="symbolsourcedia.h" />
|
||||||
|
<ClInclude Include="symbolundecorator.h" />
|
||||||
<ClInclude Include="symcache.h" />
|
<ClInclude Include="symcache.h" />
|
||||||
<ClInclude Include="taskthread.h" />
|
<ClInclude Include="taskthread.h" />
|
||||||
<ClInclude Include="tcpconnections.h" />
|
<ClInclude Include="tcpconnections.h" />
|
||||||
|
|
|
@ -997,5 +997,8 @@
|
||||||
<ClInclude Include="WinInet-Downloader\downslib.h">
|
<ClInclude Include="WinInet-Downloader\downslib.h">
|
||||||
<Filter>Header Files\Third Party\WinInet-Downloader</Filter>
|
<Filter>Header Files\Third Party\WinInet-Downloader</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
|
<ClInclude Include="symbolundecorator.h">
|
||||||
|
<Filter>Header Files\Symbols</Filter>
|
||||||
|
</ClInclude>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
</Project>
|
</Project>
|
Loading…
Reference in New Issue