CJ-SPT d33f1f3c9b
Dnlib refactor
* First compiling build

* fix out path

* fix hollow

* Traditional loops in favor of linq for clarity

* Start refactor

* Refactor part 2

* Rename variable

* Better error reason handling

* Clean up enum

* Refactor part 3

* Use combo boxes in favor of updowns

* Update tooltips

* fix is nested tree view display

* Capitialization

* Refactor part ??

* remove unused methods

* Expanded IsNested Check

* TypeFilter class + Fix CLI bug

* Remove reflection, change IsDerived and IsNested checks

* Remove optional out for IsPublic

* Remove nullable from IsPublic

* fix logger not resetting color

* actually fix it...

* remove redundant if else on IsPublic check

* Add logging to indicate all types have been filtered out

* Default IsPublic to true

* remove duplicate method call

* Refactor logger to be on its own thread

* Multithread remapping and grouped logging for threads

* 5 more filters

* Finish migrating to the new system

* bug fixes

* Add empty string validation to text fields

* re-enable renamer

* restore renamer

* Multi threaded renaming, still broken

* Basis for method renaming

* More renamer work, might get a passing build now?

* Re-enable publicizer

* Rework logging

* re-enable mapping updates

* fix hollow

* Iterate over all types instead of just one to re-link fields

* Add reference list command

---------

Co-authored-by: clodan <clodan@clodan.com>
2024-06-26 14:45:54 -04:00

74 lines
2.6 KiB
C#

using dnlib.DotNet;
using dnlib.DotNet.Emit;
using ReCodeIt.Utils;
using System.Diagnostics;
namespace ReCodeItLib.Remapper;
public static class Deobfuscator
{
public static void Deobfuscate(string assemblyPath)
{
var executablePath = Path.Combine(DataProvider.DataPath, "De4dot", "de4dot.exe");
string token;
ModuleContext modCtx = ModuleDef.CreateModuleContext();
ModuleDefMD module = ModuleDefMD.Load(assemblyPath, modCtx);
var potentialStringDelegates = new List<MethodDef>();
foreach (var type in module.GetTypes())
{
foreach (var method in type.Methods)
{
if (method.ReturnType.FullName != "System.String"
|| method.Parameters.Count != 1
|| method.Parameters[0].Type.FullName != "System.Int32"
|| method.Body == null
|| !method.IsStatic)
{
continue;
}
if (!method.Body.Instructions.Any(x =>
x.OpCode.Code == Code.Callvirt &&
((MethodDef)x.Operand).FullName == "System.Object System.AppDomain::GetData(System.String)"))
{
continue;
}
potentialStringDelegates.Add(method);
}
}
if (potentialStringDelegates.Count != 1)
{
Logger.Log($"Expected to find 1 potential string delegate method; found {potentialStringDelegates.Count}. Candidates: {string.Join("\r\n", potentialStringDelegates.Select(x => x.FullName))}");
}
var methodDef = potentialStringDelegates[0];
MDToken deobfRid = methodDef.MDToken;
// Construct the token string (similar to Mono.Cecil's format)
token = $"0x{(deobfRid.Raw | deobfRid.Rid):x4}";
Console.WriteLine($"Deobfuscation token: {token}");
var process = Process.Start(executablePath,
$"--un-name \"!^<>[a-z0-9]$&!^<>[a-z0-9]__.*$&![A-Z][A-Z]\\$<>.*$&^[a-zA-Z_<{{$][a-zA-Z_0-9<>{{}}$.`-]*$\" \"{assemblyPath}\" --strtyp delegate --strtok \"{token}\"");
process.WaitForExit();
// Fixes "ResolutionScope is null" by rewriting the assembly
var cleanedDllPath = Path.Combine(Path.GetDirectoryName(assemblyPath), Path.GetFileNameWithoutExtension(assemblyPath) + "-cleaned.dll");
ModuleDefMD assemblyRewrite = null;
using (var memoryStream = new MemoryStream(File.ReadAllBytes(cleanedDllPath)))
{
assemblyRewrite = ModuleDefMD.Load(memoryStream, modCtx);
}
assemblyRewrite.Write(cleanedDllPath);
}
}