Files
RedHotRoast-ios/HybridCLRData/LocalIl2CppData-OSXEditor/il2cpp/libil2cpp/hybridclr/metadata/RawImage.cpp
T

85 lines
2.5 KiB
C++
Raw Normal View History

2026-07-17 14:03:00 +08:00
#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;
}
}
}