#pragma once #include "flags.h" namespace RomLDR { using namespace System; using namespace System::IO; using namespace System::Runtime::InteropServices; using namespace System::Collections::Generic; #define DIR_OUT "OUT\\" #define DIR_MOD "MODULES\\" #define DIR_FIL "FILES\\" #define DIR_MODULES DIR_OUT"MODULES\\" #define DIR_FILES DIR_OUT"FILES\\" #define FIL_PRTHDR DIR_OUT"PARTHDR.txt" #define FIL_ROMHDR DIR_OUT"ROMHDR.txt" #define FIL_MAP DIR_OUT"MAP.txt" #define FIL_MAP_P DIR_OUT"MAP.physical.txt" #define STR_FROM64 " {0,-23}{1:X16}" #define STR_FROMAT " {0,-23}{1:X8}" #define STR_FROM_K " {0,-22}({1:X8})" #define STR_F_IS_P " {0,-21}P={1:X8}" #define STR_FROM_P " {0,-21}P+{1:X8}" #define STR_F_IS_R " {0,-21}R={1:X8}" #define STR_FROM_R " {0,-21}R+{1:X8}" #define STR_F_IS_V " {0,-21}V={1:X8}" #define STR_FROM_V " {0,-21}V+{1:X8}" #define STR_F_IS_D " {0,-21}D={1:X8}" #define STR_FROM_D " {0,-21}D+{1:X8}" #define STR_FROM_Z " {0,-21}0+{1:X8}" [StructLayout(LayoutKind::Sequential, Size=16)] ref struct COPYentry { unsigned int ulSource; // copy source address unsigned int ulDest; // copy destination address unsigned int ulCopyLen; // copy length unsigned int ulDestLen; // copy destination length (zero fill to end if > ulCopyLen) virtual String^ ToString() override { return String::Format("copyent {0:x8} L{1:x8} -> {2:x8} L{3:x8}", ulSource, ulCopyLen, ulDest, ulDestLen); } static property unsigned int RomSize { unsigned int get() { return Marshal::SizeOf(COPYentry::typeid); } } }; array^ GetData(BinaryReader^ br, unsigned int offset, unsigned int size) { Int64 position = br->BaseStream->Position; br->BaseStream->Seek(offset, SeekOrigin::Begin); array^ data = br->ReadBytes(size); br->BaseStream->Seek(position, System::IO::SeekOrigin::Begin); return data; } #pragma region ROM Header Structure [StructLayout(LayoutKind::Sequential, Pack=1, Size=84)] ref struct ROMHDR { unsigned int dllfirst; // first DLL address unsigned int dlllast; // last DLL address unsigned int physfirst; // first physical address unsigned int physlast; // highest physical address unsigned int nummods; // number of TOCentry's unsigned int ulRAMStart; // start of RAM unsigned int ulRAMFree; // start of RAM free space unsigned int ulRAMEnd; // end of RAM unsigned int ulCopyEntries; // number of copy section entries unsigned int ulCopyOffset; // offset to copy section unsigned int ulProfileLen; // length of PROFentries RAM unsigned int ulProfileOffset; // offset to PROFentries unsigned int numfiles; // number of FILES unsigned int ulKernelFlags; // optional kernel flags from ROMFLAGS .bib config option unsigned int ulFSRamPercent; // Percentage of RAM used for filesystem unsigned int ulDrivglobStart; // device driver global starting address unsigned int ulDrivglobLen; // device driver global length unsigned short usCPUType; // CPU (machine) Type unsigned short usMiscFlags; // Miscellaneous flags unsigned int pExtensions; // pointer to ROM Header extensions unsigned int ulTrackingStart; // tracking memory starting address unsigned int ulTrackingLen; // tracking memory ending address void WriteToText() { TextWriter^ tw = gcnew StreamWriter(File::Create(FIL_ROMHDR)); tw->WriteLine(String::Format(STR_F_IS_D, "dllfirst:", dllfirst)); tw->WriteLine(String::Format(STR_FROMAT, "dlllast:", dlllast)); tw->WriteLine(String::Format(STR_F_IS_P, "physfirst:", physfirst)); tw->WriteLine(String::Format(STR_FROMAT, "physlast:", physlast)); tw->WriteLine(String::Format(STR_FROM_K, "nummods:", nummods)); tw->WriteLine(String::Format(STR_F_IS_R, "ulRAMStart:", ulRAMStart)); tw->WriteLine(String::Format(STR_FROMAT, "ulRAMFree:", ulRAMFree)); tw->WriteLine(String::Format(STR_FROMAT, "ulRAMEnd:", ulRAMEnd)); tw->WriteLine(String::Format(STR_FROM_K, "ulCopyEntries:", ulCopyEntries)); tw->WriteLine(String::Format(STR_FROM_P, "ulCopyOffset:", ulCopyOffset - physfirst)); tw->WriteLine(String::Format(STR_FROMAT, "ulProfileLen:", ulProfileLen)); tw->WriteLine(String::Format(STR_FROMAT, "ulProfileOffset:", ulProfileOffset)); tw->WriteLine(String::Format(STR_FROM_K, "numfiles:", numfiles)); tw->WriteLine(String::Format(STR_FROMAT, "ulKernelFlags:", ulKernelFlags)); tw->WriteLine(String::Format(STR_FROMAT, "ulFSRamPercent:", ulFSRamPercent)); tw->WriteLine(String::Format(STR_FROMAT, "ulDrivglobStart:", ulDrivglobStart)); tw->WriteLine(String::Format(STR_FROMAT, "ulDrivglobLen:", ulDrivglobLen)); tw->WriteLine(String::Format(STR_FROMAT, "usCPUType:", usCPUType)); tw->WriteLine(String::Format(STR_FROMAT, "usMiscFlags:", usMiscFlags)); tw->WriteLine(String::Format(STR_FROM_P, "pExtensions:", pExtensions - physfirst)); tw->WriteLine(String::Format(STR_FROMAT, "ulTrackingStart:", ulTrackingStart)); tw->WriteLine(String::Format(STR_FROMAT, "ulTrackingLen:", ulTrackingLen)); tw->Close(); } void ReadFromText(String^ file) { TextReader^ tr = gcnew StreamReader(File::OpenRead(file)); dllfirst = GetInt32(tr); dlllast = GetInt32(tr); physfirst = GetInt32(tr); physlast = GetInt32(tr); nummods = GetInt32(tr); ulRAMStart = GetInt32(tr); ulRAMFree = GetInt32(tr); ulRAMEnd = GetInt32(tr); ulCopyEntries = GetInt32(tr); ulCopyOffset = GetInt32(tr); ulProfileLen = GetInt32(tr); ulProfileOffset = GetInt32(tr); numfiles = GetInt32(tr); ulKernelFlags = GetInt32(tr); ulFSRamPercent = GetInt32(tr); ulDrivglobStart = GetInt32(tr); ulDrivglobLen = GetInt32(tr); usCPUType = GetInt32(tr); usMiscFlags = GetInt32(tr); pExtensions = GetInt32(tr); ulTrackingStart = GetInt32(tr); ulTrackingLen = GetInt32(tr); tr->Close(); } unsigned int GetInt32(TextReader^ tr) { return GetInt32(tr, 0); } unsigned int GetInt32(TextReader^ tr, int v) { String^ line = tr->ReadLine(); unsigned int value = UInt32::Parse(line->Substring(26, 8), System::Globalization::NumberStyles::HexNumber); String^ add = line->Substring(24, 2); if(add==" (") return 0; if(add=="P+") value += physfirst; if(add=="R+") value += ulRAMStart; if(add=="D+") value += dllfirst; if(add=="V+") value += v; return value; } __int64 GetInt64(TextReader^ tr) { String^ line = tr->ReadLine(); return UInt64::Parse(line->Substring(26, 16), System::Globalization::NumberStyles::HexNumber); } unsigned short GetInt16(TextReader^ tr) { String^ line = tr->ReadLine(); return UInt16::Parse(line->Substring(30, 4), System::Globalization::NumberStyles::HexNumber); } bool IsPhys(unsigned int value) { if(physfirst <= value && value < physlast) return true; return false; } bool IsDll(unsigned int value) { if(dllfirst <= value && value < dlllast) return true; return false; } bool IsRAM(unsigned int value) { if(ulRAMStart <= value && value < ulRAMEnd) return true; return false; } property unsigned int CopyOffset[int] { unsigned int get(int index) { return ulCopyOffset - physfirst + index * Marshal::SizeOf(COPYentry::typeid); } } property unsigned int CopyEntriesCount { unsigned int get() { return ulCopyEntries; } void set(unsigned int value) { ulCopyEntries = value; } } property unsigned int ModulesCount { unsigned int get() { return nummods; } void set(unsigned int value) { nummods = value; } } property unsigned int FilesCount { unsigned int get() { return numfiles; } void set(unsigned int value) { numfiles = value; } } virtual String^ ToString () override { return String::Format("rom_00 header: dlls={0:x8}-{1:x8} phys={2:x8}-{3:x8}, {4} modules, {5} files, {6} copyentries ext={7:x8} ram={8:x8}-{9:x8} cputype={10:x8}", dllfirst, dlllast, physfirst, physlast, nummods, numfiles, ulCopyEntries, pExtensions, ulRAMStart, ulRAMEnd, usCPUType); } #pragma region static property unsigned int RomSize {get()} static property unsigned int RomSize { unsigned int get() { return Marshal::SizeOf(ROMHDR::typeid); } } #pragma endregion }; #pragma endregion ref struct G { static ROMHDR^ ROMHDR; }; #pragma region o32_rom [StructLayout(LayoutKind::Sequential, Size=24)] ref class o32_rom { unsigned long o32_vsize; /* Virtual memory size */ unsigned long o32_rva; /* Object relative virtual address */ unsigned long o32_psize; /* Physical file size of init. data */ unsigned long o32_dataptr; /* Image pages offset */ unsigned long o32_realaddr; /* pointer to actual */ unsigned long o32_flags; /* Attribute flags for the object */ public: #pragma region property unsigned long vsize {get(), set()} property unsigned long vsize { unsigned long get() { return o32_vsize; } void set(unsigned long value) { o32_vsize = value; } } #pragma endregion #pragma region property unsigned long rva {get(), set()} property unsigned long rva { unsigned long get() { return o32_rva; } void set(unsigned long value) { o32_rva = value; } } #pragma endregion #pragma region property unsigned long psize {get(), set()} property unsigned long psize { unsigned long get() { return o32_psize; } void set(unsigned long value) { o32_psize = value; } } #pragma endregion #pragma region property unsigned long dataptr {get(), set()} property unsigned long dataptr { unsigned long get() { return o32_dataptr; } void set(unsigned long value) { if(o32_dataptr == o32_realaddr) o32_realaddr = value; o32_dataptr = value; } } #pragma endregion #pragma region property unsigned long realaddr {get(), set()} property unsigned long realaddr { unsigned long get() { return o32_realaddr; } void set(unsigned long value) { o32_realaddr = value; } } #pragma endregion #pragma region property unsigned long flags {get(), set()} property unsigned long flags { unsigned long get() { return o32_flags; } void set(unsigned long value) { o32_flags = value; } } #pragma endregion #pragma region property unsigned long DataOffset {get()} property unsigned long DataOffset { unsigned long get() { if(o32_dataptr == 0) return 0; return o32_dataptr - G::ROMHDR->physfirst; } } #pragma endregion #pragma region property unsigned long DataSize {get()} property unsigned long DataSize { unsigned long get() { if(o32_vsize >= o32_psize) return o32_psize; return o32_vsize; } } #pragma endregion #pragma region String^ ToString (String^ name, int index) String^ ToString (String^ name, int index) { return String::Format("o32 region_{0} rva={1:x8} vsize={2:x8} real={3:x8} psize={4:x8} f={5:x8} for {6}", index, o32_rva, o32_vsize, o32_realaddr, o32_psize, o32_flags, name); } #pragma endregion #pragma region static property unsigned int RomSize {get()} static property unsigned int RomSize { unsigned int get() { return Marshal::SizeOf(o32_rom::typeid); } } #pragma endregion }; #pragma endregion #pragma region e32_rom #define ROM_EXTRA 9 [StructLayout(LayoutKind::Sequential)] value struct info { /* Extra information header block */ Int32 rva; /* Virtual relative address of info */ Int32 size; /* Size of information block */ }; [StructLayout(LayoutKind::Sequential, Size= ROM_EXTRA * 2 * 4 + 5 * 2 + 6 * 4)] ref class e32_rom { unsigned short e32_objcnt; /* Number of memory objects */ unsigned short e32_imageflags; /* Image flags */ unsigned long e32_entryrva; /* Relative virt. addr. of entry point */ unsigned long e32_vbase; /* Virtual base address of module */ unsigned short e32_subsysmajor;/* The subsystem major version number */ unsigned short e32_subsysminor;/* The subsystem minor version number */ unsigned long e32_stackmax; /* Maximum stack size */ unsigned long e32_vsize; /* Virtual size of the entire image */ unsigned long e32_sect14rva; /* section 14 rva */ unsigned long e32_sect14size; /* section 14 size */ [MarshalAs(UnmanagedType::ByValArray, SizeConst=ROM_EXTRA)] array^ e32_unit; /* Array of extra info units */ unsigned short e32_subsys; /* The subsystem type */ public: #pragma region property unsigned short objcnt {get()} property unsigned short objcnt { unsigned short get() { return e32_objcnt; } } #pragma endregion #pragma region property unsigned short imageflag {get()} property unsigned short imageflag { unsigned short get() { return e32_imageflags; } } #pragma endregion #pragma region property unsigned long entryrva {get()} property unsigned long entryrva { unsigned long get() { return e32_entryrva; } } #pragma endregion #pragma region property unsigned long vbase {get()} property unsigned long vbase { unsigned long get() { return e32_vbase; } } #pragma endregion #pragma region property unsigned short subsysmajor {get()} property unsigned short subsysmajor { unsigned short get() { return e32_subsysmajor; } } #pragma endregion #pragma region property unsigned short subsysminor {get()} property unsigned short subsysminor { unsigned short get() { return e32_subsysminor; } } #pragma endregion #pragma region property unsigned long stackmax {get()} property unsigned long stackmax { unsigned long get() { return e32_stackmax; } } #pragma endregion #pragma region property unsigned long vsize {get()} property unsigned long vsize { unsigned long get() { return e32_vsize; } } #pragma endregion #pragma region property unsigned long sect14rva {get()} property unsigned long sect14rva { unsigned long get() { return e32_sect14rva; } } #pragma endregion #pragma region property unsigned long sect14size {get()} property unsigned long sect14size { unsigned long get() { return e32_sect14size; } } #pragma endregion #pragma region property array^ unit {get()} property array^ unit { array^ get() { return e32_unit; } } #pragma endregion #pragma region property unsigned long subsys {get()} property unsigned long subsys { unsigned long get() { return e32_subsys; } } #pragma endregion #pragma region void WriteToText(String^ name, array^ o32, BinaryReader^ br) void WriteToText(String^ name, array^ o32, BinaryReader^ br) { Directory::CreateDirectory (DIR_MODULES+name); TextWriter^ tw = gcnew StreamWriter (File::Create (DIR_MODULES + name + "\\imageinfo.txt")); tw->WriteLine(String::Format(" Module name: {0}", name)); tw->WriteLine(String::Format(STR_FROMAT, "e32_objcnt:", e32_objcnt)); tw->WriteLine(String::Format(STR_FROMAT, "e32_imageflags:", e32_imageflags)); tw->WriteLine(String::Format(STR_FROMAT, "e32_entryrva:", e32_entryrva)); if(G::ROMHDR->IsPhys(e32_vbase)) tw->WriteLine(String::Format(STR_FROM_P, "e32_vbase:", e32_vbase-G::ROMHDR->physfirst)); else tw->WriteLine(String::Format(STR_F_IS_V, "e32_vbase:", e32_vbase)); tw->WriteLine(String::Format(STR_FROMAT, "e32_subsysmajor:", e32_subsysmajor)); tw->WriteLine(String::Format(STR_FROMAT, "e32_subsysminor:", e32_subsysminor)); tw->WriteLine(String::Format(STR_FROMAT, "e32_stackmax:", e32_stackmax)); tw->WriteLine(String::Format(STR_FROMAT, "e32_vsize:", e32_vsize)); tw->WriteLine(String::Format(STR_FROMAT, "e32_sect14rva:", e32_sect14rva)); tw->WriteLine(String::Format(STR_FROMAT, "e32_sect14size:", e32_sect14size)); for(int i = 0; i < ROM_EXTRA; i++) { tw->WriteLine(String::Format(STR_FROMAT, String::Format("e32_unit[{0}].rva:", i), e32_unit[i].rva)); tw->WriteLine(String::Format(STR_FROMAT, String::Format("e32_unit[{0}].size:", i), e32_unit[i].size)); } tw->WriteLine(String::Format(STR_FROMAT, "e32_subsys:", e32_subsys)); tw->WriteLine(); Directory::CreateDirectory(DIR_MODULES+name); for(int i = 0; i < e32_objcnt; i++) { if (br) { Stream^ writer = File::Create (DIR_MODULES + name + "\\" + String::Format ("S{0:000}", i)); writer->Write (GetData (br, o32[i]->DataOffset, o32[i]->DataSize), 0, o32[i]->DataSize); writer->Close(); } tw->WriteLine(String::Format(STR_FROMAT, String::Format ("o32[{0}].o32_vsize:", i), o32[i]->vsize)); tw->WriteLine(String::Format(STR_FROMAT, String::Format ("o32[{0}].o32_rva:", i), o32[i]->rva)); tw->WriteLine(String::Format(STR_FROMAT, String::Format ("o32[{0}].o32_psize:", i), o32[i]->psize)); if(o32[i]->dataptr) tw->WriteLine(String::Format(STR_FROM_P, String::Format ("o32[{0}].o32_dataptr:", i), o32[i]->dataptr-G::ROMHDR->physfirst)); else tw->WriteLine(String::Format(STR_FROMAT, String::Format ("o32[{0}].o32_dataptr:", i), o32[i]->dataptr)); if(G::ROMHDR->IsPhys(o32[i]->realaddr)) tw->WriteLine(String::Format(STR_FROM_P, String::Format ("o32[{0}].o32_realaddr:", i), o32[i]->realaddr-G::ROMHDR->physfirst)); else if(G::ROMHDR->IsRAM(o32[i]->realaddr)) tw->WriteLine(String::Format(STR_F_IS_R, String::Format ("o32[{0}].o32_realaddr:", i), o32[i]->realaddr)); else if(G::ROMHDR->IsDll(o32[i]->realaddr)) tw->WriteLine(String::Format(STR_F_IS_D, String::Format ("o32[{0}].o32_realaddr:", i), o32[i]->realaddr)); else if(IsBase(o32[i]->realaddr)) tw->WriteLine(String::Format(STR_FROM_V, String::Format ("o32[{0}].o32_realaddr:", i), o32[i]->realaddr-e32_vbase)); else tw->WriteLine(String::Format(STR_FROMAT, String::Format ("o32[{0}].o32_realaddr:", i), o32[i]->realaddr)); tw->WriteLine(String::Format(STR_FROMAT, String::Format ("o32[{0}].o32_flags:", i), o32[i]->flags)); tw->WriteLine(); } tw->Close(); } #pragma endregion #pragma region array^ ReadFromText(String^ path, Dictionary^ copy) array^ ReadFromText(String^ path, Dictionary^ copy) { TextReader^ tr = gcnew StreamReader(File::OpenRead(DIR_MODULES+path+"\\imageinfo.txt")); String^ name = tr->ReadLine()->Substring(15); e32_objcnt = G::ROMHDR->GetInt16(tr); e32_imageflags = G::ROMHDR->GetInt16(tr); e32_entryrva = G::ROMHDR->GetInt32(tr); e32_vbase = G::ROMHDR->GetInt32(tr); e32_subsysmajor = G::ROMHDR->GetInt16(tr); e32_subsysminor = G::ROMHDR->GetInt16(tr); e32_stackmax = G::ROMHDR->GetInt32(tr); e32_vsize = G::ROMHDR->GetInt32(tr); e32_sect14rva = G::ROMHDR->GetInt32(tr); e32_sect14size = G::ROMHDR->GetInt32(tr); e32_unit = gcnew array(ROM_EXTRA); for(int i = 0; i < ROM_EXTRA; i++) { e32_unit[i].rva = G::ROMHDR->GetInt32(tr); e32_unit[i].size = G::ROMHDR->GetInt32(tr); } e32_subsys = G::ROMHDR->GetInt32(tr); array^ o32 = gcnew array(e32_objcnt); for (int i = 0; i < e32_objcnt; i++) { tr->ReadLine(); o32[i] = gcnew o32_rom; o32[i]->vsize = G::ROMHDR->GetInt32(tr); o32[i]->rva = G::ROMHDR->GetInt32(tr); o32[i]->psize = G::ROMHDR->GetInt32(tr); o32[i]->dataptr = G::ROMHDR->GetInt32(tr); o32[i]->realaddr = G::ROMHDR->GetInt32(tr, vbase); o32[i]->flags = G::ROMHDR->GetInt32(tr); if (G::ROMHDR->IsRAM(o32[i]->realaddr) && (o32[i]->flags & IMAGE_SCN_CNT_INITIALIZED_DATA)) { COPYentry^ entry = gcnew COPYentry; entry->ulSource = o32[i]->dataptr; entry->ulCopyLen = o32[i]->psize; entry->ulDest = o32[i]->realaddr; entry->ulDestLen = o32[i]->vsize; copy->Add(String::Format("region_{0} {1}", i, path), entry); } } tr->Close(); return o32; } #pragma endregion #pragma region bool IsBase(unsigned long ptr) bool IsBase(unsigned long ptr) { return e32_vbase < ptr && ptr < e32_vbase+e32_vsize; } #pragma endregion #pragma region virtual String^ ToString(String^ name) virtual String^ ToString(String^ name) { return String::Format("e32 struct {0} objs, img={1:x4} entrypt={2:x8} base={3:x8} v{4}.{5} tp{6} {7}", e32_objcnt, e32_imageflags, e32_entryrva, e32_vbase, e32_subsysmajor, e32_subsysminor, e32_subsys, name); } #pragma endregion #pragma region static property unsigned int RomSize {get()} static property unsigned int RomSize { unsigned int get() { return Marshal::SizeOf(e32_rom::typeid)+2; } } #pragma endregion }; #pragma endregion #pragma region Module Table of Contents - follows ROMHDR in image [StructLayout(LayoutKind::Sequential, Pack=1, Size=32)] ref struct TOCentry : IComparable { // MODULE BIB section structure Int32 dwFileAttributes; Int64 ftTime; Int32 nFileSize; Int32 lpszFileName; Int32 ulE32Offset; // Offset to E32 structure Int32 ulO32Offset; // Offset to O32 structure unsigned int ulLoadOffset; // MODULE load buffer offset void WriteToText(String^ name) { TextWriter^ tw = gcnew StreamWriter(File::Create(DIR_MODULES+name+".txt")); tw->WriteLine(String::Format(" Module name: {0}", name)); tw->WriteLine(String::Format(STR_FROMAT, "dwFileAttributes:", dwFileAttributes)); tw->WriteLine(String::Format(STR_FROM64, "ftTime:", ftTime)); tw->WriteLine(String::Format(STR_FROMAT, "nFileSize:", nFileSize)); tw->WriteLine(String::Format(STR_FROM_P, "lpszFileName:", NameOffset)); tw->WriteLine(String::Format(STR_FROM_P, "ulE32Offset:", E32Offset)); tw->WriteLine(String::Format(STR_FROM_P, "ulO32Offset:", O32Offset[0])); // ulLoadOffset not writen tw->Close(); } String^ ReadFromText(String^ path) { TextReader^ tr = gcnew StreamReader(File::OpenRead(path+".txt")); String^ name = tr->ReadLine()->Substring(15); dwFileAttributes = G::ROMHDR->GetInt32(tr); ftTime = G::ROMHDR->GetInt64(tr); nFileSize = G::ROMHDR->GetInt32(tr); lpszFileName = G::ROMHDR->GetInt32(tr); ulE32Offset = G::ROMHDR->GetInt32(tr); ulO32Offset = G::ROMHDR->GetInt32(tr); tr->Close(); return name; } property int NameOffset { int get() { return lpszFileName - G::ROMHDR->physfirst; } } property int E32Offset { int get() { return ulE32Offset - G::ROMHDR->physfirst; } } property int O32Offset[int] { int get(int index) { return ulO32Offset - G::ROMHDR->physfirst + index*o32_rom::RomSize; } } virtual String^ ToString(String^ name, int i) { return String::Format("modent {0,3} {1:x8} {2:x16} {3,8} {4:x8} {5}", i, dwFileAttributes, ftTime, nFileSize, ulLoadOffset, name); } virtual int CompareTo( TOCentry^ other ) { if(ulLoadOffset == other->ulLoadOffset) nFileSize.CompareTo(other->nFileSize); return ulLoadOffset.CompareTo(other->ulLoadOffset); } static property unsigned int RomSize { unsigned int get() { return Marshal::SizeOf(TOCentry::typeid); } } }; #pragma endregion #pragma region Files Section Structure - follows Module Table in image [StructLayout(LayoutKind::Sequential, Pack=1, Size=28)] ref struct FILESentry : IComparable{ // FILES BIB section structure Int32 dwFileAttributes; Int64 ftTime; Int32 nRealFileSize; Int32 nCompFileSize; Int32 lpszFileName; Int32 ulLoadOffset; // FILES load buffer offset void WriteToText(String^ name, BinaryReader^ br) { TextWriter^ tw = gcnew StreamWriter(File::Create(DIR_FILES+name+".imageinfo.txt")); tw->WriteLine(String::Format(" File name: {0}", name)); tw->WriteLine(String::Format(STR_FROMAT, "dwFileAttributes:", dwFileAttributes)); tw->WriteLine(String::Format(STR_FROM64, "ftTime:", ftTime)); tw->WriteLine(String::Format(STR_FROMAT, "nRealFileSize:", nRealFileSize)); tw->WriteLine(String::Format(STR_FROMAT, "nCompFileSize:", nCompFileSize)); tw->WriteLine(String::Format(STR_FROM_P, "lpszFileName:", NameOffset)); tw->WriteLine(String::Format(STR_FROM_P, "ulLoadOffset:", LoadOffset)); tw->Close(); if(br) { Stream^ writer = File::Create(DIR_FILES+name); writer->Write(GetData(br, LoadOffset, nCompFileSize), 0, nCompFileSize); writer->Close(); } } String^ ReadFromText(String^ path) { TextReader^ tr = gcnew StreamReader(File::OpenRead(path)); String^ name = tr->ReadLine()->Substring(13); dwFileAttributes = G::ROMHDR->GetInt32(tr); ftTime = G::ROMHDR->GetInt64(tr); nRealFileSize = G::ROMHDR->GetInt32(tr); nCompFileSize = G::ROMHDR->GetInt32(tr); lpszFileName = G::ROMHDR->GetInt32(tr); ulLoadOffset = G::ROMHDR->GetInt32(tr); tr->Close(); return name; } property int NameOffset { int get() { return lpszFileName - G::ROMHDR->physfirst; } } property int LoadOffset { int get() { return ulLoadOffset - G::ROMHDR->physfirst; } } virtual int CompareTo( FILESentry^ other ) { if(other->nCompFileSize == nCompFileSize) return ulLoadOffset.CompareTo(other->ulLoadOffset); return other->nCompFileSize.CompareTo(nCompFileSize); } virtual String^ ToString(String^ name, int i) { return String::Format("filent {0,3} {1:x8} {2:x16} {3,8} {4,8} {5:x8} {6}", i, dwFileAttributes, ftTime, nRealFileSize, nCompFileSize, ulLoadOffset, name); } static property unsigned int RomSize { unsigned int get() { return Marshal::SizeOf(FILESentry::typeid); } } }; #pragma endregion #define ROM_SIGNATURE_OFFSET 0x40 // Offset from the image's physfirst address to the ROM signature. #define ROM_TOC_POINTER_OFFSET 0x44 // Offset from the image's physfirst address to the TOC pointer. #define ROM_TOC_OFFSET_OFFSET 0x48 // Offset from the image's physfirst address to the TOC offset (from physfirst). #define ROM_SIGNATURE 0x43454345 #define PARTITION_HEADER_BYTES 0x1000 [StructLayout(LayoutKind::Explicit, Size=PARTITION_HEADER_BYTES)] ref struct PARTHDR { [FieldOffset(0x0000)] Int32 ulRomUnknown; [FieldOffset(ROM_SIGNATURE_OFFSET)] Int32 ulRomSignature; [FieldOffset(ROM_TOC_POINTER_OFFSET)] Int32 dwRomHdrOffset; [FieldOffset(ROM_TOC_OFFSET_OFFSET)] Int32 dwRomHdrAddress; void WriteToText() { TextWriter^ tw = gcnew StreamWriter(File::Create(FIL_PRTHDR)); tw->WriteLine(String::Format(STR_FROMAT, "ulRomUnknown:", ulRomUnknown)); tw->WriteLine(String::Format(STR_FROMAT, "dwRomHdrAddress:", dwRomHdrAddress)); tw->Close(); } void ReadFromText() { TextReader^ tr = gcnew StreamReader(File::OpenRead(FIL_PRTHDR)); ulRomUnknown = G::ROMHDR->GetInt32(tr); dwRomHdrAddress = G::ROMHDR->GetInt32(tr); ulRomSignature = ROM_SIGNATURE; dwRomHdrOffset = dwRomHdrAddress+G::ROMHDR->physfirst; tr->Close(); } #pragma region static property unsigned int RomSize {get()} static property unsigned int RomSize { unsigned int get() { return Marshal::SizeOf(PARTHDR::typeid); } } #pragma endregion }; // // ROM Header extension: PID // #define PID_LENGTH 10 [StructLayout(LayoutKind::Sequential, Pack=1, Size=44)] ref struct ROMPID { [MarshalAs(UnmanagedType::ByValArray, SizeConst=PID_LENGTH)] array^ dwPID; // PID Int32 pNextExt; // pointer to next extension if any }; generic T GetStructure(BinaryReader^ br) { return (T)Marshal::PtrToStructure(Marshal::UnsafeAddrOfPinnedArrayElement(br->ReadBytes(Marshal::SizeOf(T::typeid)), 0), T::typeid); } generic T GetStructure(BinaryReader^ br, int offset) { br->BaseStream->Seek(offset, System::IO::SeekOrigin::Begin); return GetStructure(br); } generic T GetStructure(BinaryReader^ br, int offset, bool restore) { if(!restore) return GetStructure(br, offset); Int64 position = br->BaseStream->Position; T t = GetStructure(br, offset); br->BaseStream->Seek(position, System::IO::SeekOrigin::Begin); return t; } String^ GetString(BinaryReader^ br, int offset) { Int64 position = br->BaseStream->Position; br->BaseStream->Seek(offset, SeekOrigin::Begin); Char b; String^ string; while((b = br->ReadByte()) != 0x00) string += b; br->BaseStream->Seek(position, System::IO::SeekOrigin::Begin); return string; } }