Port CodeWall deobfuscator

This commit is contained in:
de4dot 2012-11-08 10:40:58 +01:00
parent eb7d4c5f88
commit f2f156dc40
6 changed files with 44 additions and 52 deletions

View File

@ -115,13 +115,13 @@
<Compile Include="deobfuscators\CodeVeil\ResourceReader.cs" /> <Compile Include="deobfuscators\CodeVeil\ResourceReader.cs" />
<Compile Include="deobfuscators\CodeVeil\StringDecrypter.cs" /> <Compile Include="deobfuscators\CodeVeil\StringDecrypter.cs" />
<Compile Include="deobfuscators\CodeVeil\TamperDetection.cs" /> <Compile Include="deobfuscators\CodeVeil\TamperDetection.cs" />
<None Include="deobfuscators\CodeWall\AssemblyDecrypter.cs" /> <Compile Include="deobfuscators\CodeWall\AssemblyDecrypter.cs" />
<None Include="deobfuscators\CodeWall\Deobfuscator.cs" /> <Compile Include="deobfuscators\CodeWall\Deobfuscator.cs" />
<None Include="deobfuscators\CodeWall\KeyGenerator.cs" /> <Compile Include="deobfuscators\CodeWall\KeyGenerator.cs" />
<None Include="deobfuscators\CodeWall\MethodsDecrypter.cs" /> <Compile Include="deobfuscators\CodeWall\MethodsDecrypter.cs" />
<None Include="deobfuscators\CodeWall\randomc\CRandomMersenne.cs" /> <Compile Include="deobfuscators\CodeWall\randomc\CRandomMersenne.cs" />
<None Include="deobfuscators\CodeWall\randomc\CRandomMother.cs" /> <Compile Include="deobfuscators\CodeWall\randomc\CRandomMother.cs" />
<None Include="deobfuscators\CodeWall\StringDecrypter.cs" /> <Compile Include="deobfuscators\CodeWall\StringDecrypter.cs" />
<Compile Include="deobfuscators\ConstantsReader.cs" /> <Compile Include="deobfuscators\ConstantsReader.cs" />
<None Include="deobfuscators\CryptoObfuscator\AntiDebugger.cs" /> <None Include="deobfuscators\CryptoObfuscator\AntiDebugger.cs" />
<None Include="deobfuscators\CryptoObfuscator\AssemblyResolver.cs" /> <None Include="deobfuscators\CryptoObfuscator\AssemblyResolver.cs" />

View File

