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:
de4dot 2014-05-10 09:00:43 +02:00
parent 580cfaf201
commit 282cabed87
13 changed files with 154 additions and 84 deletions

View File

@ -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;
}
}

View File

@ -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());

View File

@ -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);

View File

@ -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();

View File

@ -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];

View File

@ -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);
}

View File

@ -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:

View File

@ -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;
}

View File

@ -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)

View File

@ -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);
}
}

View File

@ -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)

View File

@ -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));
}
}
}

View File

@ -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) {