ImageInterpreter.hpp 8.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239
  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> _SectionRvaTable;
  21. std::map<uintptr_t, size_t> _SectionFileOffsetTable;
  22. std::map<uintptr_t, size_t> _RelocationRvaTable;
  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(size_t Idx) const;
  48. [[nodiscard]]
  49. PIMAGE_SECTION_HEADER ImageSectionHeaderByName(PCSTR lpszSectionName) const;
  50. [[nodiscard]]
  51. PIMAGE_SECTION_HEADER ImageSectionHeaderByRva(uintptr_t Rva) const;
  52. [[nodiscard]]
  53. PIMAGE_SECTION_HEADER ImageSectionHeaderByVa(uintptr_t Va) const;
  54. [[nodiscard]]
  55. PIMAGE_SECTION_HEADER ImageSectionHeaderByFileOffset(uintptr_t FileOffset) const;
  56. template<typename __PtrType = PVOID>
  57. [[nodiscard]]
  58. __PtrType ImageSectionView(PIMAGE_SECTION_HEADER SectionHeader, size_t Offset = 0) const noexcept {
  59. return ImageOffset<__PtrType>(SectionHeader->PointerToRawData + Offset);
  60. }
  61. template<typename __PtrType = PVOID>
  62. [[nodiscard]]
  63. __PtrType ImageSectionViewByName(PCSTR lpszSectionName, size_t Offset = 0) const {
  64. return ImageOffset<__PtrType>(ImageSectionHeaderByName(lpszSectionName)->PointerToRawData + Offset);
  65. }
  66. template<typename __PtrType = PVOID>
  67. [[nodiscard]]
  68. __PtrType ImageSectionViewByRva(uintptr_t Rva, size_t Offset = 0) const {
  69. return ImageOffset<__PtrType>(ImageSectionHeaderByRva(Rva)->PointerToRawData + Offset);
  70. }
  71. template<typename __PtrType = PVOID>
  72. [[nodiscard]]
  73. __PtrType ImageSectionViewByVa(uintptr_t Va, size_t Offset = 0) const {
  74. return ImageOffset<__PtrType>(ImageSectionHeaderByVa(Va)->PointerToRawData + Offset);
  75. }
  76. template<typename __PtrType = PVOID>
  77. [[nodiscard]]
  78. __PtrType ImageSectionViewByFileOffset(uintptr_t FileOffset, size_t Offset = 0) const {
  79. return ImageOffset<__PtrType>(ImageSectionHeaderByFileOffset(FileOffset)->PointerToRawData + Offset);
  80. }
  81. template<typename __ReturnType, typename __Hint>
  82. [[nodiscard]]
  83. __ReturnType SearchSection(PIMAGE_SECTION_HEADER SectionHeader, __Hint&& Hint) const {
  84. static_assert(std::is_pointer_v<__ReturnType>);
  85. auto begin = ImageSectionView<const uint8_t*>(SectionHeader);
  86. auto end = begin + SectionHeader->Misc.VirtualSize;
  87. for (; begin < end; ++begin) {
  88. if (Hint(begin) == true) {
  89. return reinterpret_cast<__ReturnType>(const_cast<uint8_t*>(begin));
  90. }
  91. }
  92. throw Exception(NKG_CURRENT_SOURCE_FILE(), NKG_CURRENT_SOURCE_LINE(), TEXT("Data is not found."));
  93. }
  94. template<typename __ReturnType, typename __Hint>
  95. [[nodiscard]]
  96. __ReturnType SearchSection(PIMAGE_SECTION_HEADER SectionHeader, size_t Offset, __Hint&& Hint) const {
  97. static_assert(std::is_pointer_v<__ReturnType>);
  98. auto begin = ImageSectionView<const uint8_t*>(SectionHeader) + Offset;
  99. auto end = begin + SectionHeader->Misc.VirtualSize;
  100. for (; begin < end; ++begin) {
  101. if (Hint(begin) == true) {
  102. return reinterpret_cast<__ReturnType>(const_cast<uint8_t*>(begin));
  103. }
  104. }
  105. throw Exception(NKG_CURRENT_SOURCE_FILE(), NKG_CURRENT_SOURCE_LINE(), TEXT("Data is not found."));
  106. }
  107. template<typename __ReturnType, typename __Hint>
  108. [[nodiscard]]
  109. __ReturnType SearchSection(PCSTR lpszSectionName, __Hint&& Hint) const {
  110. return SearchSection<__ReturnType>(ImageSectionHeaderByName(lpszSectionName), std::forward<__Hint>(Hint));
  111. }
  112. template<typename __ReturnType, typename __Hint>
  113. [[nodiscard]]
  114. __ReturnType SearchSection(PCSTR lpszSectionName, size_t Offset, __Hint&& Hint) const {
  115. return SearchSection<__ReturnType>(ImageSectionHeaderByName(lpszSectionName), Offset, std::forward<__Hint>(Hint));
  116. }
  117. [[nodiscard]]
  118. uintptr_t RvaToVa(uintptr_t Rva) const noexcept;
  119. [[nodiscard]]
  120. uintptr_t RvaToFileOffset(uintptr_t Rva) const;
  121. template<typename __PtrType = PVOID>
  122. [[nodiscard]]
  123. __PtrType RvaToPointer(uintptr_t Rva) const {
  124. static_assert(std::is_pointer_v<__PtrType>);
  125. return ImageOffset<__PtrType>(RvaToFileOffset(Rva));
  126. }
  127. [[nodiscard]]
  128. uintptr_t FileOffsetToRva(uintptr_t FileOffset) const;
  129. [[nodiscard]]
  130. uintptr_t FileOffsetToVa(uintptr_t FileOffset) const;
  131. template<typename __PtrType>
  132. [[nodiscard]]
  133. __PtrType FileOffsetToPointer(uintptr_t FileOffset) const noexcept {
  134. return ImageOffset<__PtrType>(FileOffset);
  135. }
  136. [[nodiscard]]
  137. uintptr_t VaToRva(uintptr_t Va) const noexcept;
  138. [[nodiscard]]
  139. uintptr_t VaToFileOffset(uintptr_t Va) const;
  140. template<typename __PtrType>
  141. [[nodiscard]]
  142. __PtrType VaToPointer(uintptr_t Va) const noexcept {
  143. return RvaToPointer<__PtrType>(VaToRva(Va));
  144. }
  145. template<typename __PtrType>
  146. [[nodiscard]]
  147. uintptr_t PointerToFileOffset(__PtrType Ptr) const noexcept {
  148. static_assert(std::is_pointer_v<__PtrType>);
  149. return reinterpret_cast<const volatile char*>(Ptr) - reinterpret_cast<const volatile char*>(_DosHeader);
  150. }
  151. template<typename __PtrType>
  152. [[nodiscard]]
  153. uintptr_t PointerToRva(__PtrType Ptr) const {
  154. return FileOffsetToRva(PointerToFileOffset(Ptr));
  155. }
  156. template<typename __PtrType>
  157. [[nodiscard]]
  158. uintptr_t PointerToVa(__PtrType Ptr) const {
  159. return FileOffsetToVa(PointerToFileOffset(Ptr));
  160. }
  161. [[nodiscard]]
  162. bool IsRvaRangeInRelocTable(uintptr_t Rva, size_t Size) const;
  163. [[nodiscard]]
  164. bool IsVaRangeInRelocTable(uintptr_t Va, size_t Size) const;
  165. [[nodiscard]]
  166. bool IsFileOffsetRangeInRelocTable(uintptr_t FileOffset, size_t Size) const;
  167. template<typename __PtrType>
  168. [[nodiscard]]
  169. bool IsFileOffsetRangeInRelocTable(__PtrType Ptr, size_t Size) const {
  170. return IsRvaRangeInRelocTable(PointerToRva(Ptr), Size);
  171. }
  172. [[nodiscard]]
  173. DWORD ImageFileMajorVersion() const;
  174. [[nodiscard]]
  175. DWORD ImageFileMinorVersion() const;
  176. [[nodiscard]]
  177. DWORD ImageProductMajorVersion() const;
  178. [[nodiscard]]
  179. DWORD ImageProductMinorVersion() const;
  180. [[nodiscard]]
  181. size_t NumberOfSections() const noexcept;
  182. };
  183. }