Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fixed RETDEC-74 and RETDEC-61 #1003

Merged
merged 8 commits into from
Aug 24, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
62 changes: 24 additions & 38 deletions include/retdec/fileformat/file_format/pe/pe_format_parser.h
Original file line number Diff line number Diff line change
Expand Up @@ -185,7 +185,7 @@ class PeFormatParser

std::uint32_t getNumberOfImportedLibraries() const
{
return peFile->impDir().getNumberOfFiles(PeLib::OLDDIR);
return peFile->impDir().getNumberOfFiles(false);
}

std::uint32_t getNumberOfDelayImportedLibraries() const
Expand Down Expand Up @@ -309,10 +309,10 @@ class PeFormatParser
{
const auto & imports = peFile->impDir();

if(index >= imports.getNumberOfFiles(PeLib::OLDDIR))
if(index >= imports.getNumberOfFiles(false))
return false;

fileName = imports.getFileName(index, PeLib::OLDDIR);
fileName = imports.getFileName(index, false);
return true;
}

Expand All @@ -327,51 +327,37 @@ class PeFormatParser
return true;
}

std::unique_ptr<PeImport> getImport(unsigned long long fileIndex, unsigned long long importIndex) const
std::unique_ptr<PeImport> getImport(std::size_t fileIndex, std::size_t importIndex) const
{
const PeLib::ImportDirectory & peImports = peFile->impDir();
const auto ordinalMask = peFile->imageLoader().getOrdinalMask();
const auto imageBase = peFile->imageLoader().getImageBase();
const auto bits = peFile->imageLoader().getImageBitability();
std::string importName;
std::uint32_t ordinalNumber = 0;
std::uint32_t patchRva = 0;
std::uint16_t importHint = 0;
bool isImportByOrdinal = false;

if(fileIndex >= peImports.getNumberOfFiles(PeLib::OLDDIR) ||
importIndex >= peImports.getNumberOfFunctions(fileIndex, PeLib::OLDDIR))
if(peImports.getImportedFunction(fileIndex, importIndex, importName, importHint, ordinalNumber, patchRva, isImportByOrdinal, false))
{
return nullptr;
}
auto import = std::make_unique<PeImport>(PeImportFlag::None);

auto isOrdinalNumberValid = true;
unsigned long long ordinalNumber = peImports.getFunctionHint(fileIndex, importIndex, PeLib::OLDDIR);
if(!ordinalNumber)
{
const auto firstThunk = peImports.getFirstThunk(fileIndex, importIndex, PeLib::OLDDIR);
const auto originalFirstThunk = peImports.getOriginalFirstThunk(fileIndex, importIndex, PeLib::OLDDIR);
if(firstThunk & ordinalMask)
{
ordinalNumber = firstThunk - ordinalMask;
}
else if(originalFirstThunk & ordinalMask)
{
ordinalNumber = originalFirstThunk - ordinalMask;
}
else
if(isImportByOrdinal)
{
isOrdinalNumberValid = false;
import->setOrdinalNumber(ordinalNumber);
}
}

auto import = std::make_unique<PeImport>(PeImportFlag::None);
if(isOrdinalNumberValid)
{
import->setOrdinalNumber(ordinalNumber);
}
else
{
import->invalidateOrdinalNumber();
// Note: Even when the function is imported by ordinal, there can be name
// Example: WS2_32.dll!@115 -> WSAStartup
import->setName(importName);

import->setLibraryIndex(fileIndex);
import->setAddress(imageBase + patchRva);
return import;
}
import->setName(peImports.getFunctionName(fileIndex, importIndex, PeLib::OLDDIR));
import->setAddress(peFile->imageLoader().getImageBase() + peImports.getFirstThunk(fileIndex, PeLib::OLDDIR) + importIndex * (bits / 8));
import->setLibraryIndex(fileIndex);
return import;

// Out of range
return nullptr;
}

std::unique_ptr<PeImport> getDelayImport(unsigned long long fileIndex, unsigned long long importIndex) const
Expand Down
814 changes: 328 additions & 486 deletions include/retdec/pelib/ImportDirectory.h

Large diffs are not rendered by default.

17 changes: 10 additions & 7 deletions include/retdec/pelib/PeLibAux.h
Original file line number Diff line number Diff line change
Expand Up @@ -1061,13 +1061,16 @@ namespace PeLib
{
/// The IMAGE_THUNK_DATA struct of an imported function.
PELIB_IMAGE_THUNK_DATA itd;
/// The hint of an imported function.
std::uint16_t hint;
/// The function name of an imported function.
std::string fname;
/// The RVA of the patched address (from the FirstThunk)
std::uint32_t patchRva;
/// The hint of an imported function (only if imported by name)
std::uint16_t hint;

PELIB_THUNK_DATA()
{
patchRva = 0;
hint = 0;
}

Expand Down Expand Up @@ -1108,16 +1111,16 @@ namespace PeLib
PELIB_IMAGE_IMPORT_DESCRIPTOR impdesc;
/// The name of an imported DLL.
std::string name;
/// All original first thunk values of an imported DLL.
std::vector<PELIB_THUNK_DATA> originalfirstthunk;
/// All first thunk value of an imported DLL.
std::vector<PELIB_THUNK_DATA> firstthunk;
/// The list of functions imported from the DLL
//std::vector<PELIB_THUNK_DATA> originalfirstthunk;
//std::vector<PELIB_THUNK_DATA> firstthunk;
std::vector<PELIB_THUNK_DATA> thunk_data;

inline std::uint32_t calculateSize(std::uint32_t pointerSize) const
{
std::uint32_t totalSize = sizeof(PELIB_IMAGE_IMPORT_DESCRIPTOR) + name.size() + 1; // descriptor + dllname

for(const auto & element : originalfirstthunk)
for(const auto & element : thunk_data)
totalSize += element.calculateSize(pointerSize);
return totalSize + pointerSize; // Add zero-termination
}
Expand Down
18 changes: 18 additions & 0 deletions include/retdec/utils/ord_lookup.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
/**
* @file include/retdec/utils/ord_lookup.h
* @brief Converts well-known ordinals to function names
* @copyright (c) 2017 Avast Software, licensed under the MIT license
*/

#ifndef RETDEC_UTILS_ORD_LOOKUP_H
#define RETDEC_UTILS_ORD_LOOKUP_H

namespace retdec {
namespace utils {

std::string ordLookUp(const std::string& libName, const std::size_t& ordNum, bool forceNameFromOrdinal);

} // namespace utils
} // namespace retdec

#endif
Loading