diff --git a/PEParser/PEParser.cpp b/PEParser/PEParser.cpp index 7f3b916..2a9cd4a 100644 --- a/PEParser/PEParser.cpp +++ b/PEParser/PEParser.cpp @@ -31,6 +31,7 @@ PEParser::PEParser(const wchar_t* path) :_path(path) { PEParser::PEParser(void* base) { _address = reinterpret_cast(base); _moduleBase = (DWORD_PTR)base; + _isFileMap = false; CheckValidity(); } @@ -151,60 +152,121 @@ std::vector PEParser::GetExports() const { if (dir == nullptr || dir->Size == 0) return exports; - auto data = static_cast(GetAddress(dir->VirtualAddress)); - auto count = data->NumberOfFunctions; - exports.reserve(count); + if (_isFileMap) { + auto data = static_cast(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 functionNamesMap; + std::unordered_map 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 functionNamesMap; - std::unordered_map 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::iterator iter = hintsMap.find(ordinal); - if (iter != hintsMap.end()) { - symbol.Hint = iter->second; - } + std::unordered_map::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 functionNamesMap; + std::unordered_map 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::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; } diff --git a/PEParser/PEParser.h b/PEParser/PEParser.h index cc432e9..107503c 100644 --- a/PEParser/PEParser.h +++ b/PEParser/PEParser.h @@ -293,4 +293,5 @@ class PEParser { //mutable std::unique_ptr _clrParser; bool _valid = false; bool _importLib = false, _objectFile = false; + bool _isFileMap = true; }; \ No newline at end of file diff --git a/WinArk/ApiReader.cpp b/WinArk/ApiReader.cpp index 86559ca..3b8479d 100644 --- a/WinArk/ApiReader.cpp +++ b/WinArk/ApiReader.cpp @@ -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 { @@ -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 { @@ -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 { @@ -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) { diff --git a/WinArk/HexEdit.h b/WinArk/HexEdit.h index 227dd17..fc07b50 100644 --- a/WinArk/HexEdit.h +++ b/WinArk/HexEdit.h @@ -69,7 +69,7 @@ class CHexEdit : public CWindowImpl 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]); diff --git a/WinArk/IATSearcher.cpp b/WinArk/IATSearcher.cpp index 2ff9cc7..480a973 100644 --- a/WinArk/IATSearcher.cpp +++ b/WinArk/IATSearcher.cpp @@ -7,7 +7,7 @@ bool IATSearcher::SearchImportAddressTableInProcess(DWORD_PTR startAddress, DWOR *pSize = 0; if (advance) { - FindIATAdvanced(startAddress, pIAT, pSize); + return FindIATAdvanced(startAddress, pIAT, pSize); } addressInIAT = FindAPIAddressInIAT(startAddress); @@ -66,7 +66,7 @@ bool IATSearcher::FindIATAdvanced(DWORD_PTR startAddress, DWORD_PTR* pIAT, DWORD DWORD_PTR start = *iter; *pIAT = start; iter = iatPointers.end(); - DWORD_PTR end = *iter; + DWORD_PTR end = *(--iter); *pSize = (DWORD)(end - start + sizeof(DWORD_PTR)); if (*pSize > (2000000 * sizeof(DWORD_PTR))) { @@ -104,6 +104,8 @@ DWORD_PTR IATSearcher::FindAPIAddressInIAT(DWORD_PTR startAddress) { } } } + + startAddress = FindNextFunctionAddress(); } while (startAddress != 0 && count != 8); @@ -146,7 +148,8 @@ DWORD_PTR IATSearcher::FindIATPointer() { } } else { - return INSTRUCTION_GET_RIP_TARGET(&_insts[i]); + if(_insts[i].flags & FLAG_RIP_RELATIVE) + return INSTRUCTION_GET_RIP_TARGET(&_insts[i]); } } } @@ -163,7 +166,7 @@ bool IATSearcher::IsIATPointerValid(DWORD_PTR iatPointer, bool checkRedirects) { return false; } - if (!IsApiAddressValid(apiAddress)) { + if (IsApiAddressValid(apiAddress)) { return true; } else { @@ -218,8 +221,12 @@ DWORD_PTR IATSearcher::FindIATStartAddress(DWORD_PTR baseAddress, DWORD_PTR star if ((DWORD_PTR)(pIATAddress - 1) >= (DWORD_PTR)pData) { if (IsInvalidMemoryForIAT(*(pIATAddress - 1))) { if ((DWORD_PTR)(pIATAddress - 2) >= (DWORD_PTR)pData) { - if (!IsApiAddressValid(*(pIATAddress - 2))) { - return (((DWORD_PTR)pIATAddress - (DWORD_PTR)pData) + baseAddress); + DWORD_PTR* pIATStart = pIATAddress - 2; + DWORD_PTR apiAddress = *pIATStart; + if (IsApiAddressValid(apiAddress)) { + if (!IsApiAddressValid(*(pIATStart - 1))) { + return (((DWORD_PTR)pIATStart - (DWORD_PTR)pData) + baseAddress); + } } } } @@ -240,7 +247,8 @@ DWORD IATSearcher::FindIATSize(DWORD_PTR baseAddress, DWORD_PTR iatAddress, BYTE while ((DWORD_PTR)pIATAddress < ((DWORD_PTR)pData + dataSize - 1)) { if (IsInvalidMemoryForIAT(*pIATAddress)) { if (IsInvalidMemoryForIAT(*(pIATAddress + 1))) { - if (!IsApiAddressValid(*(pIATAddress + 2))) { + DWORD_PTR apiAddress = *(pIATAddress + 2); + if (!IsApiAddressValid(apiAddress) && apiAddress != 0) { return (DWORD)((DWORD_PTR)pIATAddress - (DWORD_PTR)pData - (iatAddress - baseAddress)); } } @@ -254,16 +262,20 @@ DWORD IATSearcher::FindIATSize(DWORD_PTR baseAddress, DWORD_PTR iatAddress, BYTE void IATSearcher::FindIATPointers(std::set& iatPointers) { for (unsigned int i = 0; i < _instCount; i++) { if (_insts[i].flags != FLAG_NOT_DECODABLE) { - if (_insts[i].size >= 5) { - BOOL isWow64 = FALSE; - ::IsWow64Process(_hProcess, &isWow64); - if (isWow64) { - if (_insts[i].ops[0].type == O_DISP) { - iatPointers.insert((DWORD_PTR)_insts[i].disp); + uint16_t fc = META_GET_FC(_insts[i].meta); + if (fc == FC_CALL || fc == FC_UNC_BRANCH) { + if (_insts[i].size >= 5) { + BOOL isWow64 = FALSE; + ::IsWow64Process(_hProcess, &isWow64); + if (isWow64) { + if (_insts[i].ops[0].type == O_DISP) { + iatPointers.insert((DWORD_PTR)_insts[i].disp); + } + } + else { + if (_insts[i].flags & FLAG_RIP_RELATIVE) + iatPointers.insert(INSTRUCTION_GET_RIP_TARGET(&_insts[i])); } - } - else { - iatPointers.insert(INSTRUCTION_GET_RIP_TARGET(&_insts[i])); } } } @@ -279,7 +291,8 @@ void IATSearcher::FindExecutableMemoryPagesByStartAddress(DWORD_PTR startAddress *pBaseAddress = 0; SIZE_T len = sizeof(MEMORY_BASIC_INFORMATION); - if (VirtualQueryEx(_hProcess, (LPCVOID)startAddress, &mbi, len) != len) { + SIZE_T size = VirtualQueryEx(_hProcess, (LPCVOID)startAddress, &mbi, len); + if (size != len) { return; } @@ -288,8 +301,8 @@ void IATSearcher::FindExecutableMemoryPagesByStartAddress(DWORD_PTR startAddress *pMemorySize = mbi.RegionSize; *pBaseAddress = (DWORD_PTR)mbi.BaseAddress; tempAddress = (DWORD_PTR)mbi.BaseAddress - 1; - - if (VirtualQueryEx(_hProcess, (LPCVOID)tempAddress, &mbi, len) != len) { + size = VirtualQueryEx(_hProcess, (LPCVOID)tempAddress, &mbi, len); + if (size != len) { break; } } while (IsPageExecutable(mbi.Protect)); @@ -349,20 +362,27 @@ void IATSearcher::FilterIATPointersList(std::set& iatPointers) { lastPointer = *iter; iter++; - if ((*iter - lastPointer) > 0x100) //check pointer difference, a typical difference is 4 on 32bit systems - { - bool isLastValid = IsIATPointerValid(lastPointer, false); - bool isCurrentValid = IsIATPointerValid(*iter, false); - if (isLastValid == false || isCurrentValid == false) + for (; iter != iatPointers.end(); iter++) { + if ((*iter - lastPointer) > 0x100) //check pointer difference, a typical difference is 4 on 32bit systems { - if (isLastValid == false) + bool isLastValid = IsIATPointerValid(lastPointer, false); + bool isCurrentValid = IsIATPointerValid(*iter, false); + if (isLastValid == false || isCurrentValid == false) { - iter--; - } + if (isLastValid == false) + { + iter--; + } - iatPointers.erase(iter); - erased = true; - break; + iatPointers.erase(iter); + erased = true; + break; + } + else + { + erased = false; + lastPointer = *iter; + } } else { @@ -370,11 +390,6 @@ void IATSearcher::FilterIATPointersList(std::set& iatPointers) { lastPointer = *iter; } } - else - { - erased = false; - lastPointer = *iter; - } } } diff --git a/WinArk/ProcessAccessHelper.cpp b/WinArk/ProcessAccessHelper.cpp index 1c25f9d..cd11c92 100644 --- a/WinArk/ProcessAccessHelper.cpp +++ b/WinArk/ProcessAccessHelper.cpp @@ -271,9 +271,9 @@ bool ProcessAccessHelper::IsPageExecutable(DWORD protect) { bool ProcessAccessHelper::IsPageAccessable(DWORD protect) { if (PAGE_NOACCESS == (protect & 0xff)) { - return true; + return false; } - return false; + return true; } LPVOID ProcessAccessHelper::CreateFileMappingViewRead(const WCHAR* filePath) { @@ -354,7 +354,7 @@ bool ProcessAccessHelper::GetProcessModules(HANDLE hProcess, std::vector 0) { + searchAddress = _oepAddress.GetValue(); + if (searchAddress) { + iatSearch.SearchImportAddressTableInProcess(searchAddress, &addressIATAdv, &sizeIATAdv, true); + + iatSearch.SearchImportAddressTableInProcess(searchAddress, &addressIAT, &sizeIAT, false); + + if (addressIAT != 0 && addressIATAdv == 0) { + SetDialogIATAddressAndSize(addressIAT, sizeIAT); + } + else if (addressIAT == 0 && addressIATAdv != 0) { + SetDialogIATAddressAndSize(addressIATAdv, sizeIAT); + } + else if (addressIAT != 0 && addressIATAdv != 0) { + if (addressIAT != addressIATAdv || sizeIAT != sizeIATAdv) { + int msgboxID = MessageBox(L"Result of advanced and normal search is different. Do you want to use the IAT Search Advanced result?", + L"Information", MB_YESNO | MB_ICONINFORMATION); + if (msgboxID == IDYES) { + SetDialogIATAddressAndSize(addressIATAdv, sizeIATAdv); + } + else { + SetDialogIATAddressAndSize(addressIAT, sizeIAT); + } + } + else { + SetDialogIATAddressAndSize(addressIAT, sizeIAT); + } + } + } + } +} + +void CScyllaDlg::SetDialogIATAddressAndSize(DWORD_PTR addressIAT, DWORD sizeIAT) { + _iatAddress.SetValue(addressIAT); + _iatSize.SetValue(sizeIAT); + + swprintf_s(_text, L"IAT found:\r\n\r\nStart: " PRINTF_DWORD_PTR_FULL L"\r\nSize: 0x%04X (%d) ", addressIAT, sizeIAT, sizeIAT); + MessageBox(_text, L"IAT found", MB_ICONINFORMATION); } \ No newline at end of file diff --git a/WinArk/ScyllaDlg.h b/WinArk/ScyllaDlg.h index cf92635..d325c4b 100644 --- a/WinArk/ScyllaDlg.h +++ b/WinArk/ScyllaDlg.h @@ -32,14 +32,10 @@ class CScyllaDlg MESSAGE_HANDLER(WM_INITDIALOG, OnInitDialog) COMMAND_ID_HANDLER(IDOK, OnCloseCmd) COMMAND_ID_HANDLER(IDCANCEL, OnCloseCmd) + COMMAND_ID_HANDLER_EX(IDC_BTN_AUTO_SEARCH,OnAutoSearch) END_MSG_MAP() - // Handler prototypes (uncomment arguments if needed): - // LRESULT MessageHandler(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/) - // LRESULT CommandHandler(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& /*bHandled*/) - // LRESULT NotifyHandler(int /*idCtrl*/, LPNMHDR /*pnmh*/, BOOL& /*bHandled*/) - LRESULT OnInitDialog(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/); LRESULT OnCloseCmd(WORD /*wNotifyCode*/, WORD wID, HWND /*hWndCtl*/, BOOL& /*bHandled*/); void OnSize(UINT nType, CSize size); @@ -52,6 +48,8 @@ class CScyllaDlg void ProcessHandler(); + void OnAutoSearch(UINT uNotifyCode, int nID, CWindow wndCtl); + protected: void SetupStatusBar(); void UpdateStatusBar(); @@ -63,7 +61,7 @@ class CScyllaDlg Module, }; - + void IATAutoSearchActionHandler(); WCHAR _text[512]; ImportsHandling _importsHandling; @@ -74,6 +72,9 @@ class CScyllaDlg CIcon _hIconWarning; CIcon _hIconCheck; +protected: + void SetDialogIATAddressAndSize(DWORD_PTR addressIAT, DWORD sizeIAT); + private: ProcessInfoEx& m_px; const WinSys::ProcessManager& m_pm;