public OSRel(byte[] file, int address) { offset = ByteConverter.ToUInt16(file, address); type = file[address + 2]; section = file[address + 3]; addend = ByteConverter.ToUInt32(file, address + 4); }
public static uint?SetupEXE(ref byte[] exefile) { if (ByteConverter.ToUInt16(exefile, 0) != 0x5A4D) { return(null); } int ptr = ByteConverter.ToInt32(exefile, 0x3c); if (ByteConverter.ToInt32(exefile, (int)ptr) != 0x4550) //PE\0\0 { return(null); } ptr += 4; UInt16 numsects = ByteConverter.ToUInt16(exefile, (int)ptr + 2); ptr += 0x14; int PEHead = ptr; uint imageBase = ByteConverter.ToUInt32(exefile, ptr + 28); byte[] result = new byte[ByteConverter.ToUInt32(exefile, ptr + 56)]; Array.Copy(exefile, result, ByteConverter.ToUInt32(exefile, ptr + 60)); ptr += 0xe0; for (int i = 0; i < numsects; i++) { Array.Copy(exefile, ByteConverter.ToInt32(exefile, ptr + (int)SectOffs.FAddr), result, ByteConverter.ToInt32(exefile, ptr + (int)SectOffs.VAddr), ByteConverter.ToInt32(exefile, ptr + (int)SectOffs.FSize)); ptr += (int)SectOffs.Size; } exefile = result; return(imageBase); }
public uint bssAlign; // bss alignment constraint public OSModuleHeader(byte[] file, int address) { info = new OSModuleInfo(file, address); address += 0x20; bssSize = ByteConverter.ToUInt32(file, address); address += 4; relOffset = ByteConverter.ToUInt32(file, address); address += 4; impOffset = ByteConverter.ToUInt32(file, address); address += 4; impSize = ByteConverter.ToUInt32(file, address); address += 4; prologSection = file[address++]; epilogSection = file[address++]; unresolvedSection = file[address++]; padding0 = file[address++]; prolog = ByteConverter.ToUInt32(file, address); address += 4; epilog = ByteConverter.ToUInt32(file, address); address += 4; unresolved = ByteConverter.ToUInt32(file, address); address += 4; align = ByteConverter.ToUInt32(file, address); address += 4; bssAlign = ByteConverter.ToUInt32(file, address); }
public static int GetPointer(this byte[] file, int address, uint imageBase) { uint tmp = ByteConverter.ToUInt32(file, address); if (tmp == 0) { return(0); } return((int)(tmp - imageBase)); }
public static bool CheckBigEndianInt32(byte[] file, int address) { bool bigEndState = ByteConverter.BigEndian; ByteConverter.BigEndian = true; bool isBigEndian = BitConverter.ToUInt32(file, address) > ByteConverter.ToUInt32(file, address); ByteConverter.BigEndian = bigEndState; return(isBigEndian); }
public static uint GetNewSectionAddress(byte[] exefile) { int ptr = ByteConverter.ToInt32(exefile, 0x3c); ptr += 4; UInt16 numsects = ByteConverter.ToUInt16(exefile, (int)ptr + 2); ptr += 0x14; ptr += 0xe0; ptr += (int)SectOffs.Size * (numsects - 1); return(HelperFunctions.Align(ByteConverter.ToUInt32(exefile, ptr + (int)SectOffs.VAddr) + ByteConverter.ToUInt32(exefile, ptr + (int)SectOffs.VSize))); }
public uint version; // version number public OSModuleInfo(byte[] file, int address) { id = ByteConverter.ToUInt32(file, address); address += 4; link = new OSModuleLink(file, address); address += 8; numSections = ByteConverter.ToUInt32(file, address); address += 4; sectionInfoOffset = ByteConverter.ToUInt32(file, address); address += 4; nameOffset = ByteConverter.ToUInt32(file, address); address += 4; nameSize = ByteConverter.ToUInt32(file, address); address += 4; version = ByteConverter.ToUInt32(file, address); }
public static void CreateNewSection(ref byte[] exefile, string name, byte[] data, bool isCode) { int ptr = ByteConverter.ToInt32(exefile, 0x3c); ptr += 4; UInt16 numsects = ByteConverter.ToUInt16(exefile, ptr + 2); int sectnumptr = ptr + 2; ptr += 0x14; int PEHead = ptr; ptr += 0xe0; int sectptr = ptr; ptr += (int)SectOffs.Size * numsects; ByteConverter.GetBytes((ushort)(numsects + 1)).CopyTo(exefile, sectnumptr); Array.Clear(exefile, ptr, 8); Encoding.ASCII.GetBytes(name).CopyTo(exefile, ptr); UInt32 vaddr = HelperFunctions.Align(ByteConverter.ToUInt32(exefile, ptr - (int)SectOffs.Size + (int)SectOffs.VAddr) + ByteConverter.ToUInt32(exefile, ptr - (int)SectOffs.Size + (int)SectOffs.VSize)); ByteConverter.GetBytes(vaddr).CopyTo(exefile, ptr + (int)SectOffs.VAddr); UInt32 faddr = HelperFunctions.Align(ByteConverter.ToUInt32(exefile, ptr - (int)SectOffs.Size + (int)SectOffs.FAddr) + ByteConverter.ToUInt32(exefile, ptr - (int)SectOffs.Size + (int)SectOffs.FSize)); ByteConverter.GetBytes(faddr).CopyTo(exefile, ptr + (int)SectOffs.FAddr); ByteConverter.GetBytes(isCode ? 0x60000020 : 0xC0000040).CopyTo(exefile, ptr + (int)SectOffs.Flags); int diff = (int)HelperFunctions.Align((uint)data.Length); ByteConverter.GetBytes(diff).CopyTo(exefile, ptr + (int)SectOffs.VSize); ByteConverter.GetBytes(diff).CopyTo(exefile, ptr + (int)SectOffs.FSize); if (isCode) { ByteConverter.GetBytes(Convert.ToUInt32(ByteConverter.ToUInt32(exefile, PEHead + 4) + diff)).CopyTo(exefile, PEHead + 4); } else { ByteConverter.GetBytes(Convert.ToUInt32(ByteConverter.ToUInt32(exefile, PEHead + 8) + diff)).CopyTo(exefile, PEHead + 8); } ByteConverter.GetBytes(Convert.ToUInt32(ByteConverter.ToUInt32(exefile, PEHead + 0x38) + diff)).CopyTo(exefile, PEHead + 0x38); Array.Resize(ref exefile, exefile.Length + diff); data.CopyTo(exefile, vaddr); }
public static byte[] DecompressREL(byte[] file) { // Scan the array for the last instance of the "SaCompGC" string because there are some files with redundant headers int start = 0; bool isCompressed = false; bool bigend = ByteConverter.BigEndian; ByteConverter.BigEndian = true; for (int u = file.Length - 8; u >= 0; u--) { if (ByteConverter.ToUInt32(file, u) == 0x5361436F) // && BitConverter.ToUInt32(file, u + 4) == 0x4347706D) { start = u; isCompressed = true; break; } } if (!isCompressed) { return(file); } byte[] input = new byte[file.Length - start]; Array.Copy(file, start, input, 0, input.Length); // Process the new array IntPtr pnt_input = Marshal.AllocHGlobal(input.Length); Marshal.Copy(input, 0, pnt_input, input.Length); int size_output = (int)GetDecompressedSize(pnt_input); IntPtr pnt_output = Marshal.AllocHGlobal(size_output); DecompressBuffer(pnt_input, pnt_output); byte[] decompbuf = new byte[size_output]; Marshal.Copy(pnt_output, decompbuf, 0, size_output); Marshal.FreeHGlobal(pnt_output); Marshal.FreeHGlobal(pnt_input); ByteConverter.BigEndian = bigend; return(decompbuf); }
public override uint ReadUInt32() { return(ByteConverter.ToUInt32(ReadBytes(sizeof(uint)), 0)); }
public uint offset; // offset to OSRel instructions public OSImportInfo(byte[] file, int address) { id = ByteConverter.ToUInt32(file, address); offset = ByteConverter.ToUInt32(file, address + 4); }
public OSSectionInfo(byte[] file, int address) { offset = ByteConverter.ToUInt32(file, address); size = ByteConverter.ToUInt32(file, address + 4); }
public OSModuleLink(byte[] file, int address) { next = ByteConverter.ToUInt32(file, address); prev = ByteConverter.ToUInt32(file, address + 4); }
public static void FixRELPointers(byte[] file, uint imageBase = 0) { OSModuleHeader header = new OSModuleHeader(file, 0); OSSectionInfo[] sections = new OSSectionInfo[header.info.numSections]; for (int i = 0; i < header.info.numSections; i++) { sections[i] = new OSSectionInfo(file, (int)header.info.sectionInfoOffset + (i * 8)); } OSImportInfo[] imports = new OSImportInfo[header.impSize / 8]; for (int i = 0; i < imports.Length; i++) { imports[i] = new OSImportInfo(file, (int)header.impOffset + (i * 8)); } int reladdr = 0; for (int i = 0; i < imports.Length; i++) { if (imports[i].id == header.info.id) { reladdr = (int)imports[i].offset; break; } } OSRel rel = new OSRel(file, reladdr); int dataaddr = 0; unchecked { while (rel.type != (byte)RelocTypes.R_DOLPHIN_END) { dataaddr += rel.offset; uint sectionbase = (uint)(sections[rel.section].offset & ~1); switch (rel.type) { case 0x01: ByteConverter.GetBytes(rel.addend + sectionbase + imageBase).CopyTo(file, dataaddr); break; case 0x02: ByteConverter.GetBytes((ByteConverter.ToUInt32(file, dataaddr) & 0xFC000003) | ((rel.addend + sectionbase) & 0x3FFFFFC) + imageBase).CopyTo(file, dataaddr); break; case 0x03: case 0x04: ByteConverter.GetBytes((ushort)(rel.addend + sectionbase) + imageBase).CopyTo(file, dataaddr); break; case 0x05: ByteConverter.GetBytes((ushort)((rel.addend + sectionbase) >> 16) + imageBase).CopyTo(file, dataaddr); break; case 0x06: ByteConverter.GetBytes((ushort)(((rel.addend + sectionbase) >> 16) + (((rel.addend + sectionbase) & 0x8000) == 0x8000 ? 1 : 0)) + imageBase).CopyTo(file, dataaddr); break; case 0x0A: ByteConverter.GetBytes((uint)((ByteConverter.ToUInt32(file, dataaddr) & 0xFC000003) | (((rel.addend + sectionbase) - dataaddr) & 0x3FFFFFC)) + imageBase).CopyTo(file, dataaddr); break; case 0x00: case (byte)RelocTypes.R_DOLPHIN_NOP: case (byte)RelocTypes.R_DOLPHIN_END: break; case (byte)RelocTypes.R_DOLPHIN_SECTION: dataaddr = (int)sectionbase; break; default: throw new NotImplementedException(); } reladdr += 8; rel = new OSRel(file, reladdr); } } }
public static int GetPointer(this byte[] file, int address, uint imageBase) { return((int)(ByteConverter.ToUInt32(file, address) - imageBase)); }