예제 #1
0
		public override RelocationResults Relocate(Address addrLoad)
		{
			ImageMap imageMap = imgLoadedMap;
			ImageReader rdr = new LeImageReader(exe.RawImage, (uint) exe.e_lfaRelocations);
            var relocations = new RelocationDictionary();
			int i = exe.e_cRelocations;
			while (i != 0)
			{
				uint offset = rdr.ReadLeUInt16();
				ushort segOffset = rdr.ReadLeUInt16();
				offset += segOffset * 0x0010u;

				ushort seg = (ushort) (imgLoaded.ReadLeUInt16(offset) + addrLoad.Selector);
				imgLoaded.WriteLeUInt16(offset, seg);
				relocations.AddSegmentReference(offset, seg);

				imageMap.AddSegment(Address.SegPtr(seg, 0), seg.ToString("X4"), AccessMode.ReadWriteExecute);
				--i;
			}
		
			// Found the start address.

			Address addrStart = Address.SegPtr((ushort)(exe.e_cs + addrLoad.Selector), exe.e_ip);
			imageMap.AddSegment(Address.SegPtr(addrStart.Selector, 0), addrStart.Selector.ToString("X4"), AccessMode.ReadWriteExecute);
            return new RelocationResults(
                new List<EntryPoint> { new EntryPoint(addrStart, arch.CreateProcessorState()) },
                relocations);
		}
예제 #2
0
 private MachineInstruction RunTest(params byte [] bytes)
 {
     var image = new LoadedImage(Address.Ptr16(0x0100), bytes);
     var rdr = new LeImageReader(image, 0);
     var dasm = new Z80Disassembler(rdr);
     return dasm.First();
 }
예제 #3
0
        public ExePackLoader(IServiceProvider services, string filename, byte[] imgRaw)
            : base(services, filename, imgRaw)
        {
            arch = new IntelArchitecture(ProcessorMode.Real);
            platform = new MsdosPlatform(Services, arch);

            var exe = new ExeImageLoader(services, filename, imgRaw);
            this.exeHdrSize = (uint)(exe.e_cparHeader * 0x10U);
            this.hdrOffset = (uint)(exe.e_cparHeader + exe.e_cs) * 0x10U;
            ImageReader rdr = new LeImageReader(RawImage, hdrOffset);
            this.ip = rdr.ReadLeUInt16();
            this.cs = rdr.ReadLeUInt16();
            rdr.ReadLeUInt16();
            this.cbExepackHeader = rdr.ReadLeUInt16();
            this.sp = rdr.ReadLeUInt16();
            this.ss = rdr.ReadLeUInt16();
            this.cpUncompressed = rdr.ReadLeUInt16();

            int offset = ExePackHeaderOffset(exe);
            if (LoadedImage.CompareArrays(imgRaw, offset, signature, signature.Length))
            {
                relocationsOffset = 0x012D;
            }
            else if (LoadedImage.CompareArrays(imgRaw, offset, signature2, signature2.Length))
            {
                relocationsOffset = 0x0125;
            }
            else
                throw new ApplicationException("Not a recognized EXEPACK image.");
        }
예제 #4
0
        public void ReadCString()
        {
            var img = new LeImageReader(new byte[] {
                0x12, 0x48, 0x65, 0x6C, 0x6C, 0x6F, 0x20, 0x77, 0x6f, 0x72, 0x6c, 0x64, 0x21, 0x00, 0x12 },
                1);
            StringConstant str = img.ReadCString(PrimitiveType.Char);
            Assert.AreEqual("Hello world!", str.ToString());

        }
예제 #5
0
        public void Sr_ReadLeInt32_Field()
        {
            var rdr = new LeImageReader(new byte[] { 0x34, 0x12, 0xAB, 0xCD, 0x78, 0x56, 0x34, 0x12 }, 0);
            var test = new TestStruct2();
            var sr = new StructureReader(test);
            sr.Read(rdr);

            Assert.AreEqual((int) 0x12345678, test.lField);
        }
예제 #6
0
        public void Sr_ReadLeUInt16_Field()
        {
            var rdr = new LeImageReader(new byte[] { 0x34, 0x12 }, 0);
            var test = new TestStruct();
            var sr = new StructureReader(test);
            sr.Read(rdr);

            Assert.AreEqual((ushort) 0x1234, test.usField);
        }
