ImageInterpreter.hpp 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173
  1. #pragma once
  2. #include <stddef.h>
  3. #include <stdint.h>
  4. #include <Exception.hpp>
  5. #include <windows.h>
  6. #include <map>
  7. #include <utility>
  8. #include <type_traits>
  9. #undef NKG_CURRENT_SOURCE_FILE
  10. #undef NKG_CURRENT_SOURCE_LINE
  11. #define NKG_CURRENT_SOURCE_FILE() TEXT(".\\navicat-patcher\\ImageInterpreter.hpp")
  12. #define NKG_CURRENT_SOURCE_LINE() __LINE__
  13. namespace nkg {
  14. class ImageInterpreter {
  15. private:
  16. PIMAGE_DOS_HEADER _DosHeader;
  17. PIMAGE_NT_HEADERS _NtHeaders;
  18. PIMAGE_SECTION_HEADER _SectionHeaderTable;
  19. std::map<uint64_t, size_t> _SectionNameTable;
  20. std::map<uintptr_t, size_t> _SectionAddressTable;
  21. std::map<uintptr_t, size_t> _SectionOffsetTable;
  22. std::map<uintptr_t, size_t> _RelocationAddressTable;
  23. VS_FIXEDFILEINFO* _VsFixedFileInfo;
  24. ImageInterpreter();
  25. public:
  26. [[nodiscard]]
  27. static ImageInterpreter ParseImage(PVOID PtrToImageBase, bool DisableRelocationParsing = false);
  28. template<typename __PtrType = PVOID>
  29. [[nodiscard]]
  30. __PtrType ImageBase() const noexcept {
  31. static_assert(std::is_pointer_v<__PtrType>);
  32. return reinterpret_cast<__PtrType>(_DosHeader);
  33. }
  34. template<typename __PtrType = PVOID>
  35. [[nodiscard]]
  36. __PtrType ImageOffset(size_t Offset) const noexcept {
  37. static_assert(std::is_pointer_v<__PtrType>);
  38. return reinterpret_cast<__PtrType>(reinterpret_cast<char*>(_DosHeader) + Offset);
  39. }
  40. [[nodiscard]]
  41. PIMAGE_DOS_HEADER ImageDosHeader() const noexcept;
  42. [[nodiscard]]
  43. PIMAGE_NT_HEADERS ImageNtHeaders() const noexcept;
  44. [[nodiscard]]
  45. PIMAGE_SECTION_HEADER ImageSectionTable() const noexcept;
  46. [[nodiscard]]
  47. PIMAGE_SECTION_HEADER ImageSectionHeader(PCSTR lpszSectionName) const;
  48. [[nodiscard]]
  49. PIMAGE_SECTION_HEADER ImageSectionHeader(uintptr_t Rva) const;
  50. template<typename __PtrType = PVOID>
  51. [[nodiscard]]
  52. __PtrType ImageSectionView(PCSTR lpszSectionName, size_t Offset = 0) const {
  53. return ImageOffset<__PtrType>(ImageSectionHeader(lpszSectionName)->PointerToRawData + Offset);
  54. }
  55. template<typename __PtrType = PVOID>
  56. [[nodiscard]]
  57. __PtrType ImageSectionView(PIMAGE_SECTION_HEADER SectionHeader, size_t Offset = 0) const {
  58. return ImageOffset<__PtrType>(SectionHeader->PointerToRawData + Offset);
  59. }
  60. template<typename __ReturnType, typename __Hint>
  61. [[nodiscard]]
  62. __ReturnType SearchSection(PCSTR lpszSectionName, __Hint&& Hint) const {
  63. return SearchSection<__ReturnType>(ImageSectionHeader(lpszSectionName), std::forward<__Hint>(Hint));
  64. }
  65. template<typename __ReturnType, typename __Hint>
  66. [[nodiscard]]
  67. __ReturnType SearchSection(PCSTR lpszSectionName, size_t Offset, __Hint&& Hint) const {
  68. return SearchSection<__ReturnType>(ImageSectionHeader(lpszSectionName), Offset, std::forward<__Hint>(Hint));
  69. }
  70. template<typename __ReturnType, typename __Hint>
  71. [[nodiscard]]
  72. __ReturnType SearchSection(PIMAGE_SECTION_HEADER SectionHeader, __Hint&& Hint) const {
  73. static_assert(std::is_pointer_v<__ReturnType>);
  74. auto begin = ImageSectionView<const uint8_t*>(SectionHeader);
  75. auto end = begin + SectionHeader->Misc.VirtualSize;
  76. for (; begin < end; ++begin) {
  77. if (Hint(begin) == true) {
  78. return reinterpret_cast<__ReturnType>(const_cast<uint8_t*>(begin));
  79. }
  80. }
  81. throw Exception(NKG_CURRENT_SOURCE_FILE(), NKG_CURRENT_SOURCE_LINE(), TEXT("Data is not found."));
  82. }
  83. template<typename __ReturnType, typename __Hint>
  84. [[nodiscard]]
  85. __ReturnType SearchSection(PIMAGE_SECTION_HEADER SectionHeader, size_t Offset, __Hint&& Hint) const {
  86. static_assert(std::is_pointer_v<__ReturnType>);
  87. auto begin = ImageSectionView<const uint8_t*>(SectionHeader) + Offset;
  88. auto end = begin + SectionHeader->Misc.VirtualSize;
  89. for (; begin < end; ++begin) {
  90. if (Hint(begin) == true) {
  91. return reinterpret_cast<__ReturnType>(const_cast<uint8_t*>(begin));
  92. }
  93. }
  94. throw Exception(NKG_CURRENT_SOURCE_FILE(), NKG_CURRENT_SOURCE_LINE(), TEXT("Data is not found."));
  95. }
  96. [[nodiscard]]
  97. uintptr_t RvaToFileOffset(uintptr_t Rva) const;
  98. [[nodiscard]]
  99. uintptr_t FileOffsetToRva(uintptr_t FileOffset) const;
  100. template<typename __PtrType = PVOID>
  101. [[nodiscard]]
  102. __PtrType RvaToPointer(uintptr_t Rva) const {
  103. static_assert(std::is_pointer_v<__PtrType>);
  104. return ImageOffset<__PtrType>(RvaToFileOffset(Rva));
  105. }
  106. template<typename __PtrType>
  107. [[nodiscard]]
  108. uintptr_t PointerToRva(__PtrType Ptr) const {
  109. static_assert(std::is_pointer_v<__PtrType>);
  110. return FileOffsetToRva(reinterpret_cast<const volatile char*>(Ptr) - reinterpret_cast<const volatile char*>(_DosHeader));
  111. }
  112. template<typename __PtrType>
  113. [[nodiscard]]
  114. __PtrType FileOffsetToPointer(uintptr_t FileOffset) const noexcept {
  115. return ImageOffset<__PtrType>(FileOffset);
  116. }
  117. template<typename __PtrType>
  118. [[nodiscard]]
  119. uintptr_t PointerToFileOffset(__PtrType Ptr) const noexcept {
  120. static_assert(std::is_pointer_v<__PtrType>);
  121. return reinterpret_cast<const volatile char*>(Ptr) - reinterpret_cast<const volatile char*>(_DosHeader);
  122. }
  123. [[nodiscard]]
  124. bool IsRvaRangeInRelocTable(uintptr_t Rva, size_t Size) const;
  125. [[nodiscard]]
  126. DWORD ImageFileMajorVersion() const;
  127. [[nodiscard]]
  128. DWORD ImageFileMinorVersion() const;
  129. [[nodiscard]]
  130. DWORD ImageProductMajorVersion() const;
  131. [[nodiscard]]
  132. DWORD ImageProductMinorVersion() const;
  133. };
  134. }