Inline generic methods that DS added
This commit is contained in:
parent
e2016f6b18
commit
88d1a8ab89
|
@ -104,6 +104,10 @@ namespace de4dot.blocks.cflow {
|
|||
return tryInlineOtherMethod(patchIndex, methodToInline, instr, instrIndex, 0);
|
||||
}
|
||||
|
||||
protected virtual Instruction onAfterLoadArg(MethodDef methodToInline, Instruction instr, ref int instrIndex) {
|
||||
return instr;
|
||||
}
|
||||
|
||||
protected InstructionPatcher tryInlineOtherMethod(int patchIndex, MethodDef methodToInline, Instruction instr, int instrIndex, int popLastArgs) {
|
||||
int loadIndex = 0;
|
||||
int methodArgsCount = DotNetUtils.getArgsCount(methodToInline);
|
||||
|
@ -133,6 +137,7 @@ namespace de4dot.blocks.cflow {
|
|||
return null;
|
||||
loadIndex++;
|
||||
instr = DotNetUtils.getInstruction(methodToInline.Body.Instructions, ref instrIndex);
|
||||
instr = onAfterLoadArg(methodToInline, instr, ref instrIndex);
|
||||
}
|
||||
if (instr == null || loadIndex != methodArgsCount - popLastArgs)
|
||||
return null;
|
||||
|
@ -224,7 +229,7 @@ namespace de4dot.blocks.cflow {
|
|||
return false;
|
||||
for (int i = 0; i < methodArgs.Count; i++) {
|
||||
var methodArg = methodArgs[i];
|
||||
var methodToInlineArg = methodToInlineArgs[i].Type;
|
||||
var methodToInlineArg = getArgType(methodToInline, methodToInlineArgs[i].Type);
|
||||
if (!isCompatibleType(i, methodArg, methodToInlineArg)) {
|
||||
if (i != 0 || !hasImplicitThis)
|
||||
return false;
|
||||
|
@ -236,6 +241,19 @@ namespace de4dot.blocks.cflow {
|
|||
return true;
|
||||
}
|
||||
|
||||
static TypeSig getArgType(MethodDef method, TypeSig arg) {
|
||||
if (arg.GetElementType() != ElementType.MVar)
|
||||
return arg;
|
||||
var mvar = (GenericMVar)arg;
|
||||
foreach (var gp in method.GenericParameters) {
|
||||
if (gp.Number != mvar.Number)
|
||||
continue;
|
||||
foreach (var gpc in gp.GenericParamConstraints)
|
||||
return gpc.Constraint.ToTypeSig();
|
||||
}
|
||||
return arg;
|
||||
}
|
||||
|
||||
protected virtual bool isCompatibleType(int paramIndex, IType origType, IType newType) {
|
||||
return new SigComparer().Equals(origType, newType);
|
||||
}
|
||||
|
|
|
@ -51,8 +51,13 @@ namespace de4dot.code.deobfuscators.DeepSea {
|
|||
|
||||
bool inlineMethod(Instruction callInstr, int instrIndex) {
|
||||
var method = callInstr.Operand as MethodDef;
|
||||
if (method == null)
|
||||
return false;
|
||||
if (method == null) {
|
||||
var ms = callInstr.Operand as MethodSpec;
|
||||
if (ms != null)
|
||||
method = ms.Method as MethodDef;
|
||||
if (method == null)
|
||||
return false;
|
||||
}
|
||||
if (!canInline(method))
|
||||
return false;
|
||||
|
||||
|
@ -69,6 +74,14 @@ namespace de4dot.code.deobfuscators.DeepSea {
|
|||
return true;
|
||||
}
|
||||
|
||||
protected override Instruction onAfterLoadArg(MethodDef methodToInline, Instruction instr, ref int instrIndex) {
|
||||
if (instr.OpCode.Code != Code.Box)
|
||||
return instr;
|
||||
if (methodToInline.MethodSig.GetGenParamCount() == 0)
|
||||
return instr;
|
||||
return DotNetUtils.getInstruction(methodToInline.Body.Instructions, ref instrIndex);
|
||||
}
|
||||
|
||||
bool inlineMethod(MethodDef methodToInline, int instrIndex, int const1, int const2) {
|
||||
this.methodToInline = methodToInline = cflowDeobfuscator.deobfuscate(methodToInline);
|
||||
|
||||
|
@ -271,8 +284,7 @@ done:
|
|||
bool emulateToReturn(int index, Instruction lastInstr) {
|
||||
int pushes, pops;
|
||||
lastInstr.CalculateStackUsage(false, out pushes, out pops);
|
||||
for (int i = 0; i < pops; i++)
|
||||
instructionEmulator.pop();
|
||||
instructionEmulator.pop(pops);
|
||||
|
||||
returnValue = null;
|
||||
if (pushes != 0) {
|
||||
|
@ -300,8 +312,6 @@ done:
|
|||
return false;
|
||||
if (method.Attributes != (MethodAttributes.Assembly | MethodAttributes.Static))
|
||||
return false;
|
||||
if (method.GenericParameters.Count > 0)
|
||||
return false;
|
||||
if (method.Body.ExceptionHandlers.Count > 0)
|
||||
return false;
|
||||
|
||||
|
@ -309,6 +319,14 @@ done:
|
|||
int paramCount = parameters.Count;
|
||||
if (paramCount < 2)
|
||||
return false;
|
||||
|
||||
if (method.GenericParameters.Count > 0) {
|
||||
foreach (var gp in method.GenericParameters) {
|
||||
if (gp.GenericParamConstraints.Count == 0)
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
var param1 = parameters[paramCount - 1];
|
||||
var param2 = parameters[paramCount - 2];
|
||||
if (!isIntType(param1.ElementType))
|
||||
|
|
Loading…
Reference in New Issue
Block a user