Update methods inliner code
This commit is contained in:
parent
dd588bf9f8
commit
ffbceae488
|
@ -87,7 +87,10 @@ namespace de4dot.blocks.cflow {
|
||||||
case Code.Ldarg_1:
|
case Code.Ldarg_1:
|
||||||
case Code.Ldarg_2:
|
case Code.Ldarg_2:
|
||||||
case Code.Ldarg_3:
|
case Code.Ldarg_3:
|
||||||
|
case Code.Ldarga:
|
||||||
|
case Code.Ldarga_S:
|
||||||
case Code.Call:
|
case Code.Call:
|
||||||
|
case Code.Newobj:
|
||||||
return inlineOtherMethod(instrIndex, method, instr, index);
|
return inlineOtherMethod(instrIndex, method, instr, index);
|
||||||
|
|
||||||
case Code.Ldc_I4:
|
case Code.Ldc_I4:
|
||||||
|
@ -142,6 +145,8 @@ namespace de4dot.blocks.cflow {
|
||||||
case Code.Ldarg_1:
|
case Code.Ldarg_1:
|
||||||
case Code.Ldarg_2:
|
case Code.Ldarg_2:
|
||||||
case Code.Ldarg_3:
|
case Code.Ldarg_3:
|
||||||
|
case Code.Ldarga:
|
||||||
|
case Code.Ldarga_S:
|
||||||
if (DotNetUtils.getArgIndex(method, instr) != loadIndex)
|
if (DotNetUtils.getArgIndex(method, instr) != loadIndex)
|
||||||
return false;
|
return false;
|
||||||
loadIndex++;
|
loadIndex++;
|
||||||
|
@ -153,30 +158,70 @@ namespace de4dot.blocks.cflow {
|
||||||
if (instr == null || loadIndex != methodArgsCount)
|
if (instr == null || loadIndex != methodArgsCount)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if (instr.OpCode.Code != Code.Call && instr.OpCode.Code != Code.Callvirt)
|
if (instr.OpCode.Code == Code.Call || instr.OpCode.Code == Code.Callvirt) {
|
||||||
return false;
|
var callInstr = instr;
|
||||||
var callInstr = instr;
|
var calledMethod = callInstr.Operand as MethodReference;
|
||||||
var calledMethod = callInstr.Operand as MethodReference;
|
if (calledMethod == null)
|
||||||
if (calledMethod == null)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
if (!isCompatibleType(calledMethod.MethodReturnType.ReturnType, method.MethodReturnType.ReturnType))
|
|
||||||
return false;
|
|
||||||
var methodArgs = DotNetUtils.getArgs(method);
|
|
||||||
var calledMethodArgs = DotNetUtils.getArgs(calledMethod);
|
|
||||||
if (methodArgs.Count != calledMethodArgs.Count)
|
|
||||||
return false;
|
|
||||||
for (int i = 0; i < methodArgs.Count; i++) {
|
|
||||||
if (!isCompatibleType(calledMethodArgs[i], methodArgs[i]))
|
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
if (!isCompatibleType(calledMethod.MethodReturnType.ReturnType, method.MethodReturnType.ReturnType))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
var methodArgs = DotNetUtils.getArgs(method);
|
||||||
|
var calledMethodArgs = DotNetUtils.getArgs(calledMethod);
|
||||||
|
if (methodArgs.Count != calledMethodArgs.Count)
|
||||||
|
return false;
|
||||||
|
for (int i = 0; i < methodArgs.Count; i++) {
|
||||||
|
if (!isCompatibleType(calledMethodArgs[i], methodArgs[i]))
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
instr = DotNetUtils.getInstruction(method.Body.Instructions, ref instrIndex);
|
||||||
|
if (instr == null || instr.OpCode.Code != Code.Ret)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
block.Instructions[patchIndex] = new Instr(DotNetUtils.clone(callInstr));
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
else if (instr.OpCode.Code == Code.Newobj) {
|
||||||
|
var newobjInstr = instr;
|
||||||
|
var ctor = newobjInstr.Operand as MethodReference;
|
||||||
|
if (ctor == null)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (!isCompatibleType(ctor.DeclaringType, method.MethodReturnType.ReturnType))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
var methodArgs = DotNetUtils.getArgs(method);
|
||||||
|
var calledMethodArgs = DotNetUtils.getArgs(ctor);
|
||||||
|
if (methodArgs.Count + 1 != calledMethodArgs.Count)
|
||||||
|
return false;
|
||||||
|
for (int i = 0; i < methodArgs.Count; i++) {
|
||||||
|
if (!isCompatibleType(calledMethodArgs[i + 1], methodArgs[i]))
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
instr = DotNetUtils.getInstruction(method.Body.Instructions, ref instrIndex);
|
||||||
|
if (instr == null || instr.OpCode.Code != Code.Ret)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
block.Instructions[patchIndex] = new Instr(DotNetUtils.clone(newobjInstr));
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
else if (instr.OpCode.Code == Code.Ldfld || instr.OpCode.Code == Code.Ldflda ||
|
||||||
|
instr.OpCode.Code == Code.Ldftn || instr.OpCode.Code == Code.Ldvirtftn) {
|
||||||
|
var ldInstr = instr;
|
||||||
|
instr = DotNetUtils.getInstruction(method.Body.Instructions, ref instrIndex);
|
||||||
|
if (instr == null || instr.OpCode.Code != Code.Ret)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (methodArgsCount != 1)
|
||||||
|
return false;
|
||||||
|
block.Instructions[patchIndex] = new Instr(DotNetUtils.clone(ldInstr));
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
instr = DotNetUtils.getInstruction(method.Body.Instructions, ref instrIndex);
|
return false;
|
||||||
if (instr == null || instr.OpCode.Code != Code.Ret)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
block.Instructions[patchIndex] = new Instr(DotNetUtils.clone(callInstr));
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool isCompatibleType(TypeReference origType, TypeReference newType) {
|
static bool isCompatibleType(TypeReference origType, TypeReference newType) {
|
||||||
|
|
|
@ -34,7 +34,7 @@ namespace de4dot.code.deobfuscators {
|
||||||
foreach (var method in type.Methods) {
|
foreach (var method in type.Methods) {
|
||||||
if (!method.IsStatic)
|
if (!method.IsStatic)
|
||||||
continue;
|
continue;
|
||||||
if (!method.IsAssembly && !method.IsCompilerControlled)
|
if (!method.IsAssembly && !method.IsCompilerControlled && !method.IsPrivate)
|
||||||
continue;
|
continue;
|
||||||
if (method.GenericParameters.Count > 0)
|
if (method.GenericParameters.Count > 0)
|
||||||
continue;
|
continue;
|
||||||
|
@ -78,7 +78,10 @@ namespace de4dot.code.deobfuscators {
|
||||||
case Code.Ldarg_1:
|
case Code.Ldarg_1:
|
||||||
case Code.Ldarg_2:
|
case Code.Ldarg_2:
|
||||||
case Code.Ldarg_3:
|
case Code.Ldarg_3:
|
||||||
|
case Code.Ldarga:
|
||||||
|
case Code.Ldarga_S:
|
||||||
case Code.Call:
|
case Code.Call:
|
||||||
|
case Code.Newobj:
|
||||||
if (!isCallMethod(method))
|
if (!isCallMethod(method))
|
||||||
continue;
|
continue;
|
||||||
break;
|
break;
|
||||||
|
@ -108,6 +111,8 @@ namespace de4dot.code.deobfuscators {
|
||||||
case Code.Ldarg_1:
|
case Code.Ldarg_1:
|
||||||
case Code.Ldarg_2:
|
case Code.Ldarg_2:
|
||||||
case Code.Ldarg_3:
|
case Code.Ldarg_3:
|
||||||
|
case Code.Ldarga:
|
||||||
|
case Code.Ldarga_S:
|
||||||
if (DotNetUtils.getArgIndex(method, instr) != loadIndex)
|
if (DotNetUtils.getArgIndex(method, instr) != loadIndex)
|
||||||
return false;
|
return false;
|
||||||
loadIndex++;
|
loadIndex++;
|
||||||
|
@ -120,8 +125,18 @@ namespace de4dot.code.deobfuscators {
|
||||||
if (i + 1 >= instrs.Count)
|
if (i + 1 >= instrs.Count)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if (instrs[i].OpCode.Code != Code.Call && instrs[i].OpCode.Code != Code.Callvirt)
|
switch (instrs[i].OpCode.Code) {
|
||||||
|
case Code.Call:
|
||||||
|
case Code.Callvirt:
|
||||||
|
case Code.Newobj:
|
||||||
|
case Code.Ldfld:
|
||||||
|
case Code.Ldflda:
|
||||||
|
case Code.Ldftn:
|
||||||
|
case Code.Ldvirtftn:
|
||||||
|
break;
|
||||||
|
default:
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
if (instrs[i + 1].OpCode.Code != Code.Ret)
|
if (instrs[i + 1].OpCode.Code != Code.Ret)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue
Block a user