Merge branch 'master' into confuser
This commit is contained in:
commit
312a2fe063
|
@ -143,6 +143,16 @@ namespace de4dot.blocks.cflow {
|
||||||
if (value.isInt64())
|
if (value.isInt64())
|
||||||
return value;
|
return value;
|
||||||
return Int64Value.createUnknown();
|
return Int64Value.createUnknown();
|
||||||
|
|
||||||
|
case ElementType.R4:
|
||||||
|
if (value.isReal8())
|
||||||
|
return new Real8Value((float)((Real8Value)value).value);
|
||||||
|
return new UnknownValue();
|
||||||
|
|
||||||
|
case ElementType.R8:
|
||||||
|
if (value.isReal8())
|
||||||
|
return value;
|
||||||
|
return new UnknownValue();
|
||||||
}
|
}
|
||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
|
|
|
@ -27,8 +27,9 @@ namespace de4dot.code.deobfuscators {
|
||||||
class ConstantsReader {
|
class ConstantsReader {
|
||||||
protected IInstructions instructions;
|
protected IInstructions instructions;
|
||||||
protected IList<VariableDefinition> locals;
|
protected IList<VariableDefinition> locals;
|
||||||
protected Dictionary<VariableDefinition, int> localsValues32 = new Dictionary<VariableDefinition, int>();
|
protected Dictionary<VariableDefinition, int> localsValuesInt32 = new Dictionary<VariableDefinition, int>();
|
||||||
protected Dictionary<VariableDefinition, long> localsValues64 = new Dictionary<VariableDefinition, long>();
|
protected Dictionary<VariableDefinition, long> localsValuesInt64 = new Dictionary<VariableDefinition, long>();
|
||||||
|
protected Dictionary<VariableDefinition, double> localsValuesDouble = new Dictionary<VariableDefinition, double>();
|
||||||
bool emulateConvInstrs;
|
bool emulateConvInstrs;
|
||||||
|
|
||||||
public interface IInstructions {
|
public interface IInstructions {
|
||||||
|
@ -108,26 +109,30 @@ namespace de4dot.code.deobfuscators {
|
||||||
this.locals = locals;
|
this.locals = locals;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setConstant32(VariableDefinition local, int value) {
|
public void setConstantInt32(VariableDefinition local, int value) {
|
||||||
localsValues32[local] = value;
|
localsValuesInt32[local] = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setConstant32(VariableDefinition local, uint value) {
|
public void setConstantInt32(VariableDefinition local, uint value) {
|
||||||
setConstant32(local, (int)value);
|
setConstantInt32(local, (int)value);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setConstant64(VariableDefinition local, long value) {
|
public void setConstantInt64(VariableDefinition local, long value) {
|
||||||
localsValues64[local] = value;
|
localsValuesInt64[local] = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setConstant64(VariableDefinition local, ulong value) {
|
public void setConstantInt64(VariableDefinition local, ulong value) {
|
||||||
setConstant64(local, (long)value);
|
setConstantInt64(local, (long)value);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setConstantDouble(VariableDefinition local, double value) {
|
||||||
|
localsValuesDouble[local] = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool getNextInt32(ref int index, out int val) {
|
public bool getNextInt32(ref int index, out int val) {
|
||||||
for (; index < instructions.Count; index++) {
|
for (; index < instructions.Count; index++) {
|
||||||
var instr = instructions[index];
|
var instr = instructions[index];
|
||||||
if (!isLoadConstant32(instr))
|
if (!isLoadConstantInt32(instr))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
return getInt32(ref index, out val);
|
return getInt32(ref index, out val);
|
||||||
|
@ -137,30 +142,44 @@ namespace de4dot.code.deobfuscators {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool isLoadConstant32(Instruction instr) {
|
public bool isLoadConstantInt32(Instruction instr) {
|
||||||
if (DotNetUtils.isLdcI4(instr))
|
if (DotNetUtils.isLdcI4(instr))
|
||||||
return true;
|
return true;
|
||||||
if (DotNetUtils.isLdloc(instr)) {
|
if (DotNetUtils.isLdloc(instr)) {
|
||||||
int tmp;
|
int tmp;
|
||||||
return getLocalConstant32(instr, out tmp);
|
return getLocalConstantInt32(instr, out tmp);
|
||||||
}
|
}
|
||||||
if (DotNetUtils.isLdarg(instr)) {
|
if (DotNetUtils.isLdarg(instr)) {
|
||||||
int tmp;
|
int tmp;
|
||||||
return getArgConstant32(instr, out tmp);
|
return getArgConstantInt32(instr, out tmp);
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool isLoadConstant64(Instruction instr) {
|
public bool isLoadConstantInt64(Instruction instr) {
|
||||||
if (instr.OpCode.Code == Code.Ldc_I8)
|
if (instr.OpCode.Code == Code.Ldc_I8)
|
||||||
return true;
|
return true;
|
||||||
if (DotNetUtils.isLdloc(instr)) {
|
if (DotNetUtils.isLdloc(instr)) {
|
||||||
long tmp;
|
long tmp;
|
||||||
return getLocalConstant64(instr, out tmp);
|
return getLocalConstantInt64(instr, out tmp);
|
||||||
}
|
}
|
||||||
if (DotNetUtils.isLdarg(instr)) {
|
if (DotNetUtils.isLdarg(instr)) {
|
||||||
long tmp;
|
long tmp;
|
||||||
return getArgConstant64(instr, out tmp);
|
return getArgConstantInt64(instr, out tmp);
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool isLoadConstantDouble(Instruction instr) {
|
||||||
|
if (instr.OpCode.Code == Code.Ldc_R8)
|
||||||
|
return true;
|
||||||
|
if (DotNetUtils.isLdloc(instr)) {
|
||||||
|
double tmp;
|
||||||
|
return getLocalConstantDouble(instr, out tmp);
|
||||||
|
}
|
||||||
|
if (DotNetUtils.isLdarg(instr)) {
|
||||||
|
double tmp;
|
||||||
|
return getArgConstantDouble(instr, out tmp);
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -246,7 +265,7 @@ namespace de4dot.code.deobfuscators {
|
||||||
case Code.Ldloc_1:
|
case Code.Ldloc_1:
|
||||||
case Code.Ldloc_2:
|
case Code.Ldloc_2:
|
||||||
case Code.Ldloc_3:
|
case Code.Ldloc_3:
|
||||||
if (!getLocalConstant32(instr, out op1))
|
if (!getLocalConstantInt32(instr, out op1))
|
||||||
goto done;
|
goto done;
|
||||||
stack.Push(new ConstantInfo<int>(index, op1));
|
stack.Push(new ConstantInfo<int>(index, op1));
|
||||||
break;
|
break;
|
||||||
|
@ -257,7 +276,7 @@ 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:
|
||||||
if (!getArgConstant32(instr, out op1))
|
if (!getArgConstantInt32(instr, out op1))
|
||||||
goto done;
|
goto done;
|
||||||
stack.Push(new ConstantInfo<int>(index, op1));
|
stack.Push(new ConstantInfo<int>(index, op1));
|
||||||
break;
|
break;
|
||||||
|
@ -429,7 +448,7 @@ done:
|
||||||
case Code.Ldloc_1:
|
case Code.Ldloc_1:
|
||||||
case Code.Ldloc_2:
|
case Code.Ldloc_2:
|
||||||
case Code.Ldloc_3:
|
case Code.Ldloc_3:
|
||||||
if (!getLocalConstant64(instr, out op1))
|
if (!getLocalConstantInt64(instr, out op1))
|
||||||
goto done;
|
goto done;
|
||||||
stack.Push(new ConstantInfo<long>(index, op1));
|
stack.Push(new ConstantInfo<long>(index, op1));
|
||||||
break;
|
break;
|
||||||
|
@ -440,7 +459,7 @@ done:
|
||||||
case Code.Ldarg_1:
|
case Code.Ldarg_1:
|
||||||
case Code.Ldarg_2:
|
case Code.Ldarg_2:
|
||||||
case Code.Ldarg_3:
|
case Code.Ldarg_3:
|
||||||
if (!getArgConstant64(instr, out op1))
|
if (!getArgConstantInt64(instr, out op1))
|
||||||
goto done;
|
goto done;
|
||||||
stack.Push(new ConstantInfo<long>(index, op1));
|
stack.Push(new ConstantInfo<long>(index, op1));
|
||||||
break;
|
break;
|
||||||
|
@ -528,7 +547,122 @@ done:
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected virtual bool getLocalConstant32(Instruction instr, out int value) {
|
public bool getDouble(ref int index, out double val) {
|
||||||
|
val = 0;
|
||||||
|
if (index >= instructions.Count)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
var stack = new Stack<ConstantInfo<double>>();
|
||||||
|
|
||||||
|
double op1;
|
||||||
|
ConstantInfo<double> info1, info2;
|
||||||
|
for (; index < instructions.Count; index++) {
|
||||||
|
var instr = instructions[index];
|
||||||
|
switch (instr.OpCode.Code) {
|
||||||
|
case Code.Conv_R4:
|
||||||
|
if (!emulateConvInstrs || stack.Count < 1)
|
||||||
|
goto done;
|
||||||
|
stack.Push(new ConstantInfo<double>(index, (float)stack.Pop().constant));
|
||||||
|
break;
|
||||||
|
|
||||||
|
case Code.Conv_R8:
|
||||||
|
if (!emulateConvInstrs || stack.Count < 1)
|
||||||
|
goto done;
|
||||||
|
stack.Push(new ConstantInfo<double>(index, stack.Pop().constant));
|
||||||
|
break;
|
||||||
|
|
||||||
|
case Code.Neg:
|
||||||
|
if (stack.Count < 1)
|
||||||
|
goto done;
|
||||||
|
stack.Push(new ConstantInfo<double>(index, -stack.Pop().constant));
|
||||||
|
break;
|
||||||
|
|
||||||
|
case Code.Ldloc:
|
||||||
|
case Code.Ldloc_S:
|
||||||
|
case Code.Ldloc_0:
|
||||||
|
case Code.Ldloc_1:
|
||||||
|
case Code.Ldloc_2:
|
||||||
|
case Code.Ldloc_3:
|
||||||
|
if (!getLocalConstantDouble(instr, out op1))
|
||||||
|
goto done;
|
||||||
|
stack.Push(new ConstantInfo<double>(index, op1));
|
||||||
|
break;
|
||||||
|
|
||||||
|
case Code.Ldarg:
|
||||||
|
case Code.Ldarg_S:
|
||||||
|
case Code.Ldarg_0:
|
||||||
|
case Code.Ldarg_1:
|
||||||
|
case Code.Ldarg_2:
|
||||||
|
case Code.Ldarg_3:
|
||||||
|
if (!getArgConstantDouble(instr, out op1))
|
||||||
|
goto done;
|
||||||
|
stack.Push(new ConstantInfo<double>(index, op1));
|
||||||
|
break;
|
||||||
|
|
||||||
|
case Code.Ldc_R4:
|
||||||
|
stack.Push(new ConstantInfo<double>(index, (float)instr.Operand));
|
||||||
|
break;
|
||||||
|
|
||||||
|
case Code.Ldc_R8:
|
||||||
|
stack.Push(new ConstantInfo<double>(index, (double)instr.Operand));
|
||||||
|
break;
|
||||||
|
|
||||||
|
case Code.Add:
|
||||||
|
if (stack.Count < 2)
|
||||||
|
goto done;
|
||||||
|
info2 = stack.Pop();
|
||||||
|
info1 = stack.Pop();
|
||||||
|
stack.Push(new ConstantInfo<double>(index, info1.constant + info2.constant));
|
||||||
|
break;
|
||||||
|
|
||||||
|
case Code.Sub:
|
||||||
|
if (stack.Count < 2)
|
||||||
|
goto done;
|
||||||
|
info2 = stack.Pop();
|
||||||
|
info1 = stack.Pop();
|
||||||
|
stack.Push(new ConstantInfo<double>(index, info1.constant - info2.constant));
|
||||||
|
break;
|
||||||
|
|
||||||
|
case Code.Mul:
|
||||||
|
if (stack.Count < 2)
|
||||||
|
goto done;
|
||||||
|
info2 = stack.Pop();
|
||||||
|
info1 = stack.Pop();
|
||||||
|
stack.Push(new ConstantInfo<double>(index, info1.constant * info2.constant));
|
||||||
|
break;
|
||||||
|
|
||||||
|
case Code.Div:
|
||||||
|
if (stack.Count < 2)
|
||||||
|
goto done;
|
||||||
|
info2 = stack.Pop();
|
||||||
|
info1 = stack.Pop();
|
||||||
|
stack.Push(new ConstantInfo<double>(index, info1.constant / info2.constant));
|
||||||
|
break;
|
||||||
|
|
||||||
|
case Code.Div_Un:
|
||||||
|
if (stack.Count < 2)
|
||||||
|
goto done;
|
||||||
|
info2 = stack.Pop();
|
||||||
|
info1 = stack.Pop();
|
||||||
|
stack.Push(new ConstantInfo<double>(index, (int)((uint)info1.constant / (uint)info2.constant)));
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
done:
|
||||||
|
if (stack.Count == 0)
|
||||||
|
return false;
|
||||||
|
while (stack.Count > 1)
|
||||||
|
stack.Pop();
|
||||||
|
info1 = stack.Pop();
|
||||||
|
index = info1.index + 1;
|
||||||
|
val = info1.constant;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected virtual bool getLocalConstantInt32(Instruction instr, out int value) {
|
||||||
value = 0;
|
value = 0;
|
||||||
if (locals == null)
|
if (locals == null)
|
||||||
return false;
|
return false;
|
||||||
|
@ -537,15 +671,15 @@ done:
|
||||||
return false;
|
return false;
|
||||||
if (local.VariableType.EType != ElementType.I4 && local.VariableType.EType != ElementType.U4)
|
if (local.VariableType.EType != ElementType.I4 && local.VariableType.EType != ElementType.U4)
|
||||||
return false;
|
return false;
|
||||||
return localsValues32.TryGetValue(local, out value);
|
return localsValuesInt32.TryGetValue(local, out value);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected virtual bool getArgConstant32(Instruction instr, out int value) {
|
protected virtual bool getArgConstantInt32(Instruction instr, out int value) {
|
||||||
value = 0;
|
value = 0;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected virtual bool getLocalConstant64(Instruction instr, out long value) {
|
protected virtual bool getLocalConstantInt64(Instruction instr, out long value) {
|
||||||
value = 0;
|
value = 0;
|
||||||
if (locals == null)
|
if (locals == null)
|
||||||
return false;
|
return false;
|
||||||
|
@ -554,10 +688,27 @@ done:
|
||||||
return false;
|
return false;
|
||||||
if (local.VariableType.EType != ElementType.I8 && local.VariableType.EType != ElementType.U8)
|
if (local.VariableType.EType != ElementType.I8 && local.VariableType.EType != ElementType.U8)
|
||||||
return false;
|
return false;
|
||||||
return localsValues64.TryGetValue(local, out value);
|
return localsValuesInt64.TryGetValue(local, out value);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected virtual bool getArgConstant64(Instruction instr, out long value) {
|
protected virtual bool getArgConstantInt64(Instruction instr, out long value) {
|
||||||
|
value = 0;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected virtual bool getLocalConstantDouble(Instruction instr, out double value) {
|
||||||
|
value = 0;
|
||||||
|
if (locals == null)
|
||||||
|
return false;
|
||||||
|
var local = DotNetUtils.getLocalVar(locals, instr);
|
||||||
|
if (local == null)
|
||||||
|
return false;
|
||||||
|
if (local.VariableType.EType != ElementType.R8)
|
||||||
|
return false;
|
||||||
|
return localsValuesDouble.TryGetValue(local, out value);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected virtual bool getArgConstantDouble(Instruction instr, out double value) {
|
||||||
value = 0;
|
value = 0;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
|
@ -27,12 +27,12 @@ namespace de4dot.code.deobfuscators.DeepSea {
|
||||||
: base(instrs) {
|
: base(instrs) {
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override bool getLocalConstant32(Instruction instr, out int value) {
|
protected override bool getLocalConstantInt32(Instruction instr, out int value) {
|
||||||
value = 0;
|
value = 0;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override bool getArgConstant32(Instruction instr, out int value) {
|
protected override bool getArgConstantInt32(Instruction instr, out int value) {
|
||||||
value = 0;
|
value = 0;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
|
@ -43,12 +43,12 @@ namespace de4dot.code.deobfuscators.Eazfuscator_NET {
|
||||||
var local = DotNetUtils.getLocalVar(locals, stloc);
|
var local = DotNetUtils.getLocalVar(locals, stloc);
|
||||||
if (local == null || local.VariableType.EType != ElementType.I4)
|
if (local == null || local.VariableType.EType != ElementType.I4)
|
||||||
break;
|
break;
|
||||||
localsValues32[local] = value;
|
localsValuesInt32[local] = value;
|
||||||
index++;
|
index++;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (localsValues32.Count != 2)
|
if (localsValuesInt32.Count != 2)
|
||||||
localsValues32.Clear();
|
localsValuesInt32.Clear();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -275,7 +275,7 @@ namespace de4dot.code.deobfuscators.Eazfuscator_NET {
|
||||||
var instrs = stringMethod.Body.Instructions;
|
var instrs = stringMethod.Body.Instructions;
|
||||||
for (int i = 0; i < instrs.Count; i++) {
|
for (int i = 0; i < instrs.Count; i++) {
|
||||||
var ldci4 = instrs[i];
|
var ldci4 = instrs[i];
|
||||||
if (!stringMethodConsts.isLoadConstant32(ldci4))
|
if (!stringMethodConsts.isLoadConstantInt32(ldci4))
|
||||||
continue;
|
continue;
|
||||||
int index = i, tmp;
|
int index = i, tmp;
|
||||||
if (!stringMethodConsts.getInt32(ref index, out tmp) || !isFlagsMask(tmp))
|
if (!stringMethodConsts.getInt32(ref index, out tmp) || !isFlagsMask(tmp))
|
||||||
|
@ -320,7 +320,7 @@ namespace de4dot.code.deobfuscators.Eazfuscator_NET {
|
||||||
var instr = stringMethod.Body.Instructions[i];
|
var instr = stringMethod.Body.Instructions[i];
|
||||||
if (instr.OpCode.FlowControl != FlowControl.Next)
|
if (instr.OpCode.FlowControl != FlowControl.Next)
|
||||||
break;
|
break;
|
||||||
if (!stringMethodConsts.isLoadConstant32(instr))
|
if (!stringMethodConsts.isLoadConstantInt32(instr))
|
||||||
continue;
|
continue;
|
||||||
int index2 = i, value;
|
int index2 = i, value;
|
||||||
if (!stringMethodConsts.getInt32(ref index2, out value))
|
if (!stringMethodConsts.getInt32(ref index2, out value))
|
||||||
|
@ -512,7 +512,7 @@ namespace de4dot.code.deobfuscators.Eazfuscator_NET {
|
||||||
sb.Append((char)(val >> shift));
|
sb.Append((char)(val >> shift));
|
||||||
shift = 0;
|
shift = 0;
|
||||||
}
|
}
|
||||||
if (stringMethodConsts.isLoadConstant32(instr)) {
|
if (stringMethodConsts.isLoadConstantInt32(instr)) {
|
||||||
int tmp;
|
int tmp;
|
||||||
if (!stringMethodConsts.getInt32(ref i, out tmp))
|
if (!stringMethodConsts.getInt32(ref i, out tmp))
|
||||||
break;
|
break;
|
||||||
|
@ -599,7 +599,7 @@ namespace de4dot.code.deobfuscators.Eazfuscator_NET {
|
||||||
if (instr.OpCode.Code != Code.Call && instr.OpCode.FlowControl != FlowControl.Next)
|
if (instr.OpCode.Code != Code.Call && instr.OpCode.FlowControl != FlowControl.Next)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
if (!stringMethodConsts.isLoadConstant32(instr))
|
if (!stringMethodConsts.isLoadConstantInt32(instr))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
int tmp;
|
int tmp;
|
||||||
|
@ -795,7 +795,7 @@ namespace de4dot.code.deobfuscators.Eazfuscator_NET {
|
||||||
var instr = instrs[i];
|
var instr = instrs[i];
|
||||||
if (instr.OpCode.FlowControl != FlowControl.Next)
|
if (instr.OpCode.FlowControl != FlowControl.Next)
|
||||||
return -1;
|
return -1;
|
||||||
if (stringMethodConsts.isLoadConstant32(instr))
|
if (stringMethodConsts.isLoadConstantInt32(instr))
|
||||||
return i;
|
return i;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue
Block a user