Update CS detector and support an old string decrypter
This commit is contained in:
parent
60c98cc944
commit
d84d2e6a6c
|
@ -80,65 +80,37 @@ namespace de4dot.code.deobfuscators.CliSecure {
|
||||||
return;
|
return;
|
||||||
if (find2())
|
if (find2())
|
||||||
return;
|
return;
|
||||||
if (findOld())
|
|
||||||
return;
|
|
||||||
findNativeCode();
|
findNativeCode();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static readonly string[] requiredFields1 = new string[] {
|
||||||
|
"System.Boolean",
|
||||||
|
};
|
||||||
|
static readonly string[] requiredFields2 = new string[] {
|
||||||
|
"System.Boolean",
|
||||||
|
"System.Reflection.Assembly",
|
||||||
|
};
|
||||||
|
static readonly string[] requiredFields3 = new string[] {
|
||||||
|
"System.Boolean",
|
||||||
|
"System.Reflection.Assembly",
|
||||||
|
"System.Byte[]",
|
||||||
|
};
|
||||||
bool find2() {
|
bool find2() {
|
||||||
foreach (var type in module.Types) {
|
|
||||||
if (type.Namespace != "")
|
|
||||||
continue;
|
|
||||||
var typeName = type.FullName;
|
|
||||||
|
|
||||||
MethodDefinition cs = null;
|
|
||||||
MethodDefinition initialize = null;
|
|
||||||
MethodDefinition postInitialize = null;
|
|
||||||
MethodDefinition load = null;
|
|
||||||
|
|
||||||
int methods = 0;
|
|
||||||
foreach (var method in type.Methods) {
|
|
||||||
if (method.FullName == "System.String " + typeName + "::cs(System.String)") {
|
|
||||||
cs = method;
|
|
||||||
methods++;
|
|
||||||
}
|
|
||||||
else if (method.FullName == "System.Void " + typeName + "::Initialize()") {
|
|
||||||
initialize = method;
|
|
||||||
methods++;
|
|
||||||
}
|
|
||||||
else if (method.FullName == "System.Void " + typeName + "::PostInitialize()") {
|
|
||||||
postInitialize = method;
|
|
||||||
methods++;
|
|
||||||
}
|
|
||||||
else if (method.FullName == "System.IntPtr " + typeName + "::Load()") {
|
|
||||||
load = method;
|
|
||||||
methods++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (methods == 0 || (methods == 1 && initialize != null))
|
|
||||||
continue;
|
|
||||||
|
|
||||||
stringDecrypterMethod = cs;
|
|
||||||
initializeMethod = initialize;
|
|
||||||
postInitializeMethod = postInitialize;
|
|
||||||
loadMethod = load;
|
|
||||||
cliSecureRtType = type;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool findOld() {
|
|
||||||
foreach (var cctor in DeobUtils.getInitCctors(module, 3)) {
|
foreach (var cctor in DeobUtils.getInitCctors(module, 3)) {
|
||||||
foreach (var calledMethod in DotNetUtils.getCalledMethods(module, cctor)) {
|
foreach (var calledMethod in DotNetUtils.getCalledMethods(module, cctor)) {
|
||||||
var type = calledMethod.DeclaringType;
|
var type = calledMethod.DeclaringType;
|
||||||
if (!hasPinvokeMethod(type, "_Initialize"))
|
if (type.IsPublic)
|
||||||
continue;
|
continue;
|
||||||
if (!hasPinvokeMethod(type, "_Initialize64"))
|
var fieldTypes = new FieldTypes(type);
|
||||||
|
if (!fieldTypes.exactly(requiredFields1) && !fieldTypes.exactly(requiredFields2) && !fieldTypes.exactly(requiredFields3))
|
||||||
|
continue;
|
||||||
|
if (!hasInitializeMethod(type, "_Initialize"))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
stringDecrypterMethod = findStringDecrypterMethod(type);
|
||||||
initializeMethod = calledMethod;
|
initializeMethod = calledMethod;
|
||||||
|
postInitializeMethod = findMethod(type, "System.Void", "PostInitialize", "()");
|
||||||
|
loadMethod = findMethod(type, "System.IntPtr", "Load", "()");
|
||||||
cliSecureRtType = type;
|
cliSecureRtType = type;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -147,6 +119,47 @@ namespace de4dot.code.deobfuscators.CliSecure {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static MethodDefinition findStringDecrypterMethod(TypeDefinition type) {
|
||||||
|
foreach (var method in type.Methods) {
|
||||||
|
if (method.Body == null || !method.IsStatic)
|
||||||
|
continue;
|
||||||
|
if (!DotNetUtils.isMethod(method, "System.String", "(System.String)"))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
return method;
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
static MethodDefinition findMethod(TypeDefinition type, string returnType, string name, string parameters) {
|
||||||
|
var methodName = returnType + " " + type.FullName + "::" + name + parameters;
|
||||||
|
foreach (var method in type.Methods) {
|
||||||
|
if (method.Body == null || !method.IsStatic)
|
||||||
|
continue;
|
||||||
|
if (method.FullName != methodName)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
return method;
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool hasInitializeMethod(TypeDefinition type, string name) {
|
||||||
|
var method = DotNetUtils.getPInvokeMethod(type, name);
|
||||||
|
if (method == null)
|
||||||
|
return false;
|
||||||
|
if (method.Parameters.Count != 1)
|
||||||
|
return false;
|
||||||
|
if (method.Parameters[0].ParameterType.FullName != "System.IntPtr")
|
||||||
|
return false;
|
||||||
|
var retType = method.MethodReturnType.ReturnType.FullName;
|
||||||
|
if (retType != "System.Void" && retType != "System.Int32")
|
||||||
|
return false;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
bool findNativeCode() {
|
bool findNativeCode() {
|
||||||
if ((module.Attributes & ModuleAttributes.ILOnly) != 0)
|
if ((module.Attributes & ModuleAttributes.ILOnly) != 0)
|
||||||
return false;
|
return false;
|
||||||
|
@ -157,20 +170,8 @@ namespace de4dot.code.deobfuscators.CliSecure {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool hasPinvokeMethod(TypeDefinition type, string methodName) {
|
|
||||||
if (type == null)
|
|
||||||
return false;
|
|
||||||
foreach (var method in type.Methods) {
|
|
||||||
if (method.PInvokeInfo == null)
|
|
||||||
continue;
|
|
||||||
if (method.PInvokeInfo.EntryPoint == methodName)
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
public bool isAtLeastVersion50() {
|
public bool isAtLeastVersion50() {
|
||||||
return hasPinvokeMethod(cliSecureRtType, "LoadLibraryA");
|
return DotNetUtils.hasPinvokeMethod(cliSecureRtType, "LoadLibraryA");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -29,7 +29,7 @@ namespace de4dot.code.deobfuscators.CliSecure {
|
||||||
byte[] stringDecrypterKey;
|
byte[] stringDecrypterKey;
|
||||||
|
|
||||||
public bool Detected {
|
public bool Detected {
|
||||||
get { return stringDecrypterKey != null; }
|
get { return stringDecrypterMethod != null; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public TypeDefinition Type {
|
public TypeDefinition Type {
|
||||||
|
@ -57,6 +57,7 @@ namespace de4dot.code.deobfuscators.CliSecure {
|
||||||
}
|
}
|
||||||
|
|
||||||
public void find() {
|
public void find() {
|
||||||
|
stringDecrypterKey = new byte[1] { 0xFF };
|
||||||
foreach (var type in module.Types) {
|
foreach (var type in module.Types) {
|
||||||
if (type.FullName == "<D234>" || type.FullName == "<ClassD234>") {
|
if (type.FullName == "<D234>" || type.FullName == "<ClassD234>") {
|
||||||
stringDecrypterType = type;
|
stringDecrypterType = type;
|
||||||
|
|
Loading…
Reference in New Issue
Block a user