RawImage.cpp 2.5 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485
  1. #include "RawImage.h"
  2. #include <cstring>
  3. #include <iostream>
  4. #include "MetadataUtil.h"
  5. #include "Opcodes.h"
  6. namespace hybridclr
  7. {
  8. namespace metadata
  9. {
  10. const int kOptionalHeaderSize32 = 224;
  11. const int kOptionalHeaderSize64 = 240;
  12. const int kCliHeaderOffset32 = 208;
  13. const int kCliHeaderOffset64 = 224;
  14. LoadImageErrorCode RawImage::LoadCLIHeader(uint32_t& entryPointToken, uint32_t& metadataRva, uint32_t& metadataSize)
  15. {
  16. const byte* imageData = _imageData;
  17. const byte* ptr_lfanew = imageData + 0x3c;
  18. uint32_t lfanew = *(uint32_t*)ptr_lfanew;
  19. if (lfanew >= _imageLength)
  20. {
  21. return LoadImageErrorCode::BAD_IMAGE;
  22. }
  23. const byte* ptrSig = imageData + lfanew;
  24. /*if (ptr_sig[0] != 'P' || ptr_sig[1] != 'E' || ptr_sig[2] != 0 || ptr_sig[3] != 0)*/
  25. if (std::strncmp((const char*)ptrSig, "PE\0\0", 4))
  26. {
  27. return LoadImageErrorCode::BAD_IMAGE;
  28. }
  29. PEHeader* peHeader = (PEHeader*)(ptrSig + 4);
  30. bool isDll = (peHeader->characteristics & 0x2000);
  31. // std::cout << "load " << (_isDll ? "dll" : "exe") << std::endl;
  32. // optional size may be 224(32bit matchine) or 240 (64bit)
  33. if (peHeader->optionalHeadersize != kOptionalHeaderSize32 && peHeader->optionalHeadersize != kOptionalHeaderSize64)
  34. {
  35. return LoadImageErrorCode::BAD_IMAGE;
  36. }
  37. bool is32BitFormat = peHeader->optionalHeadersize == kOptionalHeaderSize32;
  38. PESectionHeader* _peSectionHeaders = (PESectionHeader*)((byte*)peHeader + 20 + peHeader->optionalHeadersize);
  39. for (uint16_t secIdx = 0; secIdx < peHeader->sections; secIdx++)
  40. {
  41. const PESectionHeader* ph = _peSectionHeaders + secIdx;
  42. if ((byte*)ph >= _ptrRawDataEnd)
  43. {
  44. return LoadImageErrorCode::BAD_IMAGE;
  45. }
  46. _sections.push_back({ ph->virtualAddress, ph->virtualAddress + ph->virtualSize, ph->ptrRawData - ph->virtualAddress });
  47. }
  48. const PEDirEntry* ptrCLIHeaderEntry = (PEDirEntry*)(((byte*)peHeader)
  49. + 20 /* pe header size */
  50. + (is32BitFormat ? kCliHeaderOffset32 : kCliHeaderOffset64) /* pe optional header -> pe header data directories -> cli header */);
  51. uint32_t cLIHeaderOffset;
  52. if (!TranslateRVAToImageOffset(ptrCLIHeaderEntry->rva, cLIHeaderOffset))
  53. {
  54. return LoadImageErrorCode::BAD_IMAGE;
  55. }
  56. if (cLIHeaderOffset >= _imageLength)
  57. {
  58. return LoadImageErrorCode::BAD_IMAGE;
  59. }
  60. const CLIHeader* ptrCLIHeader = (const CLIHeader*)(imageData + cLIHeaderOffset);
  61. entryPointToken = ptrCLIHeader->entryPointToken;
  62. metadataRva = ptrCLIHeader->metaData.rva;
  63. metadataSize = ptrCLIHeader->metaData.size;
  64. return LoadImageErrorCode::OK;
  65. }
  66. }
  67. }