public static byte[] AssembleCode(x86CodeGen codeGen, x86Register reg) { var stream = new MemoryStream(); using (var writer = new BinaryWriter(stream)) { /* * mov eax, esp * push ebx * push edi * push esi * sub eax, esp * cmp eax, 24 ; determine the bitness of platform * je n * mov eax, [esp + 4] ; 32 bits => argument in stack * push eax * jmp z * n: push ecx ; 64 bits => argument in register * z: XXX * pop esi * pop edi * pop ebx * pop ret * */ writer.Write(new byte[] { 0x89, 0xe0 }); writer.Write(new byte[] { 0x53 }); writer.Write(new byte[] { 0x57 }); writer.Write(new byte[] { 0x56 }); writer.Write(new byte[] { 0x29, 0xe0 }); writer.Write(new byte[] { 0x83, 0xf8, 0x18 }); writer.Write(new byte[] { 0x74, 0x07 }); writer.Write(new byte[] { 0x8b, 0x44, 0x24, 0x10 }); writer.Write(new byte[] { 0x50 }); writer.Write(new byte[] { 0xeb, 0x01 }); writer.Write(new byte[] { 0x51 }); foreach (x86Instruction i in codeGen.Instructions) writer.Write(i.Assemble()); if (reg != x86Register.EAX) writer.Write(x86Instruction.Create(x86OpCode.MOV, new x86RegisterOperand(x86Register.EAX), new x86RegisterOperand(reg)).Assemble()); writer.Write(new byte[] { 0x5e }); writer.Write(new byte[] { 0x5f }); writer.Write(new byte[] { 0x5b }); writer.Write(new byte[] { 0xc3 }); } return stream.ToArray(); }
private void Compile(RPContext ctx, out Func<int, int> expCompiled, out MethodDef native) { var var = new Variable("{VAR}"); var result = new Variable("{RESULT}"); CorLibTypeSig int32 = ctx.Module.CorLibTypes.Int32; native = new MethodDefUser(ctx.Context.Registry.GetService<INameService>().RandomName(), MethodSig.CreateStatic(int32, int32), MethodAttributes.PinvokeImpl | MethodAttributes.PrivateScope | MethodAttributes.Static); native.ImplAttributes = MethodImplAttributes.Native | MethodImplAttributes.Unmanaged | MethodImplAttributes.PreserveSig; ctx.Module.GlobalType.Methods.Add(native); ctx.Context.Registry.GetService<IMarkerService>().Mark(native); ctx.Context.Registry.GetService<INameService>().SetCanRename(native, false); x86Register? reg; var codeGen = new x86CodeGen(); Expression expression, inverse; do { ctx.DynCipher.GenerateExpressionPair( ctx.Random, new VariableExpression { Variable = var }, new VariableExpression { Variable = result }, ctx.Depth, out expression, out inverse); reg = codeGen.GenerateX86(inverse, (v, r) => { return new[] { x86Instruction.Create(x86OpCode.POP, new x86RegisterOperand(r)) }; }); } while (reg == null); byte[] code = CodeGenUtils.AssembleCode(codeGen, reg.Value); expCompiled = new DMCodeGen(typeof(int), new[] { Tuple.Create("{VAR}", typeof(int)) }) .GenerateCIL(expression) .Compile<Func<int, int>>(); nativeCodes.Add(Tuple.Create(native, code, (MethodBody)null)); if (!addedHandler) { ctx.Context.CurrentModuleWriterListener.OnWriterEvent += InjectNativeCode; addedHandler = true; } }
public void Compile(CFContext ctx) { var var = new Variable("{VAR}"); var result = new Variable("{RESULT}"); CorLibTypeSig int32 = ctx.Method.Module.CorLibTypes.Int32; native = new MethodDefUser(ctx.Context.Registry.GetService<INameService>().RandomName(), MethodSig.CreateStatic(int32, int32), MethodAttributes.PinvokeImpl | MethodAttributes.PrivateScope | MethodAttributes.Static); native.ImplAttributes = MethodImplAttributes.Native | MethodImplAttributes.Unmanaged | MethodImplAttributes.PreserveSig; // Attempt to improve performance --- failed with StackOverflowException... :/ //var suppressAttr = ctx.Method.Module.CorLibTypes.GetTypeRef("System.Security", "SuppressUnmanagedCodeSecurityAttribute").ResolveThrow(); //native.CustomAttributes.Add(new CustomAttribute((MemberRef)ctx.Method.Module.Import(suppressAttr.FindDefaultConstructor()))); //native.HasSecurity = true; ctx.Method.Module.GlobalType.Methods.Add(native); ctx.Context.Registry.GetService<IMarkerService>().Mark(native, ctx.Protection); ctx.Context.Registry.GetService<INameService>().SetCanRename(native, false); x86Register? reg; var codeGen = new x86CodeGen(); do { ctx.DynCipher.GenerateExpressionPair( ctx.Random, new VariableExpression { Variable = var }, new VariableExpression { Variable = result }, ctx.Depth, out expression, out inverse); reg = codeGen.GenerateX86(inverse, (v, r) => { return new[] { x86Instruction.Create(x86OpCode.POP, new x86RegisterOperand(r)) }; }); } while (reg == null); code = CodeGenUtils.AssembleCode(codeGen, reg.Value); expCompiled = new DMCodeGen(typeof(int), new[] { Tuple.Create("{VAR}", typeof(int)) }) .GenerateCIL(expression) .Compile<Func<int, int>>(); ctx.Context.CurrentModuleWriterListener.OnWriterEvent += InjectNativeCode; }