From b9bbf5af1ffef63e0ac5e451e773577e2f747397 Mon Sep 17 00:00:00 2001 From: Pyogenics Date: Sat, 10 May 2025 14:38:54 +0100 Subject: [PATCH] Deobfuscation utils are still ass --- utils/dasm.py | 2 +- utils/deob.py | 9 +--- utils/deobSingle.py | 88 +++++++++++++++++++++++++++++++++++++++ utils/generatemapping.py | 8 ++-- utils/generatepmapping.py | 26 ++++++++---- 5 files changed, 113 insertions(+), 20 deletions(-) create mode 100644 utils/deobSingle.py diff --git a/utils/dasm.py b/utils/dasm.py index d5ad74b..03b6efd 100644 --- a/utils/dasm.py +++ b/utils/dasm.py @@ -5,4 +5,4 @@ from sys import argv path = argv[1] paths = glob(f"{path}/*.abc") for path in paths: - subprocess.run(["rabcdasm", path]) \ No newline at end of file + subprocess.run(["RABCDAsm/rabcdasm", path]) \ No newline at end of file diff --git a/utils/deob.py b/utils/deob.py index 0e148f1..1968b76 100644 --- a/utils/deob.py +++ b/utils/deob.py @@ -16,15 +16,11 @@ detailMapping = {} with open(detailMappingPath, "r") as file: detailMapping = load(file) -paths = glob(f"{abcPath}/**/**/*.asasm") +paths = glob(f"{abcPath}/**/*.asasm", recursive=True) def deobfuscateFile(path): print(path) with open(path, "r+") as reader: - className = path.split("/")[-1] - className = className.split(".")[0] - packageName = path.split("/")[-2] - content_lines = reader.readlines() new_lines = [] @@ -44,11 +40,10 @@ def deobfuscateFile(path): rf"(^|[\"\/:]){fakePackageName}([\"\/:]|$)", rf"\1{realName}\2", line ) if fakeClassName in line: - realName = mapping[f"{fakePackageName}:{fakeClassName}"].split(":")[1] + realName = mapping[f"{fakePackageName}:{fakeClassName}"].split(":")[-1] line = re.sub( rf"(^|[\"\/:]){fakeClassName}([\"\/:]|$)", rf"\1{realName}\2", line ) - #classs = detailMapping[packageName][className] for package in detailMapping: for classs in detailMapping[package]: classs = detailMapping[package][classs] diff --git a/utils/deobSingle.py b/utils/deobSingle.py new file mode 100644 index 0000000..63b1a07 --- /dev/null +++ b/utils/deobSingle.py @@ -0,0 +1,88 @@ +from json import load +from sys import argv +from glob import glob +import re +from multiprocessing import Pool + +mappingPath = argv[1] +detailMappingPath = argv[2] +abcPath = argv[3] + +mapping = {} +with open(mappingPath, "r") as file: + mapping = load(file) + +detailMapping = {} +with open(detailMappingPath, "r") as file: + detailMapping = load(file) + +# paths = glob(f"{abcPath}/**/**/*.asasm") +# paths += glob(f"{abcPath}/**/*.asasm") + +def deobfuscateFile(path): + print(path) + with open(path, "r+") as reader: + content_lines = reader.readlines() + + new_lines = [] + + for index, line in enumerate(content_lines): + if ( + not line.strip().startswith("#include") + and not line.strip().startswith("pushstring") + and index != 0 + ): + for entry in mapping: + fakePackageName = entry.split(":")[0] + fakeClassName = entry.split(":")[1] + if fakePackageName in line: + realName = mapping[f"{fakePackageName}:{fakeClassName}"].split(":")[0] + line = re.sub( + rf"(^|[\"\/:]){fakePackageName}([\"\/:]|$)", rf"\1{realName}\2", line + ) + if fakeClassName in line: + realName = mapping[f"{fakePackageName}:{fakeClassName}"].split(":")[-1] + line = re.sub( + rf"(^|[\"\/:]){fakeClassName}([\"\/:]|$)", rf"\1{realName}\2", line + ) + for package in detailMapping: + for classs in detailMapping[package]: + classs = detailMapping[package][classs] + for member in classs: + realMember = classs[member] + if realMember == None: continue + + memberChain = member.split("/") + memberName = memberChain[-1] + if memberName == "setter" or memberName == "getter": + memberName = memberChain[-2] + elif memberName == "init" or memberName == "final" or memberName.rstrip() == "each" or memberName == "package": + continue + if ":" in memberName: + memberName = memberName.split(":")[-1] + + realMemberChain = realMember.split("/") + realMemberName = realMemberChain[-1] + if realMemberName == "set" or realMemberName == "get": + realMemberName = realMemberChain[-2] + if ":" in realMemberName: + realMemberName = realMemberName.split(":")[-1] + if realMemberName == memberName: + continue + + if memberName in line: + line = re.sub( + rf"(^|[\"\/:]){memberName}([\"\/:]|$)", rf"\1{realMemberName}\2", line + ) + + new_lines.append(line) + + # Reset the file to the beginning and truncate the content + reader.seek(0) + reader.truncate() + + # Then write the new contents to the file + reader.writelines(new_lines) + +# for path in paths: +deobfuscateFile(abcPath) \ No newline at end of file diff --git a/utils/generatemapping.py b/utils/generatemapping.py index fa0f848..be83c17 100644 --- a/utils/generatemapping.py +++ b/utils/generatemapping.py @@ -4,8 +4,7 @@ from glob import glob from json import dump path = argv[1] -paths = glob(f"{path}/**/**/*.class.asasm") -paths += glob(f"{path}/**/*.class.asasm") +paths = glob(f"{path}/**/*.class.asasm", recursive=True) names = {} for path in paths: @@ -30,7 +29,10 @@ for path in paths: line = line.split("refid \"") line = line[1][:-1] - names[packageName][className][line] = name + if name == None: + names[packageName][className][line] = None + elif ".as$" not in name: + names[packageName][className][line] = name with open("mapping.json", "w") as file: dump(names, file) \ No newline at end of file diff --git a/utils/generatepmapping.py b/utils/generatepmapping.py index d94fa19..607fe02 100644 --- a/utils/generatepmapping.py +++ b/utils/generatepmapping.py @@ -10,13 +10,21 @@ classMap = {} for packageName in mapping: package = mapping[packageName] for className in package: - clas = package[className] - func = list(clas.values()) - if len(func) != 0: - func = func[1] - realName = func.split("/")[0] - fakeName = f"{packageName}:{className}" - classMap[fakeName] = realName + clas = list(package[className].values()) + if len(clas) < 2: continue + chain = f"{packageName}:{className}" + functionName = clas[1] -with open("packagemap.json", "w") as file: - dump(classMap, file) \ No newline at end of file + realChain = "" + if len(functionName.split(":")) == 1: + realClassName = functionName.split(":")[-1].split("/")[0] + realChain = f"{realClassName}" + else: + realPackageName = functionName.split(":")[0] + realClassName = functionName.split(":")[-1].split("/")[0] + realChain = f"{realPackageName}:{realClassName}" + + classMap[chain] = realChain + +with open("packagemap.json", "w") as f: + dump(classMap, f) \ No newline at end of file