public void LoadElfIdentification() { var rdr = new BeImageReader(base.RawImage, 0); var elfMagic = rdr.ReadBeInt32(); if (elfMagic != ELF_MAGIC) { throw new BadImageFormatException("File is not in ELF format."); } this.fileClass = rdr.ReadByte(); this.endianness = rdr.ReadByte(); this.fileVersion = rdr.ReadByte(); this.osAbi = rdr.ReadByte(); }
private int GetRunLengthValue(BeImageReader a5dr, ref int a5repeat) { // Run length returned is in byte(s). // next byte read - see bit pattern from the following table for the return value // 0xxxxxxx - 0 - $7F // 10xxxxxx - 0 - $3FFF(run length and $3F + next byte, 14 bits) // 110xxxxx - 0 - $1FFFFF(run length and $1F + next two bytes, 21 bits) // 1110xxxx - next 4 bytes, 32 bits // 1111xxxx - get both new runtime length copy in bytes and new runtime length repeat count int runLength = a5dr.ReadByte(); if ((runLength & 0x80) == 0) { return(runLength); } if ((runLength & 0x40) == 0) { runLength = runLength & 0x3F; runLength = (runLength << 8) + a5dr.ReadByte(); return(runLength); } if ((runLength & 0x20) == 0) { runLength = runLength & 0x1F; runLength = (runLength << 16) + a5dr.ReadBeInt16(); return(runLength); } if ((runLength & 0x10) == 0) { return(a5dr.ReadBeInt32()); } runLength = GetRunLengthValue(a5dr, ref a5repeat); a5repeat = GetRunLengthValue(a5dr, ref a5repeat); return(runLength); }
private void A5Expand(BeImageReader a5dr, UInt32 a5dbelow) { var a5belowWriter = new BeImageWriter(platform.A5World.MemoryArea, platform.A5Offset - a5dbelow); int a5RunLengthToken = 0; int a5RunLengthCopySize = 0; int a5globalSkip = 0; int a5repeat = 0; var a5copylength = 0; bool a5dataEnd = false; // Compressed data // set Repeat count = 1, reset after each completed copy cycle // byte token lower 4 bits number of words to copy from compressed data // byte token upper 4 bits number of words to skip in global application data space // if either value is 0 then get run length value which is in bytes. // if the new run length value for copy is 0 then it's the end of compression data. do { a5repeat = 1; // Token value - upper nibble is words to skip, lower nibble is words to copy a5RunLengthToken = a5dr.ReadByte(); a5globalSkip = a5RunLengthToken; a5RunLengthCopySize = a5RunLengthToken & 0x0F; if (a5RunLengthCopySize == 0) { a5RunLengthCopySize = GetRunLengthValue(a5dr, ref a5repeat); if (a5RunLengthCopySize == 0) { a5dataEnd = true; } } else { a5RunLengthCopySize = a5RunLengthCopySize * 2; } if (!a5dataEnd) { a5globalSkip = a5globalSkip & 0xF0; if (a5globalSkip == 0) { a5globalSkip = GetRunLengthValue(a5dr, ref a5repeat); } else { // convert value 0x01 - 0x0F number of words to skip in upper nibble to number of bytes to skip a5globalSkip = a5globalSkip >> 3; } do { a5belowWriter.Position = a5belowWriter.Position + a5globalSkip; a5copylength = a5RunLengthCopySize; do { a5belowWriter.WriteByte(a5dr.ReadByte()); a5copylength -= 1; } while (a5copylength > 0); a5repeat -= 1; } while (a5repeat > 0); } } while (!a5dataEnd); }
public void Relocate() { var memA5 = (ByteMemoryArea)platform.A5World.MemoryArea; var a5belowWriter = new BeImageWriter(memA5, 0); var a5belowReader = new BeImageReader(memA5, 0); uint a5globalOffset = platform.A5Offset - a5dbelow; var a5WorldAddress = (UInt32)((platform.A5World.Address.Offset + platform.A5Offset) & 0xFFFFFFFF); // set Repeat count = 1, reset after each completed copy cycle // byte token lower 4 bits number of words to copy from compressed data // byte token upper 4 bits number of words to skip in global application data space // if either value is 0 then get run length value which is in bytes. // if the new run length value for copy is 0 then it's the end of compression data. for (;;) { int a5repeat = 1; // Skip is number of 16-bit words to skip uint a5globalSkip = a5dr.ReadByte(); if (a5globalSkip == 0) { a5globalSkip = a5dr.ReadByte(); if (a5globalSkip == 0) { break; } if (a5globalSkip > 0x7F) { a5globalSkip = ((a5globalSkip & 0x7F) << 8) + a5dr.ReadByte(); a5globalSkip = (a5globalSkip << 16) + a5dr.ReadBeUInt16(); } else { a5repeat = ResourceFork.GetRunLengthValue(a5dr, ref a5repeat); //$BUG: a5repeat could return the value 0. The do-while below will // decrement a5repeat before testing. This will lead to an effective // repeat count of 2^32; likely not wanted. } } else { if ((a5globalSkip & 0x80) == 0x80) { a5globalSkip = ((a5globalSkip & 0x7F) << 8) + a5dr.ReadByte(); } } a5globalSkip = a5globalSkip * 2; do { a5globalOffset += a5globalSkip; a5belowReader.Seek(a5globalOffset, SeekOrigin.Begin); uint a5ptrOffset = a5belowReader.ReadBeUInt32(); a5belowWriter.Position = (int)a5globalOffset; // write relocated A5World pointers to absolute address in A5World segment // Possible register/mark as Global pointer references to strings a5belowWriter.WriteBeUInt32((a5WorldAddress + a5ptrOffset) & 0xFFFFFFFF); --a5repeat; } while (a5repeat > 0); } }