diff --git a/de4dot.code/deobfuscators/ConstantsReader.cs b/de4dot.code/deobfuscators/ConstantsReader.cs index 507d33a8..4ed1440a 100644 --- a/de4dot.code/deobfuscators/ConstantsReader.cs +++ b/de4dot.code/deobfuscators/ConstantsReader.cs @@ -27,8 +27,9 @@ namespace de4dot.code.deobfuscators { class ConstantsReader { protected IInstructions instructions; protected IList locals; - protected Dictionary localsValues32 = new Dictionary(); - protected Dictionary localsValues64 = new Dictionary(); + protected Dictionary localsValuesInt32 = new Dictionary(); + protected Dictionary localsValuesInt64 = new Dictionary(); + protected Dictionary localsValuesDouble = new Dictionary(); 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(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(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(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(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>(); + + double op1; + ConstantInfo 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(index, (float)stack.Pop().constant)); + break; + + case Code.Conv_R8: + if (!emulateConvInstrs || stack.Count < 1) + goto done; + stack.Push(new ConstantInfo(index, stack.Pop().constant)); + break; + + case Code.Neg: + if (stack.Count < 1) + goto done; + stack.Push(new ConstantInfo(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(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(index, op1)); + break; + + case Code.Ldc_R4: + stack.Push(new ConstantInfo(index, (float)instr.Operand)); + break; + + case Code.Ldc_R8: + stack.Push(new ConstantInfo(index, (double)instr.Operand)); + break; + + case Code.Add: + if (stack.Count < 2) + goto done; + info2 = stack.Pop(); + info1 = stack.Pop(); + stack.Push(new ConstantInfo(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(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(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(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(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; } diff --git a/de4dot.code/deobfuscators/DeepSea/DsConstantsReader.cs b/de4dot.code/deobfuscators/DeepSea/DsConstantsReader.cs index 10daf47d..b42aa156 100644 --- a/de4dot.code/deobfuscators/DeepSea/DsConstantsReader.cs +++ b/de4dot.code/deobfuscators/DeepSea/DsConstantsReader.cs @@ -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; } diff --git a/de4dot.code/deobfuscators/Eazfuscator_NET/EfConstantsReader.cs b/de4dot.code/deobfuscators/Eazfuscator_NET/EfConstantsReader.cs index c670b4b4..e3b2e3f6 100644 --- a/de4dot.code/deobfuscators/Eazfuscator_NET/EfConstantsReader.cs +++ b/de4dot.code/deobfuscators/Eazfuscator_NET/EfConstantsReader.cs @@ -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(); } } } diff --git a/de4dot.code/deobfuscators/Eazfuscator_NET/StringDecrypter.cs b/de4dot.code/deobfuscators/Eazfuscator_NET/StringDecrypter.cs index d6f924f9..6590dc48 100644 --- a/de4dot.code/deobfuscators/Eazfuscator_NET/StringDecrypter.cs +++ b/de4dot.code/deobfuscators/Eazfuscator_NET/StringDecrypter.cs @@ -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; }