Example #1
0
        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());
        }
Example #2
0
        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());
        }
Example #3
0
 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;
 }
Example #4
0
        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);
        }
Example #5
0
        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);
        }
Example #6
0
 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())
     };
 }
Example #7
0
        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);
        }