public void Scanner_SplitBlock() { scan = CreateScanner(0x100, 0x100); var proc = new Procedure("foo", arch.CreateFrame()); Enqueue(Address.Ptr32(0x101), proc); Enqueue(Address.Ptr32(0x106), proc); Enqueue(Address.Ptr32(0x104), proc); Assert.AreEqual("l00000101", scan.FindContainingBlock(Address.Ptr32(0x103)).Name); Assert.AreEqual("l00000104", scan.FindContainingBlock(Address.Ptr32(0x105)).Name); Assert.AreEqual("l00000106", scan.FindContainingBlock(Address.Ptr32(0x106)).Name); }
public SystemService Build(IProcessorArchitecture arch) { SystemService svc = new SystemService(); svc.Name = Name; svc.SyscallInfo = new SyscallInfo(); svc.SyscallInfo.Vector = Convert.ToInt32(SyscallInfo.Vector, 16); if (SyscallInfo.RegisterValues != null) { svc.SyscallInfo.RegisterValues = new RegValue[SyscallInfo.RegisterValues.Length]; for (int i = 0; i < SyscallInfo.RegisterValues.Length; ++i) { svc.SyscallInfo.RegisterValues[i] = new RegValue { Register = arch.GetRegister(SyscallInfo.RegisterValues[i].Register), Value = Convert.ToInt32(SyscallInfo.RegisterValues[i].Value, 16), }; } } else { svc.SyscallInfo.RegisterValues = new RegValue[0]; } TypeLibraryLoader loader = new TypeLibraryLoader(arch, true); ProcedureSerializer sser = arch.CreateProcedureSerializer(loader, "stdapi"); svc.Signature = sser.Deserialize(Signature, arch.CreateFrame()); svc.Characteristics = Characteristics != null ? Characteristics : DefaultProcedureCharacteristics.Instance; return svc; }
public SystemService Build(IProcessorArchitecture arch) { SystemService svc = new SystemService(); svc.Name = Name; svc.SyscallInfo = new SyscallInfo(); svc.SyscallInfo.Vector = Convert.ToInt32(SyscallInfo.Vector, 16); if (SyscallInfo.RegisterValues != null) { svc.SyscallInfo.RegisterValues = new RegValue[SyscallInfo.RegisterValues.Length]; for (int i = 0; i < SyscallInfo.RegisterValues.Length; ++i) { svc.SyscallInfo.RegisterValues[i] = new RegValue { Register = arch.GetRegister(SyscallInfo.RegisterValues[i].Register), Value = Convert.ToInt32(SyscallInfo.RegisterValues[i].Value, 16), }; } } else { svc.SyscallInfo.RegisterValues = new RegValue[0]; } TypeLibraryLoader loader = new TypeLibraryLoader(arch, true); ProcedureSerializer sser = arch.CreateProcedureSerializer(loader, "stdapi"); svc.Signature = sser.Deserialize(Signature, arch.CreateFrame()); svc.Characteristics = Characteristics != null ? Characteristics : DefaultProcedureCharacteristics.Instance; return(svc); }
//$TODO: http://www.delorie.com/djgpp/doc/rbinter/ix/29.html int 29 for console apps! //$TODO: http://msdn.microsoft.com/en-us/data/dn774154(v=vs.99).aspx public Win32Platform(IServiceProvider services, IProcessorArchitecture arch) : base(services, arch) { int3svc = new SystemService { SyscallInfo = new SyscallInfo { Vector = 3, RegisterValues = new RegValue[0], }, Name = "int3", Signature = new ProcedureSignature(null, new Identifier[0]), Characteristics = new ProcedureCharacteristics(), }; var frame = arch.CreateFrame(); int29svc = new SystemService { SyscallInfo = new SyscallInfo { Vector = 0x29, RegisterValues = new RegValue[0] }, Name = "__fastfail", Signature = new ProcedureSignature( null, frame.EnsureRegister(Registers.ecx)), //$bug what about win64? Characteristics = new ProcedureCharacteristics { Terminates = true } }; }
public void TrfCtx_MergeState_Stack() { var state = new Dictionary <Identifier, (Expression, BitRange)>(); var stateOther = new Dictionary <Identifier, (Expression, BitRange)>(); var procFlow = new ProcedureFlow(null); var proc = Procedure.Create(arch, Address.Ptr32(0x00123400), arch.CreateFrame()); var ssa = new SsaState(proc); var ctx = new TrashedRegisterFinder.Context( ssa, null, state, procFlow); var ctxOther = new TrashedRegisterFinder.Context( ssa, null, state, procFlow); var ebp = new Identifier("ebp", PrimitiveType.Word32, new RegisterStorage("ebp", 5, 0, PrimitiveType.Word32)); var esi = new Identifier("esi", PrimitiveType.Word32, new RegisterStorage("esi", 6, 0, PrimitiveType.Word32)); var edi = new Identifier("edi", PrimitiveType.Word32, new RegisterStorage("edi", 7, 0, PrimitiveType.Word32)); ctx.StackState[-4] = ebp; ctx.StackState[-8] = esi; ctx.StackState[-16] = Constant.Word32(0x42); ctx.StackState[-20] = Constant.Word32(0x42); ctxOther.StackState[-4] = ebp; ctxOther.StackState[-12] = edi; ctxOther.StackState[-16] = Constant.Word32(0x42); ctxOther.StackState[-20] = Constant.Word32(0x4711); ctx.MergeWith(ctxOther); Assert.AreEqual(ebp, ctx.StackState[-4]); Assert.AreEqual(esi, ctx.StackState[-8]); Assert.AreEqual(edi, ctx.StackState[-12]); Assert.AreEqual("0x42<32>", ctx.StackState[-16].ToString()); Assert.IsTrue(ctx.StackState[-20] is InvalidConstant); }
private void Init(IProcessorArchitecture arch, string name, Dictionary<string, Block> blocks) { if (arch == null) throw new ArgumentNullException("arch"); this.Architecture = arch; this.Procedure = new Procedure(name, arch.CreateFrame()); this.blocks = blocks ?? new Dictionary<string, Block>(); this.unresolvedProcedures = new List<ProcUpdater>(); BuildBody(); }
/// <summary> /// Ensure that there is a procedure at address <paramref name="addr"/>. /// </summary> /// <param name="addr">The address at which there must be a procedure after /// this method returns. /// </param> /// <param name="procedureName">The name of the procedure. If null, /// this method will synthesize a new name.</param> /// <returns> /// The procedure, located at address <paramref name="addr"/>. /// </returns> public Procedure EnsureProcedure(IProcessorArchitecture arch, Address addr, string procedureName) { if (this.Procedures.TryGetValue(addr, out Procedure proc)) { return(proc); } bool deduceSignatureFromName = procedureName != null; if (this.ImageSymbols.TryGetValue(addr, out ImageSymbol sym)) { deduceSignatureFromName |= sym.Name != null; var generatedName = procedureName ?? sym.Name ?? this.NamingPolicy.ProcedureName(addr); proc = Procedure.Create(arch, generatedName, addr, arch.CreateFrame()); if (sym.Signature != null) { var sser = this.CreateProcedureSerializer(); proc.Signature = sser.Deserialize(sym.Signature, proc.Frame); deduceSignatureFromName = proc.Signature != null; } } else { var generatedName = procedureName ?? this.NamingPolicy.ProcedureName(addr); proc = Procedure.Create(arch, generatedName, addr, arch.CreateFrame()); } if (deduceSignatureFromName) { var sProc = this.Platform.SignatureFromName(procedureName); if (sProc != null) { var loader = this.CreateTypeLibraryDeserializer(); var exp = loader.LoadExternalProcedure(sProc); proc.Name = exp.Name; proc.Signature = exp.Signature; proc.EnclosingType = exp.EnclosingType; } } this.Procedures.Add(addr, proc); this.CallGraph.AddProcedure(proc); return(proc); }
public bool TryRegisterProcedure(IProcessorArchitecture arch, Address addrProc) { if (!cfg.F.TryAdd(addrProc, addrProc)) { return(false); } var frame = arch.CreateFrame(); cfg.Procedures.TryAdd(addrProc, Procedure.Create(arch, addrProc, frame)); return(true); }
private void Init(IProcessorArchitecture arch, string name, Dictionary <string, Block> blocks) { if (arch == null) { throw new ArgumentNullException("arch"); } this.Architecture = arch; this.Procedure = new Procedure(name, arch.CreateFrame()); this.blocks = blocks ?? new Dictionary <string, Block>(); this.unresolvedProcedures = new List <ProcUpdater>(); BuildBody(); }
/// <summary> /// Tries to determine if the instruction at <paramref name="addr"/> is /// a trampoline instruction. If so, we return a call to the imported /// function directly. /// procedure. /// </summary> /// <remarks> /// A trampoline is a procedure whose only contents is an indirect /// JUMP to a location that contains the address of an imported /// function. Because these trampolines may take on different /// appearances depending on the processor architecture, we have to /// call out to the architecture to assist in matching them. /// </remarks> /// <param name="addr"></param> /// <returns>Null if there was no trampoline.</returns> public ProcedureBase?GetTrampoline(IProcessorArchitecture arch, Address addr) { if (!Program.SegmentMap.IsValidAddress(addr)) { return(null); } var rdr = Program.CreateImageReader(arch, addr); var rw = arch.CreateRewriter(rdr, arch.CreateProcessorState(), arch.CreateFrame(), this); var target = Program.Platform.GetTrampolineDestination(addr, rw.SelectMany(c => c.Instructions), this); return(target); }
//$TODO: http://www.delorie.com/djgpp/doc/rbinter/ix/29.html int 29 for console apps! //$TODO: http://msdn.microsoft.com/en-us/data/dn774154(v=vs.99).aspx //$TODO: we need a Win32Base platform, possibly with a Windows base platform, and make this // x86-specific. public Win32Platform(IServiceProvider services, IProcessorArchitecture arch) : base(services, arch, "win32") { //$REVIEW: should be loaded from configuration file. Heuristics.ProcedurePrologs = new BytePattern[] { new BytePattern { Bytes = new byte[] { 0x55, 0x8B, 0xEC }, Mask = new byte[] { 0xFF, 0xFF, 0xFF } } }; var frame = arch.CreateFrame(); this.services = new Dictionary <int, SystemService> { { 3, new SystemService { SyscallInfo = new SyscallInfo { Vector = 3, RegisterValues = new RegValue[0], }, Name = "int3", Signature = new ProcedureSignature(null, new Identifier[0]), Characteristics = new ProcedureCharacteristics(), } }, { 0x29, new SystemService { SyscallInfo = new SyscallInfo { Vector = 0x29, RegisterValues = new RegValue[0] }, Name = "__fastfail", Signature = new ProcedureSignature( null, frame.EnsureRegister(Registers.ecx)), //$bug what about win64? Characteristics = new ProcedureCharacteristics { Terminates = true } } } }; }
private Procedure Given_ProcedureAt(Address address) { var proc = Procedure.Create(arch, address, arch.CreateFrame()); var block = new Block(proc, Block.GenerateName(address)); program.Procedures.Add(address, proc); program.ImageMap.AddItemWithSize( address, new ImageMapBlock { Address = address, Block = block, Size = 8 }); return(proc); }
//$TODO: http://www.delorie.com/djgpp/doc/rbinter/ix/29.html int 29 for console apps! //$TODO: http://msdn.microsoft.com/en-us/data/dn774154(v=vs.99).aspx //$TODO: we need a Win32Base platform, possibly with a Windows base platform, and make this // x86-specific. public Win32Platform(IServiceProvider services, IProcessorArchitecture arch) : base(services, arch, "win32") { var frame = arch.CreateFrame(); this.services = new Dictionary <int, SystemService> { { 3, new SystemService { SyscallInfo = new SyscallInfo { Vector = 3, RegisterValues = new RegValue[0], }, Name = "int3", Signature = FunctionType.Action(new Identifier[0]), Characteristics = new ProcedureCharacteristics(), } }, { 0x29, new SystemService { SyscallInfo = new SyscallInfo { Vector = 0x29, RegisterValues = new RegValue[0] }, Name = "__fastfail", Signature = new FunctionType( null, frame.EnsureRegister(Registers.ecx)), Characteristics = new ProcedureCharacteristics { Terminates = true } } } }; }
//$TODO: http://www.delorie.com/djgpp/doc/rbinter/ix/29.html int 29 for console apps! //$TODO: http://msdn.microsoft.com/en-us/data/dn774154(v=vs.99).aspx //$TODO: we need a Win32Base platform, possibly with a Windows base platform, and make this // x86-specific. public Win32Platform(IServiceProvider services, IProcessorArchitecture arch) : base(services, arch, "win32") { var frame = arch.CreateFrame(); this.services = new Dictionary<int, SystemService> { { 3, new SystemService { SyscallInfo = new SyscallInfo { Vector = 3, RegisterValues = new RegValue[0], }, Name = "int3", Signature = FunctionType.Action(new Identifier[0]), Characteristics = new ProcedureCharacteristics(), } }, { 0x29, new SystemService { SyscallInfo = new SyscallInfo { Vector = 0x29, RegisterValues = new RegValue[0] }, Name = "__fastfail", Signature = new FunctionType( null, frame.EnsureRegister(Registers.ecx)), Characteristics = new ProcedureCharacteristics { Terminates = true } } } }; }
//$TODO: http://www.delorie.com/djgpp/doc/rbinter/ix/29.html int 29 for console apps! //$TODO: http://msdn.microsoft.com/en-us/data/dn774154(v=vs.99).aspx public Win32Platform(IServiceProvider services, IProcessorArchitecture arch) : base(services, arch) { //$REVIEW: should probably be loaded from configuration. Heuristics.ProcedurePrologs = new BytePattern[] { new BytePattern { Bytes = new byte[]{ 0x55, 0x8B, 0xEC }, Mask = new byte[]{ 0xFF, 0xFF, 0xFF } } }; int3svc = new SystemService { SyscallInfo = new SyscallInfo { Vector = 3, RegisterValues = new RegValue[0], }, Name = "int3", Signature = new ProcedureSignature(null, new Identifier[0]), Characteristics = new ProcedureCharacteristics(), }; var frame = arch.CreateFrame(); int29svc = new SystemService { SyscallInfo = new SyscallInfo { Vector = 0x29, RegisterValues = new RegValue[0] }, Name = "__fastfail", Signature = new ProcedureSignature( null, frame.EnsureRegister(Registers.ecx)), //$bug what about win64? Characteristics = new ProcedureCharacteristics { Terminates = true } }; }
public void VpPhiWithConstants() { Constant c1 = Constant.Word16(0x4711); Constant c2 = Constant.Word16(0x4711); Identifier r1 = Reg16("r1"); Identifier r2 = Reg16("r2"); Identifier r3 = Reg16("r3"); var stm1 = new Statement(1, new Assignment(r1, c1), null); var stm2 = new Statement(2, new Assignment(r2, c2), null); var proc = new Procedure("foo", arch.CreateFrame()); var ssa = new SsaState(proc, null); var r1Sid = ssa.Identifiers.Add(r1, null, null, false); var r2Sid = ssa.Identifiers.Add(r2, null, null, false); r1Sid.DefStatement = stm1; r2Sid.DefStatement = stm2; var vp = new ValuePropagator(arch, ssa, listener); Instruction instr = new PhiAssignment(r3, new PhiFunction(r1.DataType, r1, r2)); instr = instr.Accept(vp); Assert.AreEqual("r3 = 0x4711", instr.ToString()); }
public void LoadProcedure(Procedure_v1 sp) { try { var sser = arch.CreateProcedureSerializer(this, this.defaultConvention); var signature = sser.Deserialize(sp.Signature, arch.CreateFrame()); signaturesByName[sp.Name] = signature; //$BUGBUG: catch dupes? if (sp.Ordinal != Procedure_v1.NoOrdinal) { servicesByOrdinal[sp.Ordinal] = new SystemService { Name = sp.Name, Signature = signature, }; } } catch (Exception ex) { Debug.Print("An error occurred when loading the signature of procedure {0}.", sp.Name); throw new ApplicationException( string.Format("An error occurred when loading the signature of procedure {0}.", sp.Name), ex); } }
/// <summary> /// Guesses the signature of a procedure based on its name. /// </summary> /// <param name="fnName"></param> /// <param name="loader"></param> /// <param name="arch"></param> /// <returns></returns> public static ProcedureSignature SignatureFromName(string fnName, TypeLibraryLoader loader, IProcessorArchitecture arch) { int argBytes; if (fnName[0] == '_') { // Win32 prefixes cdecl and stdcall functions with '_'. Stdcalls will have @<nn> // where <nn> is the number of bytes pushed on the stack. If 0 bytes are pushed // the result is indistinguishable from the corresponding cdecl call, which is OK. int lastAt = fnName.LastIndexOf('@'); if (lastAt < 0) { return(CdeclSignature(fnName.Substring(1), arch)); } string name = fnName.Substring(1, lastAt - 1); if (!Int32.TryParse(fnName.Substring(lastAt + 1), out argBytes)) { return(CdeclSignature(name, arch)); } else { return(StdcallSignature(name, argBytes, arch)); } } else if (fnName[0] == '@') { // Win32 prefixes fastcall functions with '@'. int lastAt = fnName.LastIndexOf('@'); if (lastAt <= 0) { return(CdeclSignature(fnName.Substring(1), arch)); } string name = fnName.Substring(1, lastAt - 1); if (!Int32.TryParse(fnName.Substring(lastAt + 1), out argBytes)) { return(CdeclSignature(name, arch)); } else { return(FastcallSignature(name, argBytes, arch)); } } else if (fnName[0] == '?') { // Microsoft-mangled signatures begin with '?' var pmnp = new MsMangledNameParser(fnName); StructField_v1 field = null; try { field = pmnp.Parse(); } catch (Exception ex) { Debug.Print("*** Error parsing {0}. {1}", fnName, ex.Message); pmnp.ToString(); return(null); } var sproc = field.Type as SerializedSignature; if (sproc != null) { var sser = arch.CreateProcedureSerializer(loader, "__cdecl"); return(sser.Deserialize(sproc, arch.CreateFrame())); //$BUGBUG: catch dupes? } } return(null); }
/// <summary> /// Guesses the signature of a procedure based on its name. /// </summary> /// <param name="fnName"></param> /// <param name="loader"></param> /// <param name="arch"></param> /// <returns></returns> public static ProcedureSignature SignatureFromName(string fnName, TypeLibraryLoader loader, IProcessorArchitecture arch) { int argBytes; if (fnName[0] == '_') { // Win32 prefixes cdecl and stdcall functions with '_'. Stdcalls will have @<nn> // where <nn> is the number of bytes pushed on the stack. If 0 bytes are pushed // the result is indistinguishable from the corresponding cdecl call, which is OK. int lastAt = fnName.LastIndexOf('@'); if (lastAt < 0) return CdeclSignature(fnName.Substring(1), arch); string name = fnName.Substring(1, lastAt - 1); if (!Int32.TryParse(fnName.Substring(lastAt + 1), out argBytes)) return CdeclSignature(name, arch); else return StdcallSignature(name, argBytes, arch); } else if (fnName[0] == '@') { // Win32 prefixes fastcall functions with '@'. int lastAt = fnName.LastIndexOf('@'); if (lastAt <= 0) return CdeclSignature(fnName.Substring(1), arch); string name = fnName.Substring(1, lastAt - 1); if (!Int32.TryParse(fnName.Substring(lastAt + 1), out argBytes)) return CdeclSignature(name, arch); else return FastcallSignature(name, argBytes, arch); } else if (fnName[0] == '?') { // Microsoft-mangled signatures begin with '?' var pmnp = new MsMangledNameParser(fnName); StructField_v1 field = null; try { field = pmnp.Parse(); } catch (Exception ex) { Debug.Print("*** Error parsing {0}. {1}", fnName, ex.Message); pmnp.ToString(); return null; } var sproc = field.Type as SerializedSignature; if (sproc != null) { var sser = arch.CreateProcedureSerializer(loader, "__cdecl"); return sser.Deserialize(sproc, arch.CreateFrame()); //$BUGBUG: catch dupes? } } return null; }