예제 #7
0
 public void ReadLengthPrefixedString()
 {
     var img =
         new LeImageReader(
             new LoadedImage(
                 Address.Ptr32(0x10000),
                 new byte[] { 0x12, 0x34, 0x03, 0x00, 0x00, 0x00, 0x46, 0x00, 0x6f, 0x00, 0x6f, 0x00, 0x02, 0x02}),
             2);
     StringConstant str = img.ReadLengthPrefixedString(PrimitiveType.Int32, PrimitiveType.WChar);
     Assert.AreEqual("Foo", str.ToString());
 }
예제 #8
0
 private MachineInstruction RunTest(params ushort [] words)
 {
     var bytes = new byte[words.Length * 2];
     LeImageWriter writer = new LeImageWriter(bytes);
     foreach (ushort word in words)
     {
         writer.WriteLeUInt16(word);
     }
     var image = new LoadedImage(Address.Ptr16(0x200), bytes);
     var rdr = new LeImageReader(image, 0);
     var arch = new Pdp11Architecture();
     var dasm = new Pdp11Disassembler(rdr, arch);
     return dasm.First();
 }
예제 #9
0
		public PeImageLoader(IServiceProvider services, string filename, byte [] img, uint peOffset) : base(services, filename, img)
		{
			ImageReader rdr = new LeImageReader(RawImage, peOffset);
			if (rdr.ReadByte() != 'P' ||
				rdr.ReadByte() != 'E' ||
				rdr.ReadByte() != 0x0 ||
				rdr.ReadByte() != 0x0)
			{
				throw new BadImageFormatException("Not a valid PE header.");
			}
            importThunks = new Dictionary<uint, PseudoProcedure>();
            importReferences = new Dictionary<Address, ImportReference>();
			short expectedMagic = ReadCoffHeader(rdr);
			ReadOptionalHeader(rdr, expectedMagic);
		}
예제 #10
0
 private FileHeader LoadHeader()
 {
     var rdr = new LeImageReader(RawImage, 0);
     var magic = rdr.ReadLeUInt16();
     switch (magic)
     {
     case 0x014C: arch = new IntelArchitecture(ProcessorMode.Protected32); break;
     default: throw new NotSupportedException();
     }
     return  new FileHeader
     {
         f_magic = magic,
         f_nscns = rdr.ReadUInt16(),
         f_timdat = rdr.ReadUInt32(),
         f_symptr = rdr.ReadUInt32(),
         f_nsyms = rdr.ReadUInt32(),
         f_opthdr = rdr.ReadUInt16(),
         f_flags = rdr.ReadUInt16(),
     };
 }
예제 #11
0
		public void ReadCommonExeFields()
		{
			ImageReader rdr = new LeImageReader(RawImage, 0);

			e_magic = rdr.ReadLeUInt16();
			e_cbLastPage = rdr.ReadLeUInt16();
			e_cpImage = rdr.ReadLeUInt16();
			this.e_cRelocations = rdr.ReadLeUInt16();
			e_cparHeader = rdr.ReadLeUInt16();
			e_minalloc = rdr.ReadLeUInt16();
			e_maxalloc = rdr.ReadLeUInt16();
			e_ss = rdr.ReadLeUInt16();
			e_sp = rdr.ReadLeUInt16();
			e_csum = rdr.ReadLeUInt16();
			e_ip = rdr.ReadLeUInt16();
			e_cs = rdr.ReadLeUInt16();
			e_lfaRelocations = rdr.ReadLeUInt16();
			e_ovno = rdr.ReadLeUInt16();
			e_res = new ushort[4];
			for (int i = 0; i != 4; ++i)
			{
				e_res[i] = rdr.ReadLeUInt16();
			}
			e_oemid = rdr.ReadLeUInt16();
			e_oeminfo = rdr.ReadLeUInt16();
			e_res2 = new ushort[10];
			for (int i = 0; i != 10; ++i)
			{
				e_res2[i] = rdr.ReadLeUInt16();
			}
			e_lfanew = rdr.ReadLeUInt32();
		}