@ -29,7 +29,7 @@ using de4dot.code.resources;
namespace de4dot.code.deobfuscators.CodeWall { namespace de4dot.code.deobfuscators.CodeWall {
class AssemblyDecrypter { class AssemblyDecrypter {
ModuleDefinition module; ModuleDefMD module;
ISimpleDeobfuscator simpleDeobfuscator; ISimpleDeobfuscator simpleDeobfuscator;
IDeobfuscator deob; IDeobfuscator deob;
List<AssemblyInfo> assemblyInfos = new List<AssemblyInfo>(); List<AssemblyInfo> assemblyInfos = new List<AssemblyInfo>();
@ -37,7 +37,7 @@ namespace de4dot.code.deobfuscators.CodeWall {
string resourcePassword; string resourcePassword;
string resourceSalt; string resourceSalt;
EmbeddedResource assemblyResource; EmbeddedResource assemblyResource;
ModuleDefinition resourceModule; ModuleDefMD resourceModule;
public class AssemblyInfo { public class AssemblyInfo {
public readonly byte[] data; public readonly byte[] data;
@ -63,7 +63,7 @@ namespace de4dot.code.deobfuscators.CodeWall {
get { return assemblyInfos; } get { return assemblyInfos; }
} }
public AssemblyDecrypter(ModuleDefinition module, ISimpleDeobfuscator simpleDeobfuscator, IDeobfuscator deob) { public AssemblyDecrypter(ModuleDefMD module, ISimpleDeobfuscator simpleDeobfuscator, IDeobfuscator deob) {
this.module = module; this.module = module;
this.simpleDeobfuscator = simpleDeobfuscator; this.simpleDeobfuscator = simpleDeobfuscator;
this.deob = deob; this.deob = deob;
@ -80,7 +80,7 @@ namespace de4dot.code.deobfuscators.CodeWall {
return; return;
deobfuscateAll(decryptAssemblyMethod); deobfuscateAll(decryptAssemblyMethod);
ModuleDefinition theResourceModule; ModuleDefMD theResourceModule;
var resource = getResource(decryptAssemblyMethod, out theResourceModule); var resource = getResource(decryptAssemblyMethod, out theResourceModule);
if (resource == null) if (resource == null)
return; return;
@ -155,7 +155,7 @@ namespace de4dot.code.deobfuscators.CodeWall {
return null; return null;
} }
EmbeddedResource getResource(MethodDef method, out ModuleDefinition theResourceModule) { EmbeddedResource getResource(MethodDef method, out ModuleDefMD theResourceModule) {
string resourceDllFileName = null; string resourceDllFileName = null;
theResourceModule = module; theResourceModule = module;
foreach (var s in DotNetUtils.getCodeStrings(method)) { foreach (var s in DotNetUtils.getCodeStrings(method)) {
@ -182,10 +182,10 @@ namespace de4dot.code.deobfuscators.CodeWall {
return null; return null;
} }
ModuleDefinition getResourceModule(string name) { ModuleDefMD getResourceModule(string name) {
try { try {
var resourceDllFileName = Path.Combine(Path.GetDirectoryName(module.FullyQualifiedName), name.Substring(1)); var resourceDllFileName = Path.Combine(Path.GetDirectoryName(module.Location), name.Substring(1));
return ModuleDefinition.ReadModule(resourceDllFileName); return ModuleDefMD.Load(resourceDllFileName);
} }
catch { catch {
return null; return null;
@ -217,15 +217,15 @@ namespace de4dot.code.deobfuscators.CodeWall {
void decryptAllAssemblies() { void decryptAllAssemblies() {
if (assemblyResource == null) if (assemblyResource == null)
return; return;
var resourceSet = ResourceReader.read(resourceModule, assemblyResource.GetResourceStream()); var resourceSet = ResourceReader.read(resourceModule, assemblyResource.Data);
foreach (var resourceElement in resourceSet.ResourceElements) { foreach (var resourceElement in resourceSet.ResourceElements) {
if (resourceElement.ResourceData.Code != ResourceTypeCode.ByteArray) if (resourceElement.ResourceData.Code != ResourceTypeCode.ByteArray)
throw new ApplicationException("Invalid resource"); throw new ApplicationException("Invalid resource");
var resourceData = (BuiltInResourceData)resourceElement.ResourceData; var resourceData = (BuiltInResourceData)resourceElement.ResourceData;
var assemblyData = decrypt((byte[])resourceData.Data); var assemblyData = decrypt((byte[])resourceData.Data);
var theModule = ModuleDefinition.ReadModule(new MemoryStream(assemblyData)); var theModule = ModuleDefMD.Load(assemblyData);
bool isMain = resourceElement.Name == entryPointAssemblyKey; bool isMain = resourceElement.Name == entryPointAssemblyKey;
assemblyInfos.Add(new AssemblyInfo(assemblyData, DeobUtils.getExtension(theModule.Kind), theModule.Assembly.FullName, theModule.Assembly.Name.Name, isMain)); assemblyInfos.Add(new AssemblyInfo(assemblyData, DeobUtils.getExtension(theModule.Kind), theModule.Assembly.FullName, theModule.Assembly.Name.String, isMain));
} }
} }

View File

@ -20,7 +20,6 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using dot10.DotNet; using dot10.DotNet;
using Mono.MyStuff;
using de4dot.blocks; using de4dot.blocks;
using de4dot.PE; using de4dot.PE;
@ -194,7 +193,7 @@ namespace de4dot.code.deobfuscators.CodeWall {
return asmInfo.data; return asmInfo.data;
} }
public override IDeobfuscator moduleReloaded(ModuleDefinition module) { public override IDeobfuscator moduleReloaded(ModuleDefMD module) {
var newOne = new Deobfuscator(options); var newOne = new Deobfuscator(options);
newOne.setModule(module); newOne.setModule(module);
newOne.methodsDecrypter = new MethodsDecrypter(module); newOne.methodsDecrypter = new MethodsDecrypter(module);
@ -209,7 +208,6 @@ namespace de4dot.code.deobfuscators.CodeWall {
public override void deobfuscateBegin() { public override void deobfuscateBegin() {
base.deobfuscateBegin(); base.deobfuscateBegin();
addAssemblyReferenceToBeRemoved(methodsDecrypter.AssemblyNameReference, "Obfuscator decrypter DLL reference");
initializeStringDecrypter(); initializeStringDecrypter();
initializeAssemblyDecrypter(); initializeAssemblyDecrypter();

View File

@ -20,7 +20,6 @@
using System; using System;
using dot10.DotNet; using dot10.DotNet;
using dot10.DotNet.Emit; using dot10.DotNet.Emit;
using Mono.MyStuff;
using de4dot.PE; using de4dot.PE;
using de4dot.blocks; using de4dot.blocks;
@ -29,18 +28,14 @@ namespace de4dot.code.deobfuscators.CodeWall {
static readonly byte[] newCodeHeader = new byte[6] { 0x2B, 4, 0, 0, 0, 0 }; static readonly byte[] newCodeHeader = new byte[6] { 0x2B, 4, 0, 0, 0, 0 };
static readonly byte[] decryptKey = new byte[10] { 0x8D, 0xB5, 0x2C, 0x3A, 0x1F, 0xC7, 0x31, 0xC3, 0xCD, 0x47 }; static readonly byte[] decryptKey = new byte[10] { 0x8D, 0xB5, 0x2C, 0x3A, 0x1F, 0xC7, 0x31, 0xC3, 0xCD, 0x47 };
ModuleDefinition module; ModuleDefMD module;
MethodReference initMethod; IMethod initMethod;
public bool Detected { public bool Detected {
get { return initMethod != null; } get { return initMethod != null; }
} }
public AssemblyNameReference AssemblyNameReference { public MethodsDecrypter(ModuleDefMD module) {
get { return initMethod == null ? null : (AssemblyNameReference)initMethod.DeclaringType.Scope; }
}
public MethodsDecrypter(ModuleDefinition module) {
this.module = module; this.module = module;
} }
@ -58,7 +53,7 @@ namespace de4dot.code.deobfuscators.CodeWall {
foreach (var instr in method.Body.Instructions) { foreach (var instr in method.Body.Instructions) {
if (instr.OpCode.Code != Code.Call) if (instr.OpCode.Code != Code.Call)
continue; continue;
var calledMethod = instr.Operand as MethodReference; var calledMethod = instr.Operand as IMethod;
if (calledMethod == null) if (calledMethod == null)
continue; continue;
if (calledMethod.DeclaringType.Scope == module) if (calledMethod.DeclaringType.Scope == module)
@ -147,8 +142,8 @@ namespace de4dot.code.deobfuscators.CodeWall {
var instr = instrs[i]; var instr = instrs[i];
if (instr.OpCode.Code != Code.Call) if (instr.OpCode.Code != Code.Call)
continue; continue;
var calledMethod = instr.Operand as MethodReference; var calledMethod = instr.Operand as IMethod;
if (!MemberReferenceHelper.compareMethodReferenceAndDeclaringType(calledMethod, initMethod)) if (!MethodEqualityComparer.CompareDeclaringTypes.Equals(calledMethod, initMethod))
continue; continue;
block.remove(i, 1); block.remove(i, 1);
i--; i--;

View File

@ -21,13 +21,14 @@ using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.IO; using System.IO;
using System.Text; using System.Text;
using dot10.IO;
using dot10.DotNet; using dot10.DotNet;
using dot10.DotNet.Emit; using dot10.DotNet.Emit;
using de4dot.blocks; using de4dot.blocks;
namespace de4dot.code.deobfuscators.CodeWall { namespace de4dot.code.deobfuscators.CodeWall {
class StringDecrypter { class StringDecrypter {
ModuleDefinition module; ModuleDefMD module;
MethodDefinitionAndDeclaringTypeDict<StringEncrypterInfo> stringEncrypterInfos = new MethodDefinitionAndDeclaringTypeDict<StringEncrypterInfo>(); MethodDefinitionAndDeclaringTypeDict<StringEncrypterInfo> stringEncrypterInfos = new MethodDefinitionAndDeclaringTypeDict<StringEncrypterInfo>();
Version version; Version version;
@ -52,7 +53,7 @@ namespace de4dot.code.deobfuscators.CodeWall {
public int Magic1 { get; set; } public int Magic1 { get; set; }
public int Magic2 { get; set; } public int Magic2 { get; set; }
public int Magic3 { get; set; } public int Magic3 { get; set; }
public BinaryReader Reader { get; set; } public IBinaryReader Reader { get; set; }
public StringEncrypterInfo(MethodDef method) { public StringEncrypterInfo(MethodDef method) {
this.method = method; this.method = method;
@ -61,7 +62,7 @@ namespace de4dot.code.deobfuscators.CodeWall {
public string decrypt(int magic1, int magic2, int magic3) { public string decrypt(int magic1, int magic2, int magic3) {
int dataLen = magic3 ^ Magic3; int dataLen = magic3 ^ Magic3;
var key = getKey(magic1 ^ Magic1, dataLen); var key = getKey(magic1 ^ Magic1, dataLen);
Reader.BaseStream.Position = getDataOffset(magic2); Reader.Position = getDataOffset(magic2);
var data = Reader.ReadBytes(dataLen); var data = Reader.ReadBytes(dataLen);
for (int i = 0; i < dataLen; i++) for (int i = 0; i < dataLen; i++)
data[i] ^= key[i]; data[i] ^= key[i];
@ -84,12 +85,10 @@ namespace de4dot.code.deobfuscators.CodeWall {
} }
byte[] getPublicKeyToken() { byte[] getPublicKeyToken() {
var module = method.Module; var module = method.OwnerModule;
if (module.Assembly == null || module.Assembly.Name.PublicKeyToken == null) if (module.Assembly == null || PublicKeyBase.IsNullOrEmpty2(module.Assembly.PublicKey))
return null; return null;
if (module.Assembly.Name.PublicKeyToken.Length != 8) return module.Assembly.PublicKeyToken.Data;
return null;
return module.Assembly.Name.PublicKeyToken;
} }
public override string ToString() { public override string ToString() {
@ -118,7 +117,7 @@ namespace de4dot.code.deobfuscators.CodeWall {
} }
} }
public StringDecrypter(ModuleDefinition module) { public StringDecrypter(ModuleDefMD module) {
this.module = module; this.module = module;
} }
@ -255,7 +254,7 @@ namespace de4dot.code.deobfuscators.CodeWall {
info.Magic1 = findMagic1(info.Method); info.Magic1 = findMagic1(info.Method);
info.Magic2 = findMagic2(info.Method); info.Magic2 = findMagic2(info.Method);
info.Magic3 = findMagic3(info.Method); info.Magic3 = findMagic3(info.Method);
info.Reader = new BinaryReader(info.Resource.GetResourceStream()); info.Reader = info.Resource.Data;
} }
} }
@ -267,14 +266,14 @@ namespace de4dot.code.deobfuscators.CodeWall {
var instrs = method.Body.Instructions; var instrs = method.Body.Instructions;
for (int i = 0; i < instrs.Count - 2; i++) { for (int i = 0; i < instrs.Count - 2; i++) {
var ldarg = instrs[i]; var ldarg = instrs[i];
if (!DotNetUtils.isLdarg(ldarg) || DotNetUtils.getArgIndex(ldarg) != 0) if (!ldarg.IsLdarg() || ldarg.GetParameterIndex() != 0)
continue; continue;
var ldci4 = instrs[i + 1]; var ldci4 = instrs[i + 1];
if (!DotNetUtils.isLdcI4(ldci4)) if (!ldci4.IsLdcI4())
continue; continue;
if (instrs[i + 2].OpCode.Code != Code.Xor) if (instrs[i + 2].OpCode.Code != Code.Xor)
continue; continue;
return DotNetUtils.getLdcI4Value(ldci4); return ldci4.GetLdcI4Value();
} }
throw new ApplicationException("Could not find magic1"); throw new ApplicationException("Could not find magic1");
} }
@ -283,14 +282,14 @@ namespace de4dot.code.deobfuscators.CodeWall {
var instrs = method.Body.Instructions; var instrs = method.Body.Instructions;
for (int i = 0; i < instrs.Count - 2; i++) { for (int i = 0; i < instrs.Count - 2; i++) {
var ldloc = instrs[i]; var ldloc = instrs[i];
if (!DotNetUtils.isLdloc(ldloc)) if (!ldloc.IsLdloc())
continue; continue;
var ldci4 = instrs[i + 1]; var ldci4 = instrs[i + 1];
if (!DotNetUtils.isLdcI4(ldci4)) if (!ldci4.IsLdcI4())
continue; continue;
if (instrs[i + 2].OpCode.Code != Code.Xor) if (instrs[i + 2].OpCode.Code != Code.Xor)
continue; continue;
return DotNetUtils.getLdcI4Value(ldci4); return ldci4.GetLdcI4Value();
} }
throw new ApplicationException("Could not find magic2"); throw new ApplicationException("Could not find magic2");
} }
@ -299,14 +298,14 @@ namespace de4dot.code.deobfuscators.CodeWall {
var instrs = method.Body.Instructions; var instrs = method.Body.Instructions;
for (int i = 0; i < instrs.Count - 2; i++) { for (int i = 0; i < instrs.Count - 2; i++) {
var ldarg = instrs[i]; var ldarg = instrs[i];
if (!DotNetUtils.isLdarg(ldarg) || DotNetUtils.getArgIndex(ldarg) != 2) if (!ldarg.IsLdarg() || ldarg.GetParameterIndex() != 2)
continue; continue;
var ldci4 = instrs[i + 1]; var ldci4 = instrs[i + 1];
if (!DotNetUtils.isLdcI4(ldci4)) if (!ldci4.IsLdcI4())
continue; continue;
if (instrs[i + 2].OpCode.Code != Code.Xor) if (instrs[i + 2].OpCode.Code != Code.Xor)
continue; continue;
return DotNetUtils.getLdcI4Value(ldci4); return ldci4.GetLdcI4Value();
} }
throw new ApplicationException("Could not find magic3"); throw new ApplicationException("Could not find magic3");
} }

View File

@ -41,8 +41,8 @@ namespace de4dot.cui {
new de4dot.code.deobfuscators.Babel_NET.DeobfuscatorInfo(), new de4dot.code.deobfuscators.Babel_NET.DeobfuscatorInfo(),
new de4dot.code.deobfuscators.CodeFort.DeobfuscatorInfo(), new de4dot.code.deobfuscators.CodeFort.DeobfuscatorInfo(),
new de4dot.code.deobfuscators.CodeVeil.DeobfuscatorInfo(), new de4dot.code.deobfuscators.CodeVeil.DeobfuscatorInfo(),
#if PORT
new de4dot.code.deobfuscators.CodeWall.DeobfuscatorInfo(), new de4dot.code.deobfuscators.CodeWall.DeobfuscatorInfo(),
#if PORT
new de4dot.code.deobfuscators.CryptoObfuscator.DeobfuscatorInfo(), new de4dot.code.deobfuscators.CryptoObfuscator.DeobfuscatorInfo(),
new de4dot.code.deobfuscators.DeepSea.DeobfuscatorInfo(), new de4dot.code.deobfuscators.DeepSea.DeobfuscatorInfo(),
#endif #endif