12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485 |
- #include "RawImage.h"
- #include <cstring>
- #include <iostream>
- #include "MetadataUtil.h"
- #include "Opcodes.h"
- namespace hybridclr
- {
- namespace metadata
- {
- const int kOptionalHeaderSize32 = 224;
- const int kOptionalHeaderSize64 = 240;
- const int kCliHeaderOffset32 = 208;
- const int kCliHeaderOffset64 = 224;
- LoadImageErrorCode RawImage::LoadCLIHeader(uint32_t& entryPointToken, uint32_t& metadataRva, uint32_t& metadataSize)
- {
- const byte* imageData = _imageData;
- const byte* ptr_lfanew = imageData + 0x3c;
- uint32_t lfanew = *(uint32_t*)ptr_lfanew;
- if (lfanew >= _imageLength)
- {
- return LoadImageErrorCode::BAD_IMAGE;
- }
- const byte* ptrSig = imageData + lfanew;
- /*if (ptr_sig[0] != 'P' || ptr_sig[1] != 'E' || ptr_sig[2] != 0 || ptr_sig[3] != 0)*/
- if (std::strncmp((const char*)ptrSig, "PE\0\0", 4))
- {
- return LoadImageErrorCode::BAD_IMAGE;
- }
- PEHeader* peHeader = (PEHeader*)(ptrSig + 4);
- bool isDll = (peHeader->characteristics & 0x2000);
- // std::cout << "load " << (_isDll ? "dll" : "exe") << std::endl;
- // optional size may be 224(32bit matchine) or 240 (64bit)
- if (peHeader->optionalHeadersize != kOptionalHeaderSize32 && peHeader->optionalHeadersize != kOptionalHeaderSize64)
- {
- return LoadImageErrorCode::BAD_IMAGE;
- }
- bool is32BitFormat = peHeader->optionalHeadersize == kOptionalHeaderSize32;
- PESectionHeader* _peSectionHeaders = (PESectionHeader*)((byte*)peHeader + 20 + peHeader->optionalHeadersize);
- for (uint16_t secIdx = 0; secIdx < peHeader->sections; secIdx++)
- {
- const PESectionHeader* ph = _peSectionHeaders + secIdx;
- if ((byte*)ph >= _ptrRawDataEnd)
- {
- return LoadImageErrorCode::BAD_IMAGE;
- }
- _sections.push_back({ ph->virtualAddress, ph->virtualAddress + ph->virtualSize, ph->ptrRawData - ph->virtualAddress });
- }
- const PEDirEntry* ptrCLIHeaderEntry = (PEDirEntry*)(((byte*)peHeader)
- + 20 /* pe header size */
- + (is32BitFormat ? kCliHeaderOffset32 : kCliHeaderOffset64) /* pe optional header -> pe header data directories -> cli header */);
- uint32_t cLIHeaderOffset;
- if (!TranslateRVAToImageOffset(ptrCLIHeaderEntry->rva, cLIHeaderOffset))
- {
- return LoadImageErrorCode::BAD_IMAGE;
- }
- if (cLIHeaderOffset >= _imageLength)
- {
- return LoadImageErrorCode::BAD_IMAGE;
- }
- const CLIHeader* ptrCLIHeader = (const CLIHeader*)(imageData + cLIHeaderOffset);
- entryPointToken = ptrCLIHeader->entryPointToken;
- metadataRva = ptrCLIHeader->metaData.rva;
- metadataSize = ptrCLIHeader->metaData.size;
- return LoadImageErrorCode::OK;
- }
- }
- }
|