예제 #12
0
        public void Sr_ReadArray()
        {
            var rdr = new LeImageReader(new byte[] {
                0x4A, 0x4B,     // signature
                0x08, 0x00, 0x00, 0x00, // pointer to directory
                0xFF, 0xFF,      // padding
                0x10, 0,      // Directory slot 0
                0x13, 0,      // Directory slot 1
                0x16, 0,      // Directory slot 2
                0x19, 0,        // Directory slot 3
                0x61, 0x62, 0x00,
                0x63, 0x64, 0x00,
                0x65, 0x66, 0x00,
                0x65, 0x78, 0x00,
            });
            var test = new TestStruct6();
            var sr = new StructureReader(test);
            sr.Read(rdr);

            Assert.IsNotNull(test.directory);
            Assert.IsNotNull(test.directory.sections);
            Assert.AreEqual(4, test.directory.sections.Length);
            Assert.AreEqual("ab", test.directory.sections[0].name);
            Assert.AreEqual("cd", test.directory.sections[1].name);
            Assert.AreEqual("ef", test.directory.sections[2].name);
            Assert.AreEqual("ex", test.directory.sections[3].name);
        }
예제 #13
0
        public void Sr_ReadStructure()
        {
            var rdr = new LeImageReader(new byte[] {
                0x4A, 0x4B,     // signature
                0x08, 0x00, 0x00, 0x00, // pointer to struct
                0xFF, 0xFF,      // padding
                0x34, 0x12,      // structure.
            });
            var test = new TestStruct5();
            var sr = new StructureReader(test);
            sr.Read(rdr);

            Assert.IsNotNull(test.extra);
            Assert.AreEqual((ushort) 0x1234, test.extra.sig);
        }
예제 #14
0
        public void Pil32_BlankIat()
        {
            Given_Pe32Header(0x00100000);
            Given_Section(".text", 0x1000, 0x1000);
            Given_Section(".idata", 0x2000, 0x2000);
            writer.Position = RvaImportDescriptor;
            var rvaId = Given_ImportDescriptor32(
                Given_Ilt32("malloc", "free", "realloc"),
                "msvcrt.dll",
                Given_Ilt32(0u, 0u, 0u));
            Given_PeLoader();
            var program = peldr.Load(addrLoad);

            var rdrId = new LeImageReader(fileImage, (uint)rvaId);
            var ret = peldr.ReadImportDescriptor(rdrId, addrLoad);
            Assert.IsTrue(ret);
            Assert.AreEqual(3, program.ImportReferences.Count); ;
            Assert.AreEqual("msvcrt.dll!malloc", program.ImportReferences[Address.Ptr32(0x0010202A)].ToString());
            Assert.AreEqual("msvcrt.dll!free", program.ImportReferences[Address.Ptr32(0x0010202E)].ToString());
            Assert.AreEqual("msvcrt.dll!realloc", program.ImportReferences[Address.Ptr32(0x00102032)].ToString());
        }
예제 #15
0
            public byte[] GetBytes()
            {
                byte[] data;
                var stm = new MemoryStream();
                var rdr = new LeImageReader(image, (uint) offset);
                byte trackNext = rdr.ReadByte();
                while (trackNext != 0)
                {
                    byte sectorNext = rdr.ReadByte();
                    data = rdr.ReadBytes(0xFE);
                    stm.Write(data, 0, data.Length);

                    rdr.Offset = (uint) SectorOffset(trackNext, sectorNext);
                    trackNext = rdr.ReadByte();
                }
                byte lastUsed = rdr.ReadByte();
                data = rdr.ReadBytes(lastUsed - 2);
                stm.Write(data, 0, data.Length);
                return stm.ToArray();
            }
