public void Bwi_CallTerminatingProcedure_StopScanning() { proc = Procedure.Create("proc", Address.Ptr32(0x102000), new Frame(PrimitiveType.Pointer32)); var terminator = Procedure.Create("terminator", Address.Ptr32(0x0001000), new Frame(PrimitiveType.Pointer32)); terminator.Characteristics = new ProcedureCharacteristics { Terminates = true, }; block = proc.AddBlock("the_block"); scanner = mr.StrictMock <IScanner>(); arch.Stub(a => a.PointerType).Return(PrimitiveType.Word32); scanner.Stub(s => s.FindContainingBlock(Arg <Address> .Is.Anything)).Return(block); scanner.Stub(s => s.GetCallSignatureAtAddress(Arg <Address> .Is.Anything)).Return(null); scanner.Stub(s => s.GetImportedProcedure(Arg <Address> .Is.Anything, Arg <Address> .Is.NotNull)).Return(null); scanner.Expect(s => s.ScanProcedure( Arg <Address> .Is.Anything, Arg <string> .Is.Anything, Arg <ProcessorState> .Is.Anything)) .Return(terminator); scanner.Expect(s => s.TerminateBlock(Arg <Block> .Is.NotNull, Arg <Address> .Is.NotNull)); arch.Stub(a => a.FramePointerType).Return(PrimitiveType.Pointer32); scanner.Stub(s => s.GetTrace(null, null, null)).IgnoreArguments().Return(trace); mr.ReplayAll(); trace.Add(m => m.Call(Address.Ptr32(0x00102000), 4)); trace.Add(m => m.SideEffect(new ProcedureConstant(VoidType.Instance, new PseudoProcedure("shouldnt_decompile_this", VoidType.Instance, 0)))); var wi = CreateWorkItem(Address.Ptr32(0x2000), new FakeProcessorState(arch)); wi.Process(); Assert.AreEqual(1, block.Statements.Count, "Should only have rewritten the Call to 'terminator'"); mr.VerifyAll(); }
public void Bwi_CallingAllocaWithNonConstant() { scanner = mr.StrictMock <IScanner>(); arch = new X86ArchitectureFlat32(); program.Platform = new DefaultPlatform(null, arch); var sig = CreateSignature(Registers.esp, Registers.eax); var alloca = new ExternalProcedure("alloca", sig, new ProcedureCharacteristics { IsAlloca = true }); trace.Add(m => m.Call(Address.Ptr32(0x102000), 4)); using (mr.Record()) { scanner.Stub(x => x.FindContainingBlock( Arg <Address> .Is.Anything)).Return(block); scanner.Expect(x => x.GetImportedProcedure( Arg <Address> .Is.Equal(Address.Ptr32(0x102000u)), Arg <Address> .Is.NotNull)).Return(alloca); scanner.Stub(x => x.GetTrace(null, null, null)).IgnoreArguments().Return(trace); } var wi = CreateWorkItem(Address.Ptr32(0x1000), new FakeProcessorState(arch)); wi.Process(); mr.VerifyAll(); Assert.AreEqual(1, block.Statements.Count); Assert.AreEqual("esp = alloca(eax)", block.Statements.Last.ToString()); }
public void Bwi_CallingAllocaWithConstant() { scanner = mr.StrictMock <IScanner>(); program.Architecture = new X86ArchitectureFlat32(); program.Platform = new DefaultPlatform(null, program.Architecture); var sig = CreateSignature(Registers.esp, Registers.eax); var alloca = new ExternalProcedure("alloca", sig); alloca.Characteristics = new ProcedureCharacteristics { IsAlloca = true }; using (mr.Record()) { scanner.Stub(x => x.FindContainingBlock( Arg <Address> .Is.Anything)).Return(block); scanner.Expect(x => x.GetImportedProcedure( Arg <Address> .Matches(a => a.ToLinear() == 0x102000u), Arg <Address> .Is.NotNull)).Return(alloca); scanner.Stub(x => x.GetTrace(null, null, null)).IgnoreArguments().Return(trace); } trace.Add(m => m.Call(Address.Ptr32(0x102000), 4)); var state = new FakeProcessorState(program.Architecture); state.SetRegister(Registers.eax, Constant.Word32(0x0400)); var wi = CreateWorkItem(Address.Ptr32(0x1000), state); wi.Process(); mr.VerifyAll(); Assert.AreEqual(1, block.Statements.Count); Assert.AreEqual("esp = esp - 0x00000400", block.Statements.Last.ToString()); }
//$TODO: big-endian version of this, please. public void BwiX86_IndirectJumpGated() { BuildTest16(delegate(X86Assembler m) { m.And(m.bx, m.Const(3)); m.Add(m.bx, m.bx); m.Jmp(m.MemW(Registers.cs, Registers.bx, "table")); m.Label("table"); m.Dw(0x1234); m.Dw(0x0C00); m.Repeat(30, mm => mm.Dw(0xC3)); //prog.image = new LoadedImage(Address.Ptr32(0x0C00, 0), new byte[100]); //var imageMap = image.CreateImageMap(); scanner.Stub(x => x.TerminateBlock( Arg <Block> .Is.Anything, Arg <Address> .Is.Anything)); scanner.Expect(x => x.CreateReader( Arg <Address> .Is.Anything)).Return(new LeImageReader(new byte[] { 0x34, 0x00, 0x36, 0x00, 0x38, 0x00, 0x3A, 0x00, 0xCC, 0xCC }, 0)); ExpectJumpTarget(0x0C00, 0x0000, "l0C00_0000"); var block1234 = ExpectJumpTarget(0x0C00, 0x0034, "foo1"); var block1236 = ExpectJumpTarget(0x0C00, 0x0036, "foo2"); var block1238 = ExpectJumpTarget(0x0C00, 0x0038, "foo3"); var block123A = ExpectJumpTarget(0x0C00, 0x003A, "foo4"); scanner.Stub(x => x.FindContainingBlock(Arg <Address> .Matches(addr => addr.Offset == 0x0000))).Return(block); scanner.Stub(x => x.FindContainingBlock(Arg <Address> .Matches(addr => addr.Offset == 0x0003))).Return(block); scanner.Stub(x => x.FindContainingBlock(Arg <Address> .Matches(addr => addr.Offset == 0x0005))).Return(block); scanner.Stub(x => x.FindContainingBlock(Arg <Address> .Matches(addr => addr.Offset == 0x0034))).Return(block1234); scanner.Stub(x => x.FindContainingBlock(Arg <Address> .Matches(addr => addr.Offset == 0x0036))).Return(block1236); scanner.Stub(x => x.FindContainingBlock(Arg <Address> .Matches(addr => addr.Offset == 0x0038))).Return(block1238); scanner.Stub(x => x.FindContainingBlock(Arg <Address> .Matches(addr => addr.Offset == 0x003A))).Return(block123A); }); wi.Process(); var sw = new StringWriter(); block.WriteStatements(Console.Out); block.WriteStatements(sw); string sExp = "\tbx = bx & 0x0003" + nl + "\tSZO = cond(bx)" + nl + "\tC = false" + nl + "\tbx = bx + bx" + nl + "\tSCZO = cond(bx)" + nl + "\tswitch (bx) { foo1 foo2 foo3 foo4 }" + nl; Assert.AreEqual(sExp, sw.ToString()); Assert.IsTrue(proc.ControlGraph.Blocks.Contains(block)); }
public void Bwi_StopOnGoto() { trace.Add(m => { m.Assign(r0, m.Word32(3)); m.Goto(Address.Ptr32(0x4000)); }); Block next = block.Procedure.AddBlock("next"); using (mr.Record()) { arch.Stub(x => x.PointerType).Return(PrimitiveType.Pointer32); arch.Stub(x => x.CreateRewriter( Arg <ImageReader> .Is.Anything, Arg <ProcessorState> .Is.Anything, Arg <Frame> .Is.Anything, Arg <IRewriterHost> .Is.Anything)).Return(trace); scanner.Stub(x => x.FindContainingBlock( Arg <Address> .Is.Anything)).Return(block); scanner.Expect(x => x.EnqueueJumpTarget( Arg <Address> .Is.NotNull, Arg <Address> .Is.Anything, Arg <Procedure> .Is.Same(block.Procedure), Arg <ProcessorState> .Is.Anything)).Return(next); scanner.Stub(x => x.TerminateBlock(null, null)).IgnoreArguments(); scanner.Stub(x => x.GetTrace(null, null, null)).IgnoreArguments().Return(trace); } var wi = CreateWorkItem(Address.Ptr32(0x1000), new FakeProcessorState(arch)); wi.Process(); Assert.AreEqual(1, block.Statements.Count); Assert.AreEqual("r0 = 0x00000003", block.Statements[0].ToString()); Assert.AreEqual(1, proc.ControlGraph.Successors(block).Count); var items = new List <Block>(proc.ControlGraph.Successors(block)); Assert.AreSame(next, items[0]); mr.VerifyAll(); }
private Block ExpectJumpTarget(ushort selector, ushort offset, string blockLabel) { var block = new Block(proc, blockLabel); scanner.Expect(x => x.EnqueueJumpTarget( Arg <Address> .Is.NotNull, Arg <Address> .Matches(q => (Niz(q, selector, offset))), Arg <Procedure> .Is.Anything, Arg <ProcessorState> .Is.Anything)).Return(block); return(block); }
private void Expect_ScannerGlobalData(uint addrExp, DataType dtExp) { scanner.Expect(s => s.EnqueueUserGlobalData( Arg <Address> .Is.Equal(Address.Ptr32(addrExp)), Arg <DataType> .Is.Same(dtExp))); }
public void Bwi_CallTerminatingProcedure_StopScanning() { proc = Procedure.Create("proc", Address.Ptr32(0x002000), new Frame(PrimitiveType.Pointer32)); var terminator = Procedure.Create("terminator", Address.Ptr32(0x0001000), new Frame(PrimitiveType.Pointer32)); terminator.Characteristics = new ProcedureCharacteristics { Terminates = true, }; block = proc.AddBlock("the_block"); scanner = mr.StrictMock<IScanner>(); arch.Stub(a => a.PointerType).Return(PrimitiveType.Word32); scanner.Stub(s => s.FindContainingBlock(Arg<Address>.Is.Anything)).Return(block); scanner.Stub(s => s.GetCallSignatureAtAddress(Arg<Address>.Is.Anything)).Return(null); scanner.Stub(s => s.GetImportedProcedure(Arg<Address>.Is.Anything, Arg<Address>.Is.NotNull)).Return(null); scanner.Expect(s => s.ScanProcedure( Arg<Address>.Is.Anything, Arg<string>.Is.Anything, Arg<ProcessorState>.Is.Anything)) .Return(terminator); scanner.Expect(s => s.TerminateBlock(Arg<Block>.Is.NotNull, Arg<Address>.Is.NotNull)); arch.Stub(a => a.FramePointerType).Return(PrimitiveType.Pointer32); scanner.Stub(s => s.GetTrace(null, null, null)).IgnoreArguments().Return(trace); mr.ReplayAll(); trace.Add(m => m.Call(Address.Ptr32(0x0001000), 4)); trace.Add(m => m.SideEffect(new ProcedureConstant(VoidType.Instance, new PseudoProcedure("shouldnt_decompile_this", VoidType.Instance, 0)))); var wi = CreateWorkItem(Address.Ptr32(0x2000), new FakeProcessorState(arch)); wi.ProcessInternal(); Assert.AreEqual(1, block.Statements.Count, "Should only have rewritten the Call to 'terminator'"); mr.VerifyAll(); }
public void Bwi_CallingAllocaWithNonConstant() { scanner = mr.StrictMock<IScanner>(); arch = new IntelArchitecture(ProcessorMode.Protected32); program.Platform = new DefaultPlatform(null, arch); var sig = CreateSignature(Registers.esp, Registers.eax); var alloca = new ExternalProcedure("alloca", sig, new ProcedureCharacteristics { IsAlloca = true }); trace.Add(m => m.Call(Address.Ptr32(0x2000), 4)); using (mr.Record()) { scanner.Stub(x => x.FindContainingBlock( Arg<Address>.Is.Anything)).Return(block); scanner.Expect(x => x.GetImportedProcedure( Arg<Address>.Is.Equal(Address.Ptr32(0x2000u)), Arg<Address>.Is.NotNull)).Return(alloca); scanner.Stub(x => x.GetTrace(null, null, null)).IgnoreArguments().Return(trace); } var wi = CreateWorkItem(Address.Ptr32(0x1000), new FakeProcessorState(arch)); wi.ProcessInternal(); mr.VerifyAll(); Assert.AreEqual(1, block.Statements.Count); Assert.AreEqual("esp = alloca(eax)", block.Statements.Last.ToString()); }
public void Bwi_CallingAllocaWithConstant() { scanner = mr.StrictMock<IScanner>(); prog.Architecture = new IntelArchitecture(ProcessorMode.Protected32); var sig = CreateSignature(Registers.esp, Registers.eax); var alloca = new ExternalProcedure("alloca", sig); alloca.Characteristics = new ProcedureCharacteristics { IsAlloca = true }; using (mr.Record()) { scanner.Stub(x => x.FindContainingBlock( Arg<Address>.Is.Anything)).Return(block); scanner.Expect(x => x.GetImportedProcedure( Arg<Address>.Matches(a => a.ToLinear() == 0x2000u), Arg<Address>.Is.NotNull)).Return(alloca); scanner.Stub(x => x.GetTrace(null, null, null)).IgnoreArguments().Return(trace); } trace.Add(m => m.Call(Address.Ptr32(0x2000), 4)); var state = new FakeProcessorState(prog.Architecture); state.SetRegister(Registers.eax, Constant.Word32(0x0400)); var wi = CreateWorkItem(Address.Ptr32(0x1000), state); wi.ProcessInternal(); mr.VerifyAll(); Assert.AreEqual(1, block.Statements.Count); Assert.AreEqual("esp = esp - 0x00000400", block.Statements.Last.ToString()); }