public VectorWorkItem(IScanner scanner, Program program, ImageMapVectorTable table, Procedure proc) : base() { this.scanner = scanner; this.program = program; this.Table = table; this.proc = proc; this.vectorUses = new Dictionary <Address, VectorUse>(); }
public UserIndirectJump GetResults() { var vb = new VectorBuilder(dlg.Services, dlg.Program, new DirectedGraphImpl <object>()); var stride = 4; //$TODO: get from dialog var entries = vb.BuildTable(dlg.VectorAddress, stride * (int)dlg.EntryCount.Value, null, stride, null); var table = new ImageMapVectorTable(dlg.VectorAddress, entries.ToArray(), 0); return(new UserIndirectJump { Address = dlg.Instruction.Address, Table = table, IndexRegister = dlg.Program.Architecture.GetRegister(dlg.IndexRegister.SelectedValue.ToString()) }); }
public void EnqueueVectorTable(Address addrFrom, Address addrTable, PrimitiveType elemSize, ushort segBase, bool calltable, Procedure proc, ProcessorState state) { ImageMapVectorTable table; if (vectors.TryGetValue(addrTable, out table)) { return; } table = new ImageMapVectorTable(addrTable, calltable); var wi = new VectorWorkItem(this, program, table, proc); wi.State = state.Clone(); wi.Stride = elemSize; wi.SegBase = segBase; wi.Table = table; wi.AddrFrom = addrFrom; imageMap.AddItem(addrTable, table); vectors[addrTable] = table; queue.Enqueue(PriorityVector, wi); }
public void SudSaveProject() { Given_Architecture(); Given_TestOS_Platform(); var eax = new RegisterStorage("eax", 0, 0, PrimitiveType.Word32); var ecx = new RegisterStorage("ecx", 1, 0, PrimitiveType.Word32); var jumpTable = new ImageMapVectorTable( Address.SegPtr(0x1000, 0x400), new Address[] { Address.SegPtr(0x1000, 0x500), Address.SegPtr(0x1000, 0x513), Address.SegPtr(0x1000, 0x5BA), }, 0); Project project = new Project { Programs = { new Program { Architecture = arch.Object, Platform = platform.Object, SegmentMap = new SegmentMap(Address.SegPtr(0x1000, 0)), //, new byte[100]), DisassemblyDirectory = "", User = new UserData { Loader = "CustomLoader", ExtractResources = true, Procedures = { { Address.SegPtr(0x1000, 0x10), new UserProcedure(Address.SegPtr(0x1000, 0x10), "foo") { Signature = new SerializedSignature { ReturnValue = new Argument_v1{ Kind = new Register_v1("eax") }, Arguments = new Argument_v1[] { new Argument_v1 { Kind = new StackVariable_v1(), Type = new PrimitiveType_v1(Domain.SignedInt, 4) }, new Argument_v1 { Kind = new StackVariable_v1(), Type = new PrimitiveType_v1(Domain.SignedInt, 4) } } } } } }, Globals = { { Address.SegPtr(0x2000, 0), new UserGlobal(Address.SegPtr(0x2000, 0), "g_20000", new StringType_v2{ Termination = StringType_v2.ZeroTermination, CharType = new PrimitiveType_v1 { Domain = Domain.Character, ByteSize = 1 } }) } }, Calls = { { Address.SegPtr(0x1000, 0x0320), new UserCallData { Address = Address.SegPtr(0x1000, 0x0320), NoReturn = true, } } }, RegisterValues = { { Address.Ptr32(0x012310), new List <UserRegisterValue> { new UserRegisterValue(eax, Constant.Word32(0x01231)), new UserRegisterValue(ecx, Constant.Word32(0x42424711)), } } }, IndirectJumps = { { Address.SegPtr(0x1000, 0x380), new UserIndirectJump { Address = jumpTable.Address, Table = jumpTable, IndexRegister = new RegisterStorage("R1", 1, 0, PrimitiveType.Word32) } } }, JumpTables = { { jumpTable.Address, jumpTable } }, OutputFilePolicy = Program.SegmentFilePolicy, } } } }; using (FileUnitTester fut = new FileUnitTester("Core/SudSaveProject.txt")) { FilteringXmlWriter writer = new FilteringXmlWriter(fut.TextWriter); writer.Formatting = System.Xml.Formatting.Indented; XmlSerializer ser = SerializedLibrary.CreateSerializer_v5(typeof(Project_v5)); Project_v5 ud = new ProjectSaver(sc).Serialize("/var/foo/foo.proj", project); ser.Serialize(writer, ud); fut.AssertFilesEqual(); } }
public void SudSaveProject() { Given_Architecture(); Given_TestOS_Platform(); var eax = new RegisterStorage("eax", 0, 0, PrimitiveType.Word32); var ecx = new RegisterStorage("ecx", 1, 0, PrimitiveType.Word32); var jumpTable = new ImageMapVectorTable( Address.SegPtr(0x1000, 0x400), new Address[] { Address.SegPtr(0x1000, 0x500), Address.SegPtr(0x1000, 0x513), Address.SegPtr(0x1000, 0x5BA), }, 0); Project project = new Project { Programs = { new Program { Architecture = arch, Platform = platform, SegmentMap = new SegmentMap(Address.SegPtr(0x1000, 0)), //, new byte[100]), DisassemblyFilename = "foo.asm", IntermediateFilename = "foo.cod", User = new UserData { Procedures = { { Address.SegPtr(0x1000, 0x10), new Procedure_v1 { Name = "foo", Signature = new SerializedSignature { ReturnValue = new Argument_v1{ Kind = new Register_v1("eax") }, Arguments = new Argument_v1[] { new Argument_v1 { Kind = new StackVariable_v1(), Type = new PrimitiveType_v1(Domain.SignedInt, 4) }, new Argument_v1 { Kind = new StackVariable_v1(), Type = new PrimitiveType_v1(Domain.SignedInt, 4) } } } } } }, Globals = { { Address.SegPtr(0x2000, 0), new GlobalDataItem_v2 { Address = Address.SegPtr(0x2000, 0).ToString(), DataType = new StringType_v2{ Termination = StringType_v2.ZeroTermination, CharType = new PrimitiveType_v1 { Domain = Domain.Character, ByteSize = 1 } } } } }, Calls = { { Address.SegPtr(0x1000, 0x0320), new UserCallData { Address = Address.SegPtr(0x1000, 0x0320), NoReturn = true, } } }, RegisterValues = { { Address.Ptr32(0x012310), new List <UserRegisterValue> { new UserRegisterValue { Register = eax, Value = Constant.Word32(0x01231) }, new UserRegisterValue { Register = ecx, Value = Constant.Word32(0x42424711) }, } } }, IndirectJumps = { { Address.SegPtr(0x1000, 0x380), new UserIndirectJump { Address = jumpTable.Address, Table = jumpTable, IndexRegister = new RegisterStorage("R1", 1, 0, PrimitiveType.Word32) } } }, JumpTables = { { jumpTable.Address, jumpTable } } } } } }; mr.ReplayAll(); using (FileUnitTester fut = new FileUnitTester("Core/SudSaveProject.txt")) { FilteringXmlWriter writer = new FilteringXmlWriter(fut.TextWriter); writer.Formatting = System.Xml.Formatting.Indented; XmlSerializer ser = SerializedLibrary.CreateSerializer_v4(typeof(Project_v4)); Project_v4 ud = new ProjectSaver(sc).Serialize("/var/foo/foo.proj", project); ser.Serialize(writer, ud); fut.AssertFilesEqual(); } }
public bool ProcessIndirectControlTransfer(Address addrSwitch, RtlTransfer xfer) { List <Address> vector; ImageMapVectorTable imgVector; Expression swExp; UserIndirectJump indJump; var listener = scanner.Services.RequireService <DecompilerEventListener>(); if (program.User.IndirectJumps.TryGetValue(addrSwitch, out indJump)) { vector = indJump.Table.Addresses; swExp = this.frame.EnsureIdentifier(indJump.IndexRegister); imgVector = indJump.Table; } else { var bw = new Backwalker <Block, Instruction>(new BackwalkerHost(this), xfer, eval); if (!bw.CanBackwalk()) { return(false); } var bwops = bw.BackWalk(blockCur); if (bwops == null || bwops.Count == 0) { return(false); //$REVIEW: warn? } Identifier idIndex = bw.Index != null ? blockCur.Procedure.Frame.EnsureRegister(bw.Index) : null; VectorBuilder builder = new VectorBuilder(scanner.Services, program, new DirectedGraphImpl <object>()); if (bw.VectorAddress == null) { return(false); } vector = builder.BuildAux(bw, addrSwitch, state); if (vector.Count == 0) { var rdr = program.CreateImageReader(bw.VectorAddress); if (!rdr.IsValid) { return(false); } // Can't determine the size of the table, but surely it has one entry? var addrEntry = arch.ReadCodeAddress(bw.Stride, rdr, state); string msg; if (this.program.SegmentMap.IsValidAddress(addrEntry)) { vector.Add(addrEntry); msg = "Can't determine size of jump vector; probing only one entry."; } else { // Nope, not even that. msg = "No valid entries could be found in jump vector."; } var nav = listener.CreateJumpTableNavigator(program, addrSwitch, bw.VectorAddress, bw.Stride); listener.Warn(nav, msg); if (vector.Count == 0) { return(false); } } imgVector = new ImageMapVectorTable( bw.VectorAddress, vector.ToArray(), builder.TableByteSize); swExp = idIndex; if (idIndex == null || idIndex.Name == "None") { swExp = bw.IndexExpression; } } ScanVectorTargets(xfer, vector); if (xfer is RtlGoto) { var blockSource = scanner.FindContainingBlock(ric.Address); blockCur = blockSource; foreach (Address addr in vector) { var dest = scanner.FindContainingBlock(addr); Debug.Assert(dest != null, "The block at address " + addr + "should have been enqueued."); blockSource.Procedure.ControlGraph.AddEdge(blockSource, dest); } if (swExp == null) { scanner.Warn(addrSwitch, "Unable to determine index variable for indirect jump."); Emit(new ReturnInstruction()); blockSource.Procedure.ControlGraph.AddEdge( blockSource, blockSource.Procedure.ExitBlock); } else { Emit(new SwitchInstruction(swExp, blockCur.Procedure.ControlGraph.Successors(blockCur).ToArray())); } } if (imgVector.Size > 0) { program.ImageMap.AddItemWithSize(imgVector.Address, imgVector); } else { program.ImageMap.AddItem(imgVector.Address, imgVector); } return(true); }