예제 #16
0
 public bool ReadDirectorySector(LeImageReader rdr, List<ArchiveDirectoryEntry> entries)
 {
     byte nextDirTrack = 0;
     byte nextDirSector = 0;
     for (int i = 0; i < 8; ++i)
     {
         if (i == 0)
         {
             nextDirTrack = rdr.ReadByte();
             nextDirSector = rdr.ReadByte();
         }
         else
         {
             rdr.Seek(2);
         }
         var fileType = (FileType) rdr.ReadByte();
         var fileTrack = rdr.ReadByte();
         var fileSector = rdr.ReadByte();
         var sName = Encoding.ASCII.GetString(rdr.ReadBytes(16))
             .TrimEnd((char) 0xA0);
         var relTrack = rdr.ReadByte();
         var relSector = rdr.ReadByte();
         var rel = rdr.ReadByte();
         rdr.Seek(6);
         var sectorSize = rdr.ReadLeInt16();
         if ((fileType & FileType.FileTypeMask) != FileType.DEL)
         {
             entries.Add(new D64FileEntry(
                 sName,
                 RawImage, 
                 SectorOffset(fileTrack, fileSector), 
                 fileType));
         }
     }
     if (nextDirTrack != 0)
     {
         rdr.Offset = (uint) SectorOffset(nextDirTrack, nextDirSector);
         return true;
     }
     else
     {
         return false;
     }
 }
예제 #17
0
 public List<ArchiveDirectoryEntry> LoadDiskDirectory()
 {
     var entries = new List<ArchiveDirectoryEntry>();
     var rdr = new LeImageReader(RawImage, (uint)SectorOffset(18, 0));
     byte track = rdr.ReadByte();
     if (track == 0)
         return entries;
     byte sector = rdr.ReadByte();
     rdr.Offset = (uint) D64Loader.SectorOffset(track, sector);
     while (ReadDirectorySector(rdr, entries))
         ;
     return entries;
 }
예제 #18
0
 public IEnumerable<Section> ReadSections(LeImageReader rdr, int sections)
 {
     for (int i = 0; i < sections; ++i)
     {
         yield return ReadSection(rdr);
     }
 }
예제 #19
0
        public override RelocationResults Relocate(Address addrLoad)
        {
            ImageReader rdr = new LeImageReader(RawImage, hdrOffset + relocationsOffset);
            ushort segCode = (ushort)(addrLoad.Selector + (ExeImageLoader.CbPsp >> 4));
            ushort dx = 0;
            for (; ; )
            {
                int cx = rdr.ReadLeUInt16();
                if (cx != 0)
                {
                    uint relocBase = ExeImageLoader.CbPsp + dx * 0x10u;
                    do
                    {
                        ushort relocOff = rdr.ReadLeUInt16();
                        ushort seg = imgU.FixupLeUInt16(relocBase + relocOff, segCode);
                        imageMap.AddSegment(Address.SegPtr(seg, 0), seg.ToString("X4"), AccessMode.ReadWriteExecute);
                    } while (--cx != 0);
                }
                if (dx == 0xF000)
                    break;
                dx += (ushort)0x1000U;
            }

            this.cs += segCode;
            imageMap.AddSegment(Address.SegPtr(cs, 0), cs.ToString("X4"), AccessMode.ReadWriteExecute);
            this.ss += segCode;
            var state = arch.CreateProcessorState();
            state.SetRegister(Registers.ds, Constant.Word16(addrLoad.Selector));
            state.SetRegister(Registers.es, Constant.Word16(addrLoad.Selector));
            state.SetRegister(Registers.cs, Constant.Word16(cs));
            state.SetRegister(Registers.ss, Constant.Word16(ss));
            state.SetRegister(Registers.bx, Constant.Word16(0));
            var entryPoints = new List<EntryPoint> 
            {
                new EntryPoint(Address.SegPtr(cs, ip), state)
            };
            return new RelocationResults(entryPoints, new RelocationDictionary());
        }
예제 #20
0
		/// <summary>
		/// Loads the sections
		/// </summary>
		/// <param name="rvaSectionTable"></param>
		/// <returns></returns>
		private SortedDictionary<string, Section> LoadSections(Address addrLoad, uint rvaSectionTable, int sections)
        {
            var sectionMap = new SortedDictionary<string, Section>();
			ImageReader rdr = new LeImageReader(RawImage, rvaSectionTable);
			var section = ReadSection(rdr);
			var sectionMax = section;
			sectionMap[section.Name] = section;
			
			for (int i = 1; i != sections; ++i)
			{
				section = ReadSection(rdr);
				sectionMap[section.Name] = section;
				if (section.VirtualAddress > sectionMax.VirtualAddress)
					sectionMax = section;
                Debug.Print("  Section: {0,10} {1:X8} {2:X8} {3:X8} {4:X8}", section.Name, section.OffsetRawData, section.SizeRawData, section.VirtualAddress, section.VirtualSize);
			}
            return sectionMap;
		}
