Some updates because of new dnlib version
- Use a GenericParamContext when resolving tokens - IDecrypter.GetMethodBody() method signature got updated - ICustomAttributeType now implements IMethod so we don't need to cast it - MemberRefFinder now scans all SecurityAttributes and MarshalType for types
This commit is contained in:
parent
580cfaf201
commit
282cabed87
|
@ -61,13 +61,13 @@ namespace de4dot.code {
|
|||
return false;
|
||||
}
|
||||
|
||||
public bool GetMethodBody(uint rid, RVA rva, IList<Parameter> parameters, out MethodBody methodBody) {
|
||||
public bool GetMethodBody(uint rid, RVA rva, IList<Parameter> parameters, GenericParamContext gpContext, out MethodBody methodBody) {
|
||||
var dm = GetDumpedMethod(rid);
|
||||
if (dm == null) {
|
||||
methodBody = null;
|
||||
return false;
|
||||
}
|
||||
methodBody = MethodBodyReader.CreateCilBody(module, dm.code, dm.extraSections, parameters, dm.mhFlags, dm.mhMaxStack, dm.mhCodeSize, dm.mhLocalVarSigTok);
|
||||
methodBody = MethodBodyReader.CreateCilBody(module, dm.code, dm.extraSections, parameters, dm.mhFlags, dm.mhMaxStack, dm.mhCodeSize, dm.mhLocalVarSigTok, gpContext);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -232,13 +232,14 @@ namespace de4dot.code.deobfuscators.Agile_NET.vm {
|
|||
if (numLocals < 0)
|
||||
throw new ApplicationException("Invalid number of locals");
|
||||
|
||||
var gpContext = GenericParamContext.Create(cilMethod);
|
||||
for (int i = 0; i < numLocals; i++)
|
||||
locals.Add(new Local(ReadTypeRef(reader)));
|
||||
locals.Add(new Local(ReadTypeRef(reader, gpContext)));
|
||||
|
||||
return locals;
|
||||
}
|
||||
|
||||
TypeSig ReadTypeRef(BinaryReader reader) {
|
||||
TypeSig ReadTypeRef(BinaryReader reader, GenericParamContext gpContext) {
|
||||
var etype = (ElementType)reader.ReadInt32();
|
||||
switch (etype) {
|
||||
case ElementType.Void: return module.CorLibTypes.Void;
|
||||
|
@ -263,12 +264,12 @@ namespace de4dot.code.deobfuscators.Agile_NET.vm {
|
|||
case ElementType.ValueType:
|
||||
case ElementType.Var:
|
||||
case ElementType.MVar:
|
||||
return (module.ResolveToken(reader.ReadUInt32()) as ITypeDefOrRef).ToTypeSig();
|
||||
return (module.ResolveToken(reader.ReadUInt32(), gpContext) as ITypeDefOrRef).ToTypeSig();
|
||||
|
||||
case ElementType.GenericInst:
|
||||
etype = (ElementType)reader.ReadInt32();
|
||||
if (etype == ElementType.ValueType)
|
||||
return (module.ResolveToken(reader.ReadUInt32()) as ITypeDefOrRef).ToTypeSig();
|
||||
return (module.ResolveToken(reader.ReadUInt32(), gpContext) as ITypeDefOrRef).ToTypeSig();
|
||||
// ElementType.Class
|
||||
return module.CorLibTypes.Object;
|
||||
|
||||
|
@ -299,6 +300,7 @@ namespace de4dot.code.deobfuscators.Agile_NET.vm {
|
|||
if (numExceptions < 0)
|
||||
throw new ApplicationException("Invalid number of exception handlers");
|
||||
|
||||
var gpContext = GenericParamContext.Create(cilMethod);
|
||||
for (int i = 0; i < numExceptions; i++) {
|
||||
var eh = new ExceptionHandler((ExceptionHandlerType)reader.ReadInt32());
|
||||
eh.TryStart = GetInstruction(reader.ReadInt32());
|
||||
|
@ -306,7 +308,7 @@ namespace de4dot.code.deobfuscators.Agile_NET.vm {
|
|||
eh.HandlerStart = GetInstruction(reader.ReadInt32());
|
||||
eh.HandlerEnd = GetInstructionEnd(reader.ReadInt32());
|
||||
if (eh.HandlerType == ExceptionHandlerType.Catch)
|
||||
eh.CatchType = module.ResolveToken(reader.ReadUInt32()) as ITypeDefOrRef;
|
||||
eh.CatchType = module.ResolveToken(reader.ReadUInt32(), gpContext) as ITypeDefOrRef;
|
||||
else if (eh.HandlerType == ExceptionHandlerType.Filter)
|
||||
eh.FilterStart = GetInstruction(reader.ReadInt32());
|
||||
|
||||
|
|
|
@ -34,12 +34,13 @@ namespace de4dot.code.deobfuscators.Agile_NET.vm.v1 {
|
|||
}
|
||||
|
||||
protected override List<Instruction> ReadInstructions(MethodDef cilMethod, CsvmMethodData csvmMethod) {
|
||||
var gpContext = GenericParamContext.Create(cilMethod);
|
||||
var reader = new BinaryReader(new MemoryStream(csvmMethod.Instructions));
|
||||
var instrs = new List<Instruction>();
|
||||
uint offset = 0;
|
||||
while (reader.BaseStream.Position < reader.BaseStream.Length) {
|
||||
int vmOpCode = reader.ReadUInt16();
|
||||
var instr = opCodeDetector.Handlers[vmOpCode].Read(reader, module);
|
||||
var instr = opCodeDetector.Handlers[vmOpCode].Read(reader, module, gpContext);
|
||||
instr.Offset = offset;
|
||||
offset += (uint)GetInstructionSize(instr);
|
||||
SetCilToVmIndex(instr, instrs.Count);
|
||||
|
|
|
@ -29,7 +29,7 @@ namespace de4dot.code.deobfuscators.Agile_NET.vm.v1 {
|
|||
public string Name { get; set; }
|
||||
public OpCodeHandlerSigInfo OpCodeHandlerSigInfo { get; set; }
|
||||
public Predicate<UnknownHandlerInfo> Check { get; set; }
|
||||
public Func<BinaryReader, IInstructionOperandResolver, Instruction> Read { get; set; }
|
||||
public Func<BinaryReader, IInstructionOperandResolver, GenericParamContext, Instruction> Read { get; set; }
|
||||
|
||||
public bool Detect(UnknownHandlerInfo info) {
|
||||
var sigInfo = OpCodeHandlerSigInfo;
|
||||
|
@ -68,7 +68,7 @@ namespace de4dot.code.deobfuscators.Agile_NET.vm.v1 {
|
|||
}
|
||||
|
||||
static partial class OpCodeHandlers {
|
||||
static Instruction arithmetic_read(BinaryReader reader, IInstructionOperandResolver resolver) {
|
||||
static Instruction arithmetic_read(BinaryReader reader, IInstructionOperandResolver resolver, GenericParamContext gpContext) {
|
||||
switch (reader.ReadByte()) {
|
||||
case 0: return OpCodes.Add.ToInstruction();
|
||||
case 1: return OpCodes.Add_Ovf.ToInstruction();
|
||||
|
@ -91,22 +91,22 @@ namespace de4dot.code.deobfuscators.Agile_NET.vm.v1 {
|
|||
return DotNetUtils.CallsMethod(info.ExecuteMethod, "System.Type System.Reflection.Module::ResolveType(System.Int32)");
|
||||
}
|
||||
|
||||
static Instruction newarr_read(BinaryReader reader, IInstructionOperandResolver resolver) {
|
||||
return new Instruction(OpCodes.Newarr, resolver.ResolveToken(reader.ReadUInt32()));
|
||||
static Instruction newarr_read(BinaryReader reader, IInstructionOperandResolver resolver, GenericParamContext gpContext) {
|
||||
return new Instruction(OpCodes.Newarr, resolver.ResolveToken(reader.ReadUInt32(), gpContext));
|
||||
}
|
||||
|
||||
static Instruction box_read(BinaryReader reader, IInstructionOperandResolver resolver) {
|
||||
static Instruction box_read(BinaryReader reader, IInstructionOperandResolver resolver, GenericParamContext gpContext) {
|
||||
var instr = new Instruction();
|
||||
switch (reader.ReadByte()) {
|
||||
case 0: instr.OpCode = OpCodes.Box; break;
|
||||
case 1: instr.OpCode = OpCodes.Unbox_Any; break;
|
||||
default: throw new ApplicationException("Invalid opcode");
|
||||
}
|
||||
instr.Operand = resolver.ResolveToken(reader.ReadUInt32());
|
||||
instr.Operand = resolver.ResolveToken(reader.ReadUInt32(), gpContext);
|
||||
return instr;
|
||||
}
|
||||
|
||||
static Instruction call_read(BinaryReader reader, IInstructionOperandResolver resolver) {
|
||||
static Instruction call_read(BinaryReader reader, IInstructionOperandResolver resolver, GenericParamContext gpContext) {
|
||||
var instr = new Instruction();
|
||||
switch (reader.ReadByte()) {
|
||||
case 0: instr.OpCode = OpCodes.Newobj; break;
|
||||
|
@ -114,22 +114,22 @@ namespace de4dot.code.deobfuscators.Agile_NET.vm.v1 {
|
|||
case 2: instr.OpCode = OpCodes.Callvirt; break;
|
||||
default: throw new ApplicationException("Invalid opcode");
|
||||
}
|
||||
instr.Operand = resolver.ResolveToken(reader.ReadUInt32());
|
||||
instr.Operand = resolver.ResolveToken(reader.ReadUInt32(), gpContext);
|
||||
return instr;
|
||||
}
|
||||
|
||||
static Instruction cast_read(BinaryReader reader, IInstructionOperandResolver resolver) {
|
||||
static Instruction cast_read(BinaryReader reader, IInstructionOperandResolver resolver, GenericParamContext gpContext) {
|
||||
var instr = new Instruction();
|
||||
switch (reader.ReadByte()) {
|
||||
case 0: instr.OpCode = OpCodes.Castclass; break;
|
||||
case 1: instr.OpCode = OpCodes.Isinst; break;
|
||||
default: throw new ApplicationException("Invalid opcode");
|
||||
}
|
||||
instr.Operand = resolver.ResolveToken(reader.ReadUInt32());
|
||||
instr.Operand = resolver.ResolveToken(reader.ReadUInt32(), gpContext);
|
||||
return instr;
|
||||
}
|
||||
|
||||
static Instruction compare_read(BinaryReader reader, IInstructionOperandResolver resolver) {
|
||||
static Instruction compare_read(BinaryReader reader, IInstructionOperandResolver resolver, GenericParamContext gpContext) {
|
||||
int type = reader.ReadByte();
|
||||
Instruction instr = new Instruction();
|
||||
switch (type) {
|
||||
|
@ -202,7 +202,7 @@ namespace de4dot.code.deobfuscators.Agile_NET.vm.v1 {
|
|||
new InstructionInfo1 { Type = 11, Second = true, Third = true, OpCode = OpCodes.Conv_Ovf_U_Un },
|
||||
new InstructionInfo1 { Type = 12, Second = true, Third = true, OpCode = OpCodes.Conv_R_Un },
|
||||
};
|
||||
static Instruction convert_read(BinaryReader reader, IInstructionOperandResolver resolver) {
|
||||
static Instruction convert_read(BinaryReader reader, IInstructionOperandResolver resolver, GenericParamContext gpContext) {
|
||||
byte type = reader.ReadByte();
|
||||
bool second = reader.ReadBoolean();
|
||||
bool third = reader.ReadBoolean();
|
||||
|
@ -221,7 +221,7 @@ namespace de4dot.code.deobfuscators.Agile_NET.vm.v1 {
|
|||
return instr;
|
||||
}
|
||||
|
||||
static Instruction dup_read(BinaryReader reader, IInstructionOperandResolver resolver) {
|
||||
static Instruction dup_read(BinaryReader reader, IInstructionOperandResolver resolver, GenericParamContext gpContext) {
|
||||
switch (reader.ReadByte()) {
|
||||
case 0: return OpCodes.Dup.ToInstruction();
|
||||
case 1: return OpCodes.Pop.ToInstruction();
|
||||
|
@ -259,7 +259,7 @@ namespace de4dot.code.deobfuscators.Agile_NET.vm.v1 {
|
|||
new InstructionInfo2 { First = true, Second = true, Value = 28, OpCode = OpCodes.Ldelem_Ref },
|
||||
new InstructionInfo2 { First = true, Second = false, Value = 0, OpCode = OpCodes.Ldelem },
|
||||
};
|
||||
static Instruction ldelem_read(BinaryReader reader, IInstructionOperandResolver resolver) {
|
||||
static Instruction ldelem_read(BinaryReader reader, IInstructionOperandResolver resolver, GenericParamContext gpContext) {
|
||||
Instruction instr = null;
|
||||
bool first = reader.ReadBoolean();
|
||||
bool second = reader.ReadBoolean();
|
||||
|
@ -273,7 +273,7 @@ namespace de4dot.code.deobfuscators.Agile_NET.vm.v1 {
|
|||
if (second)
|
||||
instr = new Instruction(info.OpCode);
|
||||
else
|
||||
instr = new Instruction(info.OpCode, resolver.ResolveToken((uint)value));
|
||||
instr = new Instruction(info.OpCode, resolver.ResolveToken((uint)value, gpContext));
|
||||
break;
|
||||
}
|
||||
if (instr == null)
|
||||
|
@ -286,13 +286,13 @@ namespace de4dot.code.deobfuscators.Agile_NET.vm.v1 {
|
|||
return DotNetUtils.CallsMethod(info.ExecuteMethod, "System.Reflection.MethodInfo System.Type::GetMethod(System.String,System.Reflection.BindingFlags)");
|
||||
}
|
||||
|
||||
static Instruction endfinally_read(BinaryReader reader, IInstructionOperandResolver resolver) {
|
||||
static Instruction endfinally_read(BinaryReader reader, IInstructionOperandResolver resolver, GenericParamContext gpContext) {
|
||||
return OpCodes.Endfinally.ToInstruction();
|
||||
}
|
||||
|
||||
static Instruction ldfld_read(BinaryReader reader, IInstructionOperandResolver resolver) {
|
||||
static Instruction ldfld_read(BinaryReader reader, IInstructionOperandResolver resolver, GenericParamContext gpContext) {
|
||||
byte b = reader.ReadByte();
|
||||
var field = resolver.ResolveToken(reader.ReadUInt32()) as IField;
|
||||
var field = resolver.ResolveToken(reader.ReadUInt32(), gpContext) as IField;
|
||||
switch (b) {
|
||||
case 0: return new Instruction(null, new FieldInstructionOperand(OpCodes.Ldsfld, OpCodes.Ldfld, field));
|
||||
case 1: return new Instruction(null, new FieldInstructionOperand(OpCodes.Ldsflda, OpCodes.Ldflda, field));
|
||||
|
@ -301,11 +301,11 @@ namespace de4dot.code.deobfuscators.Agile_NET.vm.v1 {
|
|||
}
|
||||
}
|
||||
|
||||
static Instruction initobj_read(BinaryReader reader, IInstructionOperandResolver resolver) {
|
||||
return new Instruction(OpCodes.Initobj, resolver.ResolveToken(reader.ReadUInt32()));
|
||||
static Instruction initobj_read(BinaryReader reader, IInstructionOperandResolver resolver, GenericParamContext gpContext) {
|
||||
return new Instruction(OpCodes.Initobj, resolver.ResolveToken(reader.ReadUInt32(), gpContext));
|
||||
}
|
||||
|
||||
static Instruction ldloc_read(BinaryReader reader, IInstructionOperandResolver resolver) {
|
||||
static Instruction ldloc_read(BinaryReader reader, IInstructionOperandResolver resolver, GenericParamContext gpContext) {
|
||||
bool isLdarg = reader.ReadBoolean();
|
||||
ushort index = reader.ReadUInt16();
|
||||
|
||||
|
@ -322,7 +322,7 @@ namespace de4dot.code.deobfuscators.Agile_NET.vm.v1 {
|
|||
return instr;
|
||||
}
|
||||
|
||||
static Instruction ldloca_read(BinaryReader reader, IInstructionOperandResolver resolver) {
|
||||
static Instruction ldloca_read(BinaryReader reader, IInstructionOperandResolver resolver, GenericParamContext gpContext) {
|
||||
Instruction instr = new Instruction();
|
||||
if (reader.ReadBoolean()) {
|
||||
instr.OpCode = OpCodes.Ldarga;
|
||||
|
@ -336,19 +336,19 @@ namespace de4dot.code.deobfuscators.Agile_NET.vm.v1 {
|
|||
return instr;
|
||||
}
|
||||
|
||||
static Instruction ldelema_read(BinaryReader reader, IInstructionOperandResolver resolver) {
|
||||
static Instruction ldelema_read(BinaryReader reader, IInstructionOperandResolver resolver, GenericParamContext gpContext) {
|
||||
return new Instruction(OpCodes.Ldelema, null);
|
||||
}
|
||||
|
||||
static Instruction ldlen_read(BinaryReader reader, IInstructionOperandResolver resolver) {
|
||||
static Instruction ldlen_read(BinaryReader reader, IInstructionOperandResolver resolver, GenericParamContext gpContext) {
|
||||
return OpCodes.Ldlen.ToInstruction();
|
||||
}
|
||||
|
||||
static Instruction ldobj_read(BinaryReader reader, IInstructionOperandResolver resolver) {
|
||||
static Instruction ldobj_read(BinaryReader reader, IInstructionOperandResolver resolver, GenericParamContext gpContext) {
|
||||
return new Instruction(OpCodes.Ldobj, null);
|
||||
}
|
||||
|
||||
static Instruction ldstr_read(BinaryReader reader, IInstructionOperandResolver resolver) {
|
||||
static Instruction ldstr_read(BinaryReader reader, IInstructionOperandResolver resolver, GenericParamContext gpContext) {
|
||||
return OpCodes.Ldstr.ToInstruction(reader.ReadString());
|
||||
}
|
||||
|
||||
|
@ -356,8 +356,8 @@ namespace de4dot.code.deobfuscators.Agile_NET.vm.v1 {
|
|||
return DotNetUtils.CallsMethod(info.ExecuteMethod, "System.Reflection.MemberInfo System.Reflection.Module::ResolveMember(System.Int32)");
|
||||
}
|
||||
|
||||
static Instruction ldtoken_read(BinaryReader reader, IInstructionOperandResolver resolver) {
|
||||
return new Instruction(OpCodes.Ldtoken, resolver.ResolveToken(reader.ReadUInt32()));
|
||||
static Instruction ldtoken_read(BinaryReader reader, IInstructionOperandResolver resolver, GenericParamContext gpContext) {
|
||||
return new Instruction(OpCodes.Ldtoken, resolver.ResolveToken(reader.ReadUInt32(), gpContext));
|
||||
}
|
||||
|
||||
static bool leave_check(UnknownHandlerInfo info) {
|
||||
|
@ -366,12 +366,12 @@ namespace de4dot.code.deobfuscators.Agile_NET.vm.v1 {
|
|||
!DotNetUtils.CallsMethod(info.ExecuteMethod, "System.Reflection.MemberInfo System.Reflection.Module::ResolveMember(System.Int32)");
|
||||
}
|
||||
|
||||
static Instruction leave_read(BinaryReader reader, IInstructionOperandResolver resolver) {
|
||||
static Instruction leave_read(BinaryReader reader, IInstructionOperandResolver resolver, GenericParamContext gpContext) {
|
||||
int displacement = reader.ReadInt32();
|
||||
return new Instruction(OpCodes.Leave, new TargetDisplOperand(displacement));
|
||||
}
|
||||
|
||||
static Instruction ldc_read(BinaryReader reader, IInstructionOperandResolver resolver) {
|
||||
static Instruction ldc_read(BinaryReader reader, IInstructionOperandResolver resolver, GenericParamContext gpContext) {
|
||||
switch ((ElementType)reader.ReadByte()) {
|
||||
case ElementType.I4: return Instruction.CreateLdcI4(reader.ReadInt32());
|
||||
case ElementType.I8: return OpCodes.Ldc_I8.ToInstruction(reader.ReadInt64());
|
||||
|
@ -382,24 +382,24 @@ namespace de4dot.code.deobfuscators.Agile_NET.vm.v1 {
|
|||
}
|
||||
}
|
||||
|
||||
static Instruction ldftn_read(BinaryReader reader, IInstructionOperandResolver resolver) {
|
||||
static Instruction ldftn_read(BinaryReader reader, IInstructionOperandResolver resolver, GenericParamContext gpContext) {
|
||||
byte code = reader.ReadByte();
|
||||
uint token = reader.ReadUInt32();
|
||||
|
||||
switch (code) {
|
||||
case 0:
|
||||
return new Instruction(OpCodes.Ldftn, resolver.ResolveToken(token));
|
||||
return new Instruction(OpCodes.Ldftn, resolver.ResolveToken(token, gpContext));
|
||||
|
||||
case 1:
|
||||
reader.ReadInt32(); // token of newobj .ctor
|
||||
return new Instruction(OpCodes.Ldvirtftn, resolver.ResolveToken(token));
|
||||
return new Instruction(OpCodes.Ldvirtftn, resolver.ResolveToken(token, gpContext));
|
||||
|
||||
default:
|
||||
throw new ApplicationException("Invalid opcode");
|
||||
}
|
||||
}
|
||||
|
||||
static Instruction logical_read(BinaryReader reader, IInstructionOperandResolver resolver) {
|
||||
static Instruction logical_read(BinaryReader reader, IInstructionOperandResolver resolver, GenericParamContext gpContext) {
|
||||
switch (reader.ReadByte()) {
|
||||
case 0: return OpCodes.And.ToInstruction();
|
||||
case 1: return OpCodes.Or.ToInstruction();
|
||||
|
@ -425,7 +425,7 @@ namespace de4dot.code.deobfuscators.Agile_NET.vm.v1 {
|
|||
return false;
|
||||
}
|
||||
|
||||
static Instruction nop_read(BinaryReader reader, IInstructionOperandResolver resolver) {
|
||||
static Instruction nop_read(BinaryReader reader, IInstructionOperandResolver resolver, GenericParamContext gpContext) {
|
||||
return OpCodes.Nop.ToInstruction();
|
||||
}
|
||||
|
||||
|
@ -433,7 +433,7 @@ namespace de4dot.code.deobfuscators.Agile_NET.vm.v1 {
|
|||
return DotNetUtils.CallsMethod(info.ExecuteMethod, "System.Reflection.MethodBase System.Reflection.Module::ResolveMethod(System.Int32)");
|
||||
}
|
||||
|
||||
static Instruction ret_read(BinaryReader reader, IInstructionOperandResolver resolver) {
|
||||
static Instruction ret_read(BinaryReader reader, IInstructionOperandResolver resolver, GenericParamContext gpContext) {
|
||||
reader.ReadInt32(); // token of current method
|
||||
return OpCodes.Ret.ToInstruction();
|
||||
}
|
||||
|
@ -442,11 +442,11 @@ namespace de4dot.code.deobfuscators.Agile_NET.vm.v1 {
|
|||
return info.ExecuteMethod.Body.Variables.Count == 0;
|
||||
}
|
||||
|
||||
static Instruction rethrow_read(BinaryReader reader, IInstructionOperandResolver resolver) {
|
||||
static Instruction rethrow_read(BinaryReader reader, IInstructionOperandResolver resolver, GenericParamContext gpContext) {
|
||||
return OpCodes.Rethrow.ToInstruction();
|
||||
}
|
||||
|
||||
static Instruction stloc_read(BinaryReader reader, IInstructionOperandResolver resolver) {
|
||||
static Instruction stloc_read(BinaryReader reader, IInstructionOperandResolver resolver, GenericParamContext gpContext) {
|
||||
bool isStarg = reader.ReadBoolean();
|
||||
ushort index = reader.ReadUInt16();
|
||||
|
||||
|
@ -464,11 +464,11 @@ namespace de4dot.code.deobfuscators.Agile_NET.vm.v1 {
|
|||
return instr;
|
||||
}
|
||||
|
||||
static Instruction stobj_read(BinaryReader reader, IInstructionOperandResolver resolver) {
|
||||
static Instruction stobj_read(BinaryReader reader, IInstructionOperandResolver resolver, GenericParamContext gpContext) {
|
||||
return new Instruction(OpCodes.Stobj, null);
|
||||
}
|
||||
|
||||
static Instruction switch_read(BinaryReader reader, IInstructionOperandResolver resolver) {
|
||||
static Instruction switch_read(BinaryReader reader, IInstructionOperandResolver resolver, GenericParamContext gpContext) {
|
||||
int numTargets = reader.ReadInt32();
|
||||
int[] targetDispls = new int[numTargets];
|
||||
for (int i = 0; i < targetDispls.Length; i++)
|
||||
|
@ -480,11 +480,11 @@ namespace de4dot.code.deobfuscators.Agile_NET.vm.v1 {
|
|||
return !DotNetUtils.CallsMethod(info.ExecuteMethod, "System.Reflection.MethodInfo System.Type::GetMethod(System.String,System.Reflection.BindingFlags)");
|
||||
}
|
||||
|
||||
static Instruction throw_read(BinaryReader reader, IInstructionOperandResolver resolver) {
|
||||
static Instruction throw_read(BinaryReader reader, IInstructionOperandResolver resolver, GenericParamContext gpContext) {
|
||||
return OpCodes.Throw.ToInstruction();
|
||||
}
|
||||
|
||||
static Instruction neg_read(BinaryReader reader, IInstructionOperandResolver resolver) {
|
||||
static Instruction neg_read(BinaryReader reader, IInstructionOperandResolver resolver, GenericParamContext gpContext) {
|
||||
switch (reader.ReadByte()) {
|
||||
case 0: return OpCodes.Neg.ToInstruction();
|
||||
case 1: return OpCodes.Not.ToInstruction();
|
||||
|
|
|
@ -35,7 +35,8 @@ namespace de4dot.code.deobfuscators.Agile_NET.vm.v2 {
|
|||
protected override List<Instruction> ReadInstructions(MethodDef cilMethod, CsvmMethodData csvmMethod) {
|
||||
var reader = new BinaryReader(new MemoryStream(csvmMethod.Instructions));
|
||||
var instrs = new List<Instruction>();
|
||||
var handlerInfoReader = new OpCodeHandlerInfoReader(module);
|
||||
var gpContext = GenericParamContext.Create(cilMethod);
|
||||
var handlerInfoReader = new OpCodeHandlerInfoReader(module, gpContext);
|
||||
|
||||
int numVmInstrs = reader.ReadInt32();
|
||||
var vmInstrs = new ushort[numVmInstrs];
|
||||
|
|
|
@ -27,9 +27,11 @@ namespace de4dot.code.deobfuscators.Agile_NET.vm.v2 {
|
|||
class OpCodeHandlerInfoReader {
|
||||
IInstructionOperandResolver resolver;
|
||||
Dictionary<HandlerTypeCode, Func<BinaryReader, Instruction>> readHandlers;
|
||||
readonly GenericParamContext gpContext;
|
||||
|
||||
public OpCodeHandlerInfoReader(IInstructionOperandResolver resolver) {
|
||||
public OpCodeHandlerInfoReader(IInstructionOperandResolver resolver, GenericParamContext gpContext) {
|
||||
this.resolver = resolver;
|
||||
this.gpContext = gpContext;
|
||||
this.readHandlers = new Dictionary<HandlerTypeCode, Func<BinaryReader, Instruction>> {
|
||||
{ HandlerTypeCode.Add, Handler_Add },
|
||||
{ HandlerTypeCode.Add_Ovf, Handler_Add_Ovf },
|
||||
|
@ -176,7 +178,7 @@ namespace de4dot.code.deobfuscators.Agile_NET.vm.v2 {
|
|||
}
|
||||
|
||||
Instruction Handler_Box(BinaryReader reader) {
|
||||
var type = resolver.ResolveToken(reader.ReadUInt32()) as ITypeDefOrRef;
|
||||
var type = resolver.ResolveToken(reader.ReadUInt32(), gpContext) as ITypeDefOrRef;
|
||||
return OpCodes.Box.ToInstruction(type);
|
||||
}
|
||||
|
||||
|
@ -193,17 +195,17 @@ namespace de4dot.code.deobfuscators.Agile_NET.vm.v2 {
|
|||
}
|
||||
|
||||
Instruction Handler_Call(BinaryReader reader) {
|
||||
var method = resolver.ResolveToken(reader.ReadUInt32()) as IMethod;
|
||||
var method = resolver.ResolveToken(reader.ReadUInt32(), gpContext) as IMethod;
|
||||
return OpCodes.Call.ToInstruction(method);
|
||||
}
|
||||
|
||||
Instruction Handler_Callvirt(BinaryReader reader) {
|
||||
var method = resolver.ResolveToken(reader.ReadUInt32()) as IMethod;
|
||||
var method = resolver.ResolveToken(reader.ReadUInt32(), gpContext) as IMethod;
|
||||
return OpCodes.Callvirt.ToInstruction(method);
|
||||
}
|
||||
|
||||
Instruction Handler_Castclass(BinaryReader reader) {
|
||||
var type = resolver.ResolveToken(reader.ReadUInt32()) as ITypeDefOrRef;
|
||||
var type = resolver.ResolveToken(reader.ReadUInt32(), gpContext) as ITypeDefOrRef;
|
||||
return OpCodes.Castclass.ToInstruction(type);
|
||||
}
|
||||
|
||||
|
@ -312,12 +314,12 @@ namespace de4dot.code.deobfuscators.Agile_NET.vm.v2 {
|
|||
}
|
||||
|
||||
Instruction Handler_Initobj(BinaryReader reader) {
|
||||
var type = resolver.ResolveToken(reader.ReadUInt32()) as ITypeDefOrRef;
|
||||
var type = resolver.ResolveToken(reader.ReadUInt32(), gpContext) as ITypeDefOrRef;
|
||||
return OpCodes.Initobj.ToInstruction(type);
|
||||
}
|
||||
|
||||
Instruction Handler_Isinst(BinaryReader reader) {
|
||||
var type = resolver.ResolveToken(reader.ReadUInt32()) as ITypeDefOrRef;
|
||||
var type = resolver.ResolveToken(reader.ReadUInt32(), gpContext) as ITypeDefOrRef;
|
||||
return OpCodes.Isinst.ToInstruction(type);
|
||||
}
|
||||
|
||||
|
@ -349,17 +351,17 @@ namespace de4dot.code.deobfuscators.Agile_NET.vm.v2 {
|
|||
}
|
||||
|
||||
Instruction Handler_Ldfld_Ldsfld(BinaryReader reader) {
|
||||
var field = resolver.ResolveToken(reader.ReadUInt32()) as IField;
|
||||
var field = resolver.ResolveToken(reader.ReadUInt32(), gpContext) as IField;
|
||||
return new Instruction(null, new FieldInstructionOperand(OpCodes.Ldsfld, OpCodes.Ldfld, field));
|
||||
}
|
||||
|
||||
Instruction Handler_Ldflda_Ldsflda(BinaryReader reader) {
|
||||
var field = resolver.ResolveToken(reader.ReadUInt32()) as IField;
|
||||
var field = resolver.ResolveToken(reader.ReadUInt32(), gpContext) as IField;
|
||||
return new Instruction(null, new FieldInstructionOperand(OpCodes.Ldsflda, OpCodes.Ldflda, field));
|
||||
}
|
||||
|
||||
Instruction Handler_Ldftn(BinaryReader reader) {
|
||||
var method = resolver.ResolveToken(reader.ReadUInt32()) as IMethod;
|
||||
var method = resolver.ResolveToken(reader.ReadUInt32(), gpContext) as IMethod;
|
||||
return OpCodes.Ldftn.ToInstruction(method);
|
||||
}
|
||||
|
||||
|
@ -384,12 +386,12 @@ namespace de4dot.code.deobfuscators.Agile_NET.vm.v2 {
|
|||
}
|
||||
|
||||
Instruction Handler_Ldtoken(BinaryReader reader) {
|
||||
var member = resolver.ResolveToken(reader.ReadUInt32()) as ITokenOperand;
|
||||
var member = resolver.ResolveToken(reader.ReadUInt32(), gpContext) as ITokenOperand;
|
||||
return OpCodes.Ldtoken.ToInstruction(member);
|
||||
}
|
||||
|
||||
Instruction Handler_Ldvirtftn(BinaryReader reader) {
|
||||
var method = resolver.ResolveToken(reader.ReadUInt32()) as IMethod;
|
||||
var method = resolver.ResolveToken(reader.ReadUInt32(), gpContext) as IMethod;
|
||||
reader.ReadUInt32();
|
||||
return OpCodes.Ldvirtftn.ToInstruction(method);
|
||||
}
|
||||
|
@ -415,12 +417,12 @@ namespace de4dot.code.deobfuscators.Agile_NET.vm.v2 {
|
|||
}
|
||||
|
||||
Instruction Handler_Newarr(BinaryReader reader) {
|
||||
var type = resolver.ResolveToken(reader.ReadUInt32()) as ITypeDefOrRef;
|
||||
var type = resolver.ResolveToken(reader.ReadUInt32(), gpContext) as ITypeDefOrRef;
|
||||
return OpCodes.Newarr.ToInstruction(type);
|
||||
}
|
||||
|
||||
Instruction Handler_Newobj(BinaryReader reader) {
|
||||
var method = resolver.ResolveToken(reader.ReadUInt32()) as IMethod;
|
||||
var method = resolver.ResolveToken(reader.ReadUInt32(), gpContext) as IMethod;
|
||||
return OpCodes.Newobj.ToInstruction(method);
|
||||
}
|
||||
|
||||
|
@ -449,7 +451,7 @@ namespace de4dot.code.deobfuscators.Agile_NET.vm.v2 {
|
|||
}
|
||||
|
||||
Instruction Handler_Ret(BinaryReader reader) {
|
||||
var method = resolver.ResolveToken(reader.ReadUInt32()) as IMethod;
|
||||
var method = resolver.ResolveToken(reader.ReadUInt32(), gpContext) as IMethod;
|
||||
return OpCodes.Ret.ToInstruction();
|
||||
}
|
||||
|
||||
|
@ -478,7 +480,7 @@ namespace de4dot.code.deobfuscators.Agile_NET.vm.v2 {
|
|||
}
|
||||
|
||||
Instruction Handler_Stfld_Stsfld(BinaryReader reader) {
|
||||
var field = resolver.ResolveToken(reader.ReadUInt32()) as IField;
|
||||
var field = resolver.ResolveToken(reader.ReadUInt32(), gpContext) as IField;
|
||||
return new Instruction(null, new FieldInstructionOperand(OpCodes.Stsfld, OpCodes.Stfld, field));
|
||||
}
|
||||
|
||||
|
@ -517,7 +519,7 @@ namespace de4dot.code.deobfuscators.Agile_NET.vm.v2 {
|
|||
}
|
||||
|
||||
Instruction Handler_Unbox_Any(BinaryReader reader) {
|
||||
var type = resolver.ResolveToken(reader.ReadUInt32()) as ITypeDefOrRef;
|
||||
var type = resolver.ResolveToken(reader.ReadUInt32(), gpContext) as ITypeDefOrRef;
|
||||
return OpCodes.Unbox_Any.ToInstruction(type);
|
||||
}
|
||||
|
||||
|
|
|
@ -28,6 +28,7 @@ namespace de4dot.code.deobfuscators.CryptoObfuscator {
|
|||
class MethodBodyReader : MethodBodyReaderBase {
|
||||
ModuleDefMD module;
|
||||
ushort maxStackSize;
|
||||
GenericParamContext gpContext;
|
||||
|
||||
public MethodBodyReader(ModuleDefMD module, IBinaryReader reader)
|
||||
: base(reader) {
|
||||
|
@ -35,6 +36,7 @@ namespace de4dot.code.deobfuscators.CryptoObfuscator {
|
|||
}
|
||||
|
||||
public void Read(MethodDef method) {
|
||||
this.gpContext = GenericParamContext.Create(method);
|
||||
this.parameters = method.Parameters;
|
||||
SetLocals(GetLocals(method));
|
||||
|
||||
|
@ -58,15 +60,15 @@ namespace de4dot.code.deobfuscators.CryptoObfuscator {
|
|||
}
|
||||
|
||||
protected override IField ReadInlineField(Instruction instr) {
|
||||
return module.ResolveToken(reader.ReadUInt32()) as IField;
|
||||
return module.ResolveToken(reader.ReadUInt32(), gpContext) as IField;
|
||||
}
|
||||
|
||||
protected override IMethod ReadInlineMethod(Instruction instr) {
|
||||
return module.ResolveToken(reader.ReadUInt32()) as IMethod;
|
||||
return module.ResolveToken(reader.ReadUInt32(), gpContext) as IMethod;
|
||||
}
|
||||
|
||||
protected override MethodSig ReadInlineSig(Instruction instr) {
|
||||
var sas = module.ResolveStandAloneSig(MDToken.ToRID(reader.ReadUInt32()));
|
||||
var sas = module.ResolveStandAloneSig(MDToken.ToRID(reader.ReadUInt32()), gpContext);
|
||||
return sas == null ? null : sas.MethodSig;
|
||||
}
|
||||
|
||||
|
@ -75,11 +77,11 @@ namespace de4dot.code.deobfuscators.CryptoObfuscator {
|
|||
}
|
||||
|
||||
protected override ITokenOperand ReadInlineTok(Instruction instr) {
|
||||
return module.ResolveToken(reader.ReadUInt32()) as ITokenOperand;
|
||||
return module.ResolveToken(reader.ReadUInt32(), gpContext) as ITokenOperand;
|
||||
}
|
||||
|
||||
protected override ITypeDefOrRef ReadInlineType(Instruction instr) {
|
||||
return module.ResolveToken(reader.ReadUInt32()) as ITypeDefOrRef;
|
||||
return module.ResolveToken(reader.ReadUInt32(), gpContext) as ITypeDefOrRef;
|
||||
}
|
||||
|
||||
void ReadExceptionHandlers(int numExceptionHandlers) {
|
||||
|
@ -101,7 +103,7 @@ namespace de4dot.code.deobfuscators.CryptoObfuscator {
|
|||
|
||||
switch (eh.HandlerType) {
|
||||
case ExceptionHandlerType.Catch:
|
||||
eh.CatchType = module.ResolveToken(reader.ReadUInt32()) as ITypeDefOrRef;
|
||||
eh.CatchType = module.ResolveToken(reader.ReadUInt32(), gpContext) as ITypeDefOrRef;
|
||||
break;
|
||||
|
||||
case ExceptionHandlerType.Filter:
|
||||
|
|
|
@ -32,6 +32,7 @@ namespace de4dot.code.deobfuscators.ILProtector {
|
|||
MethodFlags flags;
|
||||
TypeDef delegateType;
|
||||
bool hasDelegateTypeFlag;
|
||||
GenericParamContext gpContext;
|
||||
|
||||
[Flags]
|
||||
enum MethodFlags {
|
||||
|
@ -76,7 +77,8 @@ namespace de4dot.code.deobfuscators.ILProtector {
|
|||
this.module = module;
|
||||
}
|
||||
|
||||
public void Read() {
|
||||
public void Read(MethodDef method) {
|
||||
gpContext = GenericParamContext.Create(method);
|
||||
flags = (MethodFlags)reader.ReadByte();
|
||||
if (HasDelegateType) {
|
||||
delegateType = Resolve<TypeDef>(ReadTypeToken());
|
||||
|
@ -108,7 +110,7 @@ namespace de4dot.code.deobfuscators.ILProtector {
|
|||
}
|
||||
|
||||
T Resolve<T>(int token) {
|
||||
return (T)module.ResolveToken(token);
|
||||
return (T)module.ResolveToken(token, gpContext);
|
||||
}
|
||||
|
||||
int ReadTypeToken() {
|
||||
|
@ -182,7 +184,7 @@ namespace de4dot.code.deobfuscators.ILProtector {
|
|||
var token = reader.ReadUInt32();
|
||||
if (MDToken.ToTable(token) != Table.StandAloneSig)
|
||||
return null;
|
||||
var sas = module.ResolveStandAloneSig(MDToken.ToRID(token));
|
||||
var sas = module.ResolveStandAloneSig(MDToken.ToRID(token), gpContext);
|
||||
return sas == null ? null : sas.MethodSig;
|
||||
}
|
||||
|
||||
|
|
|
@ -87,7 +87,7 @@ namespace de4dot.code.deobfuscators.ILProtector {
|
|||
methodInfos.Remove(methodId.Value);
|
||||
var methodReader = new MethodReader(module, methodInfo.data, parameters);
|
||||
methodReader.HasDelegateTypeFlag = MethodReaderHasDelegateTypeFlag;
|
||||
methodReader.Read();
|
||||
methodReader.Read(method);
|
||||
|
||||
RestoreMethod(method, methodReader);
|
||||
if (methodReader.DelegateType != null)
|
||||
|
|
|
@ -155,14 +155,15 @@ namespace de4dot.code.deobfuscators {
|
|||
});
|
||||
}
|
||||
|
||||
protected static bool FixProxyCalls(Dictionary<Block, List<RemoveInfo>> removeInfos) {
|
||||
protected bool FixProxyCalls(MethodDef method, Dictionary<Block, List<RemoveInfo>> removeInfos) {
|
||||
var gpContext = GenericParamContext.Create(method);
|
||||
foreach (var block in removeInfos.Keys) {
|
||||
var list = removeInfos[block];
|
||||
var removeIndexes = new List<int>(list.Count);
|
||||
foreach (var info in list) {
|
||||
if (info.IsCall) {
|
||||
var opcode = info.DelegateInfo.callOpcode;
|
||||
var newInstr = Instruction.Create(opcode, info.DelegateInfo.methodRef);
|
||||
var newInstr = Instruction.Create(opcode, ReResolve(info.DelegateInfo.methodRef, gpContext));
|
||||
block.Replace(info.Index, 1, newInstr);
|
||||
}
|
||||
else
|
||||
|
@ -174,6 +175,12 @@ namespace de4dot.code.deobfuscators {
|
|||
|
||||
return removeInfos.Count > 0;
|
||||
}
|
||||
|
||||
IMethod ReResolve(IMethod method, GenericParamContext gpContext) {
|
||||
if (method.IsMethodSpec || method.IsMemberRef)
|
||||
method = module.ResolveToken(method.MDToken.Raw, gpContext) as IMethod ?? method;
|
||||
return method;
|
||||
}
|
||||
}
|
||||
|
||||
// Fixes proxy calls that call the delegate inline in the code, eg.:
|
||||
|
@ -279,7 +286,7 @@ namespace de4dot.code.deobfuscators {
|
|||
}
|
||||
}
|
||||
|
||||
return FixProxyCalls(removeInfos);
|
||||
return FixProxyCalls(blocks.Method, removeInfos);
|
||||
}
|
||||
|
||||
protected virtual BlockInstr FindProxyCall(DelegateInfo di, Block block, int index) {
|
||||
|
@ -481,7 +488,7 @@ namespace de4dot.code.deobfuscators {
|
|||
}
|
||||
}
|
||||
|
||||
return FixProxyCalls(removeInfos);
|
||||
return FixProxyCalls(blocks.Method, removeInfos);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -239,7 +239,7 @@ namespace de4dot.code.deobfuscators.SmartAssembly {
|
|||
|
||||
var attrs2 = new Dictionary<TypeDef, bool>();
|
||||
foreach (var cattr in cattrs) {
|
||||
if (!DotNetUtils.IsMethod(cattr.Constructor as IMethod, "System.Void", "(System.Int32)"))
|
||||
if (!DotNetUtils.IsMethod(cattr.Constructor, "System.Void", "(System.Int32)"))
|
||||
continue;
|
||||
var attrType = cattr.AttributeType as TypeDef;
|
||||
if (attrType == null)
|
||||
|
|
|
@ -76,6 +76,7 @@ namespace de4dot.code.deobfuscators.dotNET_Reactor.v4 {
|
|||
if (type == null)
|
||||
return;
|
||||
|
||||
var gpContext = GenericParamContext.Create(blocks.Method);
|
||||
foreach (var block in blocks.MethodBlocks.GetAllBlocks()) {
|
||||
var instrs = block.Instructions;
|
||||
for (int i = 0; i < instrs.Count - 1; i++) {
|
||||
|
@ -98,7 +99,7 @@ namespace de4dot.code.deobfuscators.dotNET_Reactor.v4 {
|
|||
|
||||
uint token = (uint)(int)instrs[i].Operand;
|
||||
instrs[i] = new Instr(OpCodes.Nop.ToInstruction());
|
||||
instrs[i + 1] = new Instr(new Instruction(OpCodes.Ldtoken, module.ResolveToken(token) as ITokenOperand));
|
||||
instrs[i + 1] = new Instr(new Instruction(OpCodes.Ldtoken, module.ResolveToken(token, gpContext) as ITokenOperand));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -285,9 +285,44 @@ namespace de4dot.code.renamer.asmmodules {
|
|||
void Add(DeclSecurity decl) {
|
||||
if (decl == null)
|
||||
return;
|
||||
Add(decl.SecurityAttributes);
|
||||
Add(decl.CustomAttributes);
|
||||
}
|
||||
|
||||
void Add(IEnumerable<SecurityAttribute> secAttrs) {
|
||||
if (secAttrs == null)
|
||||
return;
|
||||
foreach (var secAttr in secAttrs)
|
||||
Add(secAttr);
|
||||
}
|
||||
|
||||
void Add(SecurityAttribute secAttr) {
|
||||
if (secAttr == null)
|
||||
return;
|
||||
Add(secAttr.AttributeType);
|
||||
Add(secAttr.NamedArguments);
|
||||
}
|
||||
|
||||
void Add(ITypeDefOrRef tdr) {
|
||||
var td = tdr as TypeDef;
|
||||
if (td != null) {
|
||||
Add(td);
|
||||
return;
|
||||
}
|
||||
|
||||
var tr = tdr as TypeRef;
|
||||
if (tr != null) {
|
||||
Add(tr);
|
||||
return;
|
||||
}
|
||||
|
||||
var ts = tdr as TypeSpec;
|
||||
if (ts != null) {
|
||||
Add(ts);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
void Add(IEnumerable<EventDef> eds) {
|
||||
if (eds == null)
|
||||
return;
|
||||
|
@ -326,6 +361,7 @@ namespace de4dot.code.renamer.asmmodules {
|
|||
Add(fd.CustomAttributes);
|
||||
Add(fd.Signature);
|
||||
Add(fd.DeclaringType);
|
||||
Add(fd.MarshalType);
|
||||
}
|
||||
|
||||
void Add(IEnumerable<GenericParam> gps) {
|
||||
|
@ -489,6 +525,22 @@ namespace de4dot.code.renamer.asmmodules {
|
|||
return;
|
||||
Add(pd.DeclaringMethod);
|
||||
Add(pd.CustomAttributes);
|
||||
Add(pd.MarshalType);
|
||||
}
|
||||
|
||||
void Add(MarshalType mt) {
|
||||
if (mt == null)
|
||||
return;
|
||||
|
||||
switch (mt.NativeType) {
|
||||
case NativeType.SafeArray:
|
||||
Add(((SafeArrayMarshalType)mt).UserDefinedSubType);
|
||||
break;
|
||||
|
||||
case NativeType.CustomMarshaler:
|
||||
Add(((CustomMarshalType)mt).CustomMarshaler);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void Add(IEnumerable<MethodOverride> mos) {
|
||||
|
|
Loading…
Reference in New Issue
Block a user