Skip to content

Commit

Permalink
Added the ability to find IAT start addres and size.
Browse files Browse the repository at this point in the history
  • Loading branch information
BeneficialCode committed Jan 31, 2025
1 parent cc34499 commit 077ef7a
Show file tree
Hide file tree
Showing 9 changed files with 231 additions and 100 deletions.
154 changes: 108 additions & 46 deletions PEParser/PEParser.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ PEParser::PEParser(const wchar_t* path) :_path(path) {
PEParser::PEParser(void* base) {
_address = reinterpret_cast<PUCHAR>(base);
_moduleBase = (DWORD_PTR)base;
_isFileMap = false;
CheckValidity();
}

Expand Down Expand Up @@ -151,60 +152,121 @@ std::vector<ExportedSymbol> PEParser::GetExports() const {
if (dir == nullptr || dir->Size == 0)
return exports;

auto data = static_cast<IMAGE_EXPORT_DIRECTORY*>(GetAddress(dir->VirtualAddress));
auto count = data->NumberOfFunctions;
exports.reserve(count);
if (_isFileMap) {
auto data = static_cast<IMAGE_EXPORT_DIRECTORY*>(GetAddress(dir->VirtualAddress));
auto count = data->NumberOfFunctions;
exports.reserve(count);

auto names = (PBYTE)(data->AddressOfNames != 0 ? GetAddress(data->AddressOfNames) : nullptr);
auto ordinals = (PBYTE)(data->AddressOfNameOrdinals != 0 ? GetAddress(data->AddressOfNameOrdinals) : nullptr);
auto functions = (PDWORD)GetAddress(data->AddressOfFunctions);
char undecorated[1 << 10];
auto ordinalBase = data->Base;

std::unordered_map<uint32_t, std::string> functionNamesMap;
std::unordered_map<uint32_t, uint32_t> hintsMap;
for (uint32_t idx = 0; idx < data->NumberOfNames; idx++) {
uint16_t ordinal;
ordinal = *(USHORT*)(ordinals + idx * 2) + (USHORT)ordinalBase;
uint32_t name;
auto offset = *(ULONG*)(names + idx * 4);
PCSTR pName = (PCSTR)GetAddress(offset);
functionNamesMap[ordinal] = pName;
hintsMap[ordinal] = idx;
}

auto names = (PBYTE)(data->AddressOfNames != 0 ? GetAddress(data->AddressOfNames) : nullptr);
auto ordinals = (PBYTE)(data->AddressOfNameOrdinals != 0 ? GetAddress(data->AddressOfNameOrdinals) : nullptr);
auto functions = (PDWORD)GetAddress(data->AddressOfFunctions);
char undecorated[1 << 10];
auto ordinalBase = data->Base;
for (DWORD i = 0; i < data->NumberOfFunctions; i++) {
ExportedSymbol symbol;
int ordinal = i + (USHORT)ordinalBase;
symbol.Ordinal = ordinal;

std::unordered_map<uint32_t, std::string> functionNamesMap;
std::unordered_map<uint32_t, uint32_t> hintsMap;
for (uint32_t idx = 0; idx < data->NumberOfNames; idx++) {
uint16_t ordinal;
ordinal = *(USHORT*)(ordinals + idx * 2) + (USHORT)ordinalBase;
uint32_t name;
auto offset = *(ULONG*)(names + idx * 4);
functionNamesMap[ordinal] = (PCSTR)GetAddress(offset);
hintsMap[ordinal] = idx;
}

for (DWORD i = 0; i < data->NumberOfFunctions; i++) {
ExportedSymbol symbol;
int ordinal = i + (USHORT)ordinalBase;
symbol.Ordinal = ordinal;

std::unordered_map<uint32_t,uint32_t>::iterator iter = hintsMap.find(ordinal);
if (iter != hintsMap.end()) {
symbol.Hint = iter->second;
}
std::unordered_map<uint32_t, uint32_t>::iterator iter = hintsMap.find(ordinal);
if (iter != hintsMap.end()) {
symbol.Hint = iter->second;
}

bool hasName = false;
auto pos = functionNamesMap.find(ordinal);
if (pos != functionNamesMap.end()) {
hasName = true;
bool hasName = false;
auto pos = functionNamesMap.find(ordinal);
if (pos != functionNamesMap.end()) {
hasName = true;
}
if (names && hasName) {
symbol.Name = pos->second;
if (::UnDecorateSymbolName(symbol.Name.c_str(), undecorated, sizeof(undecorated), 0))
symbol.UndecoratedName = undecorated;
}
DWORD address = *(functions + symbol.Ordinal - ordinalBase);
symbol.Address = address;
symbol.IsForward = false;
symbol.HasName = false;
if (hasName) {
symbol.HasName = true;
if (address > dir->VirtualAddress && address < dir->VirtualAddress + dir->Size) {
symbol.ForwardName = (PCSTR)GetAddress(address);
symbol.IsForward = true;
}
}
exports.push_back(std::move(symbol));
}
if (names && hasName) {
symbol.Name = pos->second;
if (::UnDecorateSymbolName(symbol.Name.c_str(), undecorated, sizeof(undecorated), 0))
symbol.UndecoratedName = undecorated;
}
else {
auto data = (IMAGE_EXPORT_DIRECTORY*)(_address + dir->VirtualAddress);
auto count = data->NumberOfFunctions;
exports.reserve(count);

auto names = (PBYTE)(data->AddressOfNames != 0 ? _address + data->AddressOfNames: nullptr);
auto ordinals = (PBYTE)(data->AddressOfNameOrdinals != 0 ? _address + data->AddressOfNameOrdinals : nullptr);
auto functions = (PDWORD)(_address + data->AddressOfFunctions);
char undecorated[1 << 10];
auto ordinalBase = data->Base;

std::unordered_map<uint32_t, std::string> functionNamesMap;
std::unordered_map<uint32_t, uint32_t> hintsMap;
for (uint32_t idx = 0; idx < data->NumberOfNames; idx++) {
uint16_t ordinal;
ordinal = *(USHORT*)(ordinals + idx * 2) + (USHORT)ordinalBase;
uint32_t name;
auto offset = *(ULONG*)(names + idx * 4);
PCSTR pName = (PCSTR)_address + offset;
functionNamesMap[ordinal] = pName;
hintsMap[ordinal] = idx;
}
DWORD address = *(functions + symbol.Ordinal - ordinalBase);
symbol.Address = address;
symbol.IsForward = false;
symbol.HasName = false;
if (hasName) {
symbol.HasName = true;
if (address > dir->VirtualAddress && address < dir->VirtualAddress + dir->Size) {
symbol.ForwardName = (PCSTR)GetAddress(address);
symbol.IsForward = true;

for (DWORD i = 0; i < data->NumberOfFunctions; i++) {
ExportedSymbol symbol;
int ordinal = i + (USHORT)ordinalBase;
symbol.Ordinal = ordinal;

std::unordered_map<uint32_t, uint32_t>::iterator iter = hintsMap.find(ordinal);
if (iter != hintsMap.end()) {
symbol.Hint = iter->second;
}

bool hasName = false;
auto pos = functionNamesMap.find(ordinal);
if (pos != functionNamesMap.end()) {
hasName = true;
}
if (names && hasName) {
symbol.Name = pos->second;
if (::UnDecorateSymbolName(symbol.Name.c_str(), undecorated, sizeof(undecorated), 0))
symbol.UndecoratedName = undecorated;
}
DWORD address = *(functions + symbol.Ordinal - ordinalBase);
symbol.Address = address;
symbol.IsForward = false;
symbol.HasName = false;
if (hasName) {
symbol.HasName = true;
if (address > dir->VirtualAddress && address < dir->VirtualAddress + dir->Size) {
symbol.ForwardName = (PCSTR)_address + address;
symbol.IsForward = true;
}
}
exports.push_back(std::move(symbol));
}
exports.push_back(std::move(symbol));
}


return exports;
}
Expand Down
1 change: 1 addition & 0 deletions PEParser/PEParser.h
Original file line number Diff line number Diff line change
Expand Up @@ -293,4 +293,5 @@ class PEParser {
//mutable std::unique_ptr<CLRMetaParser> _clrParser;
bool _valid = false;
bool _importLib = false, _objectFile = false;
bool _isFileMap = true;
};
16 changes: 8 additions & 8 deletions WinArk/ApiReader.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -45,9 +45,9 @@ void ApiReader::ParseExportTable(ModuleInfo* pModule,bool isMapping,bool ownProc
if (!symbol.IsForward) {
if (symbol.HasName)
AddApi(symbol.Name.c_str(), symbol.Hint, symbol.Ordinal,
symbol.Address, symbol.Address + pModule->_modBaseAddr, false, pModule);
symbol.Address + pModule->_modBaseAddr, symbol.Address, false, pModule);
else {
AddApiWithoutName(symbol.Ordinal, symbol.Address, symbol.Address + pModule->_modBaseAddr, false, pModule);
AddApiWithoutName(symbol.Ordinal, symbol.Address + pModule->_modBaseAddr, symbol.Address, false, pModule);
}
}
else {
Expand All @@ -70,9 +70,9 @@ void ApiReader::ParseExportTable(ModuleInfo* pModule,bool isMapping,bool ownProc
if (!symbol.IsForward) {
if (symbol.HasName)
AddApi(symbol.Name.c_str(), symbol.Hint, symbol.Ordinal,
symbol.Address, symbol.Address + pModule->_modBaseAddr, false, pModule);
symbol.Address + pModule->_modBaseAddr, symbol.Address, false, pModule);
else {
AddApiWithoutName(symbol.Ordinal, symbol.Address, symbol.Address + pModule->_modBaseAddr, false, pModule);
AddApiWithoutName(symbol.Ordinal, symbol.Address + pModule->_modBaseAddr, symbol.Address, false, pModule);
}
}
else {
Expand All @@ -90,9 +90,9 @@ void ApiReader::ParseExportTable(ModuleInfo* pModule,bool isMapping,bool ownProc
if (!symbol.IsForward) {
if (symbol.HasName)
AddApi(symbol.Name.c_str(), symbol.Hint, symbol.Ordinal,
symbol.Address, symbol.Address + pModule->_modBaseAddr, false, pModule);
symbol.Address + pModule->_modBaseAddr, symbol.Address, false, pModule);
else {
AddApiWithoutName(symbol.Ordinal, symbol.Address, symbol.Address + pModule->_modBaseAddr, false, pModule);
AddApiWithoutName(symbol.Ordinal, symbol.Address + pModule->_modBaseAddr, symbol.Address, false, pModule);
}
}
else {
Expand Down Expand Up @@ -675,9 +675,9 @@ bool ApiReader::IsInvalidMemoryForIAT(DWORD_PTR address)
}

if(mbi.State == MEM_COMMIT && IsPageAccessable(mbi.Protect))
return true;
return false;

return false;
return true;
}

void ApiReader::ParseIAT(DWORD_PTR iat, BYTE* pIAT, SIZE_T size) {
Expand Down
2 changes: 1 addition & 1 deletion WinArk/HexEdit.h
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ class CHexEdit : public CWindowImpl<CHexEdit, CEdit>

ULONG_PTR _StringToNum(const TCHAR str[_strSize]) const {
ULONG_PTR cNum;
ULONG_PTR num;
ULONG_PTR num = 0;

for (int i = 0; str[i]; i++) {
cNum = _CharToNum(str[i]);
Expand Down
Loading

0 comments on commit 077ef7a

Please sign in to comment.