Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
50 changes: 44 additions & 6 deletions de4dot.code/deobfuscators/DeepSea/ArrayBlockDeobfuscator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -67,20 +67,22 @@ protected override bool Deobfuscate(Block block) {
constantsReader = null;
var instrs = block.Instructions;
for (int i = 0; i < instrs.Count; i++) {
bool ch = Deobfuscate1(block, i);
if (ch) {
if (Deobfuscate1(block, i)) {
modified = true;
continue;
}

ch = Deobfuscate2(block, i);
if (ch) {
if (Deobfuscate2(block, i)) {
modified = true;
continue;
}

ch = Deobfuscate3(block, i);
if (ch) {
if (Deobfuscate3(block, i)) {
modified = true;
continue;
}

if (Deobfuscate4(block, i)) {
modified = true;
continue;
}
Expand Down Expand Up @@ -214,6 +216,42 @@ bool Deobfuscate3(Block block, int i) {
return true;
}

bool Deobfuscate4(Block block, int i) {
var instrs = block.Instructions;
if (i + 1 >= instrs.Count)
return false;

int start = i;
var ldsfld = instrs[i];
if (ldsfld.OpCode.Code != Code.Ldsfld)
return false;
var info = arrayBlockState.GetFieldInfo(ldsfld.Operand as IField);
if (info == null)
return false;

if (!instrs[i + 1].IsLdcI4())
return false;

for (; i < instrs.Count; i++) {
if (instrs[i].OpCode.FlowControl != FlowControl.Next)
return false;
if (instrs[i].OpCode.Code == Code.Ldsfld
&& arrayBlockState.GetFieldInfo(instrs[i].Operand as IField) == null)
return false;
if (instrs[i].OpCode.Code is Code.Stelem_I1 or Code.Stelem_I2 or Code.Stelem_I4)
break;
}

if (i >= instrs.Count)
return false;
var stelem = instrs[i];
if (!IsStelem(info, stelem.OpCode.Code))
return false;

block.Remove(start, i - start + 1);
return true;
}

DsConstantsReader GetConstantsReader(Block block) {
if (constantsReader != null)
return constantsReader;
Expand Down
36 changes: 23 additions & 13 deletions de4dot.code/deobfuscators/DeepSea/ArrayBlockState.cs
Original file line number Diff line number Diff line change
Expand Up @@ -110,19 +110,27 @@ bool InitializeArrays2(ISimpleDeobfuscator simpleDeobfuscator, MethodDef method)
if (!ldci4.IsLdcI4())
continue;
i++;
bool hasCall = true;
var instrs = DotNetUtils.GetInstructions(instructions, i, OpCodes.Newarr, OpCodes.Dup, OpCodes.Ldtoken, OpCodes.Call, OpCodes.Stsfld);
if (instrs == null)
continue;
if (instrs == null) {
instrs = DotNetUtils.GetInstructions(instructions, i, OpCodes.Newarr, OpCodes.Dup, OpCodes.Ldtoken, OpCodes.Stsfld);
if (instrs == null)
continue;
hasCall = false;
}

var arrayInitField = instrs[2].Operand as FieldDef;
if (arrayInitField == null || arrayInitField.InitialValue == null || arrayInitField.InitialValue.Length == 0)
continue;

var calledMethod = instrs[3].Operand as IMethod;
if (calledMethod == null || calledMethod.FullName != "System.Void System.Runtime.CompilerServices.RuntimeHelpers::InitializeArray(System.Array,System.RuntimeFieldHandle)")
continue;
if (hasCall) {
var calledMethod = instrs[3].Operand as IMethod;
if (calledMethod == null || calledMethod.FullName !=
"System.Void System.Runtime.CompilerServices.RuntimeHelpers::InitializeArray(System.Array,System.RuntimeFieldHandle)")
continue;
}

var targetField = instrs[4].Operand as FieldDef;
var targetField = instrs[hasCall ? 4 : 3].Operand as FieldDef;
if (targetField == null || targetField.FieldType.GetElementType() != ElementType.SZArray)
continue;
var etype = ((SZArraySig)targetField.FieldType).Next.GetElementType();
Expand Down Expand Up @@ -186,17 +194,19 @@ bool RemoveInitCode(Blocks blocks, FieldInfo info) {
if (ldtoken.Operand != info.arrayInitField)
continue;
var call = instrs[i + 4];
if (call.OpCode.Code != Code.Call)
continue;
var calledMethod = call.Operand as IMethod;
if (calledMethod == null || calledMethod.FullName != "System.Void System.Runtime.CompilerServices.RuntimeHelpers::InitializeArray(System.Array,System.RuntimeFieldHandle)")
continue;
var stsfld = instrs[i + 5];
bool hasCall = call.OpCode.Code == Code.Call;
if (hasCall) {
var calledMethod = call.Operand as IMethod;
if (calledMethod == null || calledMethod.FullName !=
"System.Void System.Runtime.CompilerServices.RuntimeHelpers::InitializeArray(System.Array,System.RuntimeFieldHandle)")
continue;
}
var stsfld = instrs[i + (hasCall ? 5 : 4)];
if (stsfld.OpCode.Code != Code.Stsfld)
continue;
if (stsfld.Operand != info.field)
continue;
block.Remove(i, 6);
block.Remove(i, hasCall ? 6 : 5);
i--;
removedSomething = true;
}
Expand Down
2 changes: 2 additions & 0 deletions de4dot.code/deobfuscators/DeepSea/DsMethodCallInliner.cs
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,8 @@ bool InlineMethod(Instruction callInstr, int instrIndex) {
if (method == null) {
if (callInstr.Operand is MethodSpec ms)
method = ms.Method as MethodDef;
if (callInstr.Operand is MemberRef mref)
method = mref.ResolveMethod();
if (method == null)
return false;
}
Expand Down
Loading