Refactor ImageInterpreter
This commit is contained in:
parent
028c90b794
commit
c173b0ff50
@ -64,8 +64,8 @@ namespace nkg {
|
||||
NewImage._SectionNameTable[SectionName] = i;
|
||||
}
|
||||
|
||||
NewImage._SectionAddressTable[NewImage._SectionHeaderTable[i].VirtualAddress] = i;
|
||||
NewImage._SectionOffsetTable[NewImage._SectionHeaderTable[i].PointerToRawData] = i;
|
||||
NewImage._SectionRvaTable[NewImage._SectionHeaderTable[i].VirtualAddress] = i;
|
||||
NewImage._SectionFileOffsetTable[NewImage._SectionHeaderTable[i].PointerToRawData] = i;
|
||||
}
|
||||
|
||||
if (!DisableRelocationParsing && NewImage._NtHeaders->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress != 0) {
|
||||
@ -86,14 +86,14 @@ namespace nkg {
|
||||
case IMAGE_REL_BASED_HIGH:
|
||||
case IMAGE_REL_BASED_LOW:
|
||||
case IMAGE_REL_BASED_HIGHADJ:
|
||||
NewImage._RelocationAddressTable[Rva + (RelocItems[i] & 0x0fff)] = 2;
|
||||
NewImage._RelocationRvaTable[Rva + (RelocItems[i] & 0x0fff)] = 2;
|
||||
break;
|
||||
case IMAGE_REL_BASED_HIGHLOW:
|
||||
NewImage._RelocationAddressTable[Rva + (RelocItems[i] & 0x0fff)] = 4;
|
||||
NewImage._RelocationRvaTable[Rva + (RelocItems[i] & 0x0fff)] = 4;
|
||||
break;
|
||||
#if defined(IMAGE_REL_BASED_DIR64)
|
||||
case IMAGE_REL_BASED_DIR64:
|
||||
NewImage._RelocationAddressTable[Rva + (RelocItems[i] & 0x0fff)] = 8;
|
||||
NewImage._RelocationRvaTable[Rva + (RelocItems[i] & 0x0fff)] = 8;
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
@ -179,7 +179,16 @@ namespace nkg {
|
||||
}
|
||||
|
||||
[[nodiscard]]
|
||||
PIMAGE_SECTION_HEADER ImageInterpreter::ImageSectionHeader(PCSTR lpszSectionName) const {
|
||||
PIMAGE_SECTION_HEADER ImageInterpreter::ImageSectionHeader(size_t Idx) const {
|
||||
if (Idx < _NtHeaders->FileHeader.NumberOfSections) {
|
||||
return _SectionHeaderTable + Idx;
|
||||
} else {
|
||||
throw Exception(NKG_CURRENT_SOURCE_FILE(), NKG_CURRENT_SOURCE_LINE(), TEXT("Idx is out of range."));
|
||||
}
|
||||
}
|
||||
|
||||
[[nodiscard]]
|
||||
PIMAGE_SECTION_HEADER ImageInterpreter::ImageSectionHeaderByName(PCSTR lpszSectionName) const {
|
||||
uint64_t NameValue = 0;
|
||||
|
||||
for (int i = 0; i < sizeof(NameValue) && lpszSectionName[i]; ++i)
|
||||
@ -196,9 +205,9 @@ namespace nkg {
|
||||
}
|
||||
|
||||
[[nodiscard]]
|
||||
PIMAGE_SECTION_HEADER ImageInterpreter::ImageSectionHeader(uintptr_t Rva) const {
|
||||
auto it = _SectionAddressTable.upper_bound(Rva);
|
||||
if (it != _SectionAddressTable.begin()) {
|
||||
PIMAGE_SECTION_HEADER ImageInterpreter::ImageSectionHeaderByRva(uintptr_t Rva) const {
|
||||
auto it = _SectionRvaTable.upper_bound(Rva);
|
||||
if (it != _SectionRvaTable.begin()) {
|
||||
--it;
|
||||
}
|
||||
|
||||
@ -215,15 +224,14 @@ namespace nkg {
|
||||
}
|
||||
|
||||
[[nodiscard]]
|
||||
uintptr_t ImageInterpreter::RvaToFileOffset(uintptr_t Rva) const {
|
||||
auto SectionHeader = ImageSectionHeader(Rva);
|
||||
return SectionHeader->PointerToRawData + (Rva - static_cast<uintptr_t>(SectionHeader->VirtualAddress));
|
||||
PIMAGE_SECTION_HEADER ImageInterpreter::ImageSectionHeaderByVa(uintptr_t Va) const {
|
||||
return ImageSectionHeaderByRva(Va - _NtHeaders->OptionalHeader.ImageBase);
|
||||
}
|
||||
|
||||
[[nodiscard]]
|
||||
uintptr_t ImageInterpreter::FileOffsetToRva(uintptr_t FileOffset) const {
|
||||
auto it = _SectionOffsetTable.upper_bound(FileOffset);
|
||||
if (it != _SectionOffsetTable.begin()) {
|
||||
PIMAGE_SECTION_HEADER ImageInterpreter::ImageSectionHeaderByFileOffset(uintptr_t FileOffset) const {
|
||||
auto it = _SectionFileOffsetTable.upper_bound(FileOffset);
|
||||
if (it != _SectionFileOffsetTable.begin()) {
|
||||
--it;
|
||||
}
|
||||
|
||||
@ -232,23 +240,64 @@ namespace nkg {
|
||||
uintptr_t SectionFileOffsetEnd = SectionFileOffsetBegin + SectionHeader->SizeOfRawData;
|
||||
|
||||
if (SectionFileOffsetBegin <= FileOffset && FileOffset < SectionFileOffsetEnd) {
|
||||
return SectionHeader->VirtualAddress + (FileOffset - SectionHeader->PointerToRawData);
|
||||
return SectionHeader;
|
||||
} else {
|
||||
throw Exception(NKG_CURRENT_SOURCE_FILE(), NKG_CURRENT_SOURCE_LINE(), TEXT("Target section header is not found."))
|
||||
.AddHint(std::xstring::format(TEXT("FileOffset = 0x%zx"), FileOffset));
|
||||
}
|
||||
}
|
||||
|
||||
[[nodiscard]]
|
||||
uintptr_t ImageInterpreter::RvaToVa(uintptr_t Rva) const noexcept {
|
||||
return Rva + _NtHeaders->OptionalHeader.ImageBase;
|
||||
}
|
||||
|
||||
[[nodiscard]]
|
||||
uintptr_t ImageInterpreter::RvaToFileOffset(uintptr_t Rva) const {
|
||||
auto SectionHeader = ImageSectionHeaderByRva(Rva);
|
||||
return SectionHeader->PointerToRawData + (Rva - static_cast<uintptr_t>(SectionHeader->VirtualAddress));
|
||||
}
|
||||
|
||||
[[nodiscard]]
|
||||
uintptr_t ImageInterpreter::FileOffsetToRva(uintptr_t FileOffset) const {
|
||||
auto SectionHeader = ImageSectionHeaderByFileOffset(FileOffset);
|
||||
return SectionHeader->VirtualAddress + (FileOffset - SectionHeader->PointerToRawData);
|
||||
}
|
||||
|
||||
[[nodiscard]]
|
||||
uintptr_t ImageInterpreter::FileOffsetToVa(uintptr_t FileOffset) const {
|
||||
return FileOffsetToRva(FileOffset) + _NtHeaders->OptionalHeader.ImageBase;
|
||||
}
|
||||
|
||||
[[nodiscard]]
|
||||
uintptr_t ImageInterpreter::VaToRva(uintptr_t Va) const noexcept {
|
||||
return Va - _NtHeaders->OptionalHeader.ImageBase;
|
||||
}
|
||||
[[nodiscard]]
|
||||
uintptr_t ImageInterpreter::VaToFileOffset(uintptr_t Va) const {
|
||||
return ImageSectionHeaderByVa(Va)->PointerToRawData;
|
||||
}
|
||||
|
||||
[[nodiscard]]
|
||||
bool ImageInterpreter::IsRvaRangeInRelocTable(uintptr_t Rva, size_t Size) const {
|
||||
auto it = _RelocationAddressTable.upper_bound(Rva);
|
||||
if (it != _RelocationAddressTable.begin()) {
|
||||
auto it = _RelocationRvaTable.upper_bound(Rva);
|
||||
if (it != _RelocationRvaTable.begin()) {
|
||||
--it;
|
||||
}
|
||||
|
||||
return it->first <= Rva && Rva < it->first + it->second;
|
||||
}
|
||||
|
||||
[[nodiscard]]
|
||||
bool ImageInterpreter::IsVaRangeInRelocTable(uintptr_t Va, size_t Size) const {
|
||||
return IsRvaRangeInRelocTable(VaToRva(Va), Size);
|
||||
}
|
||||
|
||||
[[nodiscard]]
|
||||
bool ImageInterpreter::IsFileOffsetRangeInRelocTable(uintptr_t FileOffset, size_t Size) const {
|
||||
return IsRvaRangeInRelocTable(FileOffsetToRva(FileOffset), Size);
|
||||
}
|
||||
|
||||
DWORD ImageInterpreter::ImageFileMajorVersion() const {
|
||||
if (_VsFixedFileInfo) {
|
||||
return _VsFixedFileInfo->dwFileVersionMS;
|
||||
|
||||
@ -21,9 +21,9 @@ namespace nkg {
|
||||
PIMAGE_NT_HEADERS _NtHeaders;
|
||||
PIMAGE_SECTION_HEADER _SectionHeaderTable;
|
||||
std::map<uint64_t, size_t> _SectionNameTable;
|
||||
std::map<uintptr_t, size_t> _SectionAddressTable;
|
||||
std::map<uintptr_t, size_t> _SectionOffsetTable;
|
||||
std::map<uintptr_t, size_t> _RelocationAddressTable;
|
||||
std::map<uintptr_t, size_t> _SectionRvaTable;
|
||||
std::map<uintptr_t, size_t> _SectionFileOffsetTable;
|
||||
std::map<uintptr_t, size_t> _RelocationRvaTable;
|
||||
VS_FIXEDFILEINFO* _VsFixedFileInfo;
|
||||
|
||||
ImageInterpreter();
|
||||
@ -57,33 +57,48 @@ namespace nkg {
|
||||
PIMAGE_SECTION_HEADER ImageSectionTable() const noexcept;
|
||||
|
||||
[[nodiscard]]
|
||||
PIMAGE_SECTION_HEADER ImageSectionHeader(PCSTR lpszSectionName) const;
|
||||
PIMAGE_SECTION_HEADER ImageSectionHeader(size_t Idx) const;
|
||||
|
||||
[[nodiscard]]
|
||||
PIMAGE_SECTION_HEADER ImageSectionHeader(uintptr_t Rva) const;
|
||||
PIMAGE_SECTION_HEADER ImageSectionHeaderByName(PCSTR lpszSectionName) const;
|
||||
|
||||
[[nodiscard]]
|
||||
PIMAGE_SECTION_HEADER ImageSectionHeaderByRva(uintptr_t Rva) const;
|
||||
|
||||
[[nodiscard]]
|
||||
PIMAGE_SECTION_HEADER ImageSectionHeaderByVa(uintptr_t Va) const;
|
||||
|
||||
[[nodiscard]]
|
||||
PIMAGE_SECTION_HEADER ImageSectionHeaderByFileOffset(uintptr_t FileOffset) const;
|
||||
|
||||
template<typename __PtrType = PVOID>
|
||||
[[nodiscard]]
|
||||
__PtrType ImageSectionView(PCSTR lpszSectionName, size_t Offset = 0) const {
|
||||
return ImageOffset<__PtrType>(ImageSectionHeader(lpszSectionName)->PointerToRawData + Offset);
|
||||
}
|
||||
|
||||
template<typename __PtrType = PVOID>
|
||||
[[nodiscard]]
|
||||
__PtrType ImageSectionView(PIMAGE_SECTION_HEADER SectionHeader, size_t Offset = 0) const {
|
||||
__PtrType ImageSectionView(PIMAGE_SECTION_HEADER SectionHeader, size_t Offset = 0) const noexcept {
|
||||
return ImageOffset<__PtrType>(SectionHeader->PointerToRawData + Offset);
|
||||
}
|
||||
|
||||
template<typename __ReturnType, typename __Hint>
|
||||
template<typename __PtrType = PVOID>
|
||||
[[nodiscard]]
|
||||
__ReturnType SearchSection(PCSTR lpszSectionName, __Hint&& Hint) const {
|
||||
return SearchSection<__ReturnType>(ImageSectionHeader(lpszSectionName), std::forward<__Hint>(Hint));
|
||||
__PtrType ImageSectionViewByName(PCSTR lpszSectionName, size_t Offset = 0) const {
|
||||
return ImageOffset<__PtrType>(ImageSectionHeaderByName(lpszSectionName)->PointerToRawData + Offset);
|
||||
}
|
||||
|
||||
template<typename __ReturnType, typename __Hint>
|
||||
template<typename __PtrType = PVOID>
|
||||
[[nodiscard]]
|
||||
__ReturnType SearchSection(PCSTR lpszSectionName, size_t Offset, __Hint&& Hint) const {
|
||||
return SearchSection<__ReturnType>(ImageSectionHeader(lpszSectionName), Offset, std::forward<__Hint>(Hint));
|
||||
__PtrType ImageSectionViewByRva(uintptr_t Rva, size_t Offset = 0) const {
|
||||
return ImageOffset<__PtrType>(ImageSectionHeaderByRva(Rva)->PointerToRawData + Offset);
|
||||
}
|
||||
|
||||
template<typename __PtrType = PVOID>
|
||||
[[nodiscard]]
|
||||
__PtrType ImageSectionViewByVa(uintptr_t Va, size_t Offset = 0) const {
|
||||
return ImageOffset<__PtrType>(ImageSectionHeaderByVa(Va)->PointerToRawData + Offset);
|
||||
}
|
||||
|
||||
template<typename __PtrType = PVOID>
|
||||
[[nodiscard]]
|
||||
__PtrType ImageSectionViewByFileOffset(uintptr_t FileOffset, size_t Offset = 0) const {
|
||||
return ImageOffset<__PtrType>(ImageSectionHeaderByFileOffset(FileOffset)->PointerToRawData + Offset);
|
||||
}
|
||||
|
||||
template<typename __ReturnType, typename __Hint>
|
||||
@ -120,11 +135,23 @@ namespace nkg {
|
||||
throw Exception(NKG_CURRENT_SOURCE_FILE(), NKG_CURRENT_SOURCE_LINE(), TEXT("Data is not found."));
|
||||
}
|
||||
|
||||
template<typename __ReturnType, typename __Hint>
|
||||
[[nodiscard]]
|
||||
uintptr_t RvaToFileOffset(uintptr_t Rva) const;
|
||||
__ReturnType SearchSection(PCSTR lpszSectionName, __Hint&& Hint) const {
|
||||
return SearchSection<__ReturnType>(ImageSectionHeaderByName(lpszSectionName), std::forward<__Hint>(Hint));
|
||||
}
|
||||
|
||||
template<typename __ReturnType, typename __Hint>
|
||||
[[nodiscard]]
|
||||
__ReturnType SearchSection(PCSTR lpszSectionName, size_t Offset, __Hint&& Hint) const {
|
||||
return SearchSection<__ReturnType>(ImageSectionHeaderByName(lpszSectionName), Offset, std::forward<__Hint>(Hint));
|
||||
}
|
||||
|
||||
[[nodiscard]]
|
||||
uintptr_t FileOffsetToRva(uintptr_t FileOffset) const;
|
||||
uintptr_t RvaToVa(uintptr_t Rva) const noexcept;
|
||||
|
||||
[[nodiscard]]
|
||||
uintptr_t RvaToFileOffset(uintptr_t Rva) const;
|
||||
|
||||
template<typename __PtrType = PVOID>
|
||||
[[nodiscard]]
|
||||
@ -133,12 +160,11 @@ namespace nkg {
|
||||
return ImageOffset<__PtrType>(RvaToFileOffset(Rva));
|
||||
}
|
||||
|
||||
template<typename __PtrType>
|
||||
[[nodiscard]]
|
||||
uintptr_t PointerToRva(__PtrType Ptr) const {
|
||||
static_assert(std::is_pointer_v<__PtrType>);
|
||||
return FileOffsetToRva(reinterpret_cast<const volatile char*>(Ptr) - reinterpret_cast<const volatile char*>(_DosHeader));
|
||||
}
|
||||
uintptr_t FileOffsetToRva(uintptr_t FileOffset) const;
|
||||
|
||||
[[nodiscard]]
|
||||
uintptr_t FileOffsetToVa(uintptr_t FileOffset) const;
|
||||
|
||||
template<typename __PtrType>
|
||||
[[nodiscard]]
|
||||
@ -146,6 +172,18 @@ namespace nkg {
|
||||
return ImageOffset<__PtrType>(FileOffset);
|
||||
}
|
||||
|
||||
[[nodiscard]]
|
||||
uintptr_t VaToRva(uintptr_t Va) const noexcept;
|
||||
|
||||
[[nodiscard]]
|
||||
uintptr_t VaToFileOffset(uintptr_t Va) const;
|
||||
|
||||
template<typename __PtrType>
|
||||
[[nodiscard]]
|
||||
__PtrType VaToPointer(uintptr_t Va) const noexcept {
|
||||
return RvaToPointer<__PtrType>(VaToRva(Va));
|
||||
}
|
||||
|
||||
template<typename __PtrType>
|
||||
[[nodiscard]]
|
||||
uintptr_t PointerToFileOffset(__PtrType Ptr) const noexcept {
|
||||
@ -153,9 +191,33 @@ namespace nkg {
|
||||
return reinterpret_cast<const volatile char*>(Ptr) - reinterpret_cast<const volatile char*>(_DosHeader);
|
||||
}
|
||||
|
||||
template<typename __PtrType>
|
||||
[[nodiscard]]
|
||||
uintptr_t PointerToRva(__PtrType Ptr) const {
|
||||
return FileOffsetToRva(PointerToFileOffset(Ptr));
|
||||
}
|
||||
|
||||
template<typename __PtrType>
|
||||
[[nodiscard]]
|
||||
uintptr_t PointerToVa(__PtrType Ptr) const {
|
||||
return FileOffsetToVa(PointerToFileOffset(Ptr));
|
||||
}
|
||||
|
||||
[[nodiscard]]
|
||||
bool IsRvaRangeInRelocTable(uintptr_t Rva, size_t Size) const;
|
||||
|
||||
[[nodiscard]]
|
||||
bool IsVaRangeInRelocTable(uintptr_t Va, size_t Size) const;
|
||||
|
||||
[[nodiscard]]
|
||||
bool IsFileOffsetRangeInRelocTable(uintptr_t FileOffset, size_t Size) const;
|
||||
|
||||
template<typename __PtrType>
|
||||
[[nodiscard]]
|
||||
bool IsFileOffsetRangeInRelocTable(__PtrType Ptr, size_t Size) const {
|
||||
return IsRvaRangeInRelocTable(PointerToRva(Ptr), Size);
|
||||
}
|
||||
|
||||
[[nodiscard]]
|
||||
DWORD ImageFileMajorVersion() const;
|
||||
|
||||
|
||||
@ -55,8 +55,8 @@ namespace nkg {
|
||||
[[nodiscard]]
|
||||
bool PatchSolution1::FindPatchOffset() noexcept {
|
||||
try {
|
||||
PIMAGE_SECTION_HEADER SectionHeader_text = _Image.ImageSectionHeader(".text");
|
||||
PIMAGE_SECTION_HEADER SectionHeader_rdata = _Image.ImageSectionHeader(".rdata");
|
||||
PIMAGE_SECTION_HEADER SectionHeader_text = _Image.ImageSectionHeaderByName(".text");
|
||||
PIMAGE_SECTION_HEADER SectionHeader_rdata = _Image.ImageSectionHeaderByName(".rdata");
|
||||
const uint8_t* pbPatch[_countof(_PatchOffset)] = {};
|
||||
|
||||
pbPatch[0] = _Image.SearchSection<const uint8_t*>(SectionHeader_rdata, [](const uint8_t* p) {
|
||||
|
||||
@ -429,7 +429,7 @@ print('};')
|
||||
[[nodiscard]]
|
||||
bool PatchSolution2::FindPatchOffset() noexcept {
|
||||
try {
|
||||
auto SectionHeader_text = _Image.ImageSectionHeader(".text");
|
||||
auto SectionHeader_text = _Image.ImageSectionHeaderByName(".text");
|
||||
auto SectionView_text = _Image.ImageSectionView<const uint8_t*>(SectionHeader_text);
|
||||
const uint8_t* lpPatch[_countof(_PatchOffset)] = {};
|
||||
|
||||
|
||||
@ -437,7 +437,7 @@ print('};')
|
||||
bool PatchSolution2::FindPatchOffset() noexcept {
|
||||
|
||||
try {
|
||||
auto SectionHeader_text = _Image.ImageSectionHeader(".text");
|
||||
auto SectionHeader_text = _Image.ImageSectionHeaderByName(".text");
|
||||
auto SectionView_text = _Image.ImageSectionView<const uint8_t*>(SectionHeader_text);
|
||||
const uint8_t* lpPatch[_countof(_PatchOffset)] = {};
|
||||
|
||||
|
||||
@ -323,7 +323,7 @@ namespace nkg {
|
||||
}
|
||||
|
||||
size_t PublicKeyReadCursor = 0;
|
||||
auto SectionHeader_rdata = _Image.ImageSectionHeader(".rdata");
|
||||
auto SectionHeader_rdata = _Image.ImageSectionHeaderByName(".rdata");
|
||||
auto SectionView_rdata = _Image.ImageSectionView(SectionHeader_rdata);
|
||||
|
||||
for (size_t i = 0; i < _countof(_Patch); PublicKeyReadCursor += Keyword[i].Size, ++i) {
|
||||
|
||||
Loading…
Reference in New Issue
Block a user