Detect SA 1.x-5.1 assemblies
This commit is contained in:
parent
01da4a979f
commit
4c43807de7
|
@ -69,6 +69,8 @@ namespace de4dot.deobfuscators.SmartAssembly {
|
||||||
|
|
||||||
class Deobfuscator : DeobfuscatorBase {
|
class Deobfuscator : DeobfuscatorBase {
|
||||||
Options options;
|
Options options;
|
||||||
|
bool foundVersion = false;
|
||||||
|
string poweredByAttributeString = null;
|
||||||
string obfuscatorName = "SmartAssembly";
|
string obfuscatorName = "SmartAssembly";
|
||||||
bool foundSmartAssemblyAttribute = false;
|
bool foundSmartAssemblyAttribute = false;
|
||||||
|
|
||||||
|
@ -100,6 +102,13 @@ namespace de4dot.deobfuscators.SmartAssembly {
|
||||||
get { return obfuscatorName; }
|
get { return obfuscatorName; }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
string ObfuscatorName {
|
||||||
|
set {
|
||||||
|
obfuscatorName = value;
|
||||||
|
foundVersion = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public Deobfuscator(Options options)
|
public Deobfuscator(Options options)
|
||||||
: base(options) {
|
: base(options) {
|
||||||
this.options = options;
|
this.options = options;
|
||||||
|
@ -138,44 +147,129 @@ namespace de4dot.deobfuscators.SmartAssembly {
|
||||||
findAutomatedErrorReportingType();
|
findAutomatedErrorReportingType();
|
||||||
memoryManagerInfo = new MemoryManagerInfo(module);
|
memoryManagerInfo = new MemoryManagerInfo(module);
|
||||||
proxyDelegateFinder.findDelegateCreator(module);
|
proxyDelegateFinder.findDelegateCreator(module);
|
||||||
}
|
|
||||||
|
|
||||||
void findSmartAssemblyAttributes() {
|
|
||||||
bool foundVersion = false;
|
|
||||||
foreach (var type in module.Types) {
|
|
||||||
if (Utils.StartsWith(type.FullName, "SmartAssembly.Attributes.PoweredByAttribute", StringComparison.Ordinal)) {
|
|
||||||
foundSmartAssemblyAttribute = true;
|
|
||||||
addAttributeToBeRemoved(type, "Obfuscator attribute");
|
|
||||||
foundVersion |= initializeVersion(type);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!foundVersion)
|
if (!foundVersion)
|
||||||
guessVersion();
|
guessVersion();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool initializeVersion(TypeDefinition attr) {
|
void findSmartAssemblyAttributes() {
|
||||||
|
foreach (var type in module.Types) {
|
||||||
|
if (Utils.StartsWith(type.FullName, "SmartAssembly.Attributes.PoweredByAttribute", StringComparison.Ordinal)) {
|
||||||
|
foundSmartAssemblyAttribute = true;
|
||||||
|
addAttributeToBeRemoved(type, "Obfuscator attribute");
|
||||||
|
initializeVersion(type);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void initializeVersion(TypeDefinition attr) {
|
||||||
var s = DotNetUtils.getCustomArgAsString(getAssemblyAttribute(attr), 0);
|
var s = DotNetUtils.getCustomArgAsString(getAssemblyAttribute(attr), 0);
|
||||||
if (s == null)
|
if (s == null)
|
||||||
return false;
|
return;
|
||||||
|
|
||||||
|
poweredByAttributeString = s;
|
||||||
|
|
||||||
var val = System.Text.RegularExpressions.Regex.Match(s, @"^Powered by (SmartAssembly \d+\.\d+\.\d+\.\d+)$");
|
var val = System.Text.RegularExpressions.Regex.Match(s, @"^Powered by (SmartAssembly \d+\.\d+\.\d+\.\d+)$");
|
||||||
if (val.Groups.Count < 2)
|
if (val.Groups.Count < 2)
|
||||||
return false;
|
return;
|
||||||
obfuscatorName = val.Groups[1].ToString();
|
ObfuscatorName = val.Groups[1].ToString();
|
||||||
return true;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
void guessVersion() {
|
void guessVersion() {
|
||||||
if (isVersion4x())
|
if (poweredByAttributeString == "Powered by SmartAssembly") {
|
||||||
obfuscatorName = "SmartAssembly 4.x";
|
ObfuscatorName = "SmartAssembly 5.0/5.1";
|
||||||
else
|
return;
|
||||||
obfuscatorName = "SmartAssembly 5.0/5.1";
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool isVersion4x() {
|
if (poweredByAttributeString == "Powered by {smartassembly}") {
|
||||||
|
// It's SA 1.x - 4.x
|
||||||
|
|
||||||
|
if (hasEmptyClassesInEveryNamespace() || proxyDelegateFinder.Detected) {
|
||||||
|
ObfuscatorName = "SmartAssembly 4.x";
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
int ver = checkTypeIdAttribute();
|
||||||
|
if (ver == 2) {
|
||||||
|
ObfuscatorName = "SmartAssembly 2.x";
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (ver == 1) {
|
||||||
|
ObfuscatorName = "SmartAssembly 1.x-2.x";
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (hasModuleCctor()) {
|
||||||
|
ObfuscatorName = "SmartAssembly 3.x";
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
ObfuscatorName = "SmartAssembly 1.x-4.x";
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int checkTypeIdAttribute() {
|
||||||
|
var type = getTypeIdAttribute();
|
||||||
|
if (type == null)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
var fields = type.Fields;
|
||||||
|
if (fields.Count == 1)
|
||||||
|
return 1; // 1.x: int ID
|
||||||
|
if (fields.Count == 2)
|
||||||
|
return 2; // 2.x: int ID, static int AssemblyID
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
TypeDefinition getTypeIdAttribute() {
|
||||||
|
Dictionary<TypeDefinition, bool> attrs = null;
|
||||||
|
int counter = 0;
|
||||||
|
foreach (var type in module.GetTypes()) {
|
||||||
|
counter++;
|
||||||
|
var cattrs = type.CustomAttributes;
|
||||||
|
if (cattrs.Count == 0)
|
||||||
|
return null;
|
||||||
|
|
||||||
|
var attrs2 = new Dictionary<TypeDefinition, bool>();
|
||||||
|
foreach (var cattr in cattrs) {
|
||||||
|
if (!DotNetUtils.isMethod(cattr.Constructor, "System.Void", "(System.Int32)"))
|
||||||
|
continue;
|
||||||
|
var attrType = cattr.AttributeType as TypeDefinition;
|
||||||
|
if (attrType == null)
|
||||||
|
continue;
|
||||||
|
if (attrs != null && !attrs.ContainsKey(attrType))
|
||||||
|
continue;
|
||||||
|
attrs2[attrType] = true;
|
||||||
|
}
|
||||||
|
attrs = attrs2;
|
||||||
|
|
||||||
|
if (attrs.Count == 0)
|
||||||
|
return null;
|
||||||
|
if (attrs.Count == 1 && counter >= 30)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (attrs == null)
|
||||||
|
return null;
|
||||||
|
foreach (var type in attrs.Keys)
|
||||||
|
return type;
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool hasModuleCctor() {
|
||||||
|
var type = getModuleType();
|
||||||
|
if (type == null)
|
||||||
|
return false;
|
||||||
|
return DotNetUtils.getMethod(type, ".cctor") != null;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool hasEmptyClassesInEveryNamespace() {
|
||||||
var namespaces = new Dictionary<string, int>(StringComparer.Ordinal);
|
var namespaces = new Dictionary<string, int>(StringComparer.Ordinal);
|
||||||
foreach (var type in module.Types) {
|
foreach (var type in module.Types) {
|
||||||
|
if (type.FullName == "<Module>")
|
||||||
|
continue;
|
||||||
var ns = type.Namespace;
|
var ns = type.Namespace;
|
||||||
if (!namespaces.ContainsKey(ns))
|
if (!namespaces.ContainsKey(ns))
|
||||||
namespaces[ns] = 0;
|
namespaces[ns] = 0;
|
||||||
|
|
Loading…
Reference in New Issue
Block a user