ApkPatcherX 0.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- apkpatcherx-0.0/ApkPatcher/ANSI_COLORS.py +56 -0
- apkpatcherx-0.0/ApkPatcher/APK_PATCHER.py +216 -0
- apkpatcherx-0.0/ApkPatcher/CLI.py +135 -0
- apkpatcherx-0.0/ApkPatcher/MODULES.py +34 -0
- apkpatcherx-0.0/ApkPatcher/Patch/AES.py +214 -0
- apkpatcherx-0.0/ApkPatcher/Patch/Ads_Patch.py +172 -0
- apkpatcherx-0.0/ApkPatcher/Patch/Cert_Net_Config.py +184 -0
- apkpatcherx-0.0/ApkPatcher/Patch/Flutter_SSL_Patch.py +145 -0
- apkpatcherx-0.0/ApkPatcher/Patch/Manifest_Patch.py +146 -0
- apkpatcherx-0.0/ApkPatcher/Patch/Package.py +26 -0
- apkpatcherx-0.0/ApkPatcher/Patch/Pairip_CoreX.py +74 -0
- apkpatcherx-0.0/ApkPatcher/Patch/Random_INFO.py +3616 -0
- apkpatcherx-0.0/ApkPatcher/Patch/Smali_Patch.py +379 -0
- apkpatcherx-0.0/ApkPatcher/Patch/Spoof_Patch.py +318 -0
- apkpatcherx-0.0/ApkPatcher/Patch/__init__.py +0 -0
- apkpatcherx-0.0/ApkPatcher/Utils/Anti_Splits.py +52 -0
- apkpatcherx-0.0/ApkPatcher/Utils/CRC.py +42 -0
- apkpatcherx-0.0/ApkPatcher/Utils/Credits.py +26 -0
- apkpatcherx-0.0/ApkPatcher/Utils/Decompile_Compile.py +161 -0
- apkpatcherx-0.0/ApkPatcher/Utils/Files_Check.py +145 -0
- apkpatcherx-0.0/ApkPatcher/Utils/Scan.py +118 -0
- apkpatcherx-0.0/ApkPatcher/Utils/__init__.py +0 -0
- apkpatcherx-0.0/ApkPatcher/__init__.py +0 -0
- apkpatcherx-0.0/ApkPatcherX.egg-info/PKG-INFO +186 -0
- apkpatcherx-0.0/ApkPatcherX.egg-info/SOURCES.txt +33 -0
- apkpatcherx-0.0/ApkPatcherX.egg-info/dependency_links.txt +1 -0
- apkpatcherx-0.0/ApkPatcherX.egg-info/entry_points.txt +3 -0
- apkpatcherx-0.0/ApkPatcherX.egg-info/requires.txt +4 -0
- apkpatcherx-0.0/ApkPatcherX.egg-info/top_level.txt +2 -0
- apkpatcherx-0.0/LICENSE +21 -0
- apkpatcherx-0.0/PKG-INFO +186 -0
- apkpatcherx-0.0/README.md +164 -0
- apkpatcherx-0.0/VERSION +1 -0
- apkpatcherx-0.0/pyproject.toml +51 -0
- apkpatcherx-0.0/setup.cfg +4 -0
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
# ————— 𝐀𝐍𝐒𝐈 𝐂𝐎𝐋𝐎𝐑𝐒 —————
|
|
2
|
+
|
|
3
|
+
class ANSI:
|
|
4
|
+
def __init__(self):
|
|
5
|
+
|
|
6
|
+
# =====🔸𝐀𝐍𝐒𝐈 𝐂𝐎𝐋𝐎𝐑𝐒🔸=====
|
|
7
|
+
|
|
8
|
+
self.ESC = '\033' # ( Octal )
|
|
9
|
+
|
|
10
|
+
# 𝐀𝐍𝐒𝐈 𝐂𝐎𝐋𝐎𝐑 ( 𝐁𝐎𝐋𝐃 = 𝟏𝐦 | 𝐃𝐀𝐑𝐊 = 𝟐𝐦 )
|
|
11
|
+
|
|
12
|
+
self.R = self.ESC + '[31;1m' # RED
|
|
13
|
+
self.G = self.ESC + '[32;1m' # GREEN
|
|
14
|
+
self.Y = self.ESC + '[33;1m' # YELLOW
|
|
15
|
+
self.B = self.ESC + '[34;1m' # BLUE
|
|
16
|
+
self.P = self.ESC + '[35;1m' # PURPLE
|
|
17
|
+
self.C = self.ESC + '[36;1m' # CYAN
|
|
18
|
+
self.W = self.ESC + '[37;1m' # WHITE
|
|
19
|
+
|
|
20
|
+
# 𝐁𝐑𝐈𝐆𝐇𝐓 𝐂𝐎𝐋𝐎𝐑
|
|
21
|
+
|
|
22
|
+
self.BR = self.ESC + '[91;1m' # BRIGHT RED
|
|
23
|
+
self.BG = self.ESC + '[92;1m' # BRIGHT GREEN
|
|
24
|
+
self.BY = self.ESC + '[93;1m' # BRIGHT YELLOW
|
|
25
|
+
self.BB = self.ESC + '[94;1m' # BRIGHT BLUE
|
|
26
|
+
self.BP = self.ESC + '[95;1m' # BRIGHT PURPLE
|
|
27
|
+
self.BC = self.ESC + '[96;1m' # BRIGHT CYAN
|
|
28
|
+
self.BW = self.ESC + '[97;1m' # BRIGHT WHITE
|
|
29
|
+
|
|
30
|
+
# 𝐎𝐓𝐇𝐄𝐑 𝐂𝐎𝐋𝐎𝐑
|
|
31
|
+
|
|
32
|
+
self.DG = self.ESC + '[32;2m' # DARK GREEN
|
|
33
|
+
self.GR = self.ESC + '[90;1m' # GRAY
|
|
34
|
+
|
|
35
|
+
# 𝟐𝟓𝟔 𝐂𝐨𝐥𝐨𝐫𝐬 ( 𝐄𝐒𝐂 + '[𝟑𝟖;𝟓;{𝐈𝐃}𝐦' ) [ 𝐈𝐃 - https://user-images.githubusercontent.com/995050/47952855-ecb12480-df75-11e8-89d4-ac26c50e80b9.png ]
|
|
36
|
+
|
|
37
|
+
self.PN = self.ESC + '[38;5;213;1m' # PINK
|
|
38
|
+
self.OG = self.ESC + '[38;5;202;1m' # ORANGE
|
|
39
|
+
|
|
40
|
+
# 𝐂𝐋𝐄𝐀𝐑 𝐂𝐎𝐃𝐄𝐒
|
|
41
|
+
|
|
42
|
+
self.CL = self.ESC + '[2K' # CLEAR LINE
|
|
43
|
+
self.CC = self.ESC + '[0m' # CLEAR COLOR
|
|
44
|
+
|
|
45
|
+
# 𝐌𝐎𝐑𝐄 𝐈𝐍𝐅𝐎 [ 𝐋𝐈𝐍𝐊 - https://gist.github.com/fnky/458719343aabd01cfb17a3a4f7296797 ]
|
|
46
|
+
|
|
47
|
+
# =====🔹𝐓𝐀𝐆🔹=====
|
|
48
|
+
|
|
49
|
+
self.S = f'{self.B}[{self.C}'
|
|
50
|
+
self.E = f'{self.B}]'
|
|
51
|
+
self.X = f'{self.B}[ {self.P}* {self.B}]'
|
|
52
|
+
self.FYI = f'{self.B}[ {self.P}FYI {self.B}]'
|
|
53
|
+
self.INFO = f'{self.B}[ {self.Y}INFO {self.B}]{self.C}'
|
|
54
|
+
self.WARN = f'{self.B}[ {self.Y}WARN {self.B}]{self.B}'
|
|
55
|
+
self.ERROR = f'{self.B}[ {self.R}ERROR {self.B}]{self.R}'
|
|
56
|
+
self.SUGGEST = f'{self.B}[ {self.Y}SUGGEST {self.B}]{self.C}'
|
|
@@ -0,0 +1,216 @@
|
|
|
1
|
+
from .CLI import parse_arguments
|
|
2
|
+
from .ANSI_COLORS import ANSI; C = ANSI()
|
|
3
|
+
from .MODULES import IMPORT; M = IMPORT()
|
|
4
|
+
|
|
5
|
+
from ApkPatcher.Utils.CRC import CRC_Fix
|
|
6
|
+
from ApkPatcher.Utils.Credits import Credits
|
|
7
|
+
from ApkPatcher.Utils.Scan import Scan_Apk
|
|
8
|
+
from ApkPatcher.Utils.Anti_Splits import Anti_Split
|
|
9
|
+
from ApkPatcher.Utils.Files_Check import FileCheck, __version__
|
|
10
|
+
from ApkPatcher.Utils.Decompile_Compile import Decompile_Apk, Recompile_Apk, FixSigBlock, Sign_Apk
|
|
11
|
+
|
|
12
|
+
from ApkPatcher.Patch.AES import Copy_AES_Smali
|
|
13
|
+
from ApkPatcher.Patch.Smali_Patch import Smali_Patch
|
|
14
|
+
from ApkPatcher.Patch.Ads_Patch import Ads_Smali_Patch
|
|
15
|
+
from ApkPatcher.Patch.Spoof_Patch import Patch_Random_Info
|
|
16
|
+
from ApkPatcher.Patch.Cert_Net_Config import Write_Net_Config
|
|
17
|
+
from ApkPatcher.Patch.Flutter_SSL_Patch import Patch_Flutter_SSL
|
|
18
|
+
from ApkPatcher.Patch.Pairip_CoreX import Check_CoreX, Hook_Core
|
|
19
|
+
from ApkPatcher.Patch.Manifest_Patch import Fix_Manifest, Patch_Manifest, Permission_Manifest
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
def Clear():
|
|
23
|
+
M.os.system('cls' if M.os.name == 'nt' else 'clear')
|
|
24
|
+
Clear()
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
# ---------------- Install Require Module ---------------
|
|
28
|
+
required_modules = ['requests', 'r2pipe', 'asn1crypto', 'multiprocess']
|
|
29
|
+
for module in required_modules:
|
|
30
|
+
try:
|
|
31
|
+
__import__(module)
|
|
32
|
+
except ImportError:
|
|
33
|
+
print(f"{C.S} Installing {C.E} {C.OG}➸❥ {C.G}{module}...\n")
|
|
34
|
+
try:
|
|
35
|
+
M.subprocess.check_call([M.sys.executable, "-m", "pip", "install", module])
|
|
36
|
+
Clear()
|
|
37
|
+
except (M.subprocess.CalledProcessError, Exception):
|
|
38
|
+
exit(
|
|
39
|
+
f"\n{C.ERROR} No Internet Connection. ✘\n"
|
|
40
|
+
f"\n{C.INFO} Internet Connection is Required to Install {C.G} pip install {module}\n"
|
|
41
|
+
)
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
# ---------------- Check Dependencies ---------------
|
|
45
|
+
def check_dependencies():
|
|
46
|
+
try:
|
|
47
|
+
M.subprocess.run(['java', '-version'], stdout=M.subprocess.PIPE, stderr=M.subprocess.PIPE, check=True, text=True)
|
|
48
|
+
except (M.subprocess.CalledProcessError, FileNotFoundError):
|
|
49
|
+
if M.os.name == 'posix':
|
|
50
|
+
install_package('openjdk-17')
|
|
51
|
+
else:
|
|
52
|
+
exit(
|
|
53
|
+
f'\n\n{C.ERROR} Java is not installed on Your System. ✘\n'
|
|
54
|
+
f'\n{C.INFO} Install Java & Run Script Again in New CMD. ✘\n'
|
|
55
|
+
f'\n{C.INFO} Verify Java Installation {C.G} java --version\n'
|
|
56
|
+
)
|
|
57
|
+
|
|
58
|
+
if M.os.name == 'posix': install_package('aapt')
|
|
59
|
+
|
|
60
|
+
|
|
61
|
+
# ---------------- Install Package ---------------
|
|
62
|
+
def install_package(pkg):
|
|
63
|
+
try:
|
|
64
|
+
result = M.subprocess.run(['pkg', 'list-installed'], stdout=M.subprocess.PIPE, stderr=M.subprocess.PIPE, text=True)
|
|
65
|
+
if pkg not in result.stdout:
|
|
66
|
+
print(f"{C.S} Installing {C.E} {C.OG}➸❥ {C.G}{pkg}...\n")
|
|
67
|
+
M.subprocess.check_call(['pkg', 'install', '-y', pkg])
|
|
68
|
+
Clear()
|
|
69
|
+
except (M.subprocess.CalledProcessError, Exception):
|
|
70
|
+
exit(
|
|
71
|
+
f"\n\n{C.ERROR} No Internet Connection. ✘\n"
|
|
72
|
+
f"\n{C.INFO} Internet Connection is Required to Installation {C.G}pkg install {pkg}\n"
|
|
73
|
+
)
|
|
74
|
+
|
|
75
|
+
check_dependencies()
|
|
76
|
+
|
|
77
|
+
F = FileCheck(); F.Set_Path(); F.F_D()
|
|
78
|
+
|
|
79
|
+
Date = M.datetime.now().strftime('%d/%m/%y')
|
|
80
|
+
print(f"{C.OG}{f'v{__version__}':>22}")
|
|
81
|
+
|
|
82
|
+
# Logo ( 🙏 )
|
|
83
|
+
b64 = """eJzVlc9LAkEUx8/Ov9DlMXgNzLAfeMlUSAQLETx4ELGlJEehnEPgQSrqUlFYdIroHNShixDRP1DQn1DaqUv+Cc3MzszOrFtUt96u+2O+n/fmvTe7LoCwsdIEGStNzsRj8WgkSoYXe9fsdwtFp15tEsfSp8n8phyYjZKCU11tNCHTWK5V2GhE+yIUCgF1DYFplIY9s0RLGdG56EsU5PTjRgLcyfIJMk1IQNcDiaUsLCUKyYV0XoUL4H8QErNLbJxNBCtA4FSOikGdOufBj/DYAQS1L72WYreH7CB5ak+iUzPTtHSvZH32LWcYGxsX2Yp7KdIwyI2KJNx1ZpgIZ5TCURqm3qAAkNKona5qn3pkkP1QCZSbnM5QkXDG2MQpWA+fq7IuyAA8lh2e3TPNbASfBHxRkVwZI7QPkpqqUs2OjcAWLqbERv0j5uIqt685UM9bKFjUb8Swu7MFr4eX71fn/Z1jGHZ3j+CjdzfY3uufHr31OvDycAbPN4/3T90sP/B7/uKgfuckcG9/JXy//8XtFz4WiqweTJFchTi8Jtmbtq0WnLqzsl4hmmj73BeLuXTe56/FVKXl/Pt++f6XB51988Mw6ByI6tvqQxIjc+trLUHUONDYGNHz2XIhnVzILZYzuVQmITr0CawgFWQ="""
|
|
84
|
+
print(f"{M.zlib.decompress(M.base64.b64decode(b64)).decode('utf-8').rstrip('\n')} | {C.B}{Date}{C.CC}")
|
|
85
|
+
print("————————|——————————————————|—————————————————|——————————————|————")
|
|
86
|
+
|
|
87
|
+
|
|
88
|
+
# ---------------- Target All Classes Folder ---------------
|
|
89
|
+
def Find_Smali_Folders(decompile_dir, isAPKEditor):
|
|
90
|
+
|
|
91
|
+
smali_path = M.os.path.join(decompile_dir, "smali") if isAPKEditor else decompile_dir
|
|
92
|
+
|
|
93
|
+
prefix = "classes" if isAPKEditor else "smali_classes"
|
|
94
|
+
|
|
95
|
+
folders = sorted([f for f in M.os.listdir(smali_path) if f == "smali" or f.startswith(prefix)], key=lambda x: int(x.split(prefix)[-1]) if x.split(prefix)[-1].isdigit() else 0)
|
|
96
|
+
|
|
97
|
+
return [M.os.path.join(smali_path, f) for f in folders]
|
|
98
|
+
|
|
99
|
+
|
|
100
|
+
# ---------------- Execute Main Function ---------------
|
|
101
|
+
def RK_Techno_IND():
|
|
102
|
+
args = parse_arguments()
|
|
103
|
+
isCoreX = args.Hook_CoreX
|
|
104
|
+
isFlutter = args.Flutter; isPairip = args.Pairip
|
|
105
|
+
Skip_Patch = args.Skip_Patch if args.Skip_Patch else []
|
|
106
|
+
isAPKEditor = args.APKEditor; isEmulator = args.For_Emulator
|
|
107
|
+
|
|
108
|
+
if isEmulator:
|
|
109
|
+
F.isEmulator()
|
|
110
|
+
F.F_D_A()
|
|
111
|
+
|
|
112
|
+
if args.Credits_Instruction:
|
|
113
|
+
Credits()
|
|
114
|
+
|
|
115
|
+
apk_path = args.input or args.Merge
|
|
116
|
+
|
|
117
|
+
if not M.os.path.isfile(apk_path):
|
|
118
|
+
exit(
|
|
119
|
+
f"\n{C.ERROR} APK file '{apk_path}' not found. ✘\n\n"
|
|
120
|
+
f"\n{C.FYI}{C.G} Make Sure There Is 'No Extra Space' In The Folder/Apk Name In The Input Text. If Yes, Then Remove Extra Space & Correct It By Renaming It.\n"
|
|
121
|
+
)
|
|
122
|
+
|
|
123
|
+
if args.CA_Certificate:
|
|
124
|
+
isCert = [Cert for Cert in args.CA_Certificate if not M.os.path.isfile(Cert)]
|
|
125
|
+
|
|
126
|
+
if isCert:
|
|
127
|
+
exit(f"\n{C.ERROR} Not exist: {', '.join(isCert)}\n")
|
|
128
|
+
|
|
129
|
+
apk_path = Anti_Split(apk_path, args.Merge, isCoreX)
|
|
130
|
+
|
|
131
|
+
# ---------------- Set All Paths Directory ----------------
|
|
132
|
+
decompile_dir = M.os.path.join(M.os.path.expanduser("~"), f"{M.os.path.splitext(M.os.path.basename(apk_path))[0]}_decompiled")
|
|
133
|
+
|
|
134
|
+
build_dir = M.os.path.abspath(M.os.path.join(M.os.path.dirname(apk_path), f"{M.os.path.splitext(M.os.path.basename(apk_path))[0]}_Patched.apk"))
|
|
135
|
+
|
|
136
|
+
rebuild_dir = build_dir.replace('_Patched.apk', '_Patch.apk')
|
|
137
|
+
|
|
138
|
+
manifest_path = M.os.path.join(decompile_dir, 'AndroidManifest.xml')
|
|
139
|
+
|
|
140
|
+
if M.os.name == 'posix':
|
|
141
|
+
M.subprocess.run(['termux-wake-lock'])
|
|
142
|
+
print(f"\n{C.X} {C.C} Acquiring Wake Lock...\r")
|
|
143
|
+
|
|
144
|
+
start_time = M.time.time()
|
|
145
|
+
|
|
146
|
+
# ---------------- Scan & Decompile APK ---------------
|
|
147
|
+
Package_Name, isFlutter_lib, isPairip_lib = Scan_Apk(apk_path, isFlutter, isPairip)
|
|
148
|
+
Decompile_Apk(apk_path, decompile_dir, isEmulator, isAPKEditor, args.AES_Logs)
|
|
149
|
+
smali_folders = Find_Smali_Folders(decompile_dir, isAPKEditor)
|
|
150
|
+
|
|
151
|
+
# ---------------- AES Logs Inject ----------------
|
|
152
|
+
if args.AES_Logs:
|
|
153
|
+
Copy_AES_Smali(decompile_dir, smali_folders, manifest_path, args.AES_S, isAPKEditor)
|
|
154
|
+
Permission_Manifest(decompile_dir, manifest_path, isAPKEditor)
|
|
155
|
+
|
|
156
|
+
# ---------------- Remove Ads ----------------
|
|
157
|
+
if args.Remove_Ads:
|
|
158
|
+
Ads_Smali_Patch(smali_folders)
|
|
159
|
+
|
|
160
|
+
# ---------------- Fake / Spoof Device Info ----------------
|
|
161
|
+
if args.Random_Info:
|
|
162
|
+
Patch_Random_Info(smali_folders, args.Android_ID)
|
|
163
|
+
|
|
164
|
+
if args.AES_Logs or args.Remove_Ads or args.Random_Info:
|
|
165
|
+
Fix_Manifest(manifest_path, smali_folders, args.Spoof_PKG)
|
|
166
|
+
else:
|
|
167
|
+
if isFlutter and isFlutter_lib:
|
|
168
|
+
Patch_Flutter_SSL(decompile_dir, isAPKEditor)
|
|
169
|
+
|
|
170
|
+
# ---------------- Smali Patching / Hook CoreX ----------------
|
|
171
|
+
if isCoreX and isPairip and isPairip_lib and Check_CoreX(decompile_dir, isAPKEditor):
|
|
172
|
+
M.shutil.rmtree(decompile_dir)
|
|
173
|
+
exit(1)
|
|
174
|
+
|
|
175
|
+
Smali_Patch(decompile_dir, smali_folders, isAPKEditor, args.CA_Certificate, args.Android_ID, isPairip, isPairip_lib, args.Spoof_PKG, args.Purchase, args.Remove_SC, Skip_Patch, args.Remove_USB, isCoreX)
|
|
176
|
+
|
|
177
|
+
if isCoreX and isPairip and isPairip_lib:
|
|
178
|
+
Hook_Core(args.input, decompile_dir, isAPKEditor, Package_Name)
|
|
179
|
+
|
|
180
|
+
# ---------------- Patch Manifest & Write Network Config ----------------
|
|
181
|
+
Fix_Manifest(manifest_path, smali_folders, args.Spoof_PKG)
|
|
182
|
+
Patch_Manifest(decompile_dir, manifest_path)
|
|
183
|
+
Write_Net_Config(decompile_dir, isAPKEditor, args.CA_Certificate)
|
|
184
|
+
|
|
185
|
+
# ---------------- Recompile APK ----------------
|
|
186
|
+
Recompile_Apk(decompile_dir, apk_path, build_dir, isEmulator, isAPKEditor)
|
|
187
|
+
|
|
188
|
+
# ---------------- Fix CRC / Sign APK ----------------
|
|
189
|
+
if not isCoreX and isPairip and isPairip_lib:
|
|
190
|
+
|
|
191
|
+
if not isAPKEditor:
|
|
192
|
+
FixSigBlock(decompile_dir, apk_path, build_dir, rebuild_dir);
|
|
193
|
+
|
|
194
|
+
CRC_Fix(apk_path, build_dir, ["AndroidManifest.xml", ".dex"])
|
|
195
|
+
|
|
196
|
+
else:
|
|
197
|
+
Sign_Apk(build_dir)
|
|
198
|
+
|
|
199
|
+
if M.os.path.exists(build_dir):
|
|
200
|
+
print(f'{C.S} Final APK {C.E} {C.G}︻デ═一 {C.Y} {build_dir} {C.G}✔')
|
|
201
|
+
|
|
202
|
+
print(f"\n{C.CC}{'_' * 61}\n")
|
|
203
|
+
|
|
204
|
+
if not isCoreX and isPairip and isPairip_lib:
|
|
205
|
+
print(f'\n{C.FYI}{C.C} This is Pairip Apk So U Install {C.G}( Keep Apk Without Sign ) {C.C}in VM / Multi_App\n')
|
|
206
|
+
|
|
207
|
+
elapsed_time = M.time.time() - start_time
|
|
208
|
+
|
|
209
|
+
print(f'\n{C.S} Time Spent {C.E} {C.G}︻デ═一 {C.PN}{elapsed_time:.2f} {C.CC}Seconds {C.G}✔\n')
|
|
210
|
+
|
|
211
|
+
print(f'\n🚩 {C.CC}࿗ {C.OG}Jai Shree Ram {C.CC}࿗ 🚩\n 🛕🛕🙏🙏🙏🛕🛕\n')
|
|
212
|
+
|
|
213
|
+
if M.os.name == 'posix':
|
|
214
|
+
M.subprocess.run(['termux-wake-unlock'])
|
|
215
|
+
exit(f"\n{C.X} {C.C} Releasing Wake Lock...\n")
|
|
216
|
+
exit(0)
|
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
from .ANSI_COLORS import ANSI; C = ANSI()
|
|
2
|
+
from .MODULES import IMPORT; M = IMPORT()
|
|
3
|
+
|
|
4
|
+
from ApkPatcher.Utils.Files_Check import __version__
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
Tag = f"\n{C.CC}————|———————|————{C.G}•❀ {C.OG}Tag {C.G}❀•{C.CC}————|———————|————\n"
|
|
8
|
+
EX = f"{C.P}\n |\n ╰{C.CC}┈{C.OG}➢ {C.G}ApkPatcher -i Your_Apk_Path.apk {C.OG}"
|
|
9
|
+
Info = f"{C.B}[ {C.Y}INFO {C.B}] {C.C}"
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
class CustomArgumentParser(M.argparse.ArgumentParser):
|
|
13
|
+
# ---------------- Error Handling ----------------
|
|
14
|
+
def error(self, message):
|
|
15
|
+
suggestion = ""
|
|
16
|
+
for action in self._actions:
|
|
17
|
+
if action.option_strings and any(option in message for option in action.option_strings):
|
|
18
|
+
if action.dest == 'input':
|
|
19
|
+
suggestion = f'\n{C.B}[ {C.Y}FYI ! {C.B}] {C.G}Make Sure There Is "No Extra Space" In The Folder/Apk Name In The Input Text. If Yes, Then Remove Extra Space & Correct It By Renaming It.\n\n\n{Info}With Your Certificate Flag: {C.OG}-c {C.P}( Input Your pem/crt/cert Path ){EX}-c {C.Y}certificate.cert\n\n\n{Info}If you are using an Emulator in PC Then Use Flag: {C.OG}-e{EX}-c {C.Y}certificate.cert {C.OG}-e\n'
|
|
20
|
+
elif action.dest == 'Merge':
|
|
21
|
+
suggestion = f'\n{Info}Only Merge Apk\n\n\n{Info}Merge Extension {C.Y}( .apks/.xapk/.apkm )\n\n\n{C.B}[ {C.Y}Ex. {C.B}] {C.G}ApkPatcher {C.OG}-m {C.G}Your_Apk_Path.apks\n'
|
|
22
|
+
break
|
|
23
|
+
|
|
24
|
+
exit(f'\n{C.B}[ {C.R}Error ! {C.B}] {C.R} {message}\n\n{suggestion}')
|
|
25
|
+
|
|
26
|
+
# ---------------- Print Help ----------------
|
|
27
|
+
def print_help(self):
|
|
28
|
+
super().print_help()
|
|
29
|
+
print(f"\n{Info} ApkPatcher Default Patch is VPN & SSL Bypass, Show Other Patch Flags List with: {C.G}ApkPatcher -O{C.C}\n")
|
|
30
|
+
|
|
31
|
+
# ---------------- Other Patch ----------------
|
|
32
|
+
def Other_Patch(self):
|
|
33
|
+
print(f"""\n{C.B}[ {C.P}* {C.B}] {C.C}Other Patch Flags Help ( Keep Sequence in Mind )
|
|
34
|
+
|
|
35
|
+
<Flags> {C.G}─•❀•❀ {C.C}Info Patch {C.G}❀•❀•─{C.OG}
|
|
36
|
+
|
|
37
|
+
-A, {C.C}--AES_Logs {C.Y}➸ {C.G}AES Logs Inject{C.OG}
|
|
38
|
+
-D, {C.C}--Android_ID {C.Y}➸ {C.G}Hook Android ID for One Device Login Bypass{C.OG}
|
|
39
|
+
-f, {C.C}--Flutter {C.Y}➸ {C.G}Flutter SSL Bypass{C.OG}
|
|
40
|
+
-p, {C.C}--Pairip {C.Y}➸ {C.G}Pairip CERT SSL Bypass (No Sign){C.OG}
|
|
41
|
+
-P, {C.C}--Purchase {C.Y}➸ {C.G}Purchase/Paid/Price{C.OG}
|
|
42
|
+
-r, {C.C}--Random_Info {C.Y}➸ {C.G}Fake Device Info{C.OG}
|
|
43
|
+
-rmads, {C.C}--Remove_Ads {C.Y}➸ {C.G}Bypass Ads{C.OG}
|
|
44
|
+
-rmsc, {C.C}--Remove_SC {C.Y}➸ {C.G}Bypass Screenshot Restriction{C.OG}
|
|
45
|
+
-rmu, {C.C}--Remove_USB {C.Y}➸ {C.G}Bypass USB Debugging Permission{C.OG}
|
|
46
|
+
-pkg, {C.C}--Spoof_PKG {C.Y}➸ {C.G}Spoof Package Detection{C.OG}
|
|
47
|
+
-skip {C.C}[Skip_Patch ...] {C.Y}➸ {C.G}Skip Specific Patches (e.g. getAcceptedIssuers){C.OG}
|
|
48
|
+
-s, {C.C}--AES_S {C.Y}➸ {C.G}Do U Want Separate AES.smali Dex{C.OG}
|
|
49
|
+
-x, {C.C}--Hook_CoreX {C.Y}➸ {C.G}Hook CoreX Flag: {C.OG}-p -x {C.P}( Only For [ arm64 ] )""")
|
|
50
|
+
user_input = input(f"\n\n{C.B}[ {C.P}* {C.B}] {C.C} Do See Example\n{C.G} |\n └──── {C.CC}~ y / Exit to Enter {C.G}$ : {C.Y}")
|
|
51
|
+
|
|
52
|
+
if user_input.lower() == "y":
|
|
53
|
+
print(f"""\n{Tag.replace("Tag", "AES Logs Inject")}
|
|
54
|
+
|
|
55
|
+
{Info}AES MT Logs Inject Flag: {C.OG}-A{EX}-A\n\n\n{Info}Do U Want Separate AES.smali Dex Use Flag: {C.OG}-A -s{EX}-A -s
|
|
56
|
+
|
|
57
|
+
{Tag.replace("Tag", "Hook Android ID")}
|
|
58
|
+
|
|
59
|
+
{Info}Hook Android ID For One Device Login Bypass Use Flag: {C.OG}-D {C.P}( Input Your Original 16 Digit Android ID ){EX}-D {C.Y}7e9f51f096bd5c83
|
|
60
|
+
|
|
61
|
+
{Tag.replace("Tag", "isFlutter / isPairip")}
|
|
62
|
+
|
|
63
|
+
{Info}If Apk is Flutter Then Use Additional Flag: {C.OG}-f{EX}-f {C.Y}-c certificate.cert\n\n\n{Info}If Apk is Pairip Then Use Additional Flag: {C.OG}-p {C.P}( Without Sign Apk Use Only in VM / Multi_App ){EX}-p {C.Y}-c certificate.cert\n\n\n{Info}If Apk is Pairip Then Hook CoreX Use Additional Flag: {C.OG}-p -x {C.P}( Install Directly Only For [ arm64 ] ){EX}-p -x {C.Y}-c certificate.cert
|
|
64
|
+
|
|
65
|
+
{Tag.replace("Tag", "Spoof PKG / Device Info")}
|
|
66
|
+
|
|
67
|
+
{Info}Spoof Package Detection Flag: {C.OG}-pkg {C.P}( Dex / Manifest / Res ){EX}-pkg\n\n\n{Info}Fake Device Info Flag: {C.OG}-r{EX}-r\n\n\n{Info}With Your Android ID Flag: {C.OG}-r -D {C.P}( Input Your Custom 16 Digit Android ID ){EX}-r -D {C.Y}7e9f51f096bd5c83
|
|
68
|
+
|
|
69
|
+
{Tag.replace("Tag", "Bypass Ads / SC / USB")}
|
|
70
|
+
|
|
71
|
+
{Info}Bypass Ads Flag: {C.OG}-rmads{EX}-rmads\n\n\n{Info}Bypass Screenshot Restriction Flag: {C.OG}-rmsc{EX}-rmsc\n\n\n{Info}Bypass USB Debugging Permission Flag: {C.OG}-rmu{EX}-rmu
|
|
72
|
+
|
|
73
|
+
{Tag.replace("Tag", "isPurchase / Skip Patch")}
|
|
74
|
+
|
|
75
|
+
{Info}Purchase / Paid / Price Flag: {C.OG}-P{EX}-P\n\n\n{Info}Skip Patch Flag: {C.OG}-skip{EX}-skip {C.Y}getAcceptedIssuers\n""")
|
|
76
|
+
else:return
|
|
77
|
+
|
|
78
|
+
|
|
79
|
+
# ---------------- Parse Arguments ----------------
|
|
80
|
+
def parse_arguments():
|
|
81
|
+
args = M.sys.argv[1:]
|
|
82
|
+
if '-O' in args: exit(CustomArgumentParser().Other_Patch())
|
|
83
|
+
|
|
84
|
+
|
|
85
|
+
if any(arg.startswith('-') for arg in args):
|
|
86
|
+
parser = CustomArgumentParser(description=f'{C.C}ApkPatcher v{__version__}')
|
|
87
|
+
else:
|
|
88
|
+
parser = M.argparse.ArgumentParser(description=f'{C.C}ApkPatcher v{__version__}')
|
|
89
|
+
|
|
90
|
+
group = parser.add_mutually_exclusive_group(required=True)
|
|
91
|
+
|
|
92
|
+
group.add_argument('-i', dest='input', help=f'{C.Y}➸{C.G} Input APK Path...{C.C}')
|
|
93
|
+
group.add_argument('-m', dest='Merge', help=f'{C.Y}➸{C.G} Anti-Split ( Only Merge Apk ){C.C}')
|
|
94
|
+
group.add_argument('-C', dest='Credits_Instruction', action='store_true', help=f'{C.Y}➸{C.G} Show Instructions & Credits{C.C}')
|
|
95
|
+
|
|
96
|
+
additional = parser.add_argument_group(f'{C.OG}[ * ] Additional Flags{C.C}')
|
|
97
|
+
additional.add_argument('-a', '--APKEditor', action='store_true', help=f'{C.Y}➸ {C.G}APKEditor ( Default APKTool ){C.C}')
|
|
98
|
+
additional.add_argument('-e', '--For_Emulator', action='store_true', help=f'{C.Y}➸{C.G} If using emulator on PC then use -e flag{C.C}')
|
|
99
|
+
additional.add_argument('-c', dest='CA_Certificate', type=str, nargs='*', help=f"{C.Y}➸{C.G} Input Your HttpCanary/Reqable/ProxyPin etc. Capture Apk's CA-Certificate{C.C}")
|
|
100
|
+
|
|
101
|
+
# ---------------- Other Patch Flags ----------------
|
|
102
|
+
parser.add_argument('-A', '--AES_Logs', action='store_true', help=M.argparse.SUPPRESS)
|
|
103
|
+
parser.add_argument('-D', '--Android_ID', type=str, help=M.argparse.SUPPRESS)
|
|
104
|
+
parser.add_argument('-f', '--Flutter', action='store_true', help=M.argparse.SUPPRESS)
|
|
105
|
+
parser.add_argument('-p', '--Pairip', action='store_true', help=M.argparse.SUPPRESS)
|
|
106
|
+
parser.add_argument('-P', '--Purchase', action='store_true', help=M.argparse.SUPPRESS)
|
|
107
|
+
parser.add_argument('-r', '--Random_Info', action='store_true', help=M.argparse.SUPPRESS)
|
|
108
|
+
parser.add_argument('-rmads', '--Remove_Ads', action='store_true', help=M.argparse.SUPPRESS)
|
|
109
|
+
parser.add_argument('-rmsc', '--Remove_SC', action='store_true', help=M.argparse.SUPPRESS)
|
|
110
|
+
parser.add_argument('-rmu', '--Remove_USB', action='store_true', help=M.argparse.SUPPRESS)
|
|
111
|
+
parser.add_argument('-pkg', '--Spoof_PKG', action='store_true', help=M.argparse.SUPPRESS)
|
|
112
|
+
parser.add_argument('-skip', dest='Skip_Patch', nargs='*', help=M.argparse.SUPPRESS)
|
|
113
|
+
parser.add_argument('-s', '--AES_S', action='store_true', help=M.argparse.SUPPRESS)
|
|
114
|
+
parser.add_argument('-x', '--Hook_CoreX', action='store_true', help=M.argparse.SUPPRESS)
|
|
115
|
+
|
|
116
|
+
|
|
117
|
+
Ext = ('.apk', '.apks', '.apkm', '.xapk')
|
|
118
|
+
fixed = []; start = None; Valid_Ext = False
|
|
119
|
+
|
|
120
|
+
for index, option in enumerate(args):
|
|
121
|
+
if option in ['-i', '-m', '-C']:
|
|
122
|
+
start, fixed = index + 1, fixed + [option]
|
|
123
|
+
elif start and (option.endswith(Ext) or M.os.path.isdir(option)):
|
|
124
|
+
fixed, start = fixed + [' '.join(args[start:index+1])], None
|
|
125
|
+
Valid_Ext = True
|
|
126
|
+
elif not start:
|
|
127
|
+
fixed.append(option)
|
|
128
|
+
|
|
129
|
+
|
|
130
|
+
if not Valid_Ext and M.sys.argv[1:2] != ['-C']:
|
|
131
|
+
print(f"\n{C.X} {C.C} Only Supported Extensions {C.G}{Ext}\n")
|
|
132
|
+
|
|
133
|
+
print(f"\n{C.S} Input Path {C.E} {C.G}➸❥{C.Y}", *fixed, f"{C.CC}\n")
|
|
134
|
+
|
|
135
|
+
return parser.parse_args(fixed)
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
# ————— 𝐈𝐌𝐏𝐎𝐑𝐓 𝐌𝐎𝐃𝐔𝐋𝐄𝐒 —————
|
|
2
|
+
|
|
3
|
+
class IMPORT:
|
|
4
|
+
def __init__(self):
|
|
5
|
+
|
|
6
|
+
# ---------------- 𝐌𝐮𝐥𝐭𝐢𝐏𝐫𝐨𝐜𝐞𝐬𝐬 / 𝐌𝐮𝐥𝐭𝐢𝐏𝐫𝐨𝐜𝐞𝐬𝐬𝐢𝐧𝐠 ----------------
|
|
7
|
+
try:
|
|
8
|
+
mp = __import__('multiprocess')
|
|
9
|
+
except ImportError:
|
|
10
|
+
mp = __import__('multiprocessing')
|
|
11
|
+
|
|
12
|
+
# ————— 𝐋𝐢𝐛𝐫𝐚𝐫𝐢𝐞𝐬 𝐈𝐦𝐩𝐨𝐫𝐭 —————
|
|
13
|
+
self.re = __import__('re')
|
|
14
|
+
self.os = __import__('os')
|
|
15
|
+
self.sys = __import__('sys')
|
|
16
|
+
self.zlib = __import__('zlib')
|
|
17
|
+
self.json = __import__('json')
|
|
18
|
+
self.time = __import__('time')
|
|
19
|
+
self.shutil = __import__('shutil')
|
|
20
|
+
self.string = __import__('string')
|
|
21
|
+
self.zipfile = __import__('zipfile')
|
|
22
|
+
self.hashlib = __import__('hashlib')
|
|
23
|
+
self.base64 = __import__('base64')
|
|
24
|
+
self.binascii = __import__('binascii')
|
|
25
|
+
self.random = __import__('random')
|
|
26
|
+
self.argparse = __import__('argparse')
|
|
27
|
+
self.subprocess = __import__('subprocess')
|
|
28
|
+
|
|
29
|
+
# ————— 𝐄𝐱𝐭𝐫𝐚 𝐋𝐢𝐛𝐫𝐚𝐫𝐢𝐞𝐬 —————
|
|
30
|
+
self.Pool = mp.Pool
|
|
31
|
+
self.Manager = mp.Manager
|
|
32
|
+
self.cpu_count = mp.cpu_count
|
|
33
|
+
self.datetime = __import__('datetime').datetime
|
|
34
|
+
|
|
@@ -0,0 +1,214 @@
|
|
|
1
|
+
from ..ANSI_COLORS import ANSI; C = ANSI()
|
|
2
|
+
from ..MODULES import IMPORT; M = IMPORT()
|
|
3
|
+
|
|
4
|
+
from collections import defaultdict
|
|
5
|
+
from ApkPatcher.Utils.Files_Check import FileCheck
|
|
6
|
+
|
|
7
|
+
F = FileCheck(); F.Set_Path()
|
|
8
|
+
C_Line = f"{C.CC}{'_' * 61}"
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
# ---------------- Regex Scan ----------------
|
|
12
|
+
def R_S_F(smali_folders):
|
|
13
|
+
for smali_folder in smali_folders:
|
|
14
|
+
for root, _, files in M.os.walk(smali_folder):
|
|
15
|
+
for file in files:
|
|
16
|
+
file_path = M.os.path.join(root, file)
|
|
17
|
+
yield file_path, open(file_path, 'r', encoding='utf-8', errors='ignore').read()
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
# ---------------- AES Logs Inject ----------------
|
|
21
|
+
def AES_Logs_Inject(decompile_dir, smali_folders):
|
|
22
|
+
reg = M.re.compile(r'"AES/[^/]+/[^"]+"')
|
|
23
|
+
Class_P = M.re.compile(r'\.class[^;]* (L[^;]+;)')
|
|
24
|
+
Met_P = M.re.compile(r'\.method.*?\s([a-zA-Z0-9_<>\$]+)\((.*?)\)(.*)')
|
|
25
|
+
|
|
26
|
+
Match_F = defaultdict(list)
|
|
27
|
+
|
|
28
|
+
matched_files = []
|
|
29
|
+
|
|
30
|
+
total_files = 0
|
|
31
|
+
|
|
32
|
+
for file_path, content in R_S_F(smali_folders):
|
|
33
|
+
if "Ljavax/crypto/Cipher;->doFinal([B)[B" in content and "Ljavax/crypto/spec/SecretKeySpec;" in content and "Ljavax/crypto/spec/IvParameterSpec;" in content:
|
|
34
|
+
|
|
35
|
+
Class_N = Class_P.search(content)[1]
|
|
36
|
+
|
|
37
|
+
for block in content.split('.method')[1:]:
|
|
38
|
+
|
|
39
|
+
if reg.search(block):
|
|
40
|
+
Met_M = Met_P.search(".method" + block.split('\n', 1)[0])
|
|
41
|
+
|
|
42
|
+
if Met_M:
|
|
43
|
+
total_files += 1
|
|
44
|
+
|
|
45
|
+
Met_Sig = f"{Met_M[1]}({Met_M[2]}){Met_M[3]}"
|
|
46
|
+
|
|
47
|
+
match = f"{Class_N}->{Met_Sig}"
|
|
48
|
+
|
|
49
|
+
Match_F[match].append(file_path)
|
|
50
|
+
|
|
51
|
+
print(f"\r{C.S} Total Method Signature {C.E} {C.G}➸❥ {C.PN}{total_files}", end='', flush=True)
|
|
52
|
+
|
|
53
|
+
if total_files == 0:
|
|
54
|
+
M.shutil.rmtree(decompile_dir)
|
|
55
|
+
|
|
56
|
+
exit(
|
|
57
|
+
f"{C.ERROR} No Matching Patterns found ! ✘\n"
|
|
58
|
+
f"\n{C.INFO} Sorry Bro Your Bad Luck !, Not Working MT Logs Method in This Apk, Try Another Method.\n"
|
|
59
|
+
)
|
|
60
|
+
|
|
61
|
+
print(f" {C.G} ✔\n\n", flush=True)
|
|
62
|
+
|
|
63
|
+
for file_path, content in R_S_F(smali_folders):
|
|
64
|
+
if any(match in content for match in Match_F):
|
|
65
|
+
total_files += 1
|
|
66
|
+
|
|
67
|
+
matched_files.append(file_path)
|
|
68
|
+
|
|
69
|
+
print(f"\r{C.S} Find Target Smali {C.E} {C.G}➸❥ {C.PN}{total_files}", end='', flush=True)
|
|
70
|
+
|
|
71
|
+
print(f" {C.G} ✔", flush=True)
|
|
72
|
+
|
|
73
|
+
print(f'\n{C_Line}\n')
|
|
74
|
+
|
|
75
|
+
Inject_A = r"invoke-static (\{[pv]\d+\}), Ljavax/crypto/Cipher;->getInstance\(Ljava/lang/String;\)Ljavax/crypto/Cipher;[^>]*?move-result-object ([pv]\d+)"
|
|
76
|
+
|
|
77
|
+
Inject_A_matches = defaultdict(list)
|
|
78
|
+
|
|
79
|
+
for match, file_paths in Match_F.items():
|
|
80
|
+
for file_path in file_paths:
|
|
81
|
+
content = open(file_path, 'r', encoding='utf-8', errors='ignore').read()
|
|
82
|
+
matches = list(M.re.finditer(Inject_A, content))
|
|
83
|
+
|
|
84
|
+
if matches:
|
|
85
|
+
Inject_A_matches[Inject_A].append(M.os.path.basename(file_path))
|
|
86
|
+
|
|
87
|
+
updated_content = content
|
|
88
|
+
|
|
89
|
+
for m in matches:
|
|
90
|
+
invoke_pv, result_pv = m[1], m[2]
|
|
91
|
+
|
|
92
|
+
if f"invoke-static {invoke_pv}, LRK_TECHNO_INDIA/AES;->getInstance(Ljava/lang/Object;)V" not in updated_content:
|
|
93
|
+
injected_lines = [
|
|
94
|
+
f"invoke-static {invoke_pv}, LRK_TECHNO_INDIA/AES;->getInstance(Ljava/lang/Object;)V",
|
|
95
|
+
f"invoke-static {invoke_pv}, Ljavax/crypto/Cipher;->getInstance(Ljava/lang/String;)Ljavax/crypto/Cipher;",
|
|
96
|
+
f"move-result-object {result_pv}",
|
|
97
|
+
f"invoke-static {{{result_pv}}}, LRK_TECHNO_INDIA/AES;->getInstance(Ljava/lang/Object;)V",
|
|
98
|
+
]
|
|
99
|
+
match_text = m[0]
|
|
100
|
+
replacement_text = "\n ".join(injected_lines)
|
|
101
|
+
|
|
102
|
+
if match_text in updated_content:
|
|
103
|
+
updated_content = updated_content.replace(match_text, replacement_text)
|
|
104
|
+
|
|
105
|
+
open(file_path, 'w', encoding='utf-8', errors='ignore').write(updated_content)
|
|
106
|
+
|
|
107
|
+
for pattern, file_paths in Inject_A_matches.items():
|
|
108
|
+
print(f"\n{C.S} Cipher {C.E} {C.C}Method Signature {C.G}➸❥ {C.OG}{pattern}\n")
|
|
109
|
+
for file_name in file_paths:
|
|
110
|
+
print(f"{C.G} |\n └──── {C.CC}~{C.G}$ {C.Y}{file_name} {C.G}✔")
|
|
111
|
+
|
|
112
|
+
print(
|
|
113
|
+
f"\n{C.S} Pattern Applied {C.E} {C.G}➸❥ {C.P}{len(file_paths)} {C.C}Time/Smali {C.G}✔\n"
|
|
114
|
+
f"\n{C_Line}\n"
|
|
115
|
+
)
|
|
116
|
+
|
|
117
|
+
print(f'{C_Line}\n')
|
|
118
|
+
|
|
119
|
+
for match in Match_F:
|
|
120
|
+
regex = M.re.escape(match)
|
|
121
|
+
matching_files, T_P = [], 0
|
|
122
|
+
|
|
123
|
+
Inject_R = rf"invoke-static \{{(.*?)\}}, {regex}[^>]*?move-result-object ([pv]\d+)"
|
|
124
|
+
|
|
125
|
+
for file_path in matched_files:
|
|
126
|
+
content = open(file_path, 'r', encoding='utf-8', errors='ignore').read()
|
|
127
|
+
|
|
128
|
+
matches = list(M.re.finditer(Inject_R, content))
|
|
129
|
+
|
|
130
|
+
if matches:
|
|
131
|
+
T_P += 1
|
|
132
|
+
matching_files.append(M.os.path.basename(file_path))
|
|
133
|
+
|
|
134
|
+
if T_P > 0:
|
|
135
|
+
print(f"\n{C.S} Method Signature {C.E} {C.G}➸❥ {C.OG}{match}\n")
|
|
136
|
+
for file_name in matching_files:
|
|
137
|
+
print(f"{C.G} |\n └──── {C.CC}~{C.G}$ {C.Y}{M.os.path.basename(file_name)} {C.G}✔")
|
|
138
|
+
print(
|
|
139
|
+
f"\n{C.S} Pattern Applied {C.E} {C.G}➸❥ {C.P}{len(matching_files)} {C.C}Time/Smali {C.G}✔\n"
|
|
140
|
+
f"\n{C_Line}\n"
|
|
141
|
+
)
|
|
142
|
+
|
|
143
|
+
for file_path in matched_files:
|
|
144
|
+
content = open(file_path, 'r', encoding='utf-8', errors='ignore').read()
|
|
145
|
+
matches = list(M.re.finditer(Inject_R, content))
|
|
146
|
+
|
|
147
|
+
if matches:
|
|
148
|
+
updated_content = content
|
|
149
|
+
for m in matches:
|
|
150
|
+
invoke_args, result_register = m[1], m[2]
|
|
151
|
+
|
|
152
|
+
invoke_args_list = invoke_args.split(", ")
|
|
153
|
+
param_count = len(invoke_args_list)
|
|
154
|
+
|
|
155
|
+
injected_lines = []
|
|
156
|
+
if param_count == 1:
|
|
157
|
+
injected_lines.append(f"invoke-static {{{invoke_args_list[0]}}}, LRK_TECHNO_INDIA/AES;->a(Ljava/lang/Object;)V")
|
|
158
|
+
injected_lines.append(f"invoke-static {{{invoke_args}}}, {match}\n move-result-object {result_register}")
|
|
159
|
+
injected_lines.append(f"invoke-static {{{result_register}}}, LRK_TECHNO_INDIA/AES;->a(Ljava/lang/Object;)V")
|
|
160
|
+
elif param_count > 1:
|
|
161
|
+
for idx, param in enumerate(invoke_args_list, start=1):
|
|
162
|
+
injected_lines.append(f"invoke-static {{{param}}}, LRK_TECHNO_INDIA/AES;->b{idx}(Ljava/lang/Object;)V")
|
|
163
|
+
injected_lines.append(f"invoke-static {{}}, LRK_TECHNO_INDIA/AES;->b()V")
|
|
164
|
+
injected_lines.append(f"invoke-static {{{invoke_args}}}, {match}\n move-result-object {result_register}")
|
|
165
|
+
injected_lines.append(f"invoke-static {{{result_register}}}, LRK_TECHNO_INDIA/AES;->a(Ljava/lang/Object;)V")
|
|
166
|
+
|
|
167
|
+
match_text = m[0]
|
|
168
|
+
replacement_text = "\n ".join(injected_lines)
|
|
169
|
+
|
|
170
|
+
if match_text in updated_content:
|
|
171
|
+
updated_content = updated_content.replace(match_text, replacement_text)
|
|
172
|
+
|
|
173
|
+
open(file_path, 'w', encoding='utf-8', errors='ignore').write(updated_content)
|
|
174
|
+
|
|
175
|
+
|
|
176
|
+
# ---------------- Copy AES Smali ----------------
|
|
177
|
+
def Copy_AES_Smali(decompile_dir, smali_folders, manifest_path, isAES_MS, isAPKEditor):
|
|
178
|
+
|
|
179
|
+
AES_Logs_Inject(decompile_dir, smali_folders)
|
|
180
|
+
|
|
181
|
+
if isAES_MS:
|
|
182
|
+
if isAPKEditor:
|
|
183
|
+
decompile_dir = M.os.path.join(decompile_dir, "smali")
|
|
184
|
+
|
|
185
|
+
prefix = "classes" if isAPKEditor else "smali_classes"
|
|
186
|
+
|
|
187
|
+
L_S_C_F = M.os.path.join(decompile_dir, f"{prefix}{int(M.os.path.basename(smali_folders[-1])[len(prefix):]) + 1}")
|
|
188
|
+
|
|
189
|
+
M.os.makedirs(L_S_C_F, exist_ok=True)
|
|
190
|
+
else:
|
|
191
|
+
L_S_C_F = smali_folders[-1]
|
|
192
|
+
|
|
193
|
+
|
|
194
|
+
# ---------------- Copy AES.smali ----------------
|
|
195
|
+
Target_Dest = M.os.path.join(L_S_C_F, 'RK_TECHNO_INDIA', 'AES.smali')
|
|
196
|
+
M.os.makedirs(M.os.path.dirname(Target_Dest), exist_ok=True)
|
|
197
|
+
M.shutil.copy(F.AES_Smali, Target_Dest)
|
|
198
|
+
|
|
199
|
+
print(f"\n{C.S} Generate {C.E} {C.G}AES.smali {C.OG}➸❥ {C.Y}{M.os.path.relpath(Target_Dest, decompile_dir)}{C.G} ✔")
|
|
200
|
+
|
|
201
|
+
|
|
202
|
+
# ---------------- Update Package Name ----------------
|
|
203
|
+
PKG_Name = M.re.search(
|
|
204
|
+
r'package="([^"]+)"',
|
|
205
|
+
open(manifest_path, 'r', encoding='utf-8', errors='ignore').read()
|
|
206
|
+
)[1]
|
|
207
|
+
|
|
208
|
+
content = open(Target_Dest, 'r', encoding='utf-8', errors='ignore').read()
|
|
209
|
+
|
|
210
|
+
Update_PKG = content.replace('PACKAGENAME', PKG_Name)
|
|
211
|
+
|
|
212
|
+
open(Target_Dest, 'w', encoding='utf-8', errors='ignore').write(Update_PKG)
|
|
213
|
+
|
|
214
|
+
print(f"{C.G} |\n └── {C.CC}Update Package Name ~{C.G}$ {C.OG}➸❥ {C.PN}'{C.G}{PKG_Name}{C.PN}' {C.G}✔\n")
|