Merge branch 'master' into confuser

This commit is contained in:
de4dot 2012-07-31 01:15:52 +02:00
commit 312a2fe063
5 changed files with 198 additions and 37 deletions

View File

@ -143,6 +143,16 @@ namespace de4dot.blocks.cflow {
if (value.isInt64())
return value;
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;
}

View File

@ -27,8 +27,9 @@ namespace de4dot.code.deobfuscators {
class ConstantsReader {
protected IInstructions instructions;
protected IList<VariableDefinition> locals;
protected Dictionary<VariableDefinition, int> localsValues32 = new Dictionary<VariableDefinition, int>();
protected Dictionary<VariableDefinition, long> localsValues64 = new Dictionary<VariableDefinition, long>();
protected Dictionary<VariableDefinition, int> localsValuesInt32 = new Dictionary<VariableDefinition, int>();
protected Dictionary<VariableDefinition, long> localsValuesInt64 = new Dictionary<VariableDefinition, long>();
protected Dictionary<VariableDefinition, double> localsValuesDouble = new Dictionary<VariableDefinition, double>();
bool emulateConvInstrs;
public interface IInstructions {
@ -108,26 +109,30 @@ namespace de4dot.code.deobfuscators {
this.locals = locals;
}
public void setConstant32(VariableDefinition local, int value) {
localsValues32[local] = value;
public void setConstantInt32(VariableDefinition local, int value) {
localsValuesInt32[local] = value;
}
public void setConstant32(VariableDefinition local, uint value) {
setConstant32(local, (int)value);
public void setConstantInt32(VariableDefinition local, uint value) {
setConstantInt32(local, (int)value);
}
public void setConstant64(VariableDefinition local, long value) {
localsValues64[local] = value;
public void setConstantInt64(VariableDefinition local, long value) {
localsValuesInt64[local] = value;
}
public void setConstant64(VariableDefinition local, ulong value) {
setConstant64(local, (long)value);
public void setConstantInt64(VariableDefinition local, ulong value) {
setConstantInt64(local, (long)value);
}
public void setConstantDouble(VariableDefinition local, double value) {
localsValuesDouble[local] = value;
}
public bool getNextInt32(ref int index, out int val) {
for (; index < instructions.Count; index++) {
var instr = instructions[index];
if (!isLoadConstant32(instr))
if (!isLoadConstantInt32(instr))
continue;
return getInt32(ref index, out val);
@ -137,30 +142,44 @@ namespace de4dot.code.deobfuscators {
return false;
}
public bool isLoadConstant32(Instruction instr) {
public bool isLoadConstantInt32(Instruction instr) {
if (DotNetUtils.isLdcI4(instr))
return true;
if (DotNetUtils.isLdloc(instr)) {
int tmp;
return getLocalConstant32(instr, out tmp);
return getLocalConstantInt32(instr, out tmp);
}
if (DotNetUtils.isLdarg(instr)) {
int tmp;
return getArgConstant32(instr, out tmp);
return getArgConstantInt32(instr, out tmp);
}
return false;
}
public bool isLoadConstant64(Instruction instr) {
public bool isLoadConstantInt64(Instruction instr) {
if (instr.OpCode.Code == Code.Ldc_I8)
return true;
if (DotNetUtils.isLdloc(instr)) {
long tmp;
return getLocalConstant64(instr, out tmp);
return getLocalConstantInt64(instr, out tmp);
}
if (DotNetUtils.isLdarg(instr)) {
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;
}
@ -246,7 +265,7 @@ namespace de4dot.code.deobfuscators {
case Code.Ldloc_1:
case Code.Ldloc_2:
case Code.Ldloc_3:
if (!getLocalConstant32(instr, out op1))
if (!getLocalConstantInt32(instr, out op1))
goto done;
stack.Push(new ConstantInfo<int>(index, op1));
break;
@ -257,7 +276,7 @@ namespace de4dot.code.deobfuscators {
case Code.Ldarg_1:
case Code.Ldarg_2:
case Code.Ldarg_3:
if (!getArgConstant32(instr, out op1))
if (!getArgConstantInt32(instr, out op1))
goto done;
stack.Push(new ConstantInfo<int>(index, op1));
break;
@ -429,7 +448,7 @@ done:
case Code.Ldloc_1:
case Code.Ldloc_2:
case Code.Ldloc_3:
if (!getLocalConstant64(instr, out op1))
if (!getLocalConstantInt64(instr, out op1))
goto done;
stack.Push(new ConstantInfo<long>(index, op1));
break;
@ -440,7 +459,7 @@ done:
case Code.Ldarg_1:
case Code.Ldarg_2:
case Code.Ldarg_3:
if (!getArgConstant64(instr, out op1))
if (!getArgConstantInt64(instr, out op1))
goto done;
stack.Push(new ConstantInfo<long>(index, op1));
break;
@ -528,7 +547,122 @@ done:
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;
if (locals == null)
return false;
@ -537,15 +671,15 @@ done:
return false;
if (local.VariableType.EType != ElementType.I4 && local.VariableType.EType != ElementType.U4)
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;
return false;
}
protected virtual bool getLocalConstant64(Instruction instr, out long value) {
protected virtual bool getLocalConstantInt64(Instruction instr, out long value) {
value = 0;
if (locals == null)
return false;
@ -554,10 +688,27 @@ done:
return false;
if (local.VariableType.EType != ElementType.I8 && local.VariableType.EType != ElementType.U8)
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;
return false;
}

View File

@ -27,12 +27,12 @@ namespace de4dot.code.deobfuscators.DeepSea {
: base(instrs) {
}
protected override bool getLocalConstant32(Instruction instr, out int value) {
protected override bool getLocalConstantInt32(Instruction instr, out int value) {
value = 0;
return true;
}
protected override bool getArgConstant32(Instruction instr, out int value) {
protected override bool getArgConstantInt32(Instruction instr, out int value) {
value = 0;
return true;
}

View File

@ -43,12 +43,12 @@ namespace de4dot.code.deobfuscators.Eazfuscator_NET {
var local = DotNetUtils.getLocalVar(locals, stloc);
if (local == null || local.VariableType.EType != ElementType.I4)
break;
localsValues32[local] = value;
localsValuesInt32[local] = value;
index++;
}
if (localsValues32.Count != 2)
localsValues32.Clear();
if (localsValuesInt32.Count != 2)
localsValuesInt32.Clear();
}
}
}

View File

@ -275,7 +275,7 @@ namespace de4dot.code.deobfuscators.Eazfuscator_NET {
var instrs = stringMethod.Body.Instructions;
for (int i = 0; i < instrs.Count; i++) {
var ldci4 = instrs[i];
if (!stringMethodConsts.isLoadConstant32(ldci4))
if (!stringMethodConsts.isLoadConstantInt32(ldci4))
continue;
int index = i, 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];
if (instr.OpCode.FlowControl != FlowControl.Next)
break;
if (!stringMethodConsts.isLoadConstant32(instr))
if (!stringMethodConsts.isLoadConstantInt32(instr))
continue;
int index2 = i, value;
if (!stringMethodConsts.getInt32(ref index2, out value))
@ -512,7 +512,7 @@ namespace de4dot.code.deobfuscators.Eazfuscator_NET {
sb.Append((char)(val >> shift));
shift = 0;
}
if (stringMethodConsts.isLoadConstant32(instr)) {
if (stringMethodConsts.isLoadConstantInt32(instr)) {
int tmp;
if (!stringMethodConsts.getInt32(ref i, out tmp))
break;
@ -599,7 +599,7 @@ namespace de4dot.code.deobfuscators.Eazfuscator_NET {
if (instr.OpCode.Code != Code.Call && instr.OpCode.FlowControl != FlowControl.Next)
break;
if (!stringMethodConsts.isLoadConstant32(instr))
if (!stringMethodConsts.isLoadConstantInt32(instr))
continue;
int tmp;
@ -795,7 +795,7 @@ namespace de4dot.code.deobfuscators.Eazfuscator_NET {
var instr = instrs[i];
if (instr.OpCode.FlowControl != FlowControl.Next)
return -1;
if (stringMethodConsts.isLoadConstant32(instr))
if (stringMethodConsts.isLoadConstantInt32(instr))
return i;
}