mirror of
https://github.com/BeneficialCode/WinArk
synced 2026-08-09 12:00:31 +00:00
309 lines
7.2 KiB
C++
309 lines
7.2 KiB
C++
#pragma once
|
|
class CLRMetadataParser;
|
|
|
|
struct ExportedSymbol {
|
|
std::string Name;
|
|
std::string UndecoratedName;
|
|
std::string ForwardName;
|
|
DWORD Address;
|
|
unsigned short Ordinal;
|
|
bool IsForward;
|
|
WORD Hint;
|
|
bool HasName;
|
|
};
|
|
|
|
struct ImportedSymbol {
|
|
std::string Name;
|
|
std::string UndecoratedName;
|
|
unsigned short Hint;
|
|
};
|
|
|
|
struct ImportedLibrary {
|
|
std::string Name;
|
|
DWORD IAT;
|
|
std::vector<ImportedSymbol> Symbols;
|
|
};
|
|
|
|
enum class SubsystemType :short {
|
|
Unknown,
|
|
Native,
|
|
WindowsGUI,
|
|
WindowsCUI,
|
|
PosixCUI = 7,
|
|
WindowsCEGUI = 9,
|
|
EfiApplication = 10,
|
|
EfiBootServiceDriver = 11,
|
|
EfiRuntimeDriver = 12,
|
|
EfiROM = 13,
|
|
XBOX = 14
|
|
};
|
|
|
|
enum class CfgFlags :uint32_t {
|
|
CfInstrumented = 0x100,
|
|
CfwInstrumented = 0x200,
|
|
CfFunctionTablePresent = 0x400,
|
|
SecurityCookieUnused = 0x800,
|
|
ProtectDelayLoadIat = 0x1000,
|
|
DelayLoadIatInItsOwnSection = 0x2000,
|
|
CfExportSuppressionInfoPresent = 0x4000,
|
|
CfEnableExportSuppression = 0x8000,
|
|
CfLongJmpTablePresent = 0x10000,
|
|
CfFunctionTableSizeMask = 0xf0000000,
|
|
};
|
|
DEFINE_ENUM_FLAG_OPERATORS(CfgFlags);
|
|
|
|
|
|
enum class ImageCharacteristics :unsigned short {
|
|
None = 0,
|
|
RelocsStripped = 1,
|
|
ExecutableImage = 2,
|
|
LineNumsStripped = 4,
|
|
LocalSymbolsStripped = 8,
|
|
AggressiveTrimWorkingSet = 0x10,
|
|
LargeAddressAware = 0x20,
|
|
LittleEndian = 0x80,
|
|
Machine32Bit = 0x100,
|
|
DebugInfoStripped = 0x200,
|
|
RemovableRunFromSwap = 0x400,
|
|
NetRunFromSwap = 0x800,
|
|
SystemFile = 0x1000,
|
|
DllFile = 0x2000,
|
|
SingleCpuOnly = 0x4000,
|
|
BigEndian = 0x8000
|
|
};
|
|
DEFINE_ENUM_FLAG_OPERATORS(ImageCharacteristics)
|
|
|
|
enum class ImageDebugType {
|
|
Unknown,
|
|
Coff,
|
|
CodeView,
|
|
Fpo,
|
|
Misc,
|
|
Exception,
|
|
Fixup,
|
|
Borland = 9,
|
|
Repro = 16
|
|
};
|
|
|
|
enum class ControlFlowGuardFlags {
|
|
Instrumented = 0x100,
|
|
WriteInstrumented = 0x200,
|
|
FunctionTablePresent = 0x400,
|
|
SecurityCookieUnused = 0x800,
|
|
ProtectDelayLoadIAT = 0x1000,
|
|
DelayLoadIATOwnSection = 0x2000,
|
|
ExportSuppressInfo = 0x4000,
|
|
EnableExportSuppression = 0x8000,
|
|
LongJumpTablePresent = 0x10000
|
|
};
|
|
|
|
enum class SectionFlags :unsigned {
|
|
None = 0,
|
|
NoPad = 8,
|
|
Code = 0x20,
|
|
InitializedData = 0x40,
|
|
UninitializedData = 0x80,
|
|
Other = 0x100,
|
|
Info = 0x200,
|
|
Remove = 0x800,
|
|
Comdat = 0x1000,
|
|
GPRel = 0x80000,
|
|
Align1Byte = 0x100000,
|
|
Align2Bytes = 0x200000,
|
|
ExtendedReloc = 0x1000000,
|
|
Discardable = 0x2000000,
|
|
NotCached = 0x4000000,
|
|
NotPaged = 0x8000000,
|
|
Shared = 0x10000000,
|
|
Execute = 0x20000000,
|
|
Read = 0x40000000,
|
|
Write = 0x80000000,
|
|
};
|
|
DEFINE_ENUM_FLAG_OPERATORS(SectionFlags)
|
|
|
|
enum class OptionalHeaderMagic : short {
|
|
PE32 = 0x10b,
|
|
PE32Plus = 0x20b,
|
|
Rom = 0x107
|
|
};
|
|
|
|
enum class MachineType : unsigned short {
|
|
Unknown = 0,
|
|
X86 = 332,
|
|
Arm = 0x1c0,
|
|
Arm_NT = 0x1c4,
|
|
IA64 = 512,
|
|
Amd64 = 0x8664,
|
|
Arm64 = 0xAA64,
|
|
};
|
|
|
|
struct ResourceInfo {
|
|
std::string Name;
|
|
DWORD Rva;
|
|
DWORD Size;
|
|
void* Address;
|
|
WORD Id;
|
|
bool IsId{ false };
|
|
};
|
|
|
|
class PEFileSection {
|
|
public:
|
|
IMAGE_SECTION_HEADER _sectionHeader;
|
|
BYTE* _pData = nullptr;
|
|
DWORD _dataSize = 0;
|
|
DWORD _normalSize = 0;
|
|
|
|
PEFileSection() {
|
|
ZeroMemory(&_sectionHeader, sizeof(IMAGE_SECTION_HEADER));
|
|
}
|
|
};
|
|
|
|
struct RelocInfo {
|
|
uint64_t address;
|
|
uint16_t* item;
|
|
uint32_t count;
|
|
};
|
|
|
|
class PEParser {
|
|
public:
|
|
explicit PEParser(const wchar_t* path,bool isScylla = false);
|
|
~PEParser();
|
|
PEParser(void* base, SIZE_T mappedSize = 0);
|
|
|
|
bool IsValid() const;
|
|
bool IsPe64() const;
|
|
bool IsExecutable() const;
|
|
bool IsManaged() const;
|
|
bool HasExports() const;
|
|
bool HasImports() const;
|
|
bool IsSystemFile() const;
|
|
|
|
void FixPEHeader();
|
|
bool DumpProcess(DWORD_PTR modBase, DWORD_PTR entryPoint, const WCHAR* pDumpFilePath);
|
|
void GetPESections();
|
|
void GetPESectionData(DWORD_PTR offset, PEFileSection& peFileSection);
|
|
void SetEntryPointVA(DWORD_PTR entryPoint);
|
|
void SetEntryPointRVA(DWORD rva);
|
|
void SetModuleBase(DWORD_PTR va);
|
|
bool SavePEFileToDisk(const WCHAR* pNewFile);
|
|
bool OpenWriteFileHandle(const WCHAR* pNewFile);
|
|
bool WriteMemoryToFile(HANDLE hFile, LONG offset, DWORD size, LPVOID pData);
|
|
bool WriteZeroMemoryToFile(HANDLE hFile, DWORD fileOffset, DWORD size);
|
|
void GetSectionHeaders();
|
|
DWORD IsMemoryNotNull(BYTE* pData, int dataSize);
|
|
int GetSectionCount() const;
|
|
void SetSectionCount(WORD count);
|
|
void SetImportTable(DWORD va, DWORD size);
|
|
IMAGE_SECTION_HEADER* GetSectionHeader(ULONG section) const;
|
|
IMAGE_DATA_DIRECTORY* GetDataDirectory(int index) const;
|
|
const IMAGE_DOS_HEADER& GetDosHeader() const;
|
|
void* GetBaseAddress() const;
|
|
void AlignAllSectionHeaders();
|
|
DWORD AlignValue(DWORD badValue, DWORD alignTo);
|
|
|
|
ULONGLONG GetImageBase() const;
|
|
|
|
void RemoveIATDirectory();
|
|
|
|
DWORD GetSectionHeaderBasedFileSize();
|
|
DWORD GetSectionHeaderBasedSizeOfImage();
|
|
|
|
DWORD GetImageSize() const;
|
|
DWORD GetHeadersSize() const;
|
|
DWORD GetAddressOfEntryPoint() const;
|
|
|
|
ULONG GetEAT() const;
|
|
|
|
std::string GetSectionName(ULONG section) const;
|
|
|
|
void* RVA2FA(unsigned rva) const;
|
|
|
|
|
|
std::vector<ExportedSymbol> GetExports() const;
|
|
std::vector<ImportedLibrary> GetImports() const;
|
|
const IMAGE_FILE_HEADER& GetFileHeader() const;
|
|
//std::vector<ResourceInfo> EnumResources() const;
|
|
bool GetImportAddressTable() const;
|
|
//bool IsCLRMetadataAvailable() const;
|
|
|
|
std::vector<ULONG> GetTlsInfo() const;
|
|
|
|
void* GetAddress(unsigned rva) const;
|
|
|
|
void* GetMemAddress(unsigned rva) const;
|
|
|
|
BYTE* GetFileAddress(DWORD offset);
|
|
|
|
SubsystemType GetSubsystemType() const;
|
|
|
|
IMAGE_OPTIONAL_HEADER64& GetOptionalHeader64() const {
|
|
return *_opt64;
|
|
}
|
|
|
|
IMAGE_OPTIONAL_HEADER32& GetOptionalHeader32() const {
|
|
return *_opt32;
|
|
}
|
|
|
|
PVOID GetDataDirectoryAddress(UINT index, PULONG size) const;
|
|
void SetDefaultFileAligment();
|
|
DWORD GetSectionAlignment();
|
|
DWORD GetFileAlignment();
|
|
|
|
bool IsImportLib() const;
|
|
bool IsObjectFile() const;
|
|
ULONG GetExportByName(PCSTR exportName);
|
|
HANDLE GetFileHandle();
|
|
unsigned RvaToFileOffset(unsigned rva) const;
|
|
DWORD_PTR RVAToRelativeOffset(DWORD_PTR rva) const;
|
|
int RVAToSectionIndex(DWORD_PTR rva) const;
|
|
IMAGE_SECTION_HEADER* GetSections();
|
|
DWORD_PTR FileOffsetToRva(DWORD_PTR offset);
|
|
|
|
LARGE_INTEGER GetFileSize() const;
|
|
|
|
std::vector<RelocInfo> GetRelocs(void* imageBase);
|
|
static void RelocateImageByDelta(std::vector<RelocInfo>& relocs, const uint64_t delta);
|
|
|
|
BYTE* GetDosStub();
|
|
|
|
IMAGE_NT_HEADERS64* GetNtHeader();
|
|
|
|
std::vector<PEFileSection> _PESections;
|
|
|
|
protected:
|
|
static const DWORD _fileAlignmentConstant = 0x200;
|
|
|
|
bool AddNewLastSection(const char* pSectionName, DWORD sectionSize, BYTE* pSectionData);
|
|
|
|
private:
|
|
bool IsObjectPe64() const;
|
|
void CheckValidity();
|
|
void ReleaseSectionData();
|
|
|
|
|
|
//CString GetResourceName(void* data) const;
|
|
|
|
PBYTE _address{ nullptr };
|
|
DWORD_PTR _moduleBase = 0;
|
|
LARGE_INTEGER _fileSize{ 0 };
|
|
HMODULE _module{ nullptr };
|
|
HANDLE _hMemMap{ nullptr };
|
|
HANDLE _hFile{ INVALID_HANDLE_VALUE };
|
|
IMAGE_DOS_HEADER* _dosHeader = nullptr;
|
|
IMAGE_NT_HEADERS64* _ntHeader = nullptr;
|
|
IMAGE_NT_HEADERS64 _ntHeader64Copy;
|
|
IMAGE_NT_HEADERS32 _ntHeader32Copy;
|
|
IMAGE_FILE_HEADER* _fileHeader = nullptr;
|
|
IMAGE_SECTION_HEADER* _sections = nullptr;
|
|
IMAGE_OPTIONAL_HEADER32* _opt32{ nullptr };
|
|
IMAGE_OPTIONAL_HEADER64* _opt64{ nullptr };
|
|
|
|
//CComPtr<IMetaDataImport> _spMetadata;
|
|
std::wstring _path;
|
|
mutable HMODULE _resModule{ nullptr };
|
|
//mutable std::unique_ptr<CLRMetaParser> _clrParser;
|
|
bool _valid = false;
|
|
bool _importLib = false, _objectFile = false;
|
|
bool _isFileMap = true;
|
|
};
|