public override void Process() { var builder = new VectorBuilder(scanner, program, new DirectedGraphImpl<object>()); var vector = builder.Build(Table.TableAddress, AddrFrom, State); if (vector.Count == 0) { Address addrNext = Table.TableAddress + Stride.Size; if (program.Image.IsValidAddress(addrNext)) { // Can't determine the size of the table, but surely it has one entry? program.ImageMap.AddItem(addrNext, new ImageMapItem()); } return; } Table.Addresses.AddRange(vector); for (int i = 0; i < vector.Count; ++i) { var st = State.Clone(); if (isCallTable) { scanner.ScanProcedure(vector[i], null, st); } else { scanner.EnqueueJumpTarget(AddrFrom, vector[i], proc, st); } } vectorUses[AddrFrom] = new VectorUse(Table.TableAddress, builder.IndexRegister); program.ImageMap.AddItem(Table.TableAddress + builder.TableByteSize, new ImageMapItem()); }
public override void Process() { var builder = new VectorBuilder(scanner, program, new DirectedGraphImpl <object>()); var vector = builder.Build(Table.TableAddress, AddrFrom, State); if (vector.Count == 0) { Address addrNext = Table.TableAddress + Stride.Size; if (program.Image.IsValidAddress(addrNext)) { // Can't determine the size of the table, but surely it has one entry? program.ImageMap.AddItem(addrNext, new ImageMapItem()); } return; } Table.Addresses.AddRange(vector); for (int i = 0; i < vector.Count; ++i) { var st = State.Clone(); if (Table.IsCallTable) { scanner.ScanProcedure(vector[i], null, st); } else { //$TODO: BlockFromAddress. scanner.EnqueueJumpTarget(AddrFrom, vector[i], proc, st); } } vectorUses[AddrFrom] = new VectorUse(Table.TableAddress, builder.IndexRegister); program.ImageMap.AddItem(Table.TableAddress + builder.TableByteSize, new ImageMapItem()); }
private void BuildAddressTable() { var vectorBuilder = new VectorBuilder(null, dlg.Program, null); var addresses = new List<Address>(); Address addrTable; if (dlg.Program.Platform.TryParseAddress(dlg.JumpTableStartAddress.Text, out addrTable)) { var stride = TableStride(); var state = dlg.Program.Architecture.CreateProcessorState(); state.SetInstructionPointer(dlg.Instruction.Address); addresses = vectorBuilder.BuildTable(addrTable, stride * (int)dlg.EntryCount.Value, null, stride, state); } dlg.Entries.DataSource = addresses; dlg.Entries.SelectedIndex = addresses.Count - 1; }
public void Vb_CreateVector_ModifiesImageMap() { Given_Program(new byte[] { 0x10, 0x00, 0x01, 0x00, 0x11, 0x00, 0x01, 0x00, 0x12, 0x00, 0x01, 0x00, 0xCC, 0xCC, 0xCC, 0xCC, 0xC3, 0xC3, 0xC3, 0xCC, }); var scanner = mr.Stub<IScanner>(); scanner.Stub(s => s.CreateReader(program.Image.BaseAddress)) .Return(program.Image.CreateLeReader(0)); var state = mr.Stub<ProcessorState>(); mr.ReplayAll(); var vb = new VectorBuilder(scanner, program, new DirectedGraphImpl<object>()); var vector = vb.BuildTable(program.Image.BaseAddress, 12, null, 4, state); Assert.AreEqual(3, vector.Count); }
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); }
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.SelectedIndex.ToString()) }; }
public bool ProcessIndirectControlTransfer(Address addrSwitch, RtlTransfer xfer) { var bw = new Backwalker(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? } var idIndex = blockCur.Procedure.Frame.EnsureRegister(bw.Index); VectorBuilder builder = new VectorBuilder(scanner, program, new DirectedGraphImpl <object>()); if (bw.VectorAddress == null) { return(false); } List <Address> vector = builder.BuildAux(bw, addrSwitch, state); if (vector.Count == 0) { var addrNext = bw.VectorAddress + bw.Stride; var rdr = scanner.CreateReader(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); if (this.program.Image.IsValidAddress(addrEntry)) { vector.Add(addrEntry); scanner.Warn(addrSwitch, "Can't determine size of jump vector; probing only one entry."); } else { // Nope, not even that. scanner.Warn(addrSwitch, "No valid entries could be found in jump vector."); } } //$TODO: mark the vector 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); } Expression swExp = idIndex; if (idIndex.Name == "None") { swExp = bw.IndexExpression; } if (swExp == null) { throw new NotImplementedException(); } Emit(new SwitchInstruction(swExp, blockCur.Procedure.ControlGraph.Successors(blockCur).ToArray())); } //vectorUses[wi.addrFrom] = new VectorUse(wi.Address, builder.IndexRegister); program.ImageMap.AddItem(bw.VectorAddress, new ImageMapVectorTable(xfer is RtlCall, vector.ToArray(), builder.TableByteSize)); return(true); }