예제 #21
0
 public uint ReadEntryPointRva()
 {
     ImageReader rdr = new LeImageReader(RawImage, rvaSectionTable);
     for (int i = 0; i < sections; ++i)
     {
         var s = ReadSection(rdr);
         if (s.VirtualAddress <= rvaStartAddress && rvaStartAddress < s.VirtualAddress + s.VirtualSize)
         {
             return (rvaStartAddress - s.VirtualAddress) + s.OffsetRawData;
         }
     }
     return 0;
 }
예제 #22
0
		public void ApplyRelocations(uint rvaReloc, uint size, uint baseOfImage, RelocationDictionary relocations)
		{
			ImageReader rdr = new LeImageReader(RawImage, rvaReloc);
			uint rvaStop = rvaReloc + size;
			while (rdr.Offset < rvaStop)
			{
				// Read fixup block header.

				uint page = rdr.ReadLeUInt32();
				int cbBlock = rdr.ReadLeInt32();
                if (page == 0 || cbBlock == 0)
                    break;
				uint offBlockEnd = (uint)((int)rdr.Offset + cbBlock - 8);
				while (rdr.Offset < offBlockEnd)
				{
					ApplyRelocation(baseOfImage, page, rdr, relocations);
				}
			}
		}
예제 #23
0
        public void Sr_ReadLeInt32_String()
        {
            var rdr = new LeImageReader(new byte[] { 
                0x34, 0x12, 
                0xAB, 0xCD,
                0x48, 0x69, 0x00,
                0x42, 0x79, 0x65, 0x21, 0x00});
            var test = new TestStruct4();
            var sr = new StructureReader(test);
            sr.Read(rdr);

            Assert.AreEqual("Hi", test.sField04);
            Assert.AreEqual("Bye!", test.sFieldnn);
        }
예제 #24
0
		public LoadedImage Unpack(byte [] abC, Address addrLoad)
		{
			// Extract the LZ stuff.

			ImageReader rdr = new LeImageReader(abC, (uint) lzHdrOffset);
			lzIp = rdr.ReadLeUInt16();
			lzCs = rdr.ReadLeUInt16();
			ushort lzSp = rdr.ReadLeUInt16();
			ushort lzSs = rdr.ReadLeUInt16();
			ushort lzcpCompressed = rdr.ReadLeUInt16();
			ushort lzcpDecompressed = rdr.ReadLeUInt16();

			// Find the start of the compressed stream.

			int ifile = lzHdrOffset - (lzcpCompressed << 4);

			// Allocate space for the decompressed goo.

			int cbUncompressed = ((int) lzcpDecompressed + lzcpDecompressed) << 4;
			byte [] abU = new byte[cbUncompressed];

			// Decompress this sorry mess.

			int len;
			int span;
			int p = 0;
			BitStream bits = new BitStream(abC, ifile);
			for (;;)
			{
				if (bits.GetBit() != 0)
				{
					// 1....
					abU[p++] = bits.GetByte();
					continue;
				}

				if (bits.GetBit() == 0) 
				{
					// 00.....
					len = bits.GetBit() << 1;
					len |= bits.GetBit();
					len += 2;
					span = bits.GetByte() | ~0xFF;
				} 
				else
				{
					// 01.....

					span = bits.GetByte();
					len = bits.GetByte();;
					span |= ((len & ~0x07)<<5) | ~0x1FFF;
					len = (len & 0x07) + 2;
					if (len == 2)
					{
						len = bits.GetByte();

						if (len == 0)
							break;    // end mark of compressed load module 

						if (len == 1)
							continue; // segment change 
						else
							++len;
					}
				}
				for( ;len > 0; --len, ++p)
				{
					abU[p] = abU[p+span];
				}
			}

			// Create a new image based on the uncompressed data.

			this.imgLoaded = new LoadedImage(addrLoad, abU);
            this.imageMap = imgLoaded.CreateImageMap();
			return imgLoaded;
		}