Files Upload
This commit is contained in:
parent
0f137981cc
commit
fd26ca1ba9
56
ApkPatcher/ANSI_COLORS.py
Normal file
56
ApkPatcher/ANSI_COLORS.py
Normal file
@ -0,0 +1,56 @@
|
|||||||
|
# ————— 𝐀𝐍𝐒𝐈 𝐂𝐎𝐋𝐎𝐑𝐒 —————
|
||||||
|
|
||||||
|
class ANSI:
|
||||||
|
def __init__(self):
|
||||||
|
|
||||||
|
# =====🔸𝐀𝐍𝐒𝐈 𝐂𝐎𝐋𝐎𝐑𝐒🔸=====
|
||||||
|
|
||||||
|
self.ESC = '\033' # ( Octal )
|
||||||
|
|
||||||
|
# 𝐀𝐍𝐒𝐈 𝐂𝐎𝐋𝐎𝐑 ( 𝐁𝐎𝐋𝐃 = 𝟏𝐦 | 𝐃𝐀𝐑𝐊 = 𝟐𝐦 )
|
||||||
|
|
||||||
|
self.R = self.ESC + '[31;1m' # RED
|
||||||
|
self.G = self.ESC + '[32;1m' # GREEN
|
||||||
|
self.Y = self.ESC + '[33;1m' # YELLOW
|
||||||
|
self.B = self.ESC + '[34;1m' # BLUE
|
||||||
|
self.P = self.ESC + '[35;1m' # PURPLE
|
||||||
|
self.C = self.ESC + '[36;1m' # CYAN
|
||||||
|
self.W = self.ESC + '[37;1m' # WHITE
|
||||||
|
|
||||||
|
# 𝐁𝐑𝐈𝐆𝐇𝐓 𝐂𝐎𝐋𝐎𝐑
|
||||||
|
|
||||||
|
self.BR = self.ESC + '[91;1m' # BRIGHT RED
|
||||||
|
self.BG = self.ESC + '[92;1m' # BRIGHT GREEN
|
||||||
|
self.BY = self.ESC + '[93;1m' # BRIGHT YELLOW
|
||||||
|
self.BB = self.ESC + '[94;1m' # BRIGHT BLUE
|
||||||
|
self.BP = self.ESC + '[95;1m' # BRIGHT PURPLE
|
||||||
|
self.BC = self.ESC + '[96;1m' # BRIGHT CYAN
|
||||||
|
self.BW = self.ESC + '[97;1m' # BRIGHT WHITE
|
||||||
|
|
||||||
|
# 𝐎𝐓𝐇𝐄𝐑 𝐂𝐎𝐋𝐎𝐑
|
||||||
|
|
||||||
|
self.DG = self.ESC + '[32;2m' # DARK GREEN
|
||||||
|
self.GR = self.ESC + '[90;1m' # GRAY
|
||||||
|
|
||||||
|
# 𝟐𝟓𝟔 𝐂𝐨𝐥𝐨𝐫𝐬 ( 𝐄𝐒𝐂 + '[𝟑𝟖;𝟓;{𝐈𝐃}𝐦' ) [ 𝐈𝐃 - https://user-images.githubusercontent.com/995050/47952855-ecb12480-df75-11e8-89d4-ac26c50e80b9.png ]
|
||||||
|
|
||||||
|
self.PN = self.ESC + '[38;5;213;1m' # PINK
|
||||||
|
self.OG = self.ESC + '[38;5;202;1m' # ORANGE
|
||||||
|
|
||||||
|
# 𝐂𝐋𝐄𝐀𝐑 𝐂𝐎𝐃𝐄𝐒
|
||||||
|
|
||||||
|
self.CL = self.ESC + '[2K' # CLEAR LINE
|
||||||
|
self.CC = self.ESC + '[0m' # CLEAR COLOR
|
||||||
|
|
||||||
|
# 𝐌𝐎𝐑𝐄 𝐈𝐍𝐅𝐎 [ 𝐋𝐈𝐍𝐊 - https://gist.github.com/fnky/458719343aabd01cfb17a3a4f7296797 ]
|
||||||
|
|
||||||
|
# =====🔹𝐓𝐀𝐆🔹=====
|
||||||
|
|
||||||
|
self.S = f'{self.B}[{self.C}'
|
||||||
|
self.E = f'{self.B}]'
|
||||||
|
self.X = f'{self.B}[ {self.P}* {self.B}]'
|
||||||
|
self.FYI = f'{self.B}[ {self.P}FYI {self.B}]'
|
||||||
|
self.INFO = f'{self.B}[ {self.Y}INFO {self.B}]{self.C}'
|
||||||
|
self.WARN = f'{self.B}[ {self.Y}WARN {self.B}]{self.B}'
|
||||||
|
self.ERROR = f'{self.B}[ {self.R}ERROR {self.B}]{self.R}'
|
||||||
|
self.SUGGEST = f'{self.B}[ {self.Y}SUGGEST {self.B}]{self.C}'
|
||||||
241
ApkPatcher/APK_PATCHER.py
Normal file
241
ApkPatcher/APK_PATCHER.py
Normal file
@ -0,0 +1,241 @@
|
|||||||
|
from .CLI import parse_arguments
|
||||||
|
from .ANSI_COLORS import ANSI; C = ANSI()
|
||||||
|
from .MODULES import IMPORT; M = IMPORT()
|
||||||
|
|
||||||
|
from ApkPatcher.Utils.CRC import CRC_Fix
|
||||||
|
from ApkPatcher.Utils.Credits import Credits
|
||||||
|
from ApkPatcher.Utils.Scan import Scan_Apk
|
||||||
|
from ApkPatcher.Utils.Anti_Splits import Anti_Split
|
||||||
|
from ApkPatcher.Utils.Files_Check import FileCheck, __version__
|
||||||
|
from ApkPatcher.Utils.Decompile_Compile import Decompile_Apk, Recompile_Apk, FixSigBlock, Sign_APK
|
||||||
|
|
||||||
|
from ApkPatcher.Patch.AES import Copy_AES_Smali
|
||||||
|
from ApkPatcher.Patch.CERT_NSC import Write_NSC
|
||||||
|
from ApkPatcher.Patch.Smali_Patch import Smali_Patch
|
||||||
|
from ApkPatcher.Patch.TG_Patch import TG_Smali_Patch
|
||||||
|
from ApkPatcher.Patch.Ads_Patch import Ads_Smali_Patch
|
||||||
|
from ApkPatcher.Patch.Pine_Hook import Pine_Hook_Patch
|
||||||
|
from ApkPatcher.Patch.Spoof_Patch import Patch_Random_Info
|
||||||
|
from ApkPatcher.Patch.Flutter_SSL_Patch import Patch_Flutter_SSL
|
||||||
|
from ApkPatcher.Patch.Pairip_CoreX import Check_CoreX, Hook_Core
|
||||||
|
from ApkPatcher.Patch.Manifest_Patch import Fix_Manifest, Patch_Manifest, Permission_Manifest
|
||||||
|
|
||||||
|
|
||||||
|
def Clear():
|
||||||
|
M.os.system('cls' if M.os.name == 'nt' else 'clear')
|
||||||
|
Clear()
|
||||||
|
|
||||||
|
|
||||||
|
# ---------------- Install Require Module ---------------
|
||||||
|
required_modules = ['requests', 'r2pipe', 'asn1crypto', 'multiprocess']
|
||||||
|
for module in required_modules:
|
||||||
|
try:
|
||||||
|
__import__(module)
|
||||||
|
except ImportError:
|
||||||
|
print(f"{C.S} Installing {C.E} {C.OG}➸❥ {C.G}{module}...\n")
|
||||||
|
try:
|
||||||
|
M.subprocess.check_call([M.sys.executable, "-m", "pip", "install", module])
|
||||||
|
Clear()
|
||||||
|
except (M.subprocess.CalledProcessError, Exception):
|
||||||
|
exit(
|
||||||
|
f"\n{C.ERROR} No Internet Connection. ✘\n"
|
||||||
|
f"\n{C.INFO} Internet Connection is Required to Install {C.G} pip install {module}\n"
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
# ---------------- Check Dependencies ---------------
|
||||||
|
def check_dependencies():
|
||||||
|
try:
|
||||||
|
M.subprocess.run(['java', '-version'], stdout=M.subprocess.PIPE, stderr=M.subprocess.PIPE, check=True, text=True)
|
||||||
|
except (M.subprocess.CalledProcessError, FileNotFoundError):
|
||||||
|
if M.os.name == 'posix':
|
||||||
|
install_package('openjdk-17')
|
||||||
|
else:
|
||||||
|
exit(
|
||||||
|
f'\n\n{C.ERROR} Java is not installed on Your System. ✘\n'
|
||||||
|
f'\n{C.INFO} Install Java & Run Script Again in New CMD. ✘\n'
|
||||||
|
f'\n{C.INFO} Verify Java Installation {C.G} java --version\n'
|
||||||
|
)
|
||||||
|
|
||||||
|
if M.os.name == 'posix': install_package('aapt')
|
||||||
|
|
||||||
|
|
||||||
|
# ---------------- Install Package ---------------
|
||||||
|
def install_package(pkg):
|
||||||
|
try:
|
||||||
|
result = M.subprocess.run(['pkg', 'list-installed'], stdout=M.subprocess.PIPE, stderr=M.subprocess.PIPE, text=True)
|
||||||
|
if pkg not in result.stdout:
|
||||||
|
print(f"{C.S} Installing {C.E} {C.OG}➸❥ {C.G}{pkg}...\n")
|
||||||
|
M.subprocess.check_call(['pkg', 'install', '-y', pkg])
|
||||||
|
Clear()
|
||||||
|
except (M.subprocess.CalledProcessError, Exception):
|
||||||
|
exit(
|
||||||
|
f"\n\n{C.ERROR} No Internet Connection. ✘\n"
|
||||||
|
f"\n{C.INFO} Internet Connection is Required to Installation {C.G}pkg install {pkg}\n"
|
||||||
|
)
|
||||||
|
|
||||||
|
check_dependencies()
|
||||||
|
|
||||||
|
F = FileCheck(); F.Set_Path(); F.F_D()
|
||||||
|
|
||||||
|
Date = M.datetime.now().strftime('%d/%m/%y')
|
||||||
|
print(f"{C.OG}{f'v{__version__}':>22}")
|
||||||
|
|
||||||
|
# Logo ( 🙏 )
|
||||||
|
b64 = """eJzVlc9LAkEUx8/Ov9DlMXgNzLAfeMlUSAQLETx4ELGlJEehnEPgQSrqUlFYdIroHNShixDRP1DQn1DaqUv+Cc3MzszOrFtUt96u+2O+n/fmvTe7LoCwsdIEGStNzsRj8WgkSoYXe9fsdwtFp15tEsfSp8n8phyYjZKCU11tNCHTWK5V2GhE+yIUCgF1DYFplIY9s0RLGdG56EsU5PTjRgLcyfIJMk1IQNcDiaUsLCUKyYV0XoUL4H8QErNLbJxNBCtA4FSOikGdOufBj/DYAQS1L72WYreH7CB5ak+iUzPTtHSvZH32LWcYGxsX2Yp7KdIwyI2KJNx1ZpgIZ5TCURqm3qAAkNKona5qn3pkkP1QCZSbnM5QkXDG2MQpWA+fq7IuyAA8lh2e3TPNbASfBHxRkVwZI7QPkpqqUs2OjcAWLqbERv0j5uIqt685UM9bKFjUb8Swu7MFr4eX71fn/Z1jGHZ3j+CjdzfY3uufHr31OvDycAbPN4/3T90sP/B7/uKgfuckcG9/JXy//8XtFz4WiqweTJFchTi8Jtmbtq0WnLqzsl4hmmj73BeLuXTe56/FVKXl/Pt++f6XB51988Mw6ByI6tvqQxIjc+trLUHUONDYGNHz2XIhnVzILZYzuVQmITr0CawgFWQ="""
|
||||||
|
print(f"{M.zlib.decompress(M.base64.b64decode(b64)).decode('utf-8').rstrip('\n')} | {C.B}{Date}{C.CC}")
|
||||||
|
print("————————|——————————————————|—————————————————|——————————————|————")
|
||||||
|
|
||||||
|
|
||||||
|
# ---------------- Target All Classes Folder ---------------
|
||||||
|
def Find_Smali_Folders(decompile_dir, isAPKEditor, isPine_Hook):
|
||||||
|
|
||||||
|
dex_path = M.os.path.join(decompile_dir, "dex") if isAPKEditor else decompile_dir
|
||||||
|
|
||||||
|
smali_path = M.os.path.join(decompile_dir, "smali") if isAPKEditor else decompile_dir
|
||||||
|
|
||||||
|
if isPine_Hook:
|
||||||
|
|
||||||
|
classes_files = [file for file in M.os.listdir(dex_path) if file.startswith("classes") and file.endswith(".dex")]
|
||||||
|
|
||||||
|
return f"classes{len(classes_files) + 1}.dex"
|
||||||
|
|
||||||
|
else:
|
||||||
|
|
||||||
|
prefix = "classes" if isAPKEditor else "smali_classes"
|
||||||
|
|
||||||
|
folders = sorted([folder for folder in M.os.listdir(smali_path) if folder == "smali" or folder.startswith(prefix)], key=lambda x: int(x.split(prefix)[-1]) if x.split(prefix)[-1].isdigit() else 0)
|
||||||
|
|
||||||
|
return [M.os.path.join(smali_path, folder) for folder in folders]
|
||||||
|
|
||||||
|
|
||||||
|
# ---------------- Execute Main Function ---------------
|
||||||
|
def RK_Techno_IND():
|
||||||
|
args = parse_arguments()
|
||||||
|
isCoreX = args.Hook_CoreX
|
||||||
|
isFlutter = args.Flutter; isPairip = args.Pairip
|
||||||
|
Skip_Patch = args.Skip_Patch if args.Skip_Patch else []
|
||||||
|
isAPKEditor = args.APKEditor; isEmulator = args.For_Emulator
|
||||||
|
|
||||||
|
if isEmulator:
|
||||||
|
F.isEmulator()
|
||||||
|
F.F_D_A()
|
||||||
|
|
||||||
|
if args.Credits:
|
||||||
|
Credits()
|
||||||
|
|
||||||
|
apk_path = args.input or args.Merge
|
||||||
|
|
||||||
|
if not M.os.path.isfile(apk_path):
|
||||||
|
exit(
|
||||||
|
f"\n{C.ERROR} APK file '{apk_path}' not found. ✘\n\n"
|
||||||
|
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"
|
||||||
|
)
|
||||||
|
|
||||||
|
if args.CA_Certificate:
|
||||||
|
isCert = [Cert for Cert in args.CA_Certificate if not M.os.path.isfile(Cert)]
|
||||||
|
|
||||||
|
if isCert:
|
||||||
|
exit(f"\n{C.ERROR} Not exist: {', '.join(isCert)}\n")
|
||||||
|
|
||||||
|
apk_path = Anti_Split(apk_path, args.Merge, isCoreX)
|
||||||
|
|
||||||
|
# ---------------- Set All Paths Directory ----------------
|
||||||
|
decompile_dir = M.os.path.join(M.os.path.expanduser("~"), f"{M.os.path.splitext(M.os.path.basename(apk_path))[0]}_decompiled")
|
||||||
|
|
||||||
|
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"))
|
||||||
|
|
||||||
|
rebuild_dir = build_dir.replace('_Patched.apk', '_Patch.apk')
|
||||||
|
|
||||||
|
manifest_path = M.os.path.join(decompile_dir, 'AndroidManifest.xml')
|
||||||
|
|
||||||
|
if M.os.name == 'posix':
|
||||||
|
M.subprocess.run(['termux-wake-lock'])
|
||||||
|
print(f"\n{C.X}{C.C} Acquiring Wake Lock...\r")
|
||||||
|
|
||||||
|
start_time = M.time.time()
|
||||||
|
|
||||||
|
# ---------------- Scan & Decompile APK ---------------
|
||||||
|
Package_Name, isFlutter_lib, isPairip_lib = Scan_Apk(apk_path, isFlutter, isPairip)
|
||||||
|
|
||||||
|
Decompile_Apk(apk_path, decompile_dir, isEmulator, isAPKEditor, args.AES_Logs, args.Pine_Hook, Package_Name)
|
||||||
|
|
||||||
|
smali_folders = Find_Smali_Folders(decompile_dir, isAPKEditor, args.Pine_Hook)
|
||||||
|
|
||||||
|
# ---------------- Pine Hook ----------------
|
||||||
|
if args.Pine_Hook:
|
||||||
|
Pine_Hook_Patch(decompile_dir, isAPKEditor, args.Load_Modules, smali_folders)
|
||||||
|
else:
|
||||||
|
# ---------------- AES Logs Inject ----------------
|
||||||
|
if args.AES_Logs:
|
||||||
|
Copy_AES_Smali(decompile_dir, smali_folders, manifest_path, args.AES_S, isAPKEditor)
|
||||||
|
|
||||||
|
Permission_Manifest(decompile_dir, manifest_path, isAPKEditor)
|
||||||
|
|
||||||
|
# ---------------- Remove Ads ----------------
|
||||||
|
if args.Remove_Ads:
|
||||||
|
Ads_Smali_Patch(smali_folders)
|
||||||
|
|
||||||
|
# ---------------- Fake / Spoof Device Info ----------------
|
||||||
|
if args.Random_Info:
|
||||||
|
Patch_Random_Info(smali_folders, args.Android_ID)
|
||||||
|
|
||||||
|
# ---------------- TG Patch ----------------
|
||||||
|
if args.TG_Patch:
|
||||||
|
TG_Smali_Patch(decompile_dir, smali_folders, isAPKEditor)
|
||||||
|
|
||||||
|
|
||||||
|
# ---------------- Other Patch ----------------
|
||||||
|
if args.AES_Logs or args.Remove_Ads or args.Random_Info or args.Pine_Hook or args.TG_Patch:
|
||||||
|
Fix_Manifest(manifest_path, args.Spoof_PKG, args.Pine_Hook, Package_Name)
|
||||||
|
else:
|
||||||
|
if isFlutter and isFlutter_lib:
|
||||||
|
Patch_Flutter_SSL(decompile_dir, isAPKEditor)
|
||||||
|
|
||||||
|
# ---------------- Smali Patching / Hook CoreX ----------------
|
||||||
|
if isCoreX and isPairip and isPairip_lib and Check_CoreX(decompile_dir, isAPKEditor):
|
||||||
|
M.shutil.rmtree(decompile_dir)
|
||||||
|
exit(1)
|
||||||
|
|
||||||
|
Smali_Patch(decompile_dir, smali_folders, isAPKEditor, args.CA_Certificate, args.Android_ID, isPairip, isPairip_lib, args.Spoof_PKG, args.Purchase, args.Remove_SS, Skip_Patch, args.Remove_USB, isCoreX)
|
||||||
|
|
||||||
|
if isCoreX and isPairip and isPairip_lib:
|
||||||
|
Hook_Core(args.input, decompile_dir, isAPKEditor, Package_Name)
|
||||||
|
|
||||||
|
# ---------------- Patch Manifest & Write Network Config ----------------
|
||||||
|
Fix_Manifest(manifest_path, args.Spoof_PKG, args.Pine_Hook, Package_Name)
|
||||||
|
|
||||||
|
Patch_Manifest(decompile_dir, manifest_path)
|
||||||
|
|
||||||
|
Write_NSC(decompile_dir, isAPKEditor, args.CA_Certificate)
|
||||||
|
|
||||||
|
# ---------------- Recompile APK ----------------
|
||||||
|
Recompile_Apk(decompile_dir, apk_path, build_dir, isEmulator, isAPKEditor, Package_Name)
|
||||||
|
|
||||||
|
# ---------------- Fix CRC / Sign APK ----------------
|
||||||
|
if not isCoreX and isPairip and isPairip_lib or args.unsigned_apk:
|
||||||
|
|
||||||
|
if not isAPKEditor:
|
||||||
|
FixSigBlock(decompile_dir, apk_path, build_dir, rebuild_dir);
|
||||||
|
|
||||||
|
CRC_Fix(apk_path, build_dir, ["AndroidManifest.xml", ".dex"])
|
||||||
|
|
||||||
|
else:
|
||||||
|
Sign_APK(build_dir)
|
||||||
|
|
||||||
|
if M.os.path.exists(build_dir):
|
||||||
|
print(f'{C.S} Final APK {C.E} {C.G}︻デ═一 {C.Y}{build_dir} {C.G} ✔')
|
||||||
|
|
||||||
|
print(f"\n{C.CC}{'_' * 61}\n")
|
||||||
|
|
||||||
|
if not isCoreX and isPairip and isPairip_lib:
|
||||||
|
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')
|
||||||
|
|
||||||
|
print(f'\n{C.S} Time Spent {C.E} {C.G}︻デ═一 {C.PN}{M.time.time() - start_time:.2f} {C.CC}Seconds {C.G} ✔\n')
|
||||||
|
|
||||||
|
print(f'\n🚩 {C.CC}࿗ {C.OG}Jai Shree Ram {C.CC}࿗ 🚩\n 🛕🛕🙏🙏🙏🛕🛕\n')
|
||||||
|
|
||||||
|
if M.os.name == 'posix':
|
||||||
|
M.subprocess.run(['termux-wake-unlock'])
|
||||||
|
exit(f"\n{C.X}{C.C} Releasing Wake Lock...\n")
|
||||||
|
exit(0)
|
||||||
337
ApkPatcher/CLI.py
Normal file
337
ApkPatcher/CLI.py
Normal file
@ -0,0 +1,337 @@
|
|||||||
|
from .ANSI_COLORS import ANSI; C = ANSI()
|
||||||
|
from .MODULES import IMPORT; M = IMPORT()
|
||||||
|
|
||||||
|
from ApkPatcher.Utils.Files_Check import __version__
|
||||||
|
|
||||||
|
|
||||||
|
Tag = f"\n{C.CC}————|———————|————{C.G}•❀ {C.OG}Tag {C.G}❀•{C.CC}————|———————|————\n"
|
||||||
|
|
||||||
|
FE = f"{C.P}\n |\n ╰{C.CC}┈{C.OG}➢ {C.G}ApkPatcher"
|
||||||
|
|
||||||
|
EX = f"{FE} -i Your_Apk_Path.apk {C.OG}"
|
||||||
|
|
||||||
|
|
||||||
|
class CustomArgumentParser(M.argparse.ArgumentParser):
|
||||||
|
# ---------------- Error Handling ----------------
|
||||||
|
def error(self, message):
|
||||||
|
suggestion = ""
|
||||||
|
for action in self._actions:
|
||||||
|
if action.option_strings and any(option in message for option in action.option_strings):
|
||||||
|
if action.dest == 'input':
|
||||||
|
suggestion = (
|
||||||
|
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\n'
|
||||||
|
f'\n{C.INFO} With Your Certificate Flag: {C.OG}-c {C.P}( Input Your pem/crt/cert Path ){EX}-c {C.Y}certificate.cert\n\n'
|
||||||
|
f'\n{C.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'
|
||||||
|
)
|
||||||
|
|
||||||
|
elif action.dest == 'Merge':
|
||||||
|
suggestion = (
|
||||||
|
f'\n{C.INFO} Only Merge APK\n\n'
|
||||||
|
f'\n{C.INFO} Merge Extension {C.Y}( .apks/.xapk/.apkm )'
|
||||||
|
f'\n{FE}{C.OG} -m {C.G}Your_Apk_Path.apks\n'
|
||||||
|
)
|
||||||
|
|
||||||
|
break
|
||||||
|
|
||||||
|
exit(
|
||||||
|
f'\n{C.ERROR} {message}\n'
|
||||||
|
f'\n{suggestion}'
|
||||||
|
)
|
||||||
|
|
||||||
|
# ---------------- Print Help ----------------
|
||||||
|
def print_help(self):
|
||||||
|
|
||||||
|
super().print_help()
|
||||||
|
|
||||||
|
print(f"\n{C.INFO} ApkPatcher Default Patch is VPN & SSL Bypass, Show Other Patch Flags List with: {C.G}ApkPatcher -O{C.C}\n")
|
||||||
|
|
||||||
|
# ---------------- Other Patch ----------------
|
||||||
|
def Other_Patch(self):
|
||||||
|
print(
|
||||||
|
f"""\n{C.X}{C.C} Other Patch Flags Help ( Keep Sequence in Mind )
|
||||||
|
|
||||||
|
<Flags> {C.G}─•❀•❀ {C.C}Info Patch {C.G}❀•❀•─ {C.OG}
|
||||||
|
|
||||||
|
-A, {C.C}--AES_Logs {C.Y} ➸ {C.G}AES Logs Inject {C.OG}
|
||||||
|
-D, {C.C}--Android_ID {C.Y} ➸ {C.G}Hook Android ID for One Device Login Bypass {C.OG}
|
||||||
|
-f, {C.C}--Flutter {C.Y} ➸ {C.G}Flutter SSL Bypass {C.OG}
|
||||||
|
-l, {C.C}--Load_Modules {C.Y} ➸ {C.G}Path of Xposed & LSP Module {C.P}( Currently Not Supported XSharedPreferences Module ) {C.OG}
|
||||||
|
-p, {C.C}--Pairip {C.Y} ➸ {C.G}Pairip CERT SSL Bypass {C.OG}
|
||||||
|
-P, {C.C}--Purchase {C.Y} ➸ {C.G}Purchase / Paid / Price {C.OG}
|
||||||
|
-r, {C.C}--Random_Info {C.Y} ➸ {C.G}Fake Device Info {C.OG}
|
||||||
|
-rmads, {C.C}--Remove_Ads {C.Y} ➸ {C.G}Bypass Ads {C.OG}
|
||||||
|
-rmss, {C.C}--Remove_SS {C.Y} ➸ {C.G}Bypass Screenshot Restriction {C.OG}
|
||||||
|
-rmusb, {C.C}--Remove_USB {C.Y} ➸ {C.G}Bypass USB Debugging {C.OG}
|
||||||
|
-pkg, {C.C}--Spoof_PKG {C.Y} ➸ {C.G}Spoof Package Detection {C.OG}
|
||||||
|
-pine, {C.C}--Pine_Hook {C.Y} ➸ {C.G}Pine Hook {C.OG}
|
||||||
|
-skip {C.C}[Skip_Patch ...]{C.Y} ➸ {C.G}Skip Specific Patches {C.P}( e.g. getAcceptedIssuers ) {C.OG}
|
||||||
|
-s, {C.C}--AES_S {C.Y} ➸ {C.G}Do U Want Separate AES.smali Dex {C.OG}
|
||||||
|
-t, {C.C}--TG_Patch {C.Y} ➸ {C.G}Telegram / Plus Patcher {C.OG}
|
||||||
|
-x, {C.C}--Hook_CoreX {C.Y} ➸ {C.G}Hook CoreX Flag: {C.OG}-p -x {C.P}( Only For [ arm64 ] )"""
|
||||||
|
)
|
||||||
|
|
||||||
|
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}")
|
||||||
|
|
||||||
|
if user_input.lower() == "y":
|
||||||
|
print(
|
||||||
|
f"""\n{Tag.replace("Tag", "AES Logs Inject")}
|
||||||
|
|
||||||
|
{C.INFO} AES MT Logs Inject Flag: {C.OG}-A{EX}-A
|
||||||
|
|
||||||
|
|
||||||
|
{C.INFO} Do U Want Separate AES.smali Dex Use Flag: {C.OG}-A -s{EX}-A -s
|
||||||
|
|
||||||
|
{Tag.replace("Tag", "Hook Android ID")}
|
||||||
|
|
||||||
|
{C.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
|
||||||
|
|
||||||
|
{Tag.replace("Tag", "isFlutter / isPairip")}
|
||||||
|
|
||||||
|
{C.INFO} If APK is Flutter Then Use Additional Flag: {C.OG}-f{EX}-f
|
||||||
|
|
||||||
|
|
||||||
|
{C.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.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
|
||||||
|
|
||||||
|
{Tag.replace("Tag", "Spoof PKG / Device Info")}
|
||||||
|
|
||||||
|
{C.INFO} Spoof Package Detection Flag: {C.OG}-pkg {C.P}( Dex / Manifest / Res ){EX}-pkg
|
||||||
|
|
||||||
|
{C.INFO} Fake Device Info Flag: {C.OG}-r{EX}-r
|
||||||
|
|
||||||
|
|
||||||
|
{C.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
|
||||||
|
|
||||||
|
{Tag.replace("Tag", "Pine Hook")}
|
||||||
|
|
||||||
|
{C.INFO} Pine Hook Flag: {C.OG}-pine -l {C.P}( Input Path of Xposed & LSP Module ){EX}-pine -l {C.Y}NoVPNDetect.apk just.trust.me.apk
|
||||||
|
|
||||||
|
{Tag.replace("Tag", "Bypass Ads / SS / USB")}
|
||||||
|
|
||||||
|
{C.INFO} Bypass Ads Flag: {C.OG}-rmads{EX}-rmads
|
||||||
|
|
||||||
|
|
||||||
|
{C.INFO} Bypass Screenshot Restriction Flag: {C.OG}-rmss{EX}-rmss
|
||||||
|
|
||||||
|
|
||||||
|
{C.INFO} Bypass USB Debugging Flag: {C.OG}-rmusb{EX}-rmusb
|
||||||
|
|
||||||
|
{Tag.replace("Tag", "isPurchase / Skip Patch")}
|
||||||
|
|
||||||
|
{C.INFO} Purchase / Paid / Price Flag: {C.OG}-P{EX}-P
|
||||||
|
|
||||||
|
|
||||||
|
{C.INFO} Skip Patch Flag: {C.OG}-skip{EX}-skip {C.Y}getAcceptedIssuers
|
||||||
|
|
||||||
|
{Tag.replace("Tag", "Telegram / Plus Patch")}
|
||||||
|
|
||||||
|
{C.INFO} Telegram / Plus Patch Flag: {C.OG}-t{EX}-t\n"""
|
||||||
|
)
|
||||||
|
|
||||||
|
else:
|
||||||
|
return
|
||||||
|
|
||||||
|
|
||||||
|
# ---------------- Parse Arguments ----------------
|
||||||
|
def parse_arguments():
|
||||||
|
|
||||||
|
args = M.sys.argv[1:]
|
||||||
|
|
||||||
|
if '-O' in args:
|
||||||
|
exit(CustomArgumentParser().Other_Patch())
|
||||||
|
|
||||||
|
if any(arg.startswith('-') for arg in args):
|
||||||
|
parser = CustomArgumentParser(description=f'{C.C}ApkPatcher v{__version__}')
|
||||||
|
else:
|
||||||
|
parser = M.argparse.ArgumentParser()
|
||||||
|
|
||||||
|
group = parser.add_mutually_exclusive_group(required=True)
|
||||||
|
|
||||||
|
group.add_argument(
|
||||||
|
'-i',
|
||||||
|
dest='input',
|
||||||
|
help=f'{C.Y}➸{C.G} Input APK Path...{C.C}'
|
||||||
|
)
|
||||||
|
|
||||||
|
group.add_argument(
|
||||||
|
'-m',
|
||||||
|
dest='Merge',
|
||||||
|
help=f'{C.Y}➸{C.G} Anti-Split ( Only Merge APK ){C.C}'
|
||||||
|
)
|
||||||
|
|
||||||
|
group.add_argument(
|
||||||
|
'-C',
|
||||||
|
dest='Credits',
|
||||||
|
action='store_true',
|
||||||
|
help=f'{C.Y}➸{C.G} Show Credits{C.C}'
|
||||||
|
)
|
||||||
|
|
||||||
|
additional = parser.add_argument_group(f'{C.OG}[ * ] Additional Flags{C.C}')
|
||||||
|
|
||||||
|
additional.add_argument(
|
||||||
|
'-a',
|
||||||
|
'--APKEditor',
|
||||||
|
action='store_true',
|
||||||
|
help=f'{C.Y}➸ {C.G}APKEditor ( Default APKTool ){C.C}'
|
||||||
|
)
|
||||||
|
|
||||||
|
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}'
|
||||||
|
)
|
||||||
|
|
||||||
|
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}"
|
||||||
|
)
|
||||||
|
|
||||||
|
additional.add_argument(
|
||||||
|
'-u',
|
||||||
|
dest='unsigned_apk',
|
||||||
|
action='store_true',
|
||||||
|
help=f"{C.Y}➸{C.G} Keep Unsigned APK{C.C}"
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
# ---------------- Other Patch Flags ----------------
|
||||||
|
parser.add_argument(
|
||||||
|
'-A',
|
||||||
|
'--AES_Logs',
|
||||||
|
action='store_true',
|
||||||
|
help=M.argparse.SUPPRESS
|
||||||
|
)
|
||||||
|
|
||||||
|
parser.add_argument(
|
||||||
|
'-D',
|
||||||
|
'--Android_ID',
|
||||||
|
type=str,
|
||||||
|
help=M.argparse.SUPPRESS
|
||||||
|
)
|
||||||
|
|
||||||
|
parser.add_argument(
|
||||||
|
'-f',
|
||||||
|
'--Flutter',
|
||||||
|
action='store_true',
|
||||||
|
help=M.argparse.SUPPRESS
|
||||||
|
)
|
||||||
|
|
||||||
|
parser.add_argument(
|
||||||
|
'-l',
|
||||||
|
'--Load_Modules',
|
||||||
|
type=str,
|
||||||
|
nargs='*',
|
||||||
|
help=M.argparse.SUPPRESS
|
||||||
|
)
|
||||||
|
|
||||||
|
parser.add_argument(
|
||||||
|
'-p',
|
||||||
|
'--Pairip',
|
||||||
|
action='store_true',
|
||||||
|
help=M.argparse.SUPPRESS
|
||||||
|
)
|
||||||
|
|
||||||
|
parser.add_argument(
|
||||||
|
'-P',
|
||||||
|
'--Purchase',
|
||||||
|
action='store_true',
|
||||||
|
help=M.argparse.SUPPRESS
|
||||||
|
)
|
||||||
|
|
||||||
|
parser.add_argument(
|
||||||
|
'-r',
|
||||||
|
'--Random_Info',
|
||||||
|
action='store_true',
|
||||||
|
help=M.argparse.SUPPRESS
|
||||||
|
)
|
||||||
|
|
||||||
|
parser.add_argument(
|
||||||
|
'-rmads',
|
||||||
|
'--Remove_Ads',
|
||||||
|
action='store_true',
|
||||||
|
help=M.argparse.SUPPRESS
|
||||||
|
)
|
||||||
|
|
||||||
|
parser.add_argument(
|
||||||
|
'-rmss',
|
||||||
|
'--Remove_SS',
|
||||||
|
action='store_true',
|
||||||
|
help=M.argparse.SUPPRESS
|
||||||
|
)
|
||||||
|
|
||||||
|
parser.add_argument(
|
||||||
|
'-rmusb',
|
||||||
|
'--Remove_USB',
|
||||||
|
action='store_true',
|
||||||
|
help=M.argparse.SUPPRESS
|
||||||
|
)
|
||||||
|
|
||||||
|
parser.add_argument(
|
||||||
|
'-pkg',
|
||||||
|
'--Spoof_PKG',
|
||||||
|
action='store_true',
|
||||||
|
help=M.argparse.SUPPRESS
|
||||||
|
)
|
||||||
|
|
||||||
|
parser.add_argument(
|
||||||
|
'-pine',
|
||||||
|
'--Pine_Hook',
|
||||||
|
action='store_true',
|
||||||
|
help=M.argparse.SUPPRESS
|
||||||
|
)
|
||||||
|
|
||||||
|
parser.add_argument(
|
||||||
|
'-skip',
|
||||||
|
dest='Skip_Patch',
|
||||||
|
nargs='*',
|
||||||
|
help=M.argparse.SUPPRESS
|
||||||
|
)
|
||||||
|
|
||||||
|
parser.add_argument(
|
||||||
|
'-s',
|
||||||
|
'--AES_S',
|
||||||
|
action='store_true',
|
||||||
|
help=M.argparse.SUPPRESS
|
||||||
|
)
|
||||||
|
|
||||||
|
parser.add_argument(
|
||||||
|
'-t',
|
||||||
|
'--TG_Patch',
|
||||||
|
action='store_true',
|
||||||
|
help=M.argparse.SUPPRESS
|
||||||
|
)
|
||||||
|
|
||||||
|
parser.add_argument(
|
||||||
|
'-x',
|
||||||
|
'--Hook_CoreX',
|
||||||
|
action='store_true',
|
||||||
|
help=M.argparse.SUPPRESS
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
Ext = ('.apk', '.apks', '.apkm', '.xapk')
|
||||||
|
|
||||||
|
fixed = []; start = None; Valid_Ext = False
|
||||||
|
|
||||||
|
for index, option in enumerate(args):
|
||||||
|
if option in ['-i', '-m', '-C']:
|
||||||
|
start, fixed = index + 1, fixed + [option]
|
||||||
|
elif start and (option.endswith(Ext) or M.os.path.isdir(option)):
|
||||||
|
fixed, start = fixed + [' '.join(args[start:index+1])], None
|
||||||
|
Valid_Ext = True
|
||||||
|
elif not start:
|
||||||
|
fixed.append(option)
|
||||||
|
|
||||||
|
|
||||||
|
if not Valid_Ext and M.sys.argv[1:2] != ['-C']:
|
||||||
|
print(f"\n{C.X}{C.C} Only Supported Extensions {C.G}{Ext}\n")
|
||||||
|
|
||||||
|
print(f"\n{C.S} Input Path {C.E} {C.OG}➸❥{C.Y}", *fixed, f"{C.CC}\n")
|
||||||
|
|
||||||
|
return parser.parse_args(fixed)
|
||||||
34
ApkPatcher/MODULES.py
Normal file
34
ApkPatcher/MODULES.py
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
# ————— 𝐈𝐌𝐏𝐎𝐑𝐓 𝐌𝐎𝐃𝐔𝐋𝐄𝐒 —————
|
||||||
|
|
||||||
|
class IMPORT:
|
||||||
|
def __init__(self):
|
||||||
|
|
||||||
|
# ---------------- 𝐌𝐮𝐥𝐭𝐢𝐏𝐫𝐨𝐜𝐞𝐬𝐬 / 𝐌𝐮𝐥𝐭𝐢𝐏𝐫𝐨𝐜𝐞𝐬𝐬𝐢𝐧𝐠 ----------------
|
||||||
|
try:
|
||||||
|
mp = __import__('multiprocess')
|
||||||
|
except ImportError:
|
||||||
|
mp = __import__('multiprocessing')
|
||||||
|
|
||||||
|
# ————— 𝐋𝐢𝐛𝐫𝐚𝐫𝐢𝐞𝐬 𝐈𝐦𝐩𝐨𝐫𝐭 —————
|
||||||
|
self.re = __import__('re')
|
||||||
|
self.os = __import__('os')
|
||||||
|
self.sys = __import__('sys')
|
||||||
|
self.zlib = __import__('zlib')
|
||||||
|
self.json = __import__('json')
|
||||||
|
self.time = __import__('time')
|
||||||
|
self.shutil = __import__('shutil')
|
||||||
|
self.string = __import__('string')
|
||||||
|
self.zipfile = __import__('zipfile')
|
||||||
|
self.hashlib = __import__('hashlib')
|
||||||
|
self.base64 = __import__('base64')
|
||||||
|
self.binascii = __import__('binascii')
|
||||||
|
self.random = __import__('random')
|
||||||
|
self.argparse = __import__('argparse')
|
||||||
|
self.subprocess = __import__('subprocess')
|
||||||
|
|
||||||
|
# ————— 𝐄𝐱𝐭𝐫𝐚 𝐋𝐢𝐛𝐫𝐚𝐫𝐢𝐞𝐬 —————
|
||||||
|
self.Pool = mp.Pool
|
||||||
|
self.Manager = mp.Manager
|
||||||
|
self.cpu_count = mp.cpu_count
|
||||||
|
self.datetime = __import__('datetime').datetime
|
||||||
|
|
||||||
214
ApkPatcher/Patch/AES.py
Normal file
214
ApkPatcher/Patch/AES.py
Normal file
@ -0,0 +1,214 @@
|
|||||||
|
from ..ANSI_COLORS import ANSI; C = ANSI()
|
||||||
|
from ..MODULES import IMPORT; M = IMPORT()
|
||||||
|
|
||||||
|
from collections import defaultdict
|
||||||
|
from ApkPatcher.Utils.Files_Check import FileCheck
|
||||||
|
|
||||||
|
F = FileCheck(); F.Set_Path()
|
||||||
|
C_Line = f"{C.CC}{'_' * 61}"
|
||||||
|
|
||||||
|
|
||||||
|
# ---------------- Regex Scan ----------------
|
||||||
|
def R_S_F(smali_folders):
|
||||||
|
for smali_folder in smali_folders:
|
||||||
|
for root, _, files in M.os.walk(smali_folder):
|
||||||
|
for file in files:
|
||||||
|
file_path = M.os.path.join(root, file)
|
||||||
|
yield file_path, open(file_path, 'r', encoding='utf-8', errors='ignore').read()
|
||||||
|
|
||||||
|
|
||||||
|
# ---------------- AES Logs Inject ----------------
|
||||||
|
def AES_Logs_Inject(decompile_dir, smali_folders):
|
||||||
|
reg = M.re.compile(r'"AES/[^/]+/[^"]+"')
|
||||||
|
Class_P = M.re.compile(r'\.class[^;]* (L[^;]+;)')
|
||||||
|
Met_P = M.re.compile(r'\.method.*?\s([a-zA-Z0-9_<>\$]+)\((.*?)\)(.*)')
|
||||||
|
|
||||||
|
Match_F = defaultdict(list)
|
||||||
|
|
||||||
|
matched_files = []
|
||||||
|
|
||||||
|
total_files = 0
|
||||||
|
|
||||||
|
for file_path, content in R_S_F(smali_folders):
|
||||||
|
if "Ljavax/crypto/Cipher;->doFinal([B)[B" in content and "Ljavax/crypto/spec/SecretKeySpec;" in content and "Ljavax/crypto/spec/IvParameterSpec;" in content:
|
||||||
|
|
||||||
|
Class_N = Class_P.search(content)[1]
|
||||||
|
|
||||||
|
for block in content.split('.method')[1:]:
|
||||||
|
|
||||||
|
if reg.search(block):
|
||||||
|
Met_M = Met_P.search(".method" + block.split('\n', 1)[0])
|
||||||
|
|
||||||
|
if Met_M:
|
||||||
|
total_files += 1
|
||||||
|
|
||||||
|
Met_Sig = f"{Met_M[1]}({Met_M[2]}){Met_M[3]}"
|
||||||
|
|
||||||
|
match = f"{Class_N}->{Met_Sig}"
|
||||||
|
|
||||||
|
Match_F[match].append(file_path)
|
||||||
|
|
||||||
|
print(f"\r{C.S} Total Method Signature {C.E} {C.OG}➸❥ {C.PN}{total_files}", end='', flush=True)
|
||||||
|
|
||||||
|
if total_files == 0:
|
||||||
|
M.shutil.rmtree(decompile_dir)
|
||||||
|
|
||||||
|
exit(
|
||||||
|
f"{C.ERROR} No Matching Patterns found ! ✘\n"
|
||||||
|
f"\n{C.INFO} Sorry Bro Your Bad Luck !, Not Working MT Logs Method in This Apk, Try Another Method.\n"
|
||||||
|
)
|
||||||
|
|
||||||
|
print(f" {C.G} ✔\n\n", flush=True)
|
||||||
|
|
||||||
|
for file_path, content in R_S_F(smali_folders):
|
||||||
|
if any(match in content for match in Match_F):
|
||||||
|
total_files += 1
|
||||||
|
|
||||||
|
matched_files.append(file_path)
|
||||||
|
|
||||||
|
print(f"\r{C.S} Find Target Smali {C.E} {C.OG}➸❥ {C.PN}{total_files}", end='', flush=True)
|
||||||
|
|
||||||
|
print(f" {C.G} ✔", flush=True)
|
||||||
|
|
||||||
|
print(f'\n{C_Line}\n')
|
||||||
|
|
||||||
|
Inject_A = r"invoke-static (\{[pv]\d+\}), Ljavax/crypto/Cipher;->getInstance\(Ljava/lang/String;\)Ljavax/crypto/Cipher;[^>]*?move-result-object ([pv]\d+)"
|
||||||
|
|
||||||
|
Inject_A_matches = defaultdict(list)
|
||||||
|
|
||||||
|
for match, file_paths in Match_F.items():
|
||||||
|
for file_path in file_paths:
|
||||||
|
content = open(file_path, 'r', encoding='utf-8', errors='ignore').read()
|
||||||
|
matches = list(M.re.finditer(Inject_A, content))
|
||||||
|
|
||||||
|
if matches:
|
||||||
|
Inject_A_matches[Inject_A].append(M.os.path.basename(file_path))
|
||||||
|
|
||||||
|
updated_content = content
|
||||||
|
|
||||||
|
for m in matches:
|
||||||
|
invoke_pv, result_pv = m[1], m[2]
|
||||||
|
|
||||||
|
if f"invoke-static {invoke_pv}, LRK_TECHNO_INDIA/AES;->getInstance(Ljava/lang/Object;)V" not in updated_content:
|
||||||
|
injected_lines = [
|
||||||
|
f"invoke-static {invoke_pv}, LRK_TECHNO_INDIA/AES;->getInstance(Ljava/lang/Object;)V",
|
||||||
|
f"invoke-static {invoke_pv}, Ljavax/crypto/Cipher;->getInstance(Ljava/lang/String;)Ljavax/crypto/Cipher;",
|
||||||
|
f"move-result-object {result_pv}",
|
||||||
|
f"invoke-static {{{result_pv}}}, LRK_TECHNO_INDIA/AES;->getInstance(Ljava/lang/Object;)V",
|
||||||
|
]
|
||||||
|
match_text = m[0]
|
||||||
|
replacement_text = "\n ".join(injected_lines)
|
||||||
|
|
||||||
|
if match_text in updated_content:
|
||||||
|
updated_content = updated_content.replace(match_text, replacement_text)
|
||||||
|
|
||||||
|
open(file_path, 'w', encoding='utf-8', errors='ignore').write(updated_content)
|
||||||
|
|
||||||
|
for pattern, file_paths in Inject_A_matches.items():
|
||||||
|
print(f"\n{C.S} Cipher {C.E} {C.C}Method Signature {C.OG}➸❥ {C.P}{pattern}\n")
|
||||||
|
for file_name in file_paths:
|
||||||
|
print(f"{C.G} |\n └──── {C.CC}~{C.G}$ {C.Y}{file_name} {C.G} ✔")
|
||||||
|
|
||||||
|
print(
|
||||||
|
f"\n{C.S} Pattern Applied {C.E} {C.OG}➸❥ {C.PN}{len(file_paths)} {C.C}Time/Smali {C.G} ✔\n"
|
||||||
|
f"\n{C_Line}\n"
|
||||||
|
)
|
||||||
|
|
||||||
|
print(f'{C_Line}\n')
|
||||||
|
|
||||||
|
for match in Match_F:
|
||||||
|
regex = M.re.escape(match)
|
||||||
|
matching_files, T_P = [], 0
|
||||||
|
|
||||||
|
Inject_R = rf"invoke-static \{{(.*?)\}}, {regex}[^>]*?move-result-object ([pv]\d+)"
|
||||||
|
|
||||||
|
for file_path in matched_files:
|
||||||
|
content = open(file_path, 'r', encoding='utf-8', errors='ignore').read()
|
||||||
|
|
||||||
|
matches = list(M.re.finditer(Inject_R, content))
|
||||||
|
|
||||||
|
if matches:
|
||||||
|
T_P += 1
|
||||||
|
matching_files.append(M.os.path.basename(file_path))
|
||||||
|
|
||||||
|
if T_P > 0:
|
||||||
|
print(f"\n{C.S} Method Signature {C.E} {C.OG}➸❥ {C.P}{match}\n")
|
||||||
|
for file_name in matching_files:
|
||||||
|
print(f"{C.G} |\n └──── {C.CC}~{C.G}$ {C.Y}{M.os.path.basename(file_name)} {C.G} ✔")
|
||||||
|
print(
|
||||||
|
f"\n{C.S} Pattern Applied {C.E} {C.OG}➸❥ {C.PN}{len(matching_files)} {C.C}Time/Smali {C.G} ✔\n"
|
||||||
|
f"\n{C_Line}\n"
|
||||||
|
)
|
||||||
|
|
||||||
|
for file_path in matched_files:
|
||||||
|
content = open(file_path, 'r', encoding='utf-8', errors='ignore').read()
|
||||||
|
matches = list(M.re.finditer(Inject_R, content))
|
||||||
|
|
||||||
|
if matches:
|
||||||
|
updated_content = content
|
||||||
|
for m in matches:
|
||||||
|
invoke_args, result_register = m[1], m[2]
|
||||||
|
|
||||||
|
invoke_args_list = invoke_args.split(", ")
|
||||||
|
param_count = len(invoke_args_list)
|
||||||
|
|
||||||
|
injected_lines = []
|
||||||
|
if param_count == 1:
|
||||||
|
injected_lines.append(f"invoke-static {{{invoke_args_list[0]}}}, LRK_TECHNO_INDIA/AES;->a(Ljava/lang/Object;)V")
|
||||||
|
injected_lines.append(f"invoke-static {{{invoke_args}}}, {match}\n move-result-object {result_register}")
|
||||||
|
injected_lines.append(f"invoke-static {{{result_register}}}, LRK_TECHNO_INDIA/AES;->a(Ljava/lang/Object;)V")
|
||||||
|
elif param_count > 1:
|
||||||
|
for idx, param in enumerate(invoke_args_list, start=1):
|
||||||
|
injected_lines.append(f"invoke-static {{{param}}}, LRK_TECHNO_INDIA/AES;->b{idx}(Ljava/lang/Object;)V")
|
||||||
|
injected_lines.append(f"invoke-static {{}}, LRK_TECHNO_INDIA/AES;->b()V")
|
||||||
|
injected_lines.append(f"invoke-static {{{invoke_args}}}, {match}\n move-result-object {result_register}")
|
||||||
|
injected_lines.append(f"invoke-static {{{result_register}}}, LRK_TECHNO_INDIA/AES;->a(Ljava/lang/Object;)V")
|
||||||
|
|
||||||
|
match_text = m[0]
|
||||||
|
replacement_text = "\n ".join(injected_lines)
|
||||||
|
|
||||||
|
if match_text in updated_content:
|
||||||
|
updated_content = updated_content.replace(match_text, replacement_text)
|
||||||
|
|
||||||
|
open(file_path, 'w', encoding='utf-8', errors='ignore').write(updated_content)
|
||||||
|
|
||||||
|
|
||||||
|
# ---------------- Copy AES Smali ----------------
|
||||||
|
def Copy_AES_Smali(decompile_dir, smali_folders, manifest_path, isAES_MS, isAPKEditor):
|
||||||
|
|
||||||
|
AES_Logs_Inject(decompile_dir, smali_folders)
|
||||||
|
|
||||||
|
if isAES_MS:
|
||||||
|
if isAPKEditor:
|
||||||
|
decompile_dir = M.os.path.join(decompile_dir, "smali")
|
||||||
|
|
||||||
|
prefix = "classes" if isAPKEditor else "smali_classes"
|
||||||
|
|
||||||
|
L_S_C_F = M.os.path.join(decompile_dir, f"{prefix}{int(M.os.path.basename(smali_folders[-1])[len(prefix):]) + 1}")
|
||||||
|
|
||||||
|
M.os.makedirs(L_S_C_F, exist_ok=True)
|
||||||
|
else:
|
||||||
|
L_S_C_F = smali_folders[-1]
|
||||||
|
|
||||||
|
|
||||||
|
# ---------------- Copy AES.smali ----------------
|
||||||
|
Target_Dest = M.os.path.join(L_S_C_F, 'RK_TECHNO_INDIA', 'AES.smali')
|
||||||
|
M.os.makedirs(M.os.path.dirname(Target_Dest), exist_ok=True)
|
||||||
|
M.shutil.copy(F.AES_Smali, Target_Dest)
|
||||||
|
|
||||||
|
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} ✔")
|
||||||
|
|
||||||
|
|
||||||
|
# ---------------- Update Package Name ----------------
|
||||||
|
PKG_Name = M.re.search(
|
||||||
|
r'package="([^"]+)"',
|
||||||
|
open(manifest_path, 'r', encoding='utf-8', errors='ignore').read()
|
||||||
|
)[1]
|
||||||
|
|
||||||
|
content = open(Target_Dest, 'r', encoding='utf-8', errors='ignore').read()
|
||||||
|
|
||||||
|
Update_PKG = content.replace('PACKAGENAME', PKG_Name)
|
||||||
|
|
||||||
|
open(Target_Dest, 'w', encoding='utf-8', errors='ignore').write(Update_PKG)
|
||||||
|
|
||||||
|
print(f"{C.G} |\n └── {C.CC}Update Package Name ~{C.G}$ {C.OG}➸❥ {C.P}'{C.G}{PKG_Name}{C.P}' {C.G} ✔\n")
|
||||||
181
ApkPatcher/Patch/Ads_Patch.py
Normal file
181
ApkPatcher/Patch/Ads_Patch.py
Normal file
@ -0,0 +1,181 @@
|
|||||||
|
from ..ANSI_COLORS import ANSI; C = ANSI()
|
||||||
|
from ..MODULES import IMPORT; M = IMPORT()
|
||||||
|
|
||||||
|
C_Line = f"{C.CC}{'_' * 61}"
|
||||||
|
|
||||||
|
|
||||||
|
# ---------------- Regex Scan ----------------
|
||||||
|
def Regex_Scan(Smali_Path, Target_Regex, Count, Lock):
|
||||||
|
|
||||||
|
Smali = open(Smali_Path, 'r', encoding='utf-8', errors='ignore').read()
|
||||||
|
|
||||||
|
Regexs = [M.re.compile(r) for r in Target_Regex]
|
||||||
|
|
||||||
|
for Regex in Regexs:
|
||||||
|
|
||||||
|
if Regex.search(Smali):
|
||||||
|
|
||||||
|
if Lock:
|
||||||
|
try:
|
||||||
|
with Lock:
|
||||||
|
Count.value += 1
|
||||||
|
|
||||||
|
print(f"\r{C.S} Find Target Smali {C.E} {C.OG}➸❥ {C.PN}{Count.value}", end='', flush=True)
|
||||||
|
|
||||||
|
except Exception:
|
||||||
|
return None
|
||||||
|
|
||||||
|
else:
|
||||||
|
Count[0] += 1
|
||||||
|
|
||||||
|
print(f"\r{C.S} Find Target Smali {C.E} {C.OG}➸❥ {C.PN}{Count[0]}", end='', flush=True)
|
||||||
|
|
||||||
|
return Smali_Path
|
||||||
|
|
||||||
|
|
||||||
|
# ---------------- Ads Smali Patch ----------------
|
||||||
|
def Ads_Smali_Patch(smali_folders):
|
||||||
|
|
||||||
|
Smali_Paths, Match_Smali = [], []
|
||||||
|
|
||||||
|
patterns = [
|
||||||
|
(
|
||||||
|
r'"(com.google.android.play.core.appupdate.protocol.IAppUpdateService|Theme.Dialog.Alert|com.google.android.play.core.install.BIND_UPDATE_SERVICE)"',
|
||||||
|
r'""',
|
||||||
|
"Update Disable"
|
||||||
|
),
|
||||||
|
(
|
||||||
|
r'(invoke(?!.*(close|Destroy|Dismiss|Disabl|error|player|remov|expir|fail|hide|skip|stop)).*/(adcolony|admob|ads|adsdk|aerserv|appbrain|applovin|appodeal|appodealx|appsflyer|bytedance/sdk/openadsdk|chartboost|flurry|fyber|hyprmx|inmobi|ironsource|mbrg|mbridge|mintegral|moat|mobfox|mobilefuse|mopub|my/target|ogury|Omid|onesignal|presage|smaato|smartadserver|snap/adkit|snap/appadskit|startapp|taboola|tapjoy|tappx|vungle)/[^;]+;->(.*(load|show).*)\([^)]*\)V)|(invoke(?!.*(close|Deactiv|Destroy|Dismiss|Disabl|error|player|remov|expir|fail|hide|skip|stop|Throw)).*/(adcolony|admob|ads|adsdk|aerserv|appbrain|applovin|appodeal|appodealx|appsflyer|bytedance/sdk/openadsdk|chartboost|flurry|fyber|hyprmx|inmobi|ironsource|mbrg|mbridge|mintegral|moat|mobfox|mobilefuse|mopub|my/target|ogury|Omid|onesignal|presage|smaato|smartadserver|snap/adkit|snap/appadskit|startapp|taboola|tapjoy|tappx|vungle)/[^;]+;->(request.*|(.*(activat|Banner|build|Event|exec|header|html|initAd|initi|JavaScript|Interstitial|load|log|MetaData|metri|Native|onAd|propert|report|response|Rewarded|show|trac|url|(fetch|refresh|render|video)Ad).*)|.*Request)\([^)]*\)V)|(invoke(?!.*(close|Destroy|Dismiss|Disabl|error|player|remov|expir|fail|hide|skip|stop)).*/(adcolony|admob|ads|adsdk|aerserv|appbrain|applovin|appodeal|appodealx|appsflyer|bytedance/sdk/openadsdk|chartboost|flurry|fyber|hyprmx|inmobi|ironsource|mbrg|mbridge|mintegral|moat|mobfox|mobilefuse|mopub|my/target|ogury|Omid|onesignal|presage|smaato|smartadserver|snap/adkit|snap/appadskit|startapp|taboola|tapjoy|tappx|vungle)/[^;]+;->((.*(Banner|initAd|Interstitial|load|Native|onAd|Rewarded|show|(fetch|refresh|render|request|video)Ad).*))\([^)]*\)V)|invoke-.*\{.*\}, L[^;]+;->(loadAd|requestNativeAd|showInterstitial|fetchad|fetchads|onadloaded|requestInterstitialAd|showAd|loadAds|AdRequest|requestBannerAd|loadNextAd|createInterstitialAd|setNativeAd|loadBannerAd|loadNativeAd|loadRewardedAd|loadRewardedInterstitialAd|loadAds|loadAdViewAd|showInterstitialAd|shownativead|showbannerad|showvideoad|onAdFailedToLoad)\([^)]*\)V|invoke-[^{]+ \{[^\}]*\}, Lcom[^;]+;->requestInterstitialAd\([^)]*\)V|invoke-[^{]+ \{[^\}]*\}, Lcom[^;]+;->loadAds\([^)]*\)V|invoke-[^{]+ \{[^\}]*\}, Lcom[^;]+;->loadAd\([^)]*\)V|invoke-[^{]+ \{[^\}]*\}, Lcom[^;]+;->requestBannerAd\([^)]*\)V|invoke-[^{]+ \{[pv]\d\}, Lcom/facebook[^;]+;->show\([^)]*\)V|invoke-[^{]+ \{[pv]\d\}, Lcom/google[^;]+;->show\([^)]*\)V',
|
||||||
|
r'nop',
|
||||||
|
"Ads Regex 1"
|
||||||
|
),
|
||||||
|
(
|
||||||
|
r'(invoke(?!.*(close|Deactiv|Destroy|Dismiss|Disabl|error|player|remov|expir|fail|hide|skip|stop|Throw)).*/(adcolony|admob|ads|adsdk|aerserv|appbrain|applovin|appodeal|appodealx|appsflyer|bytedance/sdk/openadsdk|chartboost|flurry|fyber|hyprmx|inmobi|ironsource|mbrg|mbridge|mintegral|moat|mobfox|mobilefuse|mopub|my/target|ogury|Omid|onesignal|presage|smaato|smartadserver|snap/adkit|snap/appadskit|startapp|taboola|tapjoy|tappx|vungle)/[^;]+;->(request.*|(.*(activat|Banner|build|Event|exec|header|html|initAd|initi|JavaScript|Interstitial|load|log|MetaData|metri|Native|(can|get|is|has|was)Ad|propert|report|response|Rewarded|show|trac|url|(fetch|refresh|render|video)Ad).*)|.*Request)\([^)]*\)Z[^>]*?)move-result ([pv]\d+)|(invoke(?!.*(close|Destroy|Dismiss|Disabl|error|player|remov|expir|fail|hide|skip|stop)).*/(adcolony|admob|ads|adsdk|aerserv|appbrain|applovin|appodeal|appodealx|appsflyer|bytedance/sdk/openadsdk|chartboost|flurry|fyber|hyprmx|inmobi|ironsource|mbrg|mbridge|mintegral|moat|mobfox|mobilefuse|mopub|my/target|ogury|Omid|onesignal|presage|smaato|smartadserver|snap/adkit|snap/appadskit|startapp|taboola|tapjoy|tappx|vungle)/[^;]+;->((.*(Banner|initAd|Interstitial|load|Native|(can|get|has|is|was)Ad|Rewarded|show|(fetch|refresh|render|request|video)Ad).*))\([^)]*\)Z[^>]*?)move-result ([pv]\d+)',
|
||||||
|
r'const/4 \9, 0x0',
|
||||||
|
"Ads Regex 2"
|
||||||
|
),
|
||||||
|
(
|
||||||
|
r'(invoke(?!.*(close|Destroy|Dismiss|Disabl|error|player|remov|expir|fail|hide|skip|stop)).*/(adcolony|admob|ads|adsdk|aerserv|appbrain|applovin|appodeal|appodealx|appsflyer|bytedance/sdk/openadsdk|chartboost|flurry|fyber|hyprmx|inmobi|ironsource|mbrg|mbridge|mintegral|moat|mobfox|mobilefuse|mopub|my/target|ogury|Omid|onesignal|presage|smaato|smartadserver|snap/adkit|snap/appadskit|startapp|taboola|tapjoy|tappx|vungle)/[^;]+;->(.*(load|show).*)\([^)]*\)Z[^>]*?)move-result ([pv]\d+)',
|
||||||
|
r'const/4 \6, 0x0',
|
||||||
|
"Ads Regex 3"
|
||||||
|
),
|
||||||
|
(
|
||||||
|
r'(\.method\s(public|private|static)\s\b(?!\babstract|native\b)[^(]*?loadAd\([^)]*\)V)',
|
||||||
|
r'\1\n\treturn-void',
|
||||||
|
"Ads Regex 4"
|
||||||
|
),
|
||||||
|
(
|
||||||
|
r'(\.method\s(public|private|static)\s\b(?!\babstract|native\b)[^(]*?loadAd\([^)]*\)Z)',
|
||||||
|
r'\1\n\tconst/4 v0, 0x0\n\treturn v0',
|
||||||
|
"Ads Regex 5"
|
||||||
|
),
|
||||||
|
(
|
||||||
|
r'(invoke[^{]+ \{[^\}]*\}, L[^(]*loadAd\([^)]*\)[VZ])|(invoke[^{]+ \{[^\}]*\}, L[^(]*gms.*\>(loadUrl|loadDataWithBaseURL|requestInterstitialAd|showInterstitial|showVideo|showAd|loadData|onAdClicked|onAdLoaded|isLoading|loadAds|AdLoader|AdRequest|AdListener|AdView)\([^)]*\)V)',
|
||||||
|
r'#',
|
||||||
|
"Ads Regex 6"
|
||||||
|
),
|
||||||
|
(
|
||||||
|
r'\.method [^(]*(loadAd|requestNativeAd|showInterstitial|fetchad|fetchads|onadloaded|requestInterstitialAd|showAd|loadAds|AdRequest|requestBannerAd|loadNextAd|createInterstitialAd|setNativeAd|loadBannerAd|loadNativeAd|loadRewardedAd|loadRewardedInterstitialAd|loadAds|loadAdViewAd|showInterstitialAd|shownativead|showbannerad|showvideoad|onAdFailedToLoad)\([^)]*\)V\s+\.locals \d+[\s\S]*?\.end method',
|
||||||
|
r'#',
|
||||||
|
"Ads Regex 7"
|
||||||
|
),
|
||||||
|
(
|
||||||
|
r'"ca-app-pub-\d{16}/\d{10}"',
|
||||||
|
r'"ca-app-pub-0000000000000000/0000000000"',
|
||||||
|
"Ads Regex 8"
|
||||||
|
),
|
||||||
|
(
|
||||||
|
r'"(http.*|//.*)(61.145.124.238|-ads.|.ad.|.ads.|.analytics.localytics.com|.mobfox.com|.mp.mydas.mobi|.plus1.wapstart.ru|.scorecardresearch.com|.startappservice.com|/ad.|/ads|ad-mail|ad.*_logging|ad.api.kaffnet.com|adc3-launch|adcolony|adinformation|adkmob|admax|admob|admost|adsafeprotected|adservice|adtag|advert|adwhirl|adz.wattpad.com|alta.eqmob.com|amazon-*ads|amazon.*ads|amobee|analytics|applovin|applvn|appnext|appodeal|appsdt|appsflyer|burstly|cauly|cloudfront|com.google.android.gms.ads.identifier.service.START|crashlytics|crispwireless|doubleclick|dsp.batmobil.net|duapps|dummy|flurry|gad|getads|google.com/dfp|googleAds|googleads|googleapis.*.ad-*|googlesyndication|googletagmanager|greystripe|gstatic|inmobi|inneractive|jumptag|live.chartboost.com|madnet|millennialmedia|moatads|mopub|native_ads|pagead|pubnative|smaato|supersonicads|tapas|tapjoy|unityads|vungle|zucks).*"',
|
||||||
|
r'"="',
|
||||||
|
"Ads Regex 9"
|
||||||
|
),
|
||||||
|
(
|
||||||
|
r'"(http.*|//.*)(61\.145\.124\.238|/2mdn\.net|-ads\.|\.5rocks\.io|\.ad\.|\.adadapted|\.admitad\.|\.admost\.|\.ads\.|\.aerserv\.|\.airpush\.|\.batmobil\.|\.chartboost\.|\.cloudmobi\.|\.conviva\.|\.dov-e\.com|\.fyber\.|\.mng-ads\|\.mydas\.|\.predic\.|\.talkingdata\.|\.tapdaq\.|\.tele\.fm|\.unity3d\.|\.unity\.|\.wapstart\.|\.xdrig\.|\.zapr\.|\/ad\.|\/ads|a4\.tl|accengage|ad4push|ad4screen|ad-mail|ad\..*_logging|ad\.api\.kaffnet\.|ad\.cauly\.co\.|adbuddiz|adc3-launch|adcolony|adfurikun|adincube|adinformation|adkmob|admax\.|admixer|admob|admost|ads\.mdotm\.|adsafeprotected|adservice|adsmogo|adsrvr|adswizz|adtag|adtech\.de|advert|adwhirl|adz\.wattpad\.|alimama\.|alta\.eqmob\.|amazon-.*ads|amazon\..*ads|amobee|analytics|anvato|appboy|appbrain|applovin|applvn|appmetrica|appnext|appodeal|appsdt|appsflyer|apsalar|avocarrot|axonix|banners-slb\.mobile\.yandex\.net|banners\.mobile\.yandex\.net|brightcove\.|burstly|cauly|cloudfront|cmcm\.|com\.google\.android\.gms\.ads\.identifier\.service\.START|comscore|contextual\.media\.net|crashlytics|crispwireless|criteo\.|dmtry\.|doubleclick|duapps|dummy|flurry|fwmrm|gad|getads|gimbal|glispa|google\.com\/dfp|googleAds|googleads|googleapis\..*\.ad-.*|googlesyndication|googletagmanager|greystripe|gstatic|heyzap|hyprmx|iasds01|inmobi|inneractive|instreamatic|integralads|jumptag|jwpcdn|jwpltx|jwpsrv|kochava|localytics|madnet|mapbox|mc\.yandex\.ru|media\.net|metrics\.|millennialmedia|mixpanel|mng-ads\.com|moat\.|moatads|mobclix|mobfox|mobpowertech|moodpresence|mopub|native_ads|nativex\.|nexage\.|ooyala|openx\.|pagead|pingstart|prebid|presage\.io|pubmatic|pubnative|rayjump|saspreview|scorecardresearch|smaato|smartadserver|sponsorpay|startappservice|startup\.mobile\.yandex\.net|statistics\.videofarm\.daum\.net|supersonicads|taboola|tapas|tapjoy|tapylitics|target\.my\.com|teads\.|umeng|unityads|vungle|zucks).*"',
|
||||||
|
r'"127.0.0.1"',
|
||||||
|
"Ads Regex 10"
|
||||||
|
),
|
||||||
|
|
||||||
|
# ---------------- Fix Play ----------------
|
||||||
|
(
|
||||||
|
r'(invoke-interface \{[^\}]*\}, Lcom/google/android/vending/licensing/Policy;->allowAccess\(\)Z[^>]*?\s+)move-result ([pv]\d+)',
|
||||||
|
r'\1const/4 \2, 0x1',
|
||||||
|
"Bypass Client-Side LVL (allowAccess)"
|
||||||
|
),
|
||||||
|
(
|
||||||
|
r'(\.method [^(]*connectToLicensingService\(\)V\s+.locals \d+)[\s\S]*?(\s+return-void\n.end method)',
|
||||||
|
r'\1\2',
|
||||||
|
"connectToLicensingService"
|
||||||
|
),
|
||||||
|
(
|
||||||
|
r'(\.method [^(]*initializeLicenseCheck\(\)V\s+.locals \d+)[\s\S]*?(\s+return-void\n.end method)',
|
||||||
|
r'\1\2',
|
||||||
|
"initializeLicenseCheck"
|
||||||
|
),
|
||||||
|
(
|
||||||
|
r'(\.method [^(]*processResponse\(ILandroid/os/Bundle;\)V\s+.locals \d+)[\s\S]*?(\s+return-void\n.end method)',
|
||||||
|
r'\1\2',
|
||||||
|
"processResponse"
|
||||||
|
)
|
||||||
|
]
|
||||||
|
|
||||||
|
Target_Regex = [p[0] for p in patterns]
|
||||||
|
|
||||||
|
for smali_folder in smali_folders:
|
||||||
|
for root, _, files in M.os.walk(smali_folder):
|
||||||
|
for file in files:
|
||||||
|
if file.endswith('.smali'):
|
||||||
|
Smali_Paths.append(M.os.path.join(root, file))
|
||||||
|
|
||||||
|
try:
|
||||||
|
# ---------------- Multiple Threading ----------------
|
||||||
|
with M.Manager() as MT:
|
||||||
|
Count = MT.Value('i', 0); Lock = MT.Lock()
|
||||||
|
with M.Pool(M.cpu_count()) as PL:
|
||||||
|
Match_Smali = [path for path in PL.starmap(Regex_Scan, [(Smali_Path, Target_Regex, Count, Lock) for Smali_Path in Smali_Paths]) if path]
|
||||||
|
|
||||||
|
except Exception:
|
||||||
|
# ---------------- Single Threading ----------------
|
||||||
|
Count = [0]
|
||||||
|
for Smali_Path in Smali_Paths:
|
||||||
|
result = Regex_Scan(Smali_Path, Target_Regex, Count, None)
|
||||||
|
|
||||||
|
if result:
|
||||||
|
Match_Smali.append(result)
|
||||||
|
|
||||||
|
print(f" {C.G} ✔", flush=True)
|
||||||
|
|
||||||
|
print(f'\n{C_Line}\n')
|
||||||
|
|
||||||
|
if Match_Smali:
|
||||||
|
for pattern, replacement, description in patterns:
|
||||||
|
|
||||||
|
Count_Applied = 0
|
||||||
|
|
||||||
|
Applied_Files = set()
|
||||||
|
|
||||||
|
for file_path in Match_Smali:
|
||||||
|
|
||||||
|
content = open(file_path, 'r', encoding='utf-8', errors='ignore').read()
|
||||||
|
|
||||||
|
new_content = M.re.sub(pattern, replacement, content)
|
||||||
|
|
||||||
|
if new_content != content:
|
||||||
|
if file_path not in Applied_Files:
|
||||||
|
Applied_Files.add(file_path)
|
||||||
|
|
||||||
|
Count_Applied += 1
|
||||||
|
|
||||||
|
open(file_path, 'w', encoding='utf-8', errors='ignore').write(new_content)
|
||||||
|
|
||||||
|
if Count_Applied > 0:
|
||||||
|
print(f"\n{C.S} Tag {C.E} {C.G}{description}")
|
||||||
|
|
||||||
|
print(f"\n{C.S} Pattern {C.E} {C.OG}➸❥ {C.P}{pattern}")
|
||||||
|
|
||||||
|
for file_path in Applied_Files:
|
||||||
|
print(f"{C.G} |\n └──── {C.CC}~{C.G}$ {C.Y}{M.os.path.basename(file_path)} {C.G} ✔")
|
||||||
|
|
||||||
|
print(
|
||||||
|
f"\n{C.S} Pattern Applied {C.E} {C.OG}➸❥ {C.PN}{Count_Applied} {C.C}Time/Smali {C.G} ✔\n"
|
||||||
|
f"\n{C_Line}\n"
|
||||||
|
)
|
||||||
187
ApkPatcher/Patch/CERT_NSC.py
Normal file
187
ApkPatcher/Patch/CERT_NSC.py
Normal file
@ -0,0 +1,187 @@
|
|||||||
|
from ..ANSI_COLORS import ANSI; C = ANSI()
|
||||||
|
from ..MODULES import IMPORT; M = IMPORT()
|
||||||
|
|
||||||
|
|
||||||
|
# ---------------- Write RAW CERT ----------------
|
||||||
|
def Write_CERT(decompile_dir, isAPKEditor, CA_Cert):
|
||||||
|
|
||||||
|
if isAPKEditor:
|
||||||
|
decompile_dir = M.os.path.join(decompile_dir, 'resources', 'package_1')
|
||||||
|
|
||||||
|
Default_CERT = """\
|
||||||
|
-----BEGIN CERTIFICATE-----
|
||||||
|
MIIDczCCAlugAwIBAgIHALdlRG+pDzANBgkqhkiG9w0BAQ0FADBHMRswGQYDVQQD
|
||||||
|
DBJIdHRwQ2FuYXJ5IFJvb3QgQ0ExEzARBgNVBAoMCkh0dHBDYW5hcnkxEzARBgNV
|
||||||
|
BAsMCkh0dHBDYW5hcnkwHhcNMjIwMzA2MTIxMTAxWhcNMzMwMzAzMTIxMTAxWjBH
|
||||||
|
MRswGQYDVQQDDBJIdHRwQ2FuYXJ5IFJvb3QgQ0ExEzARBgNVBAoMCkh0dHBDYW5h
|
||||||
|
cnkxEzARBgNVBAsMCkh0dHBDYW5hcnkwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAw
|
||||||
|
ggEKAoIBAQCrzm03w7mMvHujpl0IMb/jgxEwJdUsfpazdgUVdsq+7T/Ks8O3NMFP
|
||||||
|
d4hl6sUgRbaMx3Uz8WolEtz/wu/fdGnrUVDcdWXiJKfhLUUP3KuYwE9tahrfRf14
|
||||||
|
Yg/xGoA8Pz1BEaUnsJSt6RB5qm5fwn2O8QRykAbgr11or2rr8KQWMaoeciN04tjd
|
||||||
|
kkcWmPWNSytwea7l1LOrolUXGcbFlpXpGY1cTCoB1RZJe7HkUd1zdYhKUlhHZo3P
|
||||||
|
in9FhGa/UJGlyWXmT3ybY0nuPtIvqJ3Ao4FwP1zkrrqvS0UCi3QvJZrZ8EEju0U9
|
||||||
|
NM009njCT6sX56TUG189Dk1uettEiTtlAgMBAAGjZDBiMB0GA1UdDgQWBBT0yJzC
|
||||||
|
NcHzwIVXMTnvgPp74q1KWjAPBgNVHRMBAf8EBTADAQH/MAsGA1UdDwQEAwIBtjAj
|
||||||
|
BgNVHSUEHDAaBggrBgEFBQcDAQYIKwYBBQUHAwIGBFUdJQAwDQYJKoZIhvcNAQEN
|
||||||
|
BQADggEBAA9H0nWzKUKKfgu6RI657wVgSONymRRnpzQ+GNjbDoi6CR3QWL8SvPe8
|
||||||
|
s61nM8xUP0aMFv0VYrd80sICTQXAEld+/eXoDib7qxg1I2I9v+FkLwPSN2FaJRkv
|
||||||
|
GKxfki4s6kpNNvmO5X+1eR1fK7Y/lrlp9V7zP8oMbcBuNkiWO6UYNGGGuqxFr3H4
|
||||||
|
f4LRvODZks/aGea2E0pdiAnAZCIGZS3Mg5cS7wA5vUSkKwpBIcYFVdYTF/xblJfX
|
||||||
|
OBoyS7CMCG66aSfs3zk4lT8fVwtFJjvkM01gH3A4q6T78rZ/Nkx01GC90Y1+xDAW
|
||||||
|
0o1SBaeL3tulFzqhMkl5KW0F3vYpP8k=
|
||||||
|
-----END CERTIFICATE-----"""
|
||||||
|
|
||||||
|
raw_dir = M.os.path.join(decompile_dir, 'res', 'raw')
|
||||||
|
|
||||||
|
M.os.makedirs(raw_dir, exist_ok=True)
|
||||||
|
|
||||||
|
addCERT = []
|
||||||
|
|
||||||
|
if CA_Cert:
|
||||||
|
for idx, cert_path in enumerate(CA_Cert, start=1):
|
||||||
|
raw_file = f'Techno_India_{idx}.pem' if idx > 1 else 'Techno_India.pem'
|
||||||
|
M.shutil.copy(cert_path, M.os.path.join(raw_dir, raw_file))
|
||||||
|
|
||||||
|
addCERT.append(raw_file)
|
||||||
|
|
||||||
|
print(
|
||||||
|
f"\n{C.S} Certificate {C.E}{C.C} Your Certificate Path...\n"
|
||||||
|
f"{C.G} |\n |\n └──── {C.CC}Input ~{C.G}#{C.Y} {', '.join(CA_Cert)} {C.G} ✔\n"
|
||||||
|
)
|
||||||
|
|
||||||
|
print(f"\n{C.S} Write Certificate {C.E} {C.OG}➸❥ {C.Y}raw/{', '.join(addCERT)} {C.G} ✔\n")
|
||||||
|
|
||||||
|
else:
|
||||||
|
raw_path = M.os.path.join(raw_dir, 'Techno_India.pem')
|
||||||
|
|
||||||
|
open(raw_path, 'w', encoding='utf-8', errors='ignore').write(Default_CERT)
|
||||||
|
|
||||||
|
print(f"\n{C.S} Certificate {C.E}{C.G} The default certificate is from TechnoIndia's Modded HttpCanary... ✔\n")
|
||||||
|
|
||||||
|
print(f"\n{C.S} Write Default Certificate {C.E} {C.OG}➸❥ {C.Y}{M.os.path.basename(raw_dir)}/Techno_India.pem {C.G} ✔\n")
|
||||||
|
|
||||||
|
|
||||||
|
# ---------------- Write NSC XML ----------------
|
||||||
|
def Write_NSC(decompile_dir, isAPKEditor, CA_Cert, xml_file='network_security_config.xml'):
|
||||||
|
|
||||||
|
Write_CERT(decompile_dir, isAPKEditor, CA_Cert)
|
||||||
|
|
||||||
|
if isAPKEditor:
|
||||||
|
decompile_dir = M.os.path.join(decompile_dir, 'resources', 'package_1')
|
||||||
|
|
||||||
|
NSC = """\
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<network-security-config xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
|
<domain-override host="*" domain-override-cleartext-traffic-permitted="true" />
|
||||||
|
<domain-config cleartextTrafficPermitted="true">
|
||||||
|
<domain includeSubdomains="true">*</domain>
|
||||||
|
<domain includeSubdomains="true">0.0.0.0</domain>
|
||||||
|
<domain includeSubdomains="true">127.0.0.1</domain>
|
||||||
|
<trust-anchors>
|
||||||
|
{cert_PlaceHolder}
|
||||||
|
<certificates src="system" overridePins="true" />
|
||||||
|
<certificates src="user" overridePins="true" />
|
||||||
|
</trust-anchors>
|
||||||
|
</domain-config>
|
||||||
|
<base-config cleartextTrafficPermitted="true">
|
||||||
|
<trust-anchors>
|
||||||
|
{cert_PlaceHolder}
|
||||||
|
<certificates src="system" overridePins="true" />
|
||||||
|
<certificates src="user" overridePins="true" />
|
||||||
|
</trust-anchors>
|
||||||
|
</base-config>
|
||||||
|
<debug-overrides cleartextTrafficPermitted="true">
|
||||||
|
<trust-anchors>
|
||||||
|
{cert_PlaceHolder}
|
||||||
|
<certificates src="system" overridePins="true" />
|
||||||
|
<certificates src="user" overridePins="true" />
|
||||||
|
</trust-anchors>
|
||||||
|
</debug-overrides>
|
||||||
|
</network-security-config>"""
|
||||||
|
|
||||||
|
cert_Entries = ""
|
||||||
|
|
||||||
|
if CA_Cert:
|
||||||
|
for idx, _ in enumerate(CA_Cert, start=1):
|
||||||
|
CERT_Name = f'Techno_India_{idx}' if idx > 1 else 'Techno_India'
|
||||||
|
cert_Entries += f' <certificates src="@raw/{CERT_Name}" overridePins="true" />\n'
|
||||||
|
|
||||||
|
else:
|
||||||
|
cert_Entries += ' <certificates src="@raw/Techno_India" overridePins="true" />\n'
|
||||||
|
|
||||||
|
NSC_XML = NSC.format(cert_PlaceHolder = cert_Entries.strip())
|
||||||
|
|
||||||
|
xml_dir = M.os.path.join(decompile_dir, 'res', 'xml')
|
||||||
|
|
||||||
|
M.os.makedirs(xml_dir, exist_ok=True)
|
||||||
|
|
||||||
|
xml_path = M.os.path.join(xml_dir, xml_file)
|
||||||
|
|
||||||
|
open(xml_path, 'w', encoding='utf-8', errors='ignore').write(NSC_XML)
|
||||||
|
|
||||||
|
print(f"\n{C.S} Write Network Config {C.E} {C.OG}➸❥ {C.Y}{M.os.path.basename(xml_dir)}/{xml_file} {C.G} ✔\n")
|
||||||
|
|
||||||
|
if isAPKEditor:
|
||||||
|
update_public_xml(decompile_dir, CA_Cert)
|
||||||
|
|
||||||
|
|
||||||
|
# ---------------- For isAPKEditor ----------------
|
||||||
|
def update_public_xml(decompile_dir, CA_Cert):
|
||||||
|
|
||||||
|
public_xml_path = M.os.path.join(decompile_dir, 'res', 'values', 'public.xml')
|
||||||
|
|
||||||
|
public_xml = open(public_xml_path, 'r', encoding='utf-8', errors='ignore').readlines()
|
||||||
|
|
||||||
|
raw_ids = []
|
||||||
|
xml_ids = []
|
||||||
|
|
||||||
|
raw_xml_regex = M.re.compile(r'<public id="(0x[0-9a-fA-F]+)" type="(raw|xml)" name="([^"]*)" />')
|
||||||
|
|
||||||
|
raw_found = False
|
||||||
|
xml_found = False
|
||||||
|
|
||||||
|
for line in public_xml:
|
||||||
|
for match in raw_xml_regex.findall(line):
|
||||||
|
res_id = int(match[0], 16)
|
||||||
|
res_type = match[1]
|
||||||
|
res_name = match[2]
|
||||||
|
|
||||||
|
if res_type == "raw" and res_name == "Techno_India":
|
||||||
|
raw_found = True
|
||||||
|
elif res_type == "xml" and res_name == "network_security_config":
|
||||||
|
xml_found = True
|
||||||
|
|
||||||
|
if res_type == "raw":
|
||||||
|
raw_ids.append(res_id)
|
||||||
|
elif res_type == "xml":
|
||||||
|
xml_ids.append(res_id)
|
||||||
|
|
||||||
|
if raw_found and xml_found:
|
||||||
|
return
|
||||||
|
|
||||||
|
new_raw_id = max(raw_ids) + 1 if raw_ids else 0x7fffff01
|
||||||
|
new_xml_id = max(xml_ids) + 1 if xml_ids else 0x7ffffff1
|
||||||
|
|
||||||
|
new_entries = []
|
||||||
|
|
||||||
|
if not raw_found:
|
||||||
|
if CA_Cert:
|
||||||
|
for idx, _ in enumerate(CA_Cert, start=1):
|
||||||
|
CERT_Name = f'Techno_India_{idx}' if idx > 1 else 'Techno_India'
|
||||||
|
new_entries.append(f' <public id="0x{new_raw_id:08X}" type="raw" name="{CERT_Name}" />\n')
|
||||||
|
new_raw_id += 1
|
||||||
|
|
||||||
|
else:
|
||||||
|
new_entries.append(f' <public id="0x{new_raw_id:08X}" type="raw" name="Techno_India" />\n')
|
||||||
|
|
||||||
|
if not xml_found:
|
||||||
|
new_entries.append(f' <public id="0x{new_xml_id:08X}" type="xml" name="network_security_config" />\n')
|
||||||
|
|
||||||
|
for idx in range(len(public_xml)):
|
||||||
|
if "</resources>" in public_xml[idx]:
|
||||||
|
public_xml[idx:idx] = new_entries
|
||||||
|
break
|
||||||
|
|
||||||
|
open(public_xml_path, 'w', encoding='utf-8', errors='ignore').writelines(public_xml)
|
||||||
|
|
||||||
|
print(f"\n{C.S} Write New Entries {C.E} {C.OG}➸❥ {C.G}public.xml\n\n{C.OG}{''.join(new_entries).strip()}\n")
|
||||||
146
ApkPatcher/Patch/Flutter_SSL_Patch.py
Normal file
146
ApkPatcher/Patch/Flutter_SSL_Patch.py
Normal file
@ -0,0 +1,146 @@
|
|||||||
|
# -* coding: utf-8 *-
|
||||||
|
# @auhtor: AbhiTheModder
|
||||||
|
|
||||||
|
from ..ANSI_COLORS import ANSI; C = ANSI()
|
||||||
|
from ..MODULES import IMPORT; M = IMPORT()
|
||||||
|
|
||||||
|
|
||||||
|
patterns = {
|
||||||
|
"arm64": [
|
||||||
|
"F. 0F 1C F8 F. 5. 01 A9 F. 5. 02 A9 F. .. 03 A9 .. .. .. .. 68 1A 40 F9",
|
||||||
|
"F. 43 01 D1 FE 67 01 A9 F8 5F 02 A9 F6 57 03 A9 F4 4F 04 A9 13 00 40 F9 F4 03 00 AA 68 1A 40 F9",
|
||||||
|
"FF 43 01 D1 FE 67 01 A9 .. .. 06 94 .. 7. 06 94 68 1A 40 F9 15 15 41 F9 B5 00 00 B4 B6 4A 40 F9",
|
||||||
|
"F. 0F 1C F8 F. .. 0. .. .. .. .. .9 .. .. 0. .. 68 1A 40 F9 15 .. 4. F9 B5 00 00 B4 B6 46 40 F9",
|
||||||
|
],
|
||||||
|
"arm": [
|
||||||
|
"2D E9 F. 4. D0 F8 00 80 81 46 D8 F8 18 00 D0 F8",
|
||||||
|
],
|
||||||
|
"x86": [
|
||||||
|
"55 41 57 41 56 41 55 41 54 53 50 49 89 fe 48 8b 1f 48 8b 43 30 4c 8b b8 d0 01 00 00 4d 85 ff 74 12 4d 8b a7 90 00 00 00 4d 85 e4 74 4a 49 8b 04 24 eb 46",
|
||||||
|
"55 41 57 41 56 41 55 41 54 53 50 49 89 f. 4c 8b 37 49 8b 46 30 4c 8b a. .. 0. 00 00 4d 85 e. 74 1. 4d 8b",
|
||||||
|
"55 41 57 41 56 41 55 41 54 53 48 83 EC 18 49 89 FF 48 8B 1F 48 8B 43 30 4C 8B A0 28 02 00 00 4D 85 E4 74",
|
||||||
|
"55 41 57 41 56 41 55 41 54 53 48 83 EC 38 C6 02 50 48 8B AF A. 00 00 00 48 85 ED 74 7. 48 83 7D 00 00 74",
|
||||||
|
"55 41 57 41 56 41 55 41 54 53 48 83 EC 18 49 89 FE 4C 8B 27 49 8B 44 24 30 48 8B 98 D0 01 00 00 48 85 DB",
|
||||||
|
],
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
# ---------------- Get r2 Version ----------------
|
||||||
|
def get_r2_version():
|
||||||
|
|
||||||
|
try:
|
||||||
|
result = M.subprocess.run(["r2", "-V"], capture_output=True, text=True, check=True)
|
||||||
|
results = result.stdout.strip().split()
|
||||||
|
|
||||||
|
for result in results:
|
||||||
|
if result.startswith(("5.", "6.")):
|
||||||
|
result = result.split("-")[0]
|
||||||
|
return result
|
||||||
|
|
||||||
|
return None
|
||||||
|
|
||||||
|
except (M.subprocess.CalledProcessError, FileNotFoundError):
|
||||||
|
return None
|
||||||
|
|
||||||
|
|
||||||
|
# ---------------- Find Offset ----------------
|
||||||
|
def find_offset(r2, patterns, is_iA=False):
|
||||||
|
|
||||||
|
if is_iA:
|
||||||
|
arch = M.json.loads(r2.cmd("iAj"))
|
||||||
|
else:
|
||||||
|
arch = M.json.loads(r2.cmd("iaj"))
|
||||||
|
|
||||||
|
arch_value = arch["bins"][0]["arch"]
|
||||||
|
arch_bits = arch["bins"][0]["bits"]
|
||||||
|
|
||||||
|
if arch_value == "arm" and arch_bits == 64:
|
||||||
|
arch = "arm64"
|
||||||
|
elif arch_value == "arm" and arch_bits == 16:
|
||||||
|
arch = "arm"
|
||||||
|
elif arch_value == "x86" and arch_bits == 64:
|
||||||
|
arch = "x86"
|
||||||
|
else:
|
||||||
|
print(f"\n{C.ERROR} Unsupported architecture: {arch_value}\n")
|
||||||
|
return
|
||||||
|
|
||||||
|
if arch in patterns:
|
||||||
|
for arch in patterns:
|
||||||
|
for pattern in patterns[arch]:
|
||||||
|
search_result = r2.cmd(f"/x {pattern}")
|
||||||
|
search_result = search_result.strip().split(" ")[0]
|
||||||
|
|
||||||
|
if search_result:
|
||||||
|
search_fcn = r2.cmd(f"{search_result};afl.").strip().split(" ")[0]
|
||||||
|
print(f"\n{C.X}{C.C} ssl_verify_peer_cert found at: {C.PN}{search_result}\n")
|
||||||
|
|
||||||
|
if not search_fcn and arch == "x86":
|
||||||
|
search_fcn = search_result
|
||||||
|
r2.cmd(f"af @{search_fcn}")
|
||||||
|
|
||||||
|
print(f"\n{C.X}{C.C} function at: {C.PN}{search_fcn}\n")
|
||||||
|
return search_fcn
|
||||||
|
|
||||||
|
|
||||||
|
# ---------------- Patch Flutter SSL ----------------
|
||||||
|
def Patch_Flutter_SSL(decompile_dir, isAPKEditor):
|
||||||
|
|
||||||
|
print(f"\r{C.X}{C.C} Flutter SSL Patch, Script by {C.OG}🇮🇳 AbhiTheM0dder 🇮🇳\n")
|
||||||
|
|
||||||
|
try:
|
||||||
|
r2_version = tuple(map(int, get_r2_version().split(".")))
|
||||||
|
ia_version = tuple(map(int, "5.9.5".split(".")))
|
||||||
|
|
||||||
|
if r2_version <= ia_version:
|
||||||
|
is_iA = True
|
||||||
|
else:
|
||||||
|
is_iA = False
|
||||||
|
|
||||||
|
except Exception as e:
|
||||||
|
exit(f"\n{C.ERROR} {str(e)}\n")
|
||||||
|
|
||||||
|
architectures = ["arm64-v8a", "armeabi-v7a", "armeabi", "x86_64"]
|
||||||
|
lib_so_path = None
|
||||||
|
|
||||||
|
for arch in architectures:
|
||||||
|
lib = "root/lib" if isAPKEditor else "lib"
|
||||||
|
potential_path = M.os.path.join(decompile_dir, lib, arch, 'libflutter.so')
|
||||||
|
|
||||||
|
if M.os.path.exists(potential_path):
|
||||||
|
lib_so_path = potential_path
|
||||||
|
break
|
||||||
|
|
||||||
|
if lib_so_path:
|
||||||
|
print(f"\n{C.S} Found {C.E} {C.OG}➸❥ {C.Y}{arch}/{M.os.path.basename(lib_so_path)} {C.G} ✔\n")
|
||||||
|
else:
|
||||||
|
exit(f"\n{C.ERROR} libflutter.so not found in any of the specified architectures {architectures}\n")
|
||||||
|
|
||||||
|
M.shutil.rmtree(decompile_dir)
|
||||||
|
|
||||||
|
import r2pipe
|
||||||
|
|
||||||
|
if r2pipe.in_r2():
|
||||||
|
r2 = r2pipe.open()
|
||||||
|
r2.cmd("e log.quiet=true")
|
||||||
|
r2.cmd("oo+")
|
||||||
|
else:
|
||||||
|
r2 = r2pipe.open(lib_so_path, flags=["-w", "-e", "log.quiet=true"])
|
||||||
|
|
||||||
|
print(f"\n{C.X}{C.G} Analyzing function calls...\n")
|
||||||
|
|
||||||
|
r2.cmd("aac")
|
||||||
|
|
||||||
|
print(f"\n{C.X}{C.G} Searching for offset...\n")
|
||||||
|
|
||||||
|
offset = find_offset(r2, patterns, is_iA)
|
||||||
|
|
||||||
|
if offset:
|
||||||
|
r2.cmd(f"{offset}")
|
||||||
|
r2.cmd("wao ret0")
|
||||||
|
print(f"\n{C.X}{C.C} ssl_verify_peer_cert: {C.G}Patched Successfully ! ✔\n")
|
||||||
|
else:
|
||||||
|
print(f"\n{C.ERROR} ssl_verify_peer_cert Not Found. ✘\n")
|
||||||
|
|
||||||
|
print(f"{C.CC}{'_' * 61}\n\n")
|
||||||
|
|
||||||
|
r2.quit()
|
||||||
172
ApkPatcher/Patch/Manifest_Patch.py
Normal file
172
ApkPatcher/Patch/Manifest_Patch.py
Normal file
@ -0,0 +1,172 @@
|
|||||||
|
from.Package import P
|
||||||
|
|
||||||
|
from ..ANSI_COLORS import ANSI; C = ANSI()
|
||||||
|
from ..MODULES import IMPORT; M = IMPORT()
|
||||||
|
|
||||||
|
|
||||||
|
# ---------------- Fix Manifest ----------------
|
||||||
|
def Fix_Manifest(manifest_path, isPKG, isPine_Hook, Package_Name):
|
||||||
|
|
||||||
|
if isPine_Hook:
|
||||||
|
Pine_Hook(manifest_path, Package_Name)
|
||||||
|
|
||||||
|
isPC = bool(M.re.search('piracychecker', open(manifest_path).read(), M.re.I))
|
||||||
|
|
||||||
|
patterns = [
|
||||||
|
(
|
||||||
|
r'\s+android:(splitTypes|requiredSplitTypes)="[^"]*?"',
|
||||||
|
r'',
|
||||||
|
'Splits'
|
||||||
|
),
|
||||||
|
(
|
||||||
|
r'(isSplitRequired=)"true"',
|
||||||
|
r'\1"false"',
|
||||||
|
'isSplitRequired'
|
||||||
|
),
|
||||||
|
(
|
||||||
|
r'\s+<meta-data[^>]*"com.android.(vending.|stamp.|dynamic.apk.)[^"]*"[^>]*/>',
|
||||||
|
r'',
|
||||||
|
'<meta-data>'
|
||||||
|
),
|
||||||
|
(
|
||||||
|
r'\s+<[^>]*"(com.pairip.licensecheck)[^"]*"[^>]*/>' if isPC else r'\s+<[^>]*"com.(pairip.licensecheck|android.vending.CHECK_LICENSE)[^"]*"[^>]*/>',
|
||||||
|
r'',
|
||||||
|
'CHECK_LICENSE'
|
||||||
|
)
|
||||||
|
]
|
||||||
|
|
||||||
|
if isPKG:
|
||||||
|
patterns.extend(
|
||||||
|
[
|
||||||
|
(
|
||||||
|
rf'{P.Menifest_Regex}',
|
||||||
|
r'',
|
||||||
|
'Spoof Package Detection'
|
||||||
|
)
|
||||||
|
]
|
||||||
|
)
|
||||||
|
|
||||||
|
for pattern, replacement, description in patterns:
|
||||||
|
content = open(manifest_path, 'r', encoding='utf-8', errors='ignore').read()
|
||||||
|
new_content = M.re.sub(pattern, replacement, content)
|
||||||
|
|
||||||
|
if new_content != content:
|
||||||
|
print(
|
||||||
|
f"\n{C.S} Tag {C.E} {C.OG}{description}\n"
|
||||||
|
f"\n{C.S} Applying Pattern {C.E} {C.OG}➸❥ {C.P}{pattern}\n"
|
||||||
|
f"{C.G} |\n └──── {C.CC}Patch Cleaned Up ~{C.G}$ {C.P}'{C.G}{M.os.path.basename(manifest_path)}{C.P}' {C.G} ✔\n"
|
||||||
|
)
|
||||||
|
|
||||||
|
open(manifest_path, 'w', encoding='utf-8', errors='ignore').write(new_content)
|
||||||
|
|
||||||
|
|
||||||
|
# ---------------- Patch Manifest ----------------
|
||||||
|
def Patch_Manifest(decompile_dir, manifest_path):
|
||||||
|
|
||||||
|
content = open(manifest_path, 'r', encoding='utf-8', errors='ignore').read()
|
||||||
|
|
||||||
|
application_tag = M.re.search(r'<application\s+[^>]*>', content)[0]
|
||||||
|
|
||||||
|
cleaned_tag = M.re.sub(
|
||||||
|
r'\s+android:(usesCleartextTraffic|networkSecurityConfig)="[^"]*?"',
|
||||||
|
'',
|
||||||
|
application_tag
|
||||||
|
)
|
||||||
|
|
||||||
|
content = content.replace(application_tag,
|
||||||
|
M.re.sub(
|
||||||
|
r'>',
|
||||||
|
'\n\tandroid:usesCleartextTraffic="true"\n\tandroid:networkSecurityConfig="@xml/network_security_config">',
|
||||||
|
cleaned_tag
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
open(manifest_path, 'w', encoding='utf-8', errors='ignore').write(content)
|
||||||
|
|
||||||
|
print(f'\n{C.S} Updated {C.E}{C.C} android:networkSecurityConfig={C.P}"{C.G}@xml/network_security_config{C.P}" {C.OG}➸❥ {C.Y}{M.os.path.basename(manifest_path)} {C.G} ✔\n')
|
||||||
|
|
||||||
|
print(f'\n{C.S} Updated {C.E}{C.C} android:usesCleartextTraffic={C.P}"{C.G}true{C.P}" {C.OG}➸❥ {C.Y}{M.os.path.basename(manifest_path)} {C.G} ✔\n')
|
||||||
|
|
||||||
|
|
||||||
|
# ---------------- Permission Manifest ----------------
|
||||||
|
def Permission_Manifest(decompile_dir, manifest_path, isAPKEditor):
|
||||||
|
|
||||||
|
A_Y_P = M.os.path.join(decompile_dir, 'apktool.yml')
|
||||||
|
|
||||||
|
content = open(manifest_path, 'r', encoding='utf-8', errors='ignore').read()
|
||||||
|
|
||||||
|
new_permissions = '''\t<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>\n\t<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>\n\t<uses-permission android:name="android.permission.MANAGE_EXTERNAL_STORAGE"/>'''
|
||||||
|
|
||||||
|
content = M.re.sub(
|
||||||
|
r'\s+<uses-permission[^>]*android:name="(android.permission.((READ|WRITE|MANAGE)_EXTERNAL_STORAGE))"[^>]*>',
|
||||||
|
'',
|
||||||
|
content
|
||||||
|
)
|
||||||
|
|
||||||
|
content = M.re.sub(
|
||||||
|
r'android:targetSdkVersion="\d+"',
|
||||||
|
'android:targetSdkVersion="28"',
|
||||||
|
content
|
||||||
|
)
|
||||||
|
|
||||||
|
content = M.re.sub(
|
||||||
|
r'(<manifest\s+[^>]*>)',
|
||||||
|
r'\1\n' + new_permissions,
|
||||||
|
content
|
||||||
|
)
|
||||||
|
|
||||||
|
application_tag = M.re.search(r'<application\s+[^>]*>', content)[0]
|
||||||
|
|
||||||
|
cleaned_tag = M.re.sub(
|
||||||
|
r'\s+android:(request|preserve)LegacyExternalStorage="[^"]*?"',
|
||||||
|
'',
|
||||||
|
application_tag
|
||||||
|
)
|
||||||
|
|
||||||
|
content = content.replace(application_tag,
|
||||||
|
M.re.sub(
|
||||||
|
r'>',
|
||||||
|
'\n\tandroid:requestLegacyExternalStorage="true"\n\tandroid:preserveLegacyExternalStorage="true">',
|
||||||
|
cleaned_tag
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
open(manifest_path, 'w', encoding='utf-8', errors='ignore').write(content)
|
||||||
|
|
||||||
|
print(f"\n{C.S} Storage Permission {C.E} {C.OG}➸❥ {C.P}'{C.G}AndroidManifest.xml{C.P}' {C.G} ✔\n")
|
||||||
|
|
||||||
|
if not isAPKEditor:
|
||||||
|
yml = open(A_Y_P, 'r', encoding='utf-8', errors='ignore').read()
|
||||||
|
|
||||||
|
update_yml = M.re.sub(
|
||||||
|
r'(targetSdkVersion:) (\d+)',
|
||||||
|
r'\1 28',
|
||||||
|
yml
|
||||||
|
)
|
||||||
|
|
||||||
|
open(A_Y_P, 'w', encoding='utf-8', errors='ignore').write(update_yml)
|
||||||
|
|
||||||
|
print(f"\n{C.S} targetSdkVersion {C.E} {C.PN}28 {C.OG}➸❥{C.G} apktool.yml\n")
|
||||||
|
|
||||||
|
|
||||||
|
# ---------------- Pine Hook ----------------
|
||||||
|
def Pine_Hook(manifest_path, Package_Name):
|
||||||
|
|
||||||
|
content = open(manifest_path, 'r', encoding='utf-8', errors='ignore').read()
|
||||||
|
|
||||||
|
provider = f'''
|
||||||
|
<provider
|
||||||
|
android:name="com.pinehook.plus.Loader"
|
||||||
|
android:exported="false"
|
||||||
|
android:authorities="{Package_Name}.loader"
|
||||||
|
android:initOrder="100" />'''
|
||||||
|
|
||||||
|
content = M.re.sub(
|
||||||
|
r'(<application\s+[^>]*>)',
|
||||||
|
rf'\1{provider}',
|
||||||
|
content
|
||||||
|
)
|
||||||
|
|
||||||
|
open(manifest_path, 'w', encoding='utf-8', errors='ignore').write(content)
|
||||||
|
|
||||||
|
print(f'\n{C.S} HooK Manifest {C.E}\n{C.PN} {provider} {C.G} ✔\n')
|
||||||
26
ApkPatcher/Patch/Package.py
Normal file
26
ApkPatcher/Patch/Package.py
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
from ..MODULES import IMPORT; M = IMPORT()
|
||||||
|
|
||||||
|
|
||||||
|
class P:
|
||||||
|
# ---------------- Spoof Package Detection ----------------
|
||||||
|
Find_String = ['com.noshufou.android.su.elite', 'com.noshufou.android.su', 'eu.chainfire.supersu', 'com.koushikdutta.superuser', 'com.thirdparty.superuser', 'com.yellowes.su', 'com.topjohnwu.magisk', 'com.kingroot.kinguser', 'com.kingo.root', 'com.smedialink.oneclickroot', 'com.zhiqupk.root.global', 'com.alephzain.framaroot', 'com.koushikdutta.rommanager.license', 'com.koushikdutta.rommanager', 'com.dimonvideo.luckypatcher', 'com.chelpus.lackypatch', 'com.ramdroid.appquarantinepro', 'com.ramdroid.appquarantine', 'com.android.vending.billing.InAppBillingService.COIN', 'com.android.vending.billing.InAppBillingService.LUCK', 'com.chelpus.luckypatcher', 'com.blackmartalpha', 'org.blackmart.market', 'com.allinone.free', 'com.repodroid.app', 'org.creeplays.hack', 'com.baseappfull.fwd', 'com.zmapp', 'com.dv.marketmod.installer', 'org.mobilism.android', 'com.android.wp.net.log', 'com.android.camera.update', 'cc.madkite.freedom', 'com.solohsu.android.edxp.manager', 'org.meowcat.edxposed.manager', 'com.xmodgame', 'com.cih.game_cih', 'com.charles.lpoqasert', 'catch_.me_.if_.you_.can_', 'com.devadvance.rootcloakplus', 'com.devadvance.rootcloak', 'com.saurik.substrate', 'com.zachspong.temprootremovejb', 'com.amphoras.hidemyrootadfree', 'com.amphoras.hidemyroot', 'com.formyhm.hiderootPremium', 'com.formyhm.hideroot', 'me.weishu.exp', 'moe.shizuku.privileged.', 'com.guoshi.httpcanary.premium', 'com.guoshi.httpcanary', 'com.reqable.android', 'com.network.proxy', 'com.sniffer3', 'com.sniffer2', 'com.sniffer', 'com.datacapture.pro', 'com.black.canary', 'org.httpcanary.pro', 'app.greyshirts.sslcapture', 'com.evbadroid.proxymon', 'com.minhui.networkcapture.pro', 'com.minhui.networkcapture', 'com.minhui.wifianalyzer', 'com.packagesniffer.frtparlak', 'com.evbadroid.wicapdemo', 'jp.co.taosoftware.android.packetcapture', 'com.andriell.multicast_sniffer', 'com.emanuelef.remote_capture', 'de.stefanpledl.localcast', 'bin.mt.plus.canary', 'bin.mt.plus', 'ru.maximoff.apktool', 'idm.internet.download.manager.plus', 'idm.internet.download.manager', 'com.applisto.appcloner', 'org.lsposed.lspatch', 'me.jsonet.jshook', 'br.tiagohm.restler', 'com.replit.app', 'io.virtualapp', 'de.robv.android.xposed']
|
||||||
|
|
||||||
|
Match_Regex = f'"({"|".join(Find_String[:-1])}|{Find_String[-1]}.*)"'
|
||||||
|
|
||||||
|
Menifest_Regex = rf'(\s+<package[^>]*android:name={Match_Regex}[^>]*/>)'
|
||||||
|
|
||||||
|
|
||||||
|
# ---------------- Generate Hash ----------------
|
||||||
|
def Hash(self, CA_Cert):
|
||||||
|
|
||||||
|
from asn1crypto import x509
|
||||||
|
|
||||||
|
f = open(CA_Cert,'rb').read()
|
||||||
|
|
||||||
|
if f.startswith(b'-----'): f = M.base64.b64decode(''.join(f.decode().splitlines()[1:-1]))
|
||||||
|
CERT = x509.Certificate.load(f)['tbs_certificate']['subject_public_key_info'].dump()
|
||||||
|
|
||||||
|
sha1 = M.base64.b64encode(M.hashlib.sha1(CERT).digest()).decode()
|
||||||
|
sha256 = M.base64.b64encode(M.hashlib.sha256(CERT).digest()).decode()
|
||||||
|
|
||||||
|
return sha1, sha256
|
||||||
77
ApkPatcher/Patch/Pairip_CoreX.py
Normal file
77
ApkPatcher/Patch/Pairip_CoreX.py
Normal file
@ -0,0 +1,77 @@
|
|||||||
|
from ..ANSI_COLORS import ANSI; C = ANSI()
|
||||||
|
from ..MODULES import IMPORT; M = IMPORT()
|
||||||
|
|
||||||
|
from ApkPatcher.Utils.Files_Check import FileCheck
|
||||||
|
|
||||||
|
F = FileCheck(); F.Set_Path()
|
||||||
|
|
||||||
|
|
||||||
|
# ---------------- Check CoreX ----------------
|
||||||
|
def Check_CoreX(decompile_dir, isAPKEditor):
|
||||||
|
|
||||||
|
Lib_CoreX = []
|
||||||
|
|
||||||
|
lib_paths = M.os.path.join(decompile_dir,
|
||||||
|
*(
|
||||||
|
['root', 'lib', 'arm64-v8a'] if isAPKEditor else ['lib', 'arm64-v8a']
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
for target_file in ['lib_Pairip_CoreX.so', 'libFirebaseCppApp.so']:
|
||||||
|
|
||||||
|
if M.os.path.isfile(M.os.path.join(lib_paths, target_file)):
|
||||||
|
|
||||||
|
Lib_CoreX.append(f"{C.G}{target_file} ➸❥ {C.P}arm64-v8a")
|
||||||
|
|
||||||
|
if Lib_CoreX:
|
||||||
|
print(f"{C.INFO}{C.C} Already Added {C.OG}➸❥ {f' {C.OG}& '.join(Lib_CoreX)} {C.G} ✔\n")
|
||||||
|
|
||||||
|
return True
|
||||||
|
return False
|
||||||
|
|
||||||
|
|
||||||
|
# ---------------- HooK CoreX ----------------
|
||||||
|
def Hook_Core(apk_path, decompile_dir, isAPKEditor, Package_Name):
|
||||||
|
|
||||||
|
with M.zipfile.ZipFile(apk_path, 'r') as zf:
|
||||||
|
base_apk = "base.apk" if "base.apk" in zf.namelist() else f"{Package_Name}.apk"
|
||||||
|
|
||||||
|
try:
|
||||||
|
if M.os.name == 'nt' and M.shutil.which("7z"):
|
||||||
|
M.subprocess.run(["7z", "e", apk_path, base_apk, "-y"], text=True, capture_output=True)
|
||||||
|
|
||||||
|
with M.zipfile.ZipFile(apk_path) as zf:
|
||||||
|
zf.extract(base_apk)
|
||||||
|
|
||||||
|
else:
|
||||||
|
if M.shutil.which("unzip"):
|
||||||
|
M.subprocess.run(["unzip", "-o", apk_path, base_apk], text=True, capture_output=True)
|
||||||
|
|
||||||
|
with M.zipfile.ZipFile(apk_path) as zf:
|
||||||
|
zf.extract(base_apk)
|
||||||
|
|
||||||
|
print(f'\n{C.S} Dump {C.E} {C.G}➸❥ {C.OG}{base_apk}\n')
|
||||||
|
|
||||||
|
Dump_Apk = "libFirebaseCppApp.so"
|
||||||
|
|
||||||
|
M.os.rename(base_apk, Dump_Apk)
|
||||||
|
|
||||||
|
lib_paths = M.os.path.join(decompile_dir,
|
||||||
|
*(
|
||||||
|
['root', 'lib', 'arm64-v8a'] if isAPKEditor else ['lib', 'arm64-v8a']
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
print(f"\n{C.S} Arch {C.E} {C.G}➸❥ arm64-v8a\n")
|
||||||
|
|
||||||
|
M.shutil.move(Dump_Apk, lib_paths); M.shutil.copy(F.Pairip_CoreX, lib_paths);
|
||||||
|
|
||||||
|
print(
|
||||||
|
f'\n{C.S} HooK {C.E} {C.G}➸❥ {C.OG}libFirebaseCppApp.so {C.G} ✔\n'
|
||||||
|
f'\n{C.S} HooK {C.E} {C.G}➸❥ {C.OG}lib_Pairip_CoreX.so {C.G} ✔\n'
|
||||||
|
)
|
||||||
|
|
||||||
|
return True
|
||||||
|
|
||||||
|
except Exception as e:
|
||||||
|
print(f"\n{C.ERROR} {e} ✘")
|
||||||
63
ApkPatcher/Patch/Pine_Hook.py
Normal file
63
ApkPatcher/Patch/Pine_Hook.py
Normal file
@ -0,0 +1,63 @@
|
|||||||
|
from ..ANSI_COLORS import ANSI; C = ANSI()
|
||||||
|
from ..MODULES import IMPORT; M = IMPORT()
|
||||||
|
|
||||||
|
from ApkPatcher.Utils.Files_Check import FileCheck
|
||||||
|
|
||||||
|
F = FileCheck(); F.Set_Path()
|
||||||
|
|
||||||
|
|
||||||
|
# ---------------- Pine Hook Patch ----------------
|
||||||
|
def Pine_Hook_Patch(decompile_dir, isAPKEditor, isModules, isDex):
|
||||||
|
|
||||||
|
print(f"{C.X}{C.C} Pine HooK, {C.OG}🇮🇳 AbhiTheM0dder 🇮🇳 {C.PN}& {C.OG}残页 {C.P}(canyie)\n")
|
||||||
|
|
||||||
|
Target_Path = M.os.path.join(decompile_dir,
|
||||||
|
*(
|
||||||
|
['root', 'hook'] if isAPKEditor else ['unknown', 'hook']
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
Dex_Path = M.os.path.join(decompile_dir,
|
||||||
|
*(
|
||||||
|
['dex'] if isAPKEditor else []
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
# ---------------- Hook dexloader ----------------
|
||||||
|
Loader_Dex = M.os.path.join(Dex_Path, isDex)
|
||||||
|
|
||||||
|
M.shutil.copy(F.loader, Loader_Dex)
|
||||||
|
|
||||||
|
print(f'\n{C.S} Loader {C.E} {C.G}➸❥ {C.OG}{isDex} {C.G} ✔\n')
|
||||||
|
|
||||||
|
|
||||||
|
# ---------------- Hook library ----------------
|
||||||
|
if not M.os.path.exists(Target_Path):
|
||||||
|
M.os.makedirs(Target_Path)
|
||||||
|
|
||||||
|
print(f'\n{C.S} Target Path {C.E} {C.G}➸❥ hook\n')
|
||||||
|
|
||||||
|
for Target_Files in [F.config, F.libpine32, F.libpine64]:
|
||||||
|
|
||||||
|
M.shutil.copy(Target_Files, Target_Path)
|
||||||
|
|
||||||
|
print(f'\n{C.S} HooK {C.E} {C.G}➸❥ {C.OG}{M.os.path.basename(Target_Files)} {C.G} ✔\n')
|
||||||
|
|
||||||
|
|
||||||
|
# ---------------- isModules ----------------
|
||||||
|
if isModules:
|
||||||
|
|
||||||
|
Modules_Path = M.os.path.join(Target_Path, 'modules')
|
||||||
|
|
||||||
|
if not M.os.path.exists(Modules_Path):
|
||||||
|
M.os.makedirs(Modules_Path)
|
||||||
|
|
||||||
|
print(f"\n{C.S} Modules Path {C.E} {C.G}➸❥ hook/modules\n")
|
||||||
|
|
||||||
|
Module_List = isModules if isinstance(isModules, (list, tuple)) else [isModules]
|
||||||
|
|
||||||
|
for Modules in Module_List:
|
||||||
|
if M.os.path.exists(Modules):
|
||||||
|
M.shutil.copy(Modules, Modules_Path)
|
||||||
|
|
||||||
|
print(f'\n{C.S} Module {C.E} {C.G}➸❥ {C.OG}{M.os.path.basename(Modules)} {C.G} ✔\n')
|
||||||
3616
ApkPatcher/Patch/Random_INFO.py
Normal file
3616
ApkPatcher/Patch/Random_INFO.py
Normal file
File diff suppressed because it is too large
Load Diff
400
ApkPatcher/Patch/Smali_Patch.py
Normal file
400
ApkPatcher/Patch/Smali_Patch.py
Normal file
@ -0,0 +1,400 @@
|
|||||||
|
from.Package import P
|
||||||
|
|
||||||
|
from ..ANSI_COLORS import ANSI; C = ANSI()
|
||||||
|
from ..MODULES import IMPORT; M = IMPORT()
|
||||||
|
|
||||||
|
C_Line = f"{C.CC}{'_' * 61}"
|
||||||
|
|
||||||
|
|
||||||
|
# ---------------- Scan Target Regex ----------------
|
||||||
|
def Regex_Scan(Smali_Path, Target_Regex, Count, Lock, isPKG, isCoreX):
|
||||||
|
|
||||||
|
if isPKG:
|
||||||
|
Target_Regex = [P.Match_Regex[1:-1]] if Smali_Path.endswith('.xml') else Target_Regex + [P.Match_Regex] if Smali_Path.endswith('.smali') else []
|
||||||
|
|
||||||
|
if isCoreX:
|
||||||
|
Target_Regex = Target_Regex + [ r'\.class public Lcom/pairip/VMRunner;\n']
|
||||||
|
|
||||||
|
Smali = open(Smali_Path, 'r', encoding='utf-8', errors='ignore').read()
|
||||||
|
|
||||||
|
Regexs = [M.re.compile(r) for r in Target_Regex]
|
||||||
|
|
||||||
|
# ---------------- For Regex Scan ----------------
|
||||||
|
for Regex in Regexs:
|
||||||
|
if Regex.search(Smali):
|
||||||
|
|
||||||
|
if Lock:
|
||||||
|
try:
|
||||||
|
with Lock:
|
||||||
|
Count.value += 1
|
||||||
|
|
||||||
|
print(f"\r{C.S} Find Target Smali {C.E} {C.OG}➸❥ {C.PN}{Count.value}", end='', flush=True)
|
||||||
|
|
||||||
|
except Exception:
|
||||||
|
return None
|
||||||
|
|
||||||
|
else:
|
||||||
|
Count[0] += 1
|
||||||
|
|
||||||
|
print(f"\r{C.S} Find Target Smali {C.E} {C.OG}➸❥ {C.PN}{Count[0]}", end='', flush=True)
|
||||||
|
|
||||||
|
return Smali_Path
|
||||||
|
|
||||||
|
# ---------------- For String Scan ( Without Regex ) ----------------
|
||||||
|
#for String in Target_String:
|
||||||
|
#if String in Smali:
|
||||||
|
#with Lock:
|
||||||
|
#Count.value += 1
|
||||||
|
#print(f"\r[ Find Target Smali ] ➸❥ {Count.value}", end='', flush=True)
|
||||||
|
#return Smali_Path
|
||||||
|
|
||||||
|
|
||||||
|
# ---------------- Apply Smali_Patch ----------------
|
||||||
|
def Smali_Patch(decompile_dir, smali_folders, isAPKEditor, CA_Cert, isID, isPairip, isPairip_lib, isPKG, isPurchased, isScreenShot, Skip_Patch, isUSB, isCoreX):
|
||||||
|
|
||||||
|
Smali_Paths, Match_Smali = [], []
|
||||||
|
|
||||||
|
patterns = [
|
||||||
|
# ---------------- VPN Bypass ----------------
|
||||||
|
(
|
||||||
|
r'(const/4 [pv]\d+, 0x4[^>]*?invoke-\w+ \{[^\}]*\}, Landroid/net/NetworkCapabilities;->hasTransport\(I\)Z[^>]*?)move-result ([pv]\d+)',
|
||||||
|
r'\1const/4 \2, 0x0',
|
||||||
|
"Bypassed Vpn/Proxy Detection NetworkCapabilities hasTransport"
|
||||||
|
),
|
||||||
|
(
|
||||||
|
r'(Ljava/net/NetworkInterface;->(?:isUp|isVirtual|isLoopback)\(\)Z[^>]*?)move-result ([pv]\d+)',
|
||||||
|
r'\1const/4 \2, 0x0',
|
||||||
|
"Bypassed Vpn/Proxy Detection NetworkInterface isUp"
|
||||||
|
),
|
||||||
|
(
|
||||||
|
r'(const-string [pv]\d+, "(tun|tunl0|tun0|utun0|utun1|utun2|utun3|utun4|pptp|ppp|pp0|ppp0|p2p0|ccmni0|ipsec)"[^>]*?invoke-\w+ \{[^\}]*\}, L[^\(]+;->\S+\(Ljava/lang/CharSequence;\)Z[^>]*?)move-result ([pv]\d+)',
|
||||||
|
r'\1const/4 \3, 0x0',
|
||||||
|
"Bypassed Vpn/Proxy Detection NetworkInterface"
|
||||||
|
),
|
||||||
|
|
||||||
|
# ---------------- Mock Location & Update & Pkg Install Fixed ----------------
|
||||||
|
(
|
||||||
|
r'(invoke-virtual \{[^\}]*\}, Landroid/location/Location;->(?:isFromMockProvider|isMock)\(\)Z[^>]*?)move-result ([pv]\d+)',
|
||||||
|
r'\1const/4 \2, 0x0',
|
||||||
|
"Bypassed Mock Detection"
|
||||||
|
),
|
||||||
|
(
|
||||||
|
r'(invoke-virtual \{[^\}]*\}, Landroid/content/pm/PackageManager;->getInstallerPackageName\(Ljava/lang/String;\)Ljava/lang/String;[^>]*?)move-result-object ([pv]\d+)',
|
||||||
|
r'\1const-string \2, "com.android.vending"',
|
||||||
|
"Fixed Installer"
|
||||||
|
),
|
||||||
|
|
||||||
|
# ---------------- SSL BYPASS ( MITM ) ----------------
|
||||||
|
(
|
||||||
|
r'(\.method [^(]*verify\([^\)]*(?:Ljavax/net/ssl/SSLSession;|Ljava/security/cert/X509Certificate;)[^\)]*\)Z\s+.locals \d+)[\s\S]*?(\n.end method)',
|
||||||
|
r'\1\n'
|
||||||
|
r' const v0, 0x1\n'
|
||||||
|
r' return v0\2',
|
||||||
|
"Verify SSLSession & X509Certificate"
|
||||||
|
),
|
||||||
|
(
|
||||||
|
r'(\.method [^(]*checkServerTrusted\([^\)]*Ljava/security/cert/X509Certificate;[^\)]*\)Ljava/util/List;\s+.locals \d+)[\s\S]*?(\n.end method)',
|
||||||
|
r'\1\n'
|
||||||
|
r' new-instance v0, Ljava/util/ArrayList;\n'
|
||||||
|
r' invoke-direct {v0}, Ljava/util/ArrayList;-><init>()V\n'
|
||||||
|
r' return-object v0\2',
|
||||||
|
"checkServerTrusted"
|
||||||
|
),
|
||||||
|
(
|
||||||
|
r'(\.method [^(]*check(?:Client|Server)Trusted\([^\)]*Ljava/security/cert/X509Certificate;[^\)]*\)V\s+.locals \d+)[\s\S]*?(\n.end method)',
|
||||||
|
r'\1\n\treturn-void\2',
|
||||||
|
"check(Client|Server)Trusted"
|
||||||
|
),
|
||||||
|
(
|
||||||
|
r'(\.method [^(]*check\(Ljava/lang/String;(?:Ljava/util/List;|\[Ljava/security/cert/Certificate;)\)V\s+.locals \d+)[\s\S]*?(\n.end method)',
|
||||||
|
r'\1\n\treturn-void\2',
|
||||||
|
"CertificatePinner & HostnameVerifier"
|
||||||
|
),
|
||||||
|
(
|
||||||
|
r'(\.method [^(]*check\$okhttp\(Ljava/lang/String;[^\)]*\)V\s+.locals \d+)[\s\S]*?(\n.end method)',
|
||||||
|
r'\1\n\treturn-void\2',
|
||||||
|
"check$okhttp"
|
||||||
|
),
|
||||||
|
(
|
||||||
|
r'(\.method [^(]*getAcceptedIssuers\(\)\[Ljava/security/cert/X509Certificate;\s+.locals \d+)[\s\S]*?(\n.end method)',
|
||||||
|
r'\1\n'
|
||||||
|
r' const/4 v0, 0x0\n'
|
||||||
|
r' new-array v0, v0, [Ljava/security/cert/X509Certificate;\n'
|
||||||
|
r' return-object v0\2',
|
||||||
|
"getAcceptedIssuers"
|
||||||
|
),
|
||||||
|
(
|
||||||
|
r'(\.method [^(]*\S+\(Ljava/lang/String;[^\)]*\)V\s+.locals \d+)(?:(?!\.end method)[\s\S])*?(?:check-cast [pv]\d+, Ljava/security/cert/X509Certificate;|Ljavax/net/ssl/SSLPeerUnverifiedException;)(?:(?!\.end method)[\s\S])*?(\n.end method)',
|
||||||
|
r'\1\n\treturn-void\2',
|
||||||
|
"<okhttp3>"
|
||||||
|
),
|
||||||
|
|
||||||
|
# ---------------- Fix Play ----------------
|
||||||
|
(
|
||||||
|
r'(invoke-interface \{[^\}]*\}, Lcom/google/android/vending/licensing/Policy;->allowAccess\(\)Z[^>]*?\s+)move-result ([pv]\d+)',
|
||||||
|
r'\1const/4 \2, 0x1',
|
||||||
|
"Bypass Client-Side LVL (allowAccess)"
|
||||||
|
),
|
||||||
|
(
|
||||||
|
r'(\.method [^(]*connectToLicensingService\(\)V\s+.locals \d+)[\s\S]*?(\s+return-void\n.end method)',
|
||||||
|
r'\1\2',
|
||||||
|
"connectToLicensingService"
|
||||||
|
),
|
||||||
|
(
|
||||||
|
r'(\.method [^(]*initializeLicenseCheck\(\)V\s+.locals \d+)[\s\S]*?(\s+return-void\n.end method)',
|
||||||
|
r'\1\2',
|
||||||
|
"initializeLicenseCheck"
|
||||||
|
),
|
||||||
|
(
|
||||||
|
r'(\.method [^(]*processResponse\(ILandroid/os/Bundle;\)V\s+.locals \d+)[\s\S]*?(\s+return-void\n.end method)',
|
||||||
|
r'\1\2',
|
||||||
|
"processResponse"
|
||||||
|
)
|
||||||
|
]
|
||||||
|
|
||||||
|
# if CA_Cert:
|
||||||
|
# sha1, sha256 = P().Hash(CA_Cert[0])
|
||||||
|
# ---------------- SHA-256 & SHA-1 ----------------
|
||||||
|
# patterns.extend([
|
||||||
|
# (r'(\.method [^(]*\S+\((?:Ljava/security/cert/X509Certificate;|[^)]*)\)Ljava/lang/String;\s+.locals \d+)(?:(?!\.end\smethod)[\s\S])*?"sha256/[^"]*"(?:(?!\.end\smethod)[\s\S])*?(([pv]\d+)\n.end method)', fr'\1\n\tconst-string \3, "sha256/{sha256}"\n\treturn-object \2', f"SHA-256 ➸❥ {C.OG}{sha256}"),
|
||||||
|
# (r'(\.method public [^(]*\S+\((?:Ljava/security/cert/X509Certificate;|[^)]*)\)Ljava/lang/String;\s+.*\s+)(?:(?!\.end\smethod)[\s\S])*?"sha1/[^"]*"(?:(?!\.end\smethod)[\s\S])*?(([pv]\d+)\n.end method)', fr'\1\n\tconst-string \3, "sha1/{sha1}"\n\treturn-object \2', f"SHA-1 ➸❥ {C.OG}{sha1}")
|
||||||
|
# ])
|
||||||
|
|
||||||
|
|
||||||
|
# ---------------- Custom Device ID ----------------
|
||||||
|
if isID:
|
||||||
|
patterns.append(
|
||||||
|
(
|
||||||
|
r'(const-string [pv]\d+, "android_id"[^>]*?invoke-static \{[^\}]*\}, Landroid/provider/Settings\$Secure;->getString\(Landroid/content/ContentResolver;Ljava/lang/String;\)Ljava/lang/String;[^>]*?)move-result-object ([pv]\d+)',
|
||||||
|
rf'\1const-string \2, "{isID}"',
|
||||||
|
f"Custom Android ID ➸❥ {C.OG}{isID}"
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
# ---------------- isPairip ----------------
|
||||||
|
if isPairip and isPairip_lib:
|
||||||
|
patterns.extend(
|
||||||
|
[
|
||||||
|
(
|
||||||
|
r'invoke-static \{[^\}]*\}, Lcom/pairip/SignatureCheck;->verifyIntegrity\(Landroid/content/Context;\)V',
|
||||||
|
r'#',
|
||||||
|
"VerifyIntegrity"
|
||||||
|
),
|
||||||
|
(
|
||||||
|
r'(\.method [^(]*verifyIntegrity\(Landroid/content/Context;\)V\s+.locals \d+)[\s\S]*?(\s+return-void\n.end method)',
|
||||||
|
r'\1\2',
|
||||||
|
"VerifyIntegrity"
|
||||||
|
),
|
||||||
|
(
|
||||||
|
r'(\.method [^(]*verifySignatureMatches\(Ljava/lang/String;\)Z\s+.locals \d+\s+)[\s\S]*?(\s+return ([pv]\d+)\n.end method)',
|
||||||
|
r'\1const/4 \3, 0x1\2',
|
||||||
|
"verifySignatureMatches"
|
||||||
|
)
|
||||||
|
]
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
# ---------------- Bypass Package Detection ----------------
|
||||||
|
if isPKG:
|
||||||
|
patterns.extend(
|
||||||
|
[
|
||||||
|
# ---------------- Kill Process & Exit ----------------
|
||||||
|
(
|
||||||
|
r'invoke-static \{[^\}]*\}, (?:Ljava/lang/System;->exit|Landroid/os/Process;->killProcess)\(I\)V',
|
||||||
|
'nop',
|
||||||
|
"Blocked System.exit & Process.killProcess"
|
||||||
|
),
|
||||||
|
|
||||||
|
# ---------------- Xposed Bypass & Frida Bypass ----------------
|
||||||
|
(
|
||||||
|
r'(const-string [pv]\d+, )"de.robv.android.xposed',
|
||||||
|
r'\1"com.Fuck.U',
|
||||||
|
"Bypassed Xposed Detection"
|
||||||
|
),
|
||||||
|
(
|
||||||
|
r'const-string [pv]\d+, "(generic|goldfish)"[^>]*?invoke-static \{[^\}]*\}, Landroid/os/Build;->get(Device|Hardware)\(\)Ljava/lang/String;[^>]*?move-result-object [pv]\d+[^>]*?invoke-virtual \{[^\}]*\}, Ljava/lang/String;->contains\(Ljava/lang/CharSequence;\)Z[^>]*move-result ([pv]\d+)',
|
||||||
|
r'const/4 \3, 0x0',
|
||||||
|
"Bypassed Device detection"
|
||||||
|
),
|
||||||
|
(
|
||||||
|
r'const-string [pv]\d+, "/data/local/tmp/(?:frida|frida-server)"[^>]*?invoke-static \{[^\}]*\}, Ljava/io/File;->exists\(\)Z[^>]*?move-result ([pv]\d+)',
|
||||||
|
r'const/4 \1, 0x0',
|
||||||
|
"Bypassed Frida Detection"
|
||||||
|
)
|
||||||
|
]
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
# ---------------- Purchased Status ----------------
|
||||||
|
if isPurchased:
|
||||||
|
patterns.extend(
|
||||||
|
[
|
||||||
|
(
|
||||||
|
r'(\.method [^(]*(?:getPrice|getMrp|getPro_mrp|getTotal(?:_)?Price|getOffer(?:_)?price|getSub_pack_price|getSub_actual_price|getActual_price|getDiscount(?:_)?price|getRegistration_price|getProduct_amount|getIs_locked)\(\)Ljava/lang/String;(?:(?!const-string [pv]\d+, "0")[\s\S])*?)(return-object ([pv]\d+)\n.end method)',
|
||||||
|
r'\1const-string \3, "0"\n\t\2',
|
||||||
|
"Patch 1"
|
||||||
|
),
|
||||||
|
(
|
||||||
|
r'(\.method [^(]*(?:is(?:_)?Paid|getIs(?:_)?Paid|is(?:_)?purchase(?:d)?|get(?:_)?Purchase(?:d)?|getIs(?:_)?purchase(?:d)?|getPurchaseStatus|getIs_pass|getIs_pro|getIs_pro_purchased|getIs_pro_content|isOwn|isLifetime|is(?:_)?Trial)\(.*\)(?:Ljava/lang/String;|Ljava/lang/Integer;)(?:(?!const-string [pv]\d+, "1")[\s\S])*?)(return-object ([pv]\d+)\n.end method)',
|
||||||
|
r'\1const-string \3, "1"\n\t\2',
|
||||||
|
"Patch 2"
|
||||||
|
),
|
||||||
|
(
|
||||||
|
r'(\.method [^(]*(?:is(?:_)?Paid|getInsIspaid|is(?:_)?purchase(?:d)?|getUser_purchase_status|getPurchaseId|is(?:_)?Trial)\(\)(?:I|Z)(?:(?!const [pv]\d+, 0x1)[\s\S])*?)(return ([pv]\d+)\n.end method)',
|
||||||
|
r'\1const \3, 0x1\n\t\2',
|
||||||
|
"Patch 3"
|
||||||
|
)
|
||||||
|
]
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
# ---------------- Bypass SS ----------------
|
||||||
|
if isScreenShot:
|
||||||
|
patterns.extend(
|
||||||
|
[
|
||||||
|
(
|
||||||
|
r'(const/16 [pv]\d+, 0x)200(0\s+(.line \d+\s+)*?invoke-virtual \{[^\}]*\}, Landroid/view/Window;->(?:add|set)Flags\(II\)V)',
|
||||||
|
r'\1\2',
|
||||||
|
"Bypassed Anti-Screen Detection <(add|set)Flags>"
|
||||||
|
),
|
||||||
|
(
|
||||||
|
r'(invoke-static \{[^\}]*\}, L[^\(]+;->isSecuredNow\(Landroid/view/Window;\)Z\s+(.line \d+\s+)*?move-result [pv]\d+\s+(.line \d+\s+)*?const/16 ([pv]\d+),) 0x2000',
|
||||||
|
r'\1 0x0',
|
||||||
|
"Bypassed Anti-Screen Detection <isSecuredNow>"
|
||||||
|
),
|
||||||
|
(
|
||||||
|
r'(iget [pv]\d+, [pv]\d+, Landroid/view/WindowManager\$LayoutParams;->flags:I\s+(.line \d+\s+)*?or-int/lit16 [pv]\d+, [pv]\d+,) 0x2000',
|
||||||
|
r'\1 0x0',
|
||||||
|
"Bypassed Anti-Screen Detection <flags:I>"
|
||||||
|
),
|
||||||
|
(
|
||||||
|
r'(invoke-virtual \{([pv]\d+), ([pv]\d+)\}, Landroid/view/SurfaceView;->setSecure\(Z\)V)',
|
||||||
|
r'const/4 \3, 0x0\n\n\t\1',
|
||||||
|
"Bypassed Anti-Screen Detection <setSecure>"
|
||||||
|
)
|
||||||
|
]
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
# ---------------- Remove USB Debugging ----------------
|
||||||
|
if isUSB:
|
||||||
|
patterns.extend(
|
||||||
|
[
|
||||||
|
(
|
||||||
|
r'(const-string [pv]\d+, "development_settings_enabled"[^>]*invoke-static \{[^\}]*\}, L[^\(]+;->getInt\([^\)]*Ljava\/lang\/String;I\)I[^>]*)move-result ([pv]\d+)',
|
||||||
|
r'\1const/4 \2, 0x0',
|
||||||
|
'Remove USB Debugging <development_settings_enabled>'
|
||||||
|
),
|
||||||
|
(
|
||||||
|
r'(const-string [pv]\d+, "adb_enabled"[^>]*invoke-static \{[^\}]*\}, L[^\(]+;->getInt\([^\(]*Ljava\/lang\/String;I\)I[^>]*)move-result ([pv]\d+)',
|
||||||
|
r'\1const/4 \2, 0x0',
|
||||||
|
'Remove USB Debugging <adb_enabled>'
|
||||||
|
)
|
||||||
|
]
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
Target_Regex = [p[0] for p in patterns]
|
||||||
|
|
||||||
|
|
||||||
|
# ---------------- Spoof Package Detection ----------------
|
||||||
|
if isPKG:
|
||||||
|
counter = [1]
|
||||||
|
patterns.extend(
|
||||||
|
[
|
||||||
|
(
|
||||||
|
rf'{P.Match_Regex}', lambda m:
|
||||||
|
f'"com.Fuck.Me{(lambda x: counter.__setitem__(0, x+1) or x)(counter[0])}"',
|
||||||
|
'Spoof Package Detection in Dex'
|
||||||
|
),
|
||||||
|
(
|
||||||
|
rf'{P.Match_Regex[1:-1]}', lambda m:
|
||||||
|
f'"com.Fuck.Me{(lambda x: counter.__setitem__(0, x+1) or x)(counter[0])}"',
|
||||||
|
'Spoof Package Detection in Res'
|
||||||
|
)
|
||||||
|
]
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
# ---------------- loadLibrary ➢ '_Pairip_CoreX' ----------------
|
||||||
|
if isCoreX:
|
||||||
|
patterns.append(
|
||||||
|
(
|
||||||
|
r'(\.method [^<]*<clinit>\(\)V\s+.locals \d+\n)',
|
||||||
|
r'\1'
|
||||||
|
r' const-string v0, "_Pairip_CoreX"\n'
|
||||||
|
r' invoke-static {v0}, Ljava/lang/System;->loadLibrary(Ljava/lang/String;)V\n',
|
||||||
|
f'CoreX_Hook ➸❥ {C.OG}"lib_Pairip_CoreX.so"'
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
if isPKG:
|
||||||
|
smali_folders = [M.os.path.join(decompile_dir, 'resources' if isAPKEditor else 'res')] + smali_folders
|
||||||
|
|
||||||
|
for smali_folder in smali_folders:
|
||||||
|
for root, _, files in M.os.walk(smali_folder):
|
||||||
|
for file in files:
|
||||||
|
if file.endswith(('.xml', '.smali') if isPKG else ('.smali')):
|
||||||
|
Smali_Paths.append(M.os.path.join(root, file))
|
||||||
|
|
||||||
|
try:
|
||||||
|
# ---------------- Multi Threading ----------------
|
||||||
|
with M.Manager() as MT:
|
||||||
|
Count = MT.Value('i', 0); Lock = MT.Lock()
|
||||||
|
with M.Pool(M.cpu_count()) as PL:
|
||||||
|
Match_Smali = [path for path in PL.starmap(Regex_Scan, [(Smali_Path, Target_Regex, Count, Lock, isPKG, isCoreX) for Smali_Path in Smali_Paths]) if path]
|
||||||
|
|
||||||
|
except Exception:
|
||||||
|
# ---------------- Single Threading ----------------
|
||||||
|
Count = [0]
|
||||||
|
for Smali_Path in Smali_Paths:
|
||||||
|
result = Regex_Scan(Smali_Path, Target_Regex, Count, None, isPKG, isCoreX)
|
||||||
|
|
||||||
|
if result:
|
||||||
|
Match_Smali.append(result)
|
||||||
|
|
||||||
|
print(f" {C.G} ✔", flush=True)
|
||||||
|
|
||||||
|
print(f'\n{C_Line}\n')
|
||||||
|
|
||||||
|
if Match_Smali:
|
||||||
|
for pattern, replacement, description in patterns:
|
||||||
|
|
||||||
|
Count_Applied = 0
|
||||||
|
|
||||||
|
Applied_Files = set()
|
||||||
|
|
||||||
|
if description in Skip_Patch:
|
||||||
|
print(f"\n{C.S} Skip Patch {C.E} {C.OG}➸❥ {C.G}{description}\n")
|
||||||
|
|
||||||
|
continue
|
||||||
|
|
||||||
|
for file_path in Match_Smali:
|
||||||
|
if description.startswith("CoreX_Hook") and not file_path.endswith("VMRunner.smali"):
|
||||||
|
continue
|
||||||
|
|
||||||
|
content = open(file_path, 'r', encoding='utf-8', errors='ignore').read()
|
||||||
|
|
||||||
|
new_content = M.re.sub(pattern, replacement, content)
|
||||||
|
|
||||||
|
if new_content != content:
|
||||||
|
if file_path not in Applied_Files:
|
||||||
|
Applied_Files.add(file_path)
|
||||||
|
|
||||||
|
Count_Applied += 1
|
||||||
|
|
||||||
|
open(file_path, 'w', encoding='utf-8', errors='ignore').write(new_content)
|
||||||
|
|
||||||
|
if Count_Applied > 0:
|
||||||
|
print(f"\n{C.S} Tag {C.E} {C.G}{description}")
|
||||||
|
|
||||||
|
print(f"\n{C.S} Pattern {C.E} {C.OG}➸❥ {C.P}{pattern}")
|
||||||
|
|
||||||
|
for file_path in Applied_Files:
|
||||||
|
print(f"{C.G} |\n └──── {C.CC}~{C.G}$ {C.Y}{M.os.path.basename(file_path)} {C.G} ✔")
|
||||||
|
|
||||||
|
print(
|
||||||
|
f"\n{C.S} Pattern Applied {C.E} {C.OG}➸❥ {C.PN}{Count_Applied} {C.C}Time/Smali {C.G} ✔\n"
|
||||||
|
f"\n{C_Line}\n"
|
||||||
|
)
|
||||||
328
ApkPatcher/Patch/Spoof_Patch.py
Normal file
328
ApkPatcher/Patch/Spoof_Patch.py
Normal file
@ -0,0 +1,328 @@
|
|||||||
|
from ..ANSI_COLORS import ANSI; C = ANSI()
|
||||||
|
from ..MODULES import IMPORT; M = IMPORT()
|
||||||
|
|
||||||
|
from.Random_INFO import R_I; RI = R_I()
|
||||||
|
|
||||||
|
C_Line = f"{C.CC}{'_' * 61}"
|
||||||
|
|
||||||
|
|
||||||
|
# ---------------- Generate IMEI ----------------
|
||||||
|
def generate_imei():
|
||||||
|
imei = ''.join(str(M.random.randint(0, 9)) for _ in range(14))
|
||||||
|
check_digit = (sum(int(d) if i % 2 == 0 else sum(divmod(int(d) * 2, 10)) for i, d in enumerate(imei)) * 9) % 10
|
||||||
|
return imei + str(check_digit)
|
||||||
|
|
||||||
|
|
||||||
|
isIMEI = generate_imei()
|
||||||
|
|
||||||
|
|
||||||
|
# ---------------- Generate lat lon hex ----------------
|
||||||
|
def generate_lat_lon_hex():
|
||||||
|
scale_factor = 10**12
|
||||||
|
lat, lon = round(M.random.uniform(-90.0, 90.0), 6), round(M.random.uniform(-180.0, 180.0), 6)
|
||||||
|
lat_hex = hex(int(abs(lat) * scale_factor)) + "L"
|
||||||
|
lon_hex = hex(int(abs(lon) * scale_factor)) + "L"
|
||||||
|
return lat_hex, lon_hex
|
||||||
|
|
||||||
|
|
||||||
|
lat_hex, lon_hex = generate_lat_lon_hex()
|
||||||
|
|
||||||
|
|
||||||
|
# ---------------- Generate Mac Add ----------------
|
||||||
|
def generate_mac_add():
|
||||||
|
return ':'.join([''.join(M.random.choices('0123456789ABCDEF', k=2)) for _ in range(6)])
|
||||||
|
|
||||||
|
|
||||||
|
isMac1, isMac2, isMac3, isMac4 = [generate_mac_add() for _ in range(4)]
|
||||||
|
|
||||||
|
|
||||||
|
# ---------------- Generate Device ID ----------------
|
||||||
|
def generateDeviceId():
|
||||||
|
volatile_seed = "12345"
|
||||||
|
seed = ''.join(M.random.choice(M.string.ascii_letters + M.string.digits) for _ in range(16))
|
||||||
|
m = M.hashlib.md5()
|
||||||
|
m.update(seed.encode('utf-8') + volatile_seed.encode('utf-8'))
|
||||||
|
return m.hexdigest()[:16], seed
|
||||||
|
|
||||||
|
|
||||||
|
device_id, random_seed = generateDeviceId()
|
||||||
|
|
||||||
|
|
||||||
|
# ---------------- Regex Scan ----------------
|
||||||
|
def Regex_Scan(Smali_Path, Target_Regex, Count, Lock):
|
||||||
|
|
||||||
|
Smali = open(Smali_Path, 'r', encoding='utf-8', errors='ignore').read()
|
||||||
|
|
||||||
|
Regexs = [M.re.compile(r) for r in Target_Regex]
|
||||||
|
|
||||||
|
for Regex in Regexs:
|
||||||
|
if Regex.search(Smali):
|
||||||
|
|
||||||
|
if Lock:
|
||||||
|
try:
|
||||||
|
with Lock:
|
||||||
|
Count.value += 1
|
||||||
|
|
||||||
|
print(f"\r{C.S} Find Target Smali {C.E} {C.OG}➸❥ {C.PN}{Count.value}", end='', flush=True)
|
||||||
|
|
||||||
|
except Exception:
|
||||||
|
return None
|
||||||
|
|
||||||
|
else:
|
||||||
|
Count[0] += 1
|
||||||
|
|
||||||
|
print(f"\r{C.S} Find Target Smali {C.E} {C.OG}➸❥ {C.PN}{Count[0]}", end='', flush=True)
|
||||||
|
|
||||||
|
return Smali_Path
|
||||||
|
|
||||||
|
|
||||||
|
# ---------------- Patch Random Info ----------------
|
||||||
|
def Patch_Random_Info(smali_folders, isID):
|
||||||
|
|
||||||
|
RI.get_random_device_info()
|
||||||
|
|
||||||
|
Smali_Paths, Match_Smali = [], []
|
||||||
|
|
||||||
|
patterns = [
|
||||||
|
# ---------------- Build Info ----------------
|
||||||
|
(
|
||||||
|
r'sget-object ([pv]\d+), Landroid/os/Build;->MANUFACTURER:Ljava/lang/String;',
|
||||||
|
rf'const-string \1, "{RI.is_manufacturer}"',
|
||||||
|
f"MANUFACTURER ➸❥ {C.OG}{RI.is_manufacturer}"
|
||||||
|
),
|
||||||
|
(
|
||||||
|
r'sget-object ([pv]\d+), Landroid/os/Build;->BRAND:Ljava/lang/String;',
|
||||||
|
rf'const-string \1, "{RI.is_brand}"',
|
||||||
|
f"BRAND ➸❥ {C.OG}{RI.is_brand}"
|
||||||
|
),
|
||||||
|
(
|
||||||
|
r'sget-object ([pv]\d+), Landroid/os/Build;->MODEL:Ljava/lang/String;',
|
||||||
|
rf'const-string \1, "{RI.is_model}"',
|
||||||
|
f"MODEL ➸❥ {C.OG}{RI.is_model}"
|
||||||
|
),
|
||||||
|
(
|
||||||
|
r'sget-object ([pv]\d+), Landroid/os/Build;->PRODUCT:Ljava/lang/String;',
|
||||||
|
rf'const-string \1, "{RI.is_product}"',
|
||||||
|
f"PRODUCT ➸❥ {C.OG}{RI.is_product}"
|
||||||
|
),
|
||||||
|
(
|
||||||
|
r'sget-object ([pv]\d+), Landroid/os/Build;->DEVICE:Ljava/lang/String;',
|
||||||
|
rf'const-string \1, "{RI.is_device}"',
|
||||||
|
f"DEVICE ➸❥ {C.OG}{RI.is_device}"
|
||||||
|
),
|
||||||
|
(
|
||||||
|
r'sget-object ([pv]\d+), Landroid/os/Build;->BOARD:Ljava/lang/String;',
|
||||||
|
rf'const-string \1, "{RI.is_board}"',
|
||||||
|
f"BOARD ➸❥ {C.OG}{RI.is_board}"
|
||||||
|
),
|
||||||
|
(
|
||||||
|
r'invoke-static \{\}, Landroid/os/Build;->getRadioVersion\(\)Ljava/lang/String;[^>]*?move-result-object ([pv]\d+)',
|
||||||
|
rf'const-string \1, "Unknown"',
|
||||||
|
f"getRadioVersion ➸❥ {C.OG}Unknown"
|
||||||
|
),
|
||||||
|
(
|
||||||
|
r'sget-object ([pv]\d+), Landroid/os/Build;->RADIO:Ljava/lang/String;',
|
||||||
|
rf'const-string \1, "Unknown"',
|
||||||
|
f"RADIO ➸❥ {C.OG}Unknown"
|
||||||
|
),
|
||||||
|
(
|
||||||
|
r'sget-object ([pv]\d+), Landroid/os/Build;->HARDWARE:Ljava/lang/String;',
|
||||||
|
rf'const-string \1, "{RI.is_hardware}"',
|
||||||
|
f"HARDWARE ➸❥ {C.OG}{RI.is_hardware}"
|
||||||
|
),
|
||||||
|
(
|
||||||
|
r'sget-object ([pv]\d+), Landroid/os/Build;->BOOTLOADER:Ljava/lang/String;',
|
||||||
|
rf'const-string \1, "Unknown"',
|
||||||
|
f"BOOTLOADER ➸❥ {C.OG}Unknown"
|
||||||
|
),
|
||||||
|
(
|
||||||
|
r'sget-object ([pv]\d+), Landroid/os/Build;->FINGERPRINT:Ljava/lang/String;',
|
||||||
|
rf'const-string \1, "{RI.is_fingerprint}"',
|
||||||
|
f"FINGERPRINT ➸❥ {C.OG}{RI.is_fingerprint}"
|
||||||
|
),
|
||||||
|
(
|
||||||
|
r'sget-object ([pv]\d+), Landroid/os/Build;->ID:Ljava/lang/String;',
|
||||||
|
rf'const-string \1, "{RI.is_id}"',
|
||||||
|
f"ID ➸❥ {C.OG}{RI.is_id}"
|
||||||
|
),
|
||||||
|
(
|
||||||
|
r'sget-object ([pv]\d+), Landroid/os/Build;->SERIAL:Ljava/lang/String;',
|
||||||
|
rf'const-string \1, "Unknown"',
|
||||||
|
f"SERIAL ➸❥ {C.OG}Unknown"
|
||||||
|
),
|
||||||
|
(
|
||||||
|
r'sget-object ([pv]\d+), Landroid/os/Build;->DISPLAY:Ljava/lang/String;',
|
||||||
|
rf'const-string \1, "{RI.is_display}"',
|
||||||
|
f"DISPLAY ➸❥ {C.OG}{RI.is_display}"
|
||||||
|
),
|
||||||
|
(
|
||||||
|
r'sget-object ([pv]\d+), Landroid/os/Build;->HOST:Ljava/lang/String;',
|
||||||
|
rf'const-string \1, "localhost"',
|
||||||
|
f"HOST ➸❥ {C.OG}localhost"
|
||||||
|
),
|
||||||
|
(
|
||||||
|
r'const-string [pv]\d+, "(?:generic|goldfish)"[^>]*?invoke-static \{[^\}]*\}, Landroid/os/Build;->get(?:Device|Hardware)\(\)Ljava/lang/String;[^>]*?move-result-object [pv]\d+[^>]*?invoke-virtual \{[^\}]*\}, Ljava/lang/String;->contains\(Ljava/lang/CharSequence;\)Z[^>]*?move-result ([pv]\d+)',
|
||||||
|
rf'const/4 \1, 0x0',
|
||||||
|
"Bypassed Device detection"
|
||||||
|
),
|
||||||
|
|
||||||
|
# ---------------- Mock Location & Update & PKG Install Fixed ----------------
|
||||||
|
(
|
||||||
|
r'(invoke-virtual \{[^\}]*\}, Landroid/location/Location;->getLongitude\(\)D[^>]*?)move-result-wide ([pv]\d+)',
|
||||||
|
rf'\1const-wide \2, {lon_hex}',
|
||||||
|
f"Longitude ➸❥ {C.OG}{lon_hex}"
|
||||||
|
),
|
||||||
|
(
|
||||||
|
r'(invoke-virtual \{[^\}]*\}, Landroid/location/Location;->getLatitude\(\)D[^>]*?)move-result-wide ([pv]\d+)',
|
||||||
|
rf'\1const-wide \2, {lat_hex}',
|
||||||
|
f"Latitude ➸❥ {C.OG}{lat_hex}"
|
||||||
|
),
|
||||||
|
(
|
||||||
|
r'invoke-virtual \{[^\}]*\}, Landroid/location/Location;->(?:isFromMockProvider|isMock)\(\)Z[^>]*?move-result ([pv]\d+)',
|
||||||
|
rf'const/4 \1, 0x0',
|
||||||
|
"Bypassed Mock Detection"
|
||||||
|
),
|
||||||
|
(
|
||||||
|
r'iget-object ([pv]\d+), [pv]\d+, L[^;]*;->ip:Ljava/lang/String;',
|
||||||
|
rf'const-string \1, "127.0.0.1"',
|
||||||
|
f"IP To LocalHost ➸❥ {C.OG}127.0.0.1"
|
||||||
|
),
|
||||||
|
(
|
||||||
|
r'(invoke-virtual \{[^\}]*\}, Landroid/content/pm/PackageManager;->getInstallerPackageName\(Ljava/lang/String;\)Ljava/lang/String;[^>]*?)move-result-object ([pv]\d+)',
|
||||||
|
r'\1const-string \2, "com.android.vending"',
|
||||||
|
"Fixed Installer"
|
||||||
|
),
|
||||||
|
|
||||||
|
# ---------------- Settings$Secure ----------------
|
||||||
|
(
|
||||||
|
r'(const-string [pv]\d+, "bluetooth_address"[^>]*?invoke-static \{[^\}]*\}, Landroid/provider/Settings\$Secure;->getString\(Landroid/content/ContentResolver;Ljava/lang/String;\)Ljava/lang/String;[^>]*?)move-result-object ([pv]\d+)',
|
||||||
|
rf'\1const-string \2, "{isMac1}"',
|
||||||
|
f"Bluetooth Address ➸❥ {C.OG}{isMac1}"
|
||||||
|
),
|
||||||
|
|
||||||
|
# ---------------- Network Info ----------------
|
||||||
|
(
|
||||||
|
r'(invoke-virtual \{[^\}]*\}, Landroid/net/wifi/WifiInfo;->getBSSID\(\)Ljava/lang/String;[^>]*?)move-result-object ([pv]\d+)',
|
||||||
|
rf'\1const-string \2, "{isMac2}"',
|
||||||
|
f"WifiInfo BSSID ➸❥ {C.OG}{isMac2}"
|
||||||
|
),
|
||||||
|
(
|
||||||
|
r'(invoke-virtual \{[^\}]*\}, Landroid/net/wifi/WifiInfo;->getMacAddress\(\)Ljava/lang/String;[^>]*?)move-result-object ([pv]\d+)',
|
||||||
|
rf'\1const-string \2, "{isMac3}"',
|
||||||
|
f"WifiInfo MacAddress ➸❥ {C.OG}{isMac3}"
|
||||||
|
),
|
||||||
|
(
|
||||||
|
r'(invoke-virtual \{[^\}]*\}, Landroid/bluetooth/BluetoothDevice;->getAddress\(\)Ljava/lang/String;[^>]*?)move-result-object ([pv]\d+)',
|
||||||
|
rf'\1const-string \2, "{isMac4}"',
|
||||||
|
f"BluetoothDevice Address ➸❥ {C.OG}{isMac4}"
|
||||||
|
),
|
||||||
|
|
||||||
|
# ---------------- Telephony Manager ----------------
|
||||||
|
(
|
||||||
|
r'(invoke-virtual \{[^\}]*\}, Landroid/telephony/TelephonyManager;->getDeviceId\(\)Ljava/lang/String;[^>]*?)move-result-object ([pv]\d+)',
|
||||||
|
rf'\1const-string \2, "{isIMEI}"',
|
||||||
|
f"IMEI NO (Device ID) ➸❥ {C.OG}{isIMEI}"
|
||||||
|
),
|
||||||
|
|
||||||
|
# ---------------- Fix Play ----------------
|
||||||
|
(
|
||||||
|
r'(invoke-interface \{[^\}]*\}, Lcom/google/android/vending/licensing/Policy;->allowAccess\(\)Z[^>]*?\s+)move-result ([pv]\d+)',
|
||||||
|
r'\1const/4 \2, 0x1',
|
||||||
|
"Bypass Client-Side LVL (allowAccess)"
|
||||||
|
),
|
||||||
|
(
|
||||||
|
r'(\.method [^(]*connectToLicensingService\(\)V\s+.locals \d+)[\s\S]*?(\s+return-void\n.end method)',
|
||||||
|
r'\1\2',
|
||||||
|
"connectToLicensingService"
|
||||||
|
),
|
||||||
|
(
|
||||||
|
r'(\.method [^(]*initializeLicenseCheck\(\)V\s+.locals \d+)[\s\S]*?(\s+return-void\n.end method)',
|
||||||
|
r'\1\2',
|
||||||
|
"initializeLicenseCheck"
|
||||||
|
),
|
||||||
|
(
|
||||||
|
r'(\.method [^(]*processResponse\(ILandroid/os/Bundle;\)V\s+.locals \d+)[\s\S]*?(\s+return-void\n.end method)',
|
||||||
|
r'\1\2',
|
||||||
|
"processResponse"
|
||||||
|
)
|
||||||
|
]
|
||||||
|
|
||||||
|
if isID:
|
||||||
|
# ---------------- Custom Device ID ----------------
|
||||||
|
patterns.append(
|
||||||
|
(
|
||||||
|
r'(const-string [pv]\d+, "android_id"[^>]*?invoke-static \{[^\}]*\}, Landroid/provider/Settings\$Secure;->getString\(Landroid/content/ContentResolver;Ljava/lang/String;\)Ljava/lang/String;[^>]*?)move-result-object ([pv]\d+)',
|
||||||
|
rf'\1const-string \2, "{isID}"',
|
||||||
|
f"Custom Android ID ➸❥ {C.OG}{isID}"
|
||||||
|
)
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
patterns.append(
|
||||||
|
(
|
||||||
|
r'(const-string [pv]\d+, "android_id"[^>]*?invoke-static \{[^\}]*\}, Landroid/provider/Settings\$Secure;->getString\(Landroid/content/ContentResolver;Ljava/lang/String;\)Ljava/lang/String;[^>]*?)move-result-object ([pv]\d+)',
|
||||||
|
rf'\1const-string \2, "{device_id}"',
|
||||||
|
f"Random Android ID ➸❥ {C.OG}{device_id}"
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
Target_Regex = [p[0] for p in patterns]
|
||||||
|
|
||||||
|
for smali_folder in smali_folders:
|
||||||
|
for root, _, files in M.os.walk(smali_folder):
|
||||||
|
for file in files:
|
||||||
|
if file.endswith('.smali'):
|
||||||
|
Smali_Paths.append(M.os.path.join(root, file))
|
||||||
|
|
||||||
|
try:
|
||||||
|
# ---------------- Multi Threading ----------------
|
||||||
|
with M.Manager() as MT:
|
||||||
|
Count = MT.Value('i', 0); Lock = MT.Lock()
|
||||||
|
with M.Pool(M.cpu_count()) as PL:
|
||||||
|
Match_Smali = [path for path in PL.starmap(Regex_Scan, [(Smali_Path, Target_Regex, Count, Lock) for Smali_Path in Smali_Paths]) if path]
|
||||||
|
|
||||||
|
except Exception:
|
||||||
|
# ---------------- Single Threading ----------------
|
||||||
|
Count = [0]
|
||||||
|
for Smali_Path in Smali_Paths:
|
||||||
|
result = Regex_Scan(Smali_Path, Target_Regex, Count, None)
|
||||||
|
|
||||||
|
if result:
|
||||||
|
Match_Smali.append(result)
|
||||||
|
|
||||||
|
print(f" {C.G} ✔", flush=True)
|
||||||
|
|
||||||
|
print(f'\n{C_Line}\n')
|
||||||
|
|
||||||
|
if Match_Smali:
|
||||||
|
for pattern, replacement, description in patterns:
|
||||||
|
|
||||||
|
Count_Applied = 0
|
||||||
|
|
||||||
|
Applied_Files = set()
|
||||||
|
|
||||||
|
for file_path in Match_Smali:
|
||||||
|
|
||||||
|
content = open(file_path, 'r', encoding='utf-8', errors='ignore').read()
|
||||||
|
|
||||||
|
new_content = M.re.sub(pattern, replacement, content)
|
||||||
|
|
||||||
|
if new_content != content:
|
||||||
|
if file_path not in Applied_Files:
|
||||||
|
Applied_Files.add(file_path)
|
||||||
|
|
||||||
|
Count_Applied += 1
|
||||||
|
|
||||||
|
open(file_path, 'w', encoding='utf-8', errors='ignore').write(new_content)
|
||||||
|
|
||||||
|
if Count_Applied > 0:
|
||||||
|
print(f"\n{C.S} Tag {C.E} {C.G}{description}")
|
||||||
|
|
||||||
|
print(f"\n{C.S} Pattern {C.E} {C.OG}➸❥ {C.P}{pattern}")
|
||||||
|
|
||||||
|
for file_path in Applied_Files:
|
||||||
|
print(f"{C.G} |\n └──── {C.CC}~{C.G}$ {C.Y}{M.os.path.basename(file_path)} {C.G} ✔")
|
||||||
|
|
||||||
|
print(
|
||||||
|
f"\n{C.S} Pattern Applied {C.E} {C.OG}➸❥ {C.PN}{Count_Applied} {C.C}Time/Smali {C.G} ✔\n"
|
||||||
|
f"\n{C_Line}\n"
|
||||||
|
)
|
||||||
490
ApkPatcher/Patch/TG_Patch.py
Normal file
490
ApkPatcher/Patch/TG_Patch.py
Normal file
@ -0,0 +1,490 @@
|
|||||||
|
# TG Patch Inspired By AbhiTheM0dder Script
|
||||||
|
|
||||||
|
# Link - https://github.com/AbhiTheModder/termux-scripts/blob/main/tgpatcher.py
|
||||||
|
|
||||||
|
from ..ANSI_COLORS import ANSI; C = ANSI()
|
||||||
|
from ..MODULES import IMPORT; M = IMPORT()
|
||||||
|
from ApkPatcher.Utils.Files_Check import FileCheck
|
||||||
|
|
||||||
|
F = FileCheck(); F.Set_Path()
|
||||||
|
|
||||||
|
C_Line = f"{C.CC}{'_' * 61}"
|
||||||
|
|
||||||
|
|
||||||
|
# ---------------- Regex Scan ----------------
|
||||||
|
def Regex_Scan(Smali_Path, Target_Regex, Count, Lock):
|
||||||
|
|
||||||
|
Smali = open(Smali_Path, 'r', encoding='utf-8', errors='ignore').read()
|
||||||
|
|
||||||
|
Regexs = [M.re.compile(r) for r in Target_Regex]
|
||||||
|
|
||||||
|
matched_idx = []
|
||||||
|
|
||||||
|
for idx, Regex in enumerate(Regexs):
|
||||||
|
if Regex.search(Smali):
|
||||||
|
matched_idx.append(idx)
|
||||||
|
|
||||||
|
if matched_idx:
|
||||||
|
if Lock:
|
||||||
|
try:
|
||||||
|
with Lock:
|
||||||
|
Count.value += 1
|
||||||
|
print(f"\r{C.S} Find Target Smali {C.E} {C.OG}➸❥ {C.PN}{Count.value}", end='', flush=True)
|
||||||
|
except Exception:
|
||||||
|
return None
|
||||||
|
else:
|
||||||
|
Count[0] += 1
|
||||||
|
print(f"\r{C.S} Find Target Smali {C.E} {C.OG}➸❥ {C.PN}{Count[0]}", end='', flush=True)
|
||||||
|
|
||||||
|
return (Smali_Path, matched_idx)
|
||||||
|
|
||||||
|
|
||||||
|
# ---------------- TG Smali Patch ----------------
|
||||||
|
def TG_Smali_Patch(decompile_dir, smali_folders, isAPKEditor):
|
||||||
|
|
||||||
|
Smali_Paths, Smali_Files, Match_Smali = [], [], []
|
||||||
|
|
||||||
|
Target_Smali = [
|
||||||
|
"TextCell.smali",
|
||||||
|
"UserConfig.smali",
|
||||||
|
"StoryViewer.smali",
|
||||||
|
"PhotoViewer.smali",
|
||||||
|
"AndroidUtilities.smali",
|
||||||
|
"TranslateAlert2.smali",
|
||||||
|
"MessageObject.smali",
|
||||||
|
"StoriesController.smali",
|
||||||
|
"MessagesStorage.smali",
|
||||||
|
"FileLoadOperation.smali",
|
||||||
|
"FlagSecureReason.smali",
|
||||||
|
"SecretMediaViewer.smali",
|
||||||
|
"MessagesController.smali",
|
||||||
|
"PaymentFormActivity.smali",
|
||||||
|
"PremiumPreviewFragment.smali",
|
||||||
|
"ProfileActivity$SearchAdapter.smali",
|
||||||
|
"PremiumPreviewFragment$Adapter.smali",
|
||||||
|
"ConnectionsManager$GoogleDnsLoadTask.smali",
|
||||||
|
"ConnectionsManager$ResolveHostByNameTask.smali"
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
|
# ---------------- is scan Patterns ----------------
|
||||||
|
scanPatterns = [
|
||||||
|
# ---------------- Bypass SS ----------------
|
||||||
|
(
|
||||||
|
r'(iget-boolean ([pv]\d+), [pv]\d+, Lorg/telegram/ui/[^;]+;->allowScreenshots:Z)',
|
||||||
|
r'\1\nconst \2, 0x1',
|
||||||
|
"Bypass Anti-Screen <allowScreenshots>",
|
||||||
|
[]
|
||||||
|
),
|
||||||
|
(
|
||||||
|
r'(sget-boolean ([pv]\d+), Lorg/telegram/messenger/SharedConfig;->allowScreenCapture:Z)',
|
||||||
|
r'\1\nconst \2, 0x1',
|
||||||
|
"Bypass Anti-Screen <allowScreenCapture>",
|
||||||
|
[]
|
||||||
|
),
|
||||||
|
|
||||||
|
# ---------------- Access Banned Channels [Related] ----------------
|
||||||
|
(
|
||||||
|
r'(iget-boolean ([pv]\d+), [pv]\d+, Lorg/telegram/[^;]+;->isRestrictedMessage:Z)',
|
||||||
|
r'\1\n\tconst \2, 0x0',
|
||||||
|
"Access Banned Channels [Related]",
|
||||||
|
[]
|
||||||
|
),
|
||||||
|
|
||||||
|
# ---------------- Enabling Saving Media Everywhere ----------------
|
||||||
|
(
|
||||||
|
r'(iget-boolean ([pv]\d+), [pv]\d+, Lorg/telegram/[^;]+;->noforwards:Z)',
|
||||||
|
r'\1\n\tconst \2, 0x0',
|
||||||
|
"enableSavingMedia",
|
||||||
|
[]
|
||||||
|
),
|
||||||
|
|
||||||
|
# ---------------- make premiumLocked bool false ----------------
|
||||||
|
(
|
||||||
|
r'(iget-boolean ([pv]\d+), [pv]\d+, Lorg/telegram/[^;]+;->premiumLocked:Z)',
|
||||||
|
r'\1\n\tconst \2, 0x0',
|
||||||
|
"premiumLocked ➢ False",
|
||||||
|
[]
|
||||||
|
)
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
|
# ---------------- is smali Patterns ( only For Target_Smali ) ----------------
|
||||||
|
smaliPatterns = [
|
||||||
|
# ---------------- Bypass SS ----------------
|
||||||
|
(
|
||||||
|
r'(const/16 [pv]\d+, 0x)200(0\s+(.line \d+\s+)*?invoke-virtual \{[^\}]*\}, Landroid/view/Window;->(?:add|set|clear)Flags\((?:I|II)\)V)',
|
||||||
|
r'\1\2',
|
||||||
|
"Bypass Anti-Screen <(add|set|clear)Flags>",
|
||||||
|
None
|
||||||
|
),
|
||||||
|
(
|
||||||
|
r'(const/16 [pv]\d+, 0x)200(0\n)',
|
||||||
|
r'\1\2',
|
||||||
|
"Bypass Anti-Screen <0x2000>",
|
||||||
|
["AndroidUtilities.smali", "TranslateAlert2.smali", "StoryViewer.smali", "PaymentFormActivity.smali"]
|
||||||
|
),
|
||||||
|
(
|
||||||
|
r'(invoke-static \{[^\}]*\}, L[^\(]+;->isSecuredNow\(Landroid/view/Window;\)Z\s+(.line \d+\s+)*?move-result [pv]\d+\s+(.line \d+\s+)*?const/16 ([pv]\d+),) 0x2000',
|
||||||
|
r'\1 0x0',
|
||||||
|
"Bypass Anti-Screen <isSecuredNow>",
|
||||||
|
"FlagSecureReason.smali"
|
||||||
|
),
|
||||||
|
(
|
||||||
|
r'(\s+or-int/lit16 [pv]\d+, [pv]\d+,) 0x2000',
|
||||||
|
r'\1 0x0',
|
||||||
|
"Bypass Anti-Screen <PhotoViewer|SecretMediaViewer>",
|
||||||
|
["PhotoViewer.smali", "SecretMediaViewer.smali"]
|
||||||
|
),
|
||||||
|
(
|
||||||
|
r'(invoke-virtual \{([pv]\d+), ([pv]\d+)\}, Landroid/view/SurfaceView;->setSecure\(Z\)V)',
|
||||||
|
r'const/4 \3, 0x0\n\n\t\1',
|
||||||
|
"Bypass Anti-Screen <setSecure>",
|
||||||
|
"StoryViewer.smali"
|
||||||
|
),
|
||||||
|
|
||||||
|
# ---------------- Disable Signature Verification ----------------
|
||||||
|
(
|
||||||
|
r'(\.method public static getCertificateSHA256Fingerprint\(\)Ljava/lang/String;\n)[\S\s+]*?(\n.end method)',
|
||||||
|
r'\1\t.locals 1\n'
|
||||||
|
r' const-string v0, "49C1522548EBACD46CE322B6FD47F6092BB745D0F88082145CAF35E14DCC38E1"\n'
|
||||||
|
r' return-object v0\2',
|
||||||
|
"Disable Signature Verification",
|
||||||
|
"AndroidUtilities.smali"
|
||||||
|
),
|
||||||
|
|
||||||
|
# ---------------- markStoryAsRead ----------------
|
||||||
|
(
|
||||||
|
r'(\.method public markStoryAsRead\((JLorg/telegram/tgnet/tl/TL_stories\$StoryItem;|Lorg/telegram/tgnet/tl/TL_stories\$PeerStories;Lorg/telegram/tgnet/tl/TL_stories\$StoryItem;Z)\)Z\n)[\S\s+]*?(\s+return ([pv]\d+)\n.end method)',
|
||||||
|
r'\1\t.locals 4\n\tconst/4 \4, 0x0\3',
|
||||||
|
"markStoryAsRead",
|
||||||
|
"StoriesController.smali"
|
||||||
|
),
|
||||||
|
|
||||||
|
# ---------------- Premium ----------------
|
||||||
|
(
|
||||||
|
r'(\.method (?:private|public final) isPremium\(J\)Z\n)[\S\s+]*?(\n.end method)',
|
||||||
|
r'\1\t.locals 3\n\tconst/4 p1, 0x1\n\treturn p1\2',
|
||||||
|
"isPremium ➢ StoriesController",
|
||||||
|
"StoriesController.smali"
|
||||||
|
),
|
||||||
|
(
|
||||||
|
r'(\.method public isPremium\(\)Z\n)[\S\s]*?(\n.end method)',
|
||||||
|
r'\1\t.locals 1\n\tconst/4 v0, 0x1\n\treturn v0\2',
|
||||||
|
"isPremium ➢ UserConfig",
|
||||||
|
"UserConfig.smali"
|
||||||
|
),
|
||||||
|
(
|
||||||
|
r'(\.method (?:private|public final) isPremiumFeatureAvailable\(I\)Z\n(?:(?!\.end method)[\s\S])*?const/4 v1,) 0x0([\S\s+]*?\n.end method)',
|
||||||
|
r'\1 0x1\2',
|
||||||
|
"isPremiumFeatureAvailable",
|
||||||
|
"ProfileActivity$SearchAdapter.smali"
|
||||||
|
),
|
||||||
|
(
|
||||||
|
r'(\.method static synthetic access\$3000\(Lorg/telegram/ui/PremiumPreviewFragment;\)Z\n)(?:(?!\.end method)[\s\S])*?iget-boolean [pv]\d+, [pv]\d+, Lorg/telegram/ui/PremiumPreviewFragment;->forcePremium:Z[\S\s+]*?(\s+return ([pv]\d+)\n.end method)',
|
||||||
|
r'\1\t.locals 1\n\tconst/4 \3, 0x1\2',
|
||||||
|
"forcePremium",
|
||||||
|
"PremiumPreviewFragment.smali"
|
||||||
|
),
|
||||||
|
|
||||||
|
# ---------------- Secret Media Enable ----------------
|
||||||
|
(
|
||||||
|
r'(\.method public getSecretTimeLeft\(\)I\n(?:(?!\.end method)[\s\S])*?const/4 v1,) 0x0([\S\s+]*?\n.end method)',
|
||||||
|
r'\1 0x1\2',
|
||||||
|
"Secret Media Enable",
|
||||||
|
"MessageObject.smali"
|
||||||
|
),
|
||||||
|
(
|
||||||
|
r'(\.method public isSecretMedia\(\)Z\n(?:(?!\.end method)[\s\S])*?iget-object [pv]\d+, [pv]\d+, Lorg/telegram/messenger/MessageObject;->messageOwner:Lorg/telegram/tgnet/TLRPC\$Message;\s+instance-of [pv]\d+, [pv]\d+, Lorg/telegram/tgnet/TLRPC\$TL_message_secret;\s+)[\S\s+]*?(\n.end method)',
|
||||||
|
r'\1const/4 v3, 0x0\n\treturn v3\2',
|
||||||
|
"Secret Media Enable",
|
||||||
|
"MessageObject.smali"
|
||||||
|
),
|
||||||
|
(
|
||||||
|
r'(\.method public static isSecretPhotoOrVideo\(Lorg/telegram/tgnet/TLRPC\$Message;\)Z\n(?:(?!\.end method)[\s\S])*?instance-of [pv]\d+, [pv]\d+, Lorg/telegram/tgnet/TLRPC\$TL_message_secret;\s+)[\S\s+]*?(\n.end method)',
|
||||||
|
r'\1const/4 v2, 0x0\n\treturn v2\2',
|
||||||
|
"Secret Media Enable",
|
||||||
|
"MessageObject.smali"
|
||||||
|
),
|
||||||
|
(
|
||||||
|
r'(\.method public static isSecretMedia\(Lorg/telegram/tgnet/TLRPC\$Message;\)Z\n(?:(?!\.end method)[\s\S])*?instance-of [pv]\d+, [pv]\d+, Lorg/telegram/tgnet/TLRPC\$TL_message_secret;\s+)[\S\s+]*?(\n.end method)',
|
||||||
|
r'\1const/4 v2, 0x0\n\treturn v2\2',
|
||||||
|
"Secret Media Enable",
|
||||||
|
"MessageObject.smali"
|
||||||
|
),
|
||||||
|
|
||||||
|
# ---------------- isSponsored Check ----------------
|
||||||
|
(
|
||||||
|
r'(\.method public isSponsored\(\)Z\n)[\S\s]*?(\n.end method)',
|
||||||
|
r'\1\t.locals 3\n\tconst/4 v0, 0x0\n\treturn v0\2',
|
||||||
|
"isSponsored ➢ False",
|
||||||
|
"MessageObject.smali"
|
||||||
|
),
|
||||||
|
(
|
||||||
|
r'(\.method public isSponsoredDisabled\(\)Z\n)[\S\s]*?(\n.end method)',
|
||||||
|
r'\1\t.locals 3\n\tconst/4 v0, 0x1\n\treturn v0\2',
|
||||||
|
"isSponsoredDisabled ➢ True",
|
||||||
|
"MessagesController.smali"
|
||||||
|
),
|
||||||
|
(
|
||||||
|
r'(\.method private checkPromoInfoInternal\(Z\)V\n)[\S\s]*?(\n.end method)',
|
||||||
|
r'\1\t.locals 2\n\treturn-void\2',
|
||||||
|
"Remove Proxy Sponsored Channels",
|
||||||
|
"MessagesController.smali"
|
||||||
|
),
|
||||||
|
|
||||||
|
# ---------------- isChatNoForwards ----------------
|
||||||
|
(
|
||||||
|
r'(\.method public isChatNoForwards\((?:J|Lorg/telegram/tgnet/TLRPC\$Chat;)\)Z\n)[\S\s+]*?(\n.end method)',
|
||||||
|
r'\1\t.locals 3\n\tconst/4 p1, 0x0\n\treturn p1\2',
|
||||||
|
"isChatNoForwards ➢ forceForward",
|
||||||
|
"MessagesController.smali"
|
||||||
|
),
|
||||||
|
|
||||||
|
# ---------------- Access Banned Channels [Main] ----------------
|
||||||
|
(
|
||||||
|
r'(\.method public checkCanOpenChat\(Landroid/os/Bundle;Lorg/telegram/ui/ActionBar/BaseFragment;.*\)Z\n)[\S\s]*?(\n.end method)',
|
||||||
|
r'\1\t.locals 3\n\tconst/4 p1, 0x1\n\treturn p1\2',
|
||||||
|
"Access Banned Channels [Main]",
|
||||||
|
"MessagesController.smali"
|
||||||
|
),
|
||||||
|
|
||||||
|
# ---------------- dnsBooster ( ResolveHostByNameTask ) ----------------
|
||||||
|
(
|
||||||
|
r'"dns.google.com"',
|
||||||
|
r'"one.one.one.one"',
|
||||||
|
"+ CloudFlare DNS",
|
||||||
|
"ConnectionsManager$ResolveHostByNameTask.smali"
|
||||||
|
),
|
||||||
|
(
|
||||||
|
r'"https://www.google.com/resolve\?name="',
|
||||||
|
r'"https://cloudflare-dns.com/dns-query?name="',
|
||||||
|
"+ CloudFlare DNS Resolver",
|
||||||
|
"ConnectionsManager$ResolveHostByNameTask.smali"
|
||||||
|
),
|
||||||
|
(
|
||||||
|
r'(invoke-virtual \{[pv]\d+, ([pv]\d+), ([pv]\d+)\}, Ljava/net/URLConnection;->addRequestProperty\(Ljava/lang/String;Ljava/lang/String;\)V)(\s+(.line \d+\s+)*?const/16 [pv]\d+, 0x3e8)',
|
||||||
|
r'\1\n'
|
||||||
|
r' const-string \2, "accept"\n'
|
||||||
|
r' const-string \3, "application/dns-json"\n'
|
||||||
|
r' \1'
|
||||||
|
r' \4',
|
||||||
|
"+ CloudFlare Header",
|
||||||
|
"ConnectionsManager$ResolveHostByNameTask.smali"
|
||||||
|
),
|
||||||
|
|
||||||
|
# ---------------- dnsBooster ( GoogleDnsLoadTask ) ----------------
|
||||||
|
(
|
||||||
|
r'"https://dns.google.com/resolve\?name="',
|
||||||
|
r'"https://cloudflare-dns.com/dns-query?name="',
|
||||||
|
"+ CloudFlare DNS Resolver",
|
||||||
|
"ConnectionsManager$GoogleDnsLoadTask.smali"
|
||||||
|
),
|
||||||
|
(
|
||||||
|
r'("&type=)ANY(&random_padding=")',
|
||||||
|
r'\1TXT\2',
|
||||||
|
"DNS Type ANY To TXT",
|
||||||
|
"ConnectionsManager$GoogleDnsLoadTask.smali"
|
||||||
|
),
|
||||||
|
(
|
||||||
|
r'(invoke-virtual \{[pv]\d+, ([pv]\d+), ([pv]\d+)\}, Ljava/net/URLConnection;->addRequestProperty\(Ljava/lang/String;Ljava/lang/String;\)V)',
|
||||||
|
r'\1\n'
|
||||||
|
r' const-string \2, "accept"\n'
|
||||||
|
r' const-string \3, "application/dns-json"\n'
|
||||||
|
r' \1',
|
||||||
|
"+ CloudFlare Header",
|
||||||
|
"ConnectionsManager$GoogleDnsLoadTask.smali"
|
||||||
|
),
|
||||||
|
|
||||||
|
# ---------------- updateParams ----------------
|
||||||
|
(
|
||||||
|
r'(\.method private updateParams\(\)V\n(?:(?!\.end method)[\s\S])*?const/high16 v0,) 0x20000((?:(?!\.end method)[\s\S])*?)const/4 v0, 0x4([\S\s+]*?\n.end method)',
|
||||||
|
r'\1 0x80000\2const/16 v0, 0x8\3',
|
||||||
|
"updateParams ➢ SpeedBoost",
|
||||||
|
"FileLoadOperation.smali"
|
||||||
|
),
|
||||||
|
|
||||||
|
# ---------------- markMessagesAsDeleted ----------------
|
||||||
|
(
|
||||||
|
r'(\.method public markMessagesAsDeleted\(JIZZ\)Ljava/util/ArrayList;\s+\.locals \d+(\s+\.annotation[\s\S]*?.end annotation)?)',
|
||||||
|
r'\1\n'
|
||||||
|
r' sget-boolean v0, Lorg/telegram/abhi/Hook;->candelMessages:Z\n'
|
||||||
|
r' if-eqz v0, :cond_7\n'
|
||||||
|
r' const/4 p1, 0x0\n'
|
||||||
|
r' return-object p1\n'
|
||||||
|
r' :cond_7',
|
||||||
|
"markMessagesAsDeleted",
|
||||||
|
"MessagesStorage.smali"
|
||||||
|
),
|
||||||
|
(
|
||||||
|
r'(\.method public markMessagesAsDeleted\(JLjava/util/ArrayList;ZZII\)Ljava/util/ArrayList;\s+\.locals \d+(\s+\.annotation[\s\S]*?.end annotation)?)',
|
||||||
|
r'\1\n'
|
||||||
|
r' sget-boolean v0, Lorg/telegram/abhi/Hook;->candelMessages:Z\n'
|
||||||
|
r' if-eqz v0, :cond_7\n'
|
||||||
|
r' const/4 v1, 0x0\n'
|
||||||
|
r' return-object v1\n'
|
||||||
|
r' :cond_7',
|
||||||
|
"markMessagesAsDeleted",
|
||||||
|
"MessagesStorage.smali"
|
||||||
|
),
|
||||||
|
|
||||||
|
# ---------------- add setTextAndCheck_2 Method ----------------
|
||||||
|
(
|
||||||
|
r'((\.method public setTextAndCheck)(\(Ljava/lang/CharSequence;ZZ\)V[\S\s]*?)(\s+return-void\n.end method\n))',
|
||||||
|
r'\1\n\2_2\3\n'
|
||||||
|
r' invoke-virtual {p0}, Landroid/view/View;->getContext()Landroid/content/Context;\n'
|
||||||
|
r' move-result-object v1\n'
|
||||||
|
r' const-string v0, "Turned off"\n'
|
||||||
|
r' if-eqz p2, :cond_48\n'
|
||||||
|
r' const-string v0, "Turned on"\n'
|
||||||
|
r' :cond_48\n'
|
||||||
|
r' invoke-static {v1, v0, v2}, Landroid/widget/Toast;->makeText(Landroid/content/Context;Ljava/lang/CharSequence;I)Landroid/widget/Toast;\n'
|
||||||
|
r' move-result-object v0\n'
|
||||||
|
r' invoke-virtual {v0}, Landroid/widget/Toast;->show()V\n'
|
||||||
|
r' if-eqz p2, :cond_55\n'
|
||||||
|
r' invoke-static {}, Lorg/telegram/abhi/Hook;->hook()V\n'
|
||||||
|
r' goto :goto_58\n'
|
||||||
|
r' :cond_55\n'
|
||||||
|
r' invoke-static {}, Lorg/telegram/abhi/Hook;->unhook()V\n'
|
||||||
|
r' :goto_58\n\4',
|
||||||
|
"add setTextAndCheck_2 Method",
|
||||||
|
"TextCell.smali"
|
||||||
|
),
|
||||||
|
|
||||||
|
# ---------------- Anti-Delete Messages ----------------
|
||||||
|
(
|
||||||
|
r'(invoke-virtual \{.*\}, Lorg/telegram/ui/Cells/TextCell;->setTextAndCheck)(\(Ljava/lang/CharSequence;ZZ\)V)',
|
||||||
|
r'\1_2\2',
|
||||||
|
"Rename setTextAndCheck_2",
|
||||||
|
"PremiumPreviewFragment$Adapter.smali"
|
||||||
|
),
|
||||||
|
(
|
||||||
|
r'sget ([pv]\d+), Lorg/telegram/messenger/R\$string;->ShowAds:I\s+(invoke-static \{.*\}, Lorg/telegram/messenger/LocaleController;->getString\(I\)Ljava/lang/String;\s+move-result-object [pv]\d+)',
|
||||||
|
r'const-string \1, "Do Not Delete Messages"',
|
||||||
|
"Do Not Delete Messages",
|
||||||
|
"PremiumPreviewFragment$Adapter.smali"
|
||||||
|
),
|
||||||
|
(
|
||||||
|
r'sget ([pv]\d+), Lorg/telegram/messenger/R\$string;->ShowAdsInfo:I\s+(invoke-static \{.*\}, Lorg/telegram/messenger/LocaleController;->getString\(I\)Ljava/lang/String;\s+move-result-object [pv]\d+)',
|
||||||
|
r'const-string \1, "After enabling or disabling the feature, ensure you revisit this page for the changes to take effect.\\nMod by Abhi"',
|
||||||
|
"Mod by Abhi",
|
||||||
|
"PremiumPreviewFragment$Adapter.smali"
|
||||||
|
),
|
||||||
|
(
|
||||||
|
r'sget ([pv]\d+), Lorg/telegram/messenger/R\$string;->ShowAdsTitle:I\s+(invoke-static \{.*\}, Lorg/telegram/messenger/LocaleController;->getString\(I\)Ljava/lang/String;\s+move-result-object [pv]\d+)',
|
||||||
|
r'const-string \1, "Anti-Delete Messages"\n'
|
||||||
|
r' invoke-virtual {v1, \1}, Lorg/telegram/ui/Cells/HeaderCell;->setText(Ljava/lang/CharSequence;)V\n'
|
||||||
|
r' return-void',
|
||||||
|
"Anti-Delete Messages",
|
||||||
|
"PremiumPreviewFragment$Adapter.smali"
|
||||||
|
)
|
||||||
|
]
|
||||||
|
|
||||||
|
Target_Regex = [p[0] for p in scanPatterns]
|
||||||
|
|
||||||
|
for smali_folder in smali_folders:
|
||||||
|
for root, _, files in M.os.walk(smali_folder):
|
||||||
|
for file in files:
|
||||||
|
full_path = M.os.path.join(root, file)
|
||||||
|
if file.endswith('.smali'):
|
||||||
|
Smali_Paths.append(full_path)
|
||||||
|
if file in Target_Smali:
|
||||||
|
Smali_Files.append(full_path)
|
||||||
|
|
||||||
|
try:
|
||||||
|
# ---------------- Multiple Threading ----------------
|
||||||
|
with M.Manager() as MT:
|
||||||
|
Count = MT.Value('i', 0); Lock = MT.Lock()
|
||||||
|
with M.Pool(M.cpu_count()) as PL:
|
||||||
|
Match_Smali = [path for path in PL.starmap(Regex_Scan, [(Smali_Path, Target_Regex, Count, Lock) for Smali_Path in Smali_Paths]) if path]
|
||||||
|
|
||||||
|
except Exception:
|
||||||
|
# ---------------- Single Threading ----------------
|
||||||
|
Count = [0]
|
||||||
|
for Smali_Path in Smali_Paths:
|
||||||
|
result = Regex_Scan(Smali_Path, Target_Regex, Count, None)
|
||||||
|
|
||||||
|
if result:
|
||||||
|
Match_Smali.append(result)
|
||||||
|
|
||||||
|
print(f" {C.G} ✔\n", flush=True)
|
||||||
|
|
||||||
|
print(f"\n{C.X}{C.C} TG Patch, Script by {C.OG}🇮🇳 AbhiTheM0dder 🇮🇳")
|
||||||
|
|
||||||
|
print(f'\n{C_Line}\n')
|
||||||
|
|
||||||
|
allPatterns = scanPatterns + smaliPatterns
|
||||||
|
|
||||||
|
isMatched = {}
|
||||||
|
|
||||||
|
for is_Path, is_idx in Match_Smali:
|
||||||
|
if isinstance(is_idx, list): # Multi Match in Single Smali
|
||||||
|
for index in is_idx:
|
||||||
|
isMatched.setdefault(index, set()).add(is_Path)
|
||||||
|
else:
|
||||||
|
isMatched.setdefault(is_idx, set()).add(is_Path)
|
||||||
|
|
||||||
|
for idx, (pattern, replacement, description, target_files) in enumerate(allPatterns):
|
||||||
|
|
||||||
|
count_applied = 0
|
||||||
|
applied_files= set()
|
||||||
|
|
||||||
|
if target_files:
|
||||||
|
Map_Smali = set()
|
||||||
|
for Path in Smali_Files:
|
||||||
|
if isinstance(target_files, list): # Multi Smali
|
||||||
|
if M.os.path.basename(Path) in target_files:
|
||||||
|
Map_Smali.add(Path)
|
||||||
|
else:
|
||||||
|
if M.os.path.basename(Path) == target_files:
|
||||||
|
Map_Smali.add(Path)
|
||||||
|
else:
|
||||||
|
|
||||||
|
if target_files is None:
|
||||||
|
Map_Smali = {X for X, _ in Match_Smali}
|
||||||
|
else:
|
||||||
|
Map_Smali = isMatched.get(idx, set())
|
||||||
|
|
||||||
|
for File_Path in Map_Smali:
|
||||||
|
content = open(File_Path, 'r', encoding='utf-8', errors='ignore').read()
|
||||||
|
|
||||||
|
new_content = M.re.sub(pattern, replacement, content)
|
||||||
|
|
||||||
|
if new_content != content:
|
||||||
|
applied_files.add(File_Path)
|
||||||
|
|
||||||
|
count_applied += 1
|
||||||
|
|
||||||
|
open(File_Path, 'w', encoding='utf-8', errors='ignore').write(new_content)
|
||||||
|
|
||||||
|
if count_applied > 0:
|
||||||
|
print(f"\n{C.S} Tag {C.E} {C.G}{description}")
|
||||||
|
print(f"\n{C.S} Pattern {C.E} {C.OG}➸❥ {C.P}{pattern}")
|
||||||
|
|
||||||
|
for File_Path in applied_files:
|
||||||
|
print(f"{C.G} |\n └──── {C.CC}~{C.G}$ {C.Y}{M.os.path.basename(File_Path)} {C.G} ✔")
|
||||||
|
|
||||||
|
print(
|
||||||
|
f"\n{C.S} Pattern Applied {C.E} {C.OG}➸❥ {C.PN}{count_applied} {C.C}Time/Smali {C.G} ✔\n"
|
||||||
|
f"\n{C_Line}\n"
|
||||||
|
)
|
||||||
|
|
||||||
|
Hook_Smali(decompile_dir, isAPKEditor)
|
||||||
|
|
||||||
|
|
||||||
|
# ---------------- Hook Smali ----------------
|
||||||
|
def Hook_Smali(decompile_dir, isAPKEditor):
|
||||||
|
|
||||||
|
targetSmali_Dir = M.os.path.join(decompile_dir,
|
||||||
|
*(
|
||||||
|
['smali', 'classes'] if isAPKEditor else ['smali']
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
Target_Dest = M.os.path.join(targetSmali_Dir, "org", "telegram", "abhi", 'Hook.smali')
|
||||||
|
|
||||||
|
M.os.makedirs(M.os.path.dirname(Target_Dest), exist_ok=True)
|
||||||
|
|
||||||
|
M.shutil.copy(F.Hook_Smali, Target_Dest)
|
||||||
|
|
||||||
|
print(f"\n{C.S} Generate {C.E} {C.G}Hook.smali {C.OG}➸❥ {C.Y}{M.os.path.relpath(Target_Dest, decompile_dir)} {C.G} ✔\n")
|
||||||
0
ApkPatcher/Patch/__init__.py
Normal file
0
ApkPatcher/Patch/__init__.py
Normal file
62
ApkPatcher/Utils/Anti_Splits.py
Normal file
62
ApkPatcher/Utils/Anti_Splits.py
Normal file
@ -0,0 +1,62 @@
|
|||||||
|
from ..ANSI_COLORS import ANSI; C = ANSI()
|
||||||
|
from ..MODULES import IMPORT; M = IMPORT()
|
||||||
|
|
||||||
|
from .Files_Check import FileCheck
|
||||||
|
|
||||||
|
F = FileCheck(); F.Set_Path()
|
||||||
|
|
||||||
|
C_Line = f"{C.CC}{'_' * 61}"
|
||||||
|
|
||||||
|
Merge_Ext = ['.apks', '.apkm', '.xapk']
|
||||||
|
|
||||||
|
|
||||||
|
# ---------------- Anti Split ----------------
|
||||||
|
def Anti_Split(apk_path, isMerge, isCoreX):
|
||||||
|
|
||||||
|
base_name, Ext = M.os.path.splitext(apk_path)
|
||||||
|
|
||||||
|
if apk_path and isCoreX and M.os.path.splitext(apk_path)[-1].lower() not in Merge_Ext:
|
||||||
|
exit(f"\n{C.X}{C.C} Only Supported Extensions {C.G}{Merge_Ext} with {C.OG}CoreX\n")
|
||||||
|
|
||||||
|
if Ext in Merge_Ext:
|
||||||
|
output_path = f"{base_name.replace(' ', '_')}.apk"
|
||||||
|
|
||||||
|
print(
|
||||||
|
f"{C_Line}\n\n"
|
||||||
|
f"\n{C.X}{C.C} Anti-Split Start..."
|
||||||
|
)
|
||||||
|
|
||||||
|
print(
|
||||||
|
f"{C.G} |\n └──── {C.CC}Decompiling ~{C.G}$ java -jar {M.os.path.basename(F.APKEditor_Path)} m -i {apk_path} -f -o {output_path}"
|
||||||
|
+ (" -extractNativeLibs true" if isCoreX else "")
|
||||||
|
+ f"\n\n{C_Line}{C.G}\n"
|
||||||
|
)
|
||||||
|
|
||||||
|
cmd = ["java", "-jar", F.APKEditor_Path, "m", "-i", apk_path, "-f", "-o", output_path]
|
||||||
|
|
||||||
|
if isCoreX:
|
||||||
|
cmd += ["-extractNativeLibs", "true"]
|
||||||
|
|
||||||
|
try:
|
||||||
|
result = M.subprocess.run(cmd, check=True)
|
||||||
|
|
||||||
|
print(
|
||||||
|
f"\n{C.X}{C.C} Anti-Split Successful {C.G} ✔\n"
|
||||||
|
f"\n{C_Line}\n"
|
||||||
|
)
|
||||||
|
|
||||||
|
if isMerge:
|
||||||
|
exit(0)
|
||||||
|
|
||||||
|
return output_path
|
||||||
|
|
||||||
|
except M.subprocess.CalledProcessError as e:
|
||||||
|
exit(f"\n{C.ERROR} Anti-Split Failed ! ✘\n")
|
||||||
|
|
||||||
|
if isMerge and Ext not in Merge_Ext:
|
||||||
|
exit(
|
||||||
|
f"\n{C.ERROR} Split ✘\n\n"
|
||||||
|
f"\n{C.INFO} {C.C} Only Supported Extensions {C.G}{Merge_Ext}\n"
|
||||||
|
)
|
||||||
|
|
||||||
|
return apk_path
|
||||||
54
ApkPatcher/Utils/CRC.py
Normal file
54
ApkPatcher/Utils/CRC.py
Normal file
@ -0,0 +1,54 @@
|
|||||||
|
from ..ANSI_COLORS import ANSI; C = ANSI()
|
||||||
|
from ..MODULES import IMPORT; M = IMPORT()
|
||||||
|
|
||||||
|
|
||||||
|
# ---------------- Format Time ----------------
|
||||||
|
def Format_Time(timestamp):
|
||||||
|
return M.datetime.fromtimestamp(timestamp).strftime("%Y-%m-%d %H:%M:%S")
|
||||||
|
|
||||||
|
|
||||||
|
# ---------------- CRC Fix ----------------
|
||||||
|
def CRC_Fix(apk_path, build_dir, file_types):
|
||||||
|
|
||||||
|
Logs = []
|
||||||
|
|
||||||
|
origin_entries, mod_entries = [
|
||||||
|
{
|
||||||
|
entry.filename: (entry.CRC, entry.date_time)
|
||||||
|
for entry in M.zipfile.ZipFile(file_path, 'r').infolist()
|
||||||
|
if any(file_type in entry.filename for file_type in file_types)
|
||||||
|
} for file_path in (apk_path, build_dir)
|
||||||
|
]
|
||||||
|
|
||||||
|
binary_content = open(build_dir, 'rb').read()
|
||||||
|
|
||||||
|
for filename, (origin_crc, origin_time) in origin_entries.items():
|
||||||
|
if filename in mod_entries and origin_crc != mod_entries[filename][0]:
|
||||||
|
origin_crc_bytes = origin_crc.to_bytes(4, 'little')
|
||||||
|
|
||||||
|
mod_crc_bytes = mod_entries[filename][0].to_bytes(4, 'little')
|
||||||
|
|
||||||
|
binary_content = binary_content.replace(mod_crc_bytes, origin_crc_bytes)
|
||||||
|
|
||||||
|
Logs.append(
|
||||||
|
(
|
||||||
|
filename,
|
||||||
|
f"{origin_crc:08x}",
|
||||||
|
f"{mod_entries[filename][0]:08x}",
|
||||||
|
Format_Time(M.datetime(*origin_time).timestamp()),
|
||||||
|
Format_Time(M.datetime(*mod_entries[filename][1]).timestamp())
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
open(build_dir, 'wb').write(binary_content)
|
||||||
|
|
||||||
|
print(f"\n{'':20}✨ {C.G}CRCFix by {C.OG}Kirlif{C.G}' ✨\n")
|
||||||
|
|
||||||
|
print(f"{C.C}{'File Name':<22}{'CRC':<12}{'FIX':<12}{'Modified'}")
|
||||||
|
|
||||||
|
for e in Logs:
|
||||||
|
print(f"\n{C.G}{e[0]:<22}{e[1]}{'':<4}{e[2]}{'':<4}{e[4]}\n")
|
||||||
|
|
||||||
|
print(f"{C.CC}{'_' * 61}\n\n")
|
||||||
|
|
||||||
|
return build_dir
|
||||||
28
ApkPatcher/Utils/Credits.py
Normal file
28
ApkPatcher/Utils/Credits.py
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
from ..ANSI_COLORS import ANSI; C = ANSI()
|
||||||
|
|
||||||
|
|
||||||
|
# ---------------- Credits ----------------
|
||||||
|
def Credits():
|
||||||
|
exit(f"""
|
||||||
|
💢 Credit 💢
|
||||||
|
|
||||||
|
{C.S} Flutter SSL & TG Patch {C.E}{C.G} 🇮🇳 AbhiTheM0dder 🇮🇳 {C.S}{C.P} @AbhiTheM0dder {C.E}
|
||||||
|
|
||||||
|
{C.S} Pine Hook {C.E}{C.G} 🇮🇳 AbhiTheM0dder 🇮🇳 | 残页 {C.S}{C.P} @AbhiTheM0dder | @canyie {C.E}
|
||||||
|
|
||||||
|
{C.S} MITM {C.E}{C.G} Niklas Higi {C.S}{C.P} https://github.com/shroudedcode/apk-mitm {C.E}
|
||||||
|
|
||||||
|
{C.S} APKTool {C.E}{C.G} Connor Tumbleson {C.S}{C.P} @iBotPeaches {C.E}
|
||||||
|
|
||||||
|
{C.S} APKEditor {C.E}{C.G} REAndroid {C.S}{C.P} @kikfox {C.E}
|
||||||
|
|
||||||
|
{C.S} Uber-Apk-Signer {C.E}{C.G} Patrick Favre {C.S}{C.P} @patrickfav {C.E}
|
||||||
|
|
||||||
|
{C.S} My Channel {C.E}{C.CC} 🇮🇳 ࿗ {C.OG}T̴͢͢e̴͢͢c̴͢͢h̴͢͢n̴͢͢o̴͢͢ {C.B}☣{C.G} I̴͢͢n̴͢͢d̴͢͢i̴͢͢a̴͢͢ {C.CC}࿗ 🇮🇳 {C.S}{C.P} @rktechnoindians {C.E}
|
||||||
|
|
||||||
|
{C.S} CREATOR {C.E}{C.G} 𓄂 Ꭱꫝℑ 𓆐 ︻デ═一 ࿗ Я͓̽K͓̽ ࿗ {C.S}{C.P} @RK_TECHNO_INDIA {C.E}
|
||||||
|
|
||||||
|
|
||||||
|
{C.S} NOTE {C.E} {C.Y} Please Maintain Our Credits. 🙏🙏
|
||||||
|
|
||||||
|
""")
|
||||||
170
ApkPatcher/Utils/Decompile_Compile.py
Normal file
170
ApkPatcher/Utils/Decompile_Compile.py
Normal file
@ -0,0 +1,170 @@
|
|||||||
|
from ..ANSI_COLORS import ANSI; C = ANSI()
|
||||||
|
from ..MODULES import IMPORT; M = IMPORT()
|
||||||
|
|
||||||
|
from .Files_Check import FileCheck;
|
||||||
|
|
||||||
|
F = FileCheck(); F.Set_Path(); F.isEmulator()
|
||||||
|
|
||||||
|
C_Line = f"{C.CC}{'_' * 61}"
|
||||||
|
|
||||||
|
SUGGEST = (
|
||||||
|
f"{C_Line}\n\n"
|
||||||
|
f"\n{C.SUGGEST} Try With APKEditor, Flag {C.OG}-a"
|
||||||
|
f"\n |\n └──── {C.CC}~ Ex. {C.G}$ {C.OG}ApkPatcher {C.Y}{' '.join(M.sys.argv[1:])} {C.OG}-a\n"
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
# ---------------- Decompile APK ----------------
|
||||||
|
def Decompile_Apk(apk_path, decompile_dir, isEmulator, isAPKEditor, isAES, isPine_Hook, Package_Name):
|
||||||
|
|
||||||
|
A_P = F.APKTool_Path_E if isEmulator else F.APKTool_Path
|
||||||
|
|
||||||
|
AA = f"{'APKEditor' if isAPKEditor else 'APKTool'}"
|
||||||
|
|
||||||
|
print(
|
||||||
|
f"\n{C_Line}\n\n"
|
||||||
|
f"\n{C.X}{C.C} Decompile APK with {AA}..."
|
||||||
|
)
|
||||||
|
|
||||||
|
if isAPKEditor:
|
||||||
|
cmd = ["java", "-jar", F.APKEditor_Path, "d", "-i", apk_path, "-o", decompile_dir, "-f", "-no-dex-debug", "-dex-lib", "jf"]
|
||||||
|
|
||||||
|
if isPine_Hook:
|
||||||
|
cmd += ["-dex"]
|
||||||
|
|
||||||
|
print(
|
||||||
|
f"{C.G} |\n └──── {C.CC}Decompiling ~{C.G}$ java -jar {M.os.path.basename(F.APKEditor_Path)} d -i {apk_path} -o {M.os.path.basename(decompile_dir)} -f -no-dex-debug -dex-lib jf\n"
|
||||||
|
f"\n{C_Line}{C.G}\n"
|
||||||
|
)
|
||||||
|
|
||||||
|
else:
|
||||||
|
cmd = ["java", "-jar", A_P, "d", "-f", "--only-main-classes"] + (["--no-debug-info"] if isAES else []) + [apk_path, "-o", decompile_dir, "-p", decompile_dir]
|
||||||
|
|
||||||
|
if isPine_Hook:
|
||||||
|
cmd += ["-s"]
|
||||||
|
|
||||||
|
print(
|
||||||
|
f"{C.G} |\n └──── {C.CC}Decompiling ~{C.G}$ java -jar {M.os.path.basename(A_P)} d -f {apk_path} -o {M.os.path.basename(decompile_dir)}\n"
|
||||||
|
f"\n{C_Line}{C.G}\n"
|
||||||
|
)
|
||||||
|
|
||||||
|
try:
|
||||||
|
M.subprocess.run(cmd, check=True)
|
||||||
|
|
||||||
|
print(
|
||||||
|
f"\n{C.X}{C.C} Decompile Successful {C.G} ✔\n"
|
||||||
|
f"\n{C_Line}\n\n"
|
||||||
|
)
|
||||||
|
|
||||||
|
except M.subprocess.CalledProcessError:
|
||||||
|
M.shutil.rmtree(decompile_dir)
|
||||||
|
|
||||||
|
print(f"\n{C.ERROR} Decompile {Package_Name}.apk Failed with {AA} ✘\n")
|
||||||
|
|
||||||
|
if not isAPKEditor:
|
||||||
|
print(SUGGEST)
|
||||||
|
|
||||||
|
exit(1)
|
||||||
|
|
||||||
|
|
||||||
|
# ---------------- Recompile APK ----------------
|
||||||
|
def Recompile_Apk(decompile_dir, apk_path, build_dir, isEmulator, isAPKEditor, Package_Name):
|
||||||
|
|
||||||
|
A_P = F.APKTool_Path_E if isEmulator else F.APKTool_Path
|
||||||
|
|
||||||
|
AA = f"{'APKEditor' if isAPKEditor else 'APKTool'}"
|
||||||
|
|
||||||
|
print(
|
||||||
|
f"{C_Line}\n\n"
|
||||||
|
f"\n{C.X}{C.C} Recompile APK with {AA}..."
|
||||||
|
)
|
||||||
|
|
||||||
|
if isAPKEditor:
|
||||||
|
cmd = ["java", "-jar", F.APKEditor_Path, "b", "-i", decompile_dir, "-o", build_dir, "-f", "-dex-lib", "jf"]
|
||||||
|
|
||||||
|
print(
|
||||||
|
f"{C.G} |\n └──── {C.CC}Recompiling ~{C.G}$ java -jar {M.os.path.basename(F.APKEditor_Path)} b -i {M.os.path.basename(decompile_dir)} -o {M.os.path.basename(build_dir)} -f -dex-lib jf\n"
|
||||||
|
f"\n{C_Line}{C.G}\n"
|
||||||
|
)
|
||||||
|
|
||||||
|
else:
|
||||||
|
cmd = ["java", "-jar", A_P, "b", "-f", decompile_dir, "-o", build_dir, "-p", decompile_dir]
|
||||||
|
|
||||||
|
print(
|
||||||
|
f"{C.G} |\n └──── {C.CC}Recompiling ~{C.G}$ java -jar {M.os.path.basename(A_P)} b -f {M.os.path.basename(decompile_dir)} -o {M.os.path.basename(build_dir)}\n"
|
||||||
|
f"\n{C_Line}{C.G}\n"
|
||||||
|
)
|
||||||
|
|
||||||
|
try:
|
||||||
|
M.subprocess.run(cmd, check=True)
|
||||||
|
|
||||||
|
print(
|
||||||
|
f"\n{C.X}{C.C} Recompile Successful {C.G} ✔\n"
|
||||||
|
f"\n{C_Line}\n"
|
||||||
|
)
|
||||||
|
|
||||||
|
except M.subprocess.CalledProcessError:
|
||||||
|
M.shutil.rmtree(decompile_dir)
|
||||||
|
|
||||||
|
print(f"\n{C.ERROR} Recompile {Package_Name}.apk Failed with {AA}... ✘\n")
|
||||||
|
|
||||||
|
if not isAPKEditor:
|
||||||
|
print(SUGGEST)
|
||||||
|
|
||||||
|
exit(1)
|
||||||
|
|
||||||
|
if M.os.path.exists(build_dir):
|
||||||
|
print(
|
||||||
|
f"\n{C.S} APK Created {C.E} {C.OG}➸❥ {C.Y}{build_dir} {C.G} ✔\n"
|
||||||
|
f"\n{C_Line}\n"
|
||||||
|
)
|
||||||
|
|
||||||
|
M.shutil.rmtree(decompile_dir)
|
||||||
|
|
||||||
|
|
||||||
|
# ---------------- FixSigBlock ----------------
|
||||||
|
def FixSigBlock(decompile_dir, apk_path, build_dir, rebuild_dir):
|
||||||
|
|
||||||
|
M.os.rename(build_dir, rebuild_dir)
|
||||||
|
|
||||||
|
sig_dir = decompile_dir.replace('_decompiled', '_SigBlock')
|
||||||
|
|
||||||
|
for operation in ["d", "b"]:
|
||||||
|
cmd = ["java", "-jar", F.APKEditor_Path, operation, "-t", "sig", "-i", (apk_path if operation == "d" else rebuild_dir), "-f", "-sig", sig_dir]
|
||||||
|
|
||||||
|
if operation == "b":
|
||||||
|
cmd.extend(["-o", build_dir])
|
||||||
|
|
||||||
|
M.subprocess.run(cmd, check=True, text=True, capture_output=True)
|
||||||
|
|
||||||
|
M.shutil.rmtree(sig_dir)
|
||||||
|
|
||||||
|
M.os.remove(rebuild_dir)
|
||||||
|
|
||||||
|
|
||||||
|
# ---------------- Sign APK ----------------
|
||||||
|
def Sign_APK(build_dir):
|
||||||
|
|
||||||
|
cmd = ["java", "-jar", F.Sign_Jar, "-a", build_dir, "--overwrite"]
|
||||||
|
|
||||||
|
print(f"\n{C.X}{C.C} Signing APK...")
|
||||||
|
|
||||||
|
print(
|
||||||
|
f"{C.G} |\n └──── {C.CC}Signing ~{C.G}$ java -jar {M.os.path.basename(F.Sign_Jar)} --overwrite -a {build_dir}\n"
|
||||||
|
f"\n{C_Line}{C.G}\n"
|
||||||
|
)
|
||||||
|
|
||||||
|
try:
|
||||||
|
M.subprocess.run(cmd, check=True)
|
||||||
|
|
||||||
|
print(f"\n{C.X}{C.C} Sign Successful {C.G} ✔\n")
|
||||||
|
|
||||||
|
idsig_file = build_dir + ".idsig"
|
||||||
|
|
||||||
|
if M.os.path.exists(idsig_file):
|
||||||
|
M.os.remove(idsig_file)
|
||||||
|
|
||||||
|
print(f'{C_Line}\n\n')
|
||||||
|
|
||||||
|
except M.subprocess.CalledProcessError:
|
||||||
|
exit(f"\n{C.ERROR} Sign Failed ! ✘\n")
|
||||||
436
ApkPatcher/Utils/Files/AES.smali
Normal file
436
ApkPatcher/Utils/Files/AES.smali
Normal file
@ -0,0 +1,436 @@
|
|||||||
|
.class public LRK_TECHNO_INDIA/AES;
|
||||||
|
.super Ljava/lang/Thread;
|
||||||
|
# static fields
|
||||||
|
.field private static final PARAMETER_BUFFER:Ljava/lang/ThreadLocal;
|
||||||
|
.field private static final QUEUE:Ljava/util/concurrent/LinkedBlockingQueue;
|
||||||
|
.field private static final TIME_FORMAT1:Ljava/text/SimpleDateFormat;
|
||||||
|
.field private static final TIME_FORMAT2:Ljava/text/SimpleDateFormat;
|
||||||
|
# direct methods
|
||||||
|
.method static constructor <clinit>()V
|
||||||
|
.registers 2
|
||||||
|
new-instance v0, Ljava/text/SimpleDateFormat;
|
||||||
|
const-string v1, "HH:mm:ss.SSS"
|
||||||
|
invoke-direct {v0, v1}, Ljava/text/SimpleDateFormat;-><init>(Ljava/lang/String;)V
|
||||||
|
sput-object v0, LRK_TECHNO_INDIA/AES;->TIME_FORMAT1:Ljava/text/SimpleDateFormat;
|
||||||
|
new-instance v0, Ljava/text/SimpleDateFormat;
|
||||||
|
const-string v1, "yyyyMMddHHmmssSSS"
|
||||||
|
invoke-direct {v0, v1}, Ljava/text/SimpleDateFormat;-><init>(Ljava/lang/String;)V
|
||||||
|
sput-object v0, LRK_TECHNO_INDIA/AES;->TIME_FORMAT2:Ljava/text/SimpleDateFormat;
|
||||||
|
new-instance v0, Ljava/util/concurrent/LinkedBlockingQueue;
|
||||||
|
invoke-direct {v0}, Ljava/util/concurrent/LinkedBlockingQueue;-><init>()V
|
||||||
|
sput-object v0, LRK_TECHNO_INDIA/AES;->QUEUE:Ljava/util/concurrent/LinkedBlockingQueue;
|
||||||
|
new-instance v0, Ljava/lang/ThreadLocal;
|
||||||
|
invoke-direct {v0}, Ljava/lang/ThreadLocal;-><init>()V
|
||||||
|
sput-object v0, LRK_TECHNO_INDIA/AES;->PARAMETER_BUFFER:Ljava/lang/ThreadLocal;
|
||||||
|
new-instance v0, LRK_TECHNO_INDIA/AES;
|
||||||
|
invoke-direct {v0}, LRK_TECHNO_INDIA/AES;-><init>()V
|
||||||
|
const/4 v1, 0x1
|
||||||
|
invoke-virtual {v0, v1}, LRK_TECHNO_INDIA/AES;->setDaemon(Z)V
|
||||||
|
invoke-virtual {v0}, LRK_TECHNO_INDIA/AES;->start()V
|
||||||
|
return-void
|
||||||
|
.end method
|
||||||
|
.method public constructor <init>()V
|
||||||
|
.registers 1
|
||||||
|
invoke-direct {p0}, Ljava/lang/Thread;-><init>()V
|
||||||
|
return-void
|
||||||
|
.end method
|
||||||
|
.method public static a(Ljava/lang/Object;)V
|
||||||
|
.registers 2
|
||||||
|
invoke-static {p0}, LRK_TECHNO_INDIA/AES;->y(Ljava/lang/Object;)Ljava/lang/String;
|
||||||
|
move-result-object v0
|
||||||
|
invoke-static {v0}, LRK_TECHNO_INDIA/AES;->z(Ljava/lang/String;)V
|
||||||
|
return-void
|
||||||
|
.end method
|
||||||
|
.method public static b()V
|
||||||
|
.registers 2
|
||||||
|
sget-object v0, LRK_TECHNO_INDIA/AES;->PARAMETER_BUFFER:Ljava/lang/ThreadLocal;
|
||||||
|
invoke-virtual {v0}, Ljava/lang/ThreadLocal;->get()Ljava/lang/Object;
|
||||||
|
move-result-object v1
|
||||||
|
check-cast v1, Ljava/lang/StringBuilder;
|
||||||
|
invoke-virtual {v1}, Ljava/lang/StringBuilder;->toString()Ljava/lang/String;
|
||||||
|
move-result-object v1
|
||||||
|
invoke-static {v1}, LRK_TECHNO_INDIA/AES;->z(Ljava/lang/String;)V
|
||||||
|
invoke-virtual {v0}, Ljava/lang/ThreadLocal;->remove()V
|
||||||
|
return-void
|
||||||
|
.end method
|
||||||
|
.method public static b1(Ljava/lang/Object;)V
|
||||||
|
.registers 3
|
||||||
|
new-instance v0, Ljava/lang/StringBuilder;
|
||||||
|
invoke-direct {v0}, Ljava/lang/StringBuilder;-><init>()V
|
||||||
|
const-string v1, "𝐃𝐚𝐭𝐚 ︻デ═一 "
|
||||||
|
invoke-virtual {v0, v1}, Ljava/lang/StringBuilder;->append(Ljava/lang/String;)Ljava/lang/StringBuilder;
|
||||||
|
invoke-static {p0}, LRK_TECHNO_INDIA/AES;->y(Ljava/lang/Object;)Ljava/lang/String;
|
||||||
|
move-result-object v1
|
||||||
|
invoke-virtual {v0, v1}, Ljava/lang/StringBuilder;->append(Ljava/lang/String;)Ljava/lang/StringBuilder;
|
||||||
|
invoke-virtual {v0}, Ljava/lang/StringBuilder;->toString()Ljava/lang/String;
|
||||||
|
move-result-object v0
|
||||||
|
invoke-static {v0}, LRK_TECHNO_INDIA/AES;->x(Ljava/lang/String;)V
|
||||||
|
return-void
|
||||||
|
.end method
|
||||||
|
.method public static b2(Ljava/lang/Object;)V
|
||||||
|
.registers 3
|
||||||
|
new-instance v0, Ljava/lang/StringBuilder;
|
||||||
|
invoke-direct {v0}, Ljava/lang/StringBuilder;-><init>()V
|
||||||
|
const-string v1, "𝐃𝐚𝐭𝐚/𝐊𝐞𝐲 ︻デ═一 "
|
||||||
|
invoke-virtual {v0, v1}, Ljava/lang/StringBuilder;->append(Ljava/lang/String;)Ljava/lang/StringBuilder;
|
||||||
|
invoke-static {p0}, LRK_TECHNO_INDIA/AES;->y(Ljava/lang/Object;)Ljava/lang/String;
|
||||||
|
move-result-object v1
|
||||||
|
invoke-virtual {v0, v1}, Ljava/lang/StringBuilder;->append(Ljava/lang/String;)Ljava/lang/StringBuilder;
|
||||||
|
invoke-virtual {v0}, Ljava/lang/StringBuilder;->toString()Ljava/lang/String;
|
||||||
|
move-result-object v0
|
||||||
|
invoke-static {v0}, LRK_TECHNO_INDIA/AES;->x(Ljava/lang/String;)V
|
||||||
|
return-void
|
||||||
|
.end method
|
||||||
|
.method public static b3(Ljava/lang/Object;)V
|
||||||
|
.registers 3
|
||||||
|
new-instance v0, Ljava/lang/StringBuilder;
|
||||||
|
invoke-direct {v0}, Ljava/lang/StringBuilder;-><init>()V
|
||||||
|
const-string v1, "𝐈𝐕/𝐊𝐞𝐲 ︻デ═一 "
|
||||||
|
invoke-virtual {v0, v1}, Ljava/lang/StringBuilder;->append(Ljava/lang/String;)Ljava/lang/StringBuilder;
|
||||||
|
invoke-static {p0}, LRK_TECHNO_INDIA/AES;->y(Ljava/lang/Object;)Ljava/lang/String;
|
||||||
|
move-result-object v1
|
||||||
|
invoke-virtual {v0, v1}, Ljava/lang/StringBuilder;->append(Ljava/lang/String;)Ljava/lang/StringBuilder;
|
||||||
|
invoke-virtual {v0}, Ljava/lang/StringBuilder;->toString()Ljava/lang/String;
|
||||||
|
move-result-object v0
|
||||||
|
invoke-static {v0}, LRK_TECHNO_INDIA/AES;->x(Ljava/lang/String;)V
|
||||||
|
return-void
|
||||||
|
.end method
|
||||||
|
.method public static b4(Ljava/lang/Object;)V
|
||||||
|
.registers 3
|
||||||
|
new-instance v0, Ljava/lang/StringBuilder;
|
||||||
|
invoke-direct {v0}, Ljava/lang/StringBuilder;-><init>()V
|
||||||
|
const-string v1, "𝐏𝐚𝐫𝐚𝐦𝐞𝐭𝐞𝐫 4 ︻デ═一 "
|
||||||
|
invoke-virtual {v0, v1}, Ljava/lang/StringBuilder;->append(Ljava/lang/String;)Ljava/lang/StringBuilder;
|
||||||
|
invoke-static {p0}, LRK_TECHNO_INDIA/AES;->y(Ljava/lang/Object;)Ljava/lang/String;
|
||||||
|
move-result-object v1
|
||||||
|
invoke-virtual {v0, v1}, Ljava/lang/StringBuilder;->append(Ljava/lang/String;)Ljava/lang/StringBuilder;
|
||||||
|
invoke-virtual {v0}, Ljava/lang/StringBuilder;->toString()Ljava/lang/String;
|
||||||
|
move-result-object v0
|
||||||
|
invoke-static {v0}, LRK_TECHNO_INDIA/AES;->x(Ljava/lang/String;)V
|
||||||
|
return-void
|
||||||
|
.end method
|
||||||
|
.method public static b5(Ljava/lang/Object;)V
|
||||||
|
.registers 3
|
||||||
|
new-instance v0, Ljava/lang/StringBuilder;
|
||||||
|
invoke-direct {v0}, Ljava/lang/StringBuilder;-><init>()V
|
||||||
|
const-string v1, "𝐏𝐚𝐫𝐚𝐦𝐞𝐭𝐞𝐫 5 ︻デ═一 "
|
||||||
|
invoke-virtual {v0, v1}, Ljava/lang/StringBuilder;->append(Ljava/lang/String;)Ljava/lang/StringBuilder;
|
||||||
|
invoke-static {p0}, LRK_TECHNO_INDIA/AES;->y(Ljava/lang/Object;)Ljava/lang/String;
|
||||||
|
move-result-object v1
|
||||||
|
invoke-virtual {v0, v1}, Ljava/lang/StringBuilder;->append(Ljava/lang/String;)Ljava/lang/StringBuilder;
|
||||||
|
invoke-virtual {v0}, Ljava/lang/StringBuilder;->toString()Ljava/lang/String;
|
||||||
|
move-result-object v0
|
||||||
|
invoke-static {v0}, LRK_TECHNO_INDIA/AES;->x(Ljava/lang/String;)V
|
||||||
|
return-void
|
||||||
|
.end method
|
||||||
|
.method public static b6(Ljava/lang/Object;)V
|
||||||
|
.registers 3
|
||||||
|
new-instance v0, Ljava/lang/StringBuilder;
|
||||||
|
invoke-direct {v0}, Ljava/lang/StringBuilder;-><init>()V
|
||||||
|
const-string v1, "𝐏𝐚𝐫𝐚𝐦𝐞𝐭𝐞𝐫 6 ︻デ═一 "
|
||||||
|
invoke-virtual {v0, v1}, Ljava/lang/StringBuilder;->append(Ljava/lang/String;)Ljava/lang/StringBuilder;
|
||||||
|
invoke-static {p0}, LRK_TECHNO_INDIA/AES;->y(Ljava/lang/Object;)Ljava/lang/String;
|
||||||
|
move-result-object v1
|
||||||
|
invoke-virtual {v0, v1}, Ljava/lang/StringBuilder;->append(Ljava/lang/String;)Ljava/lang/StringBuilder;
|
||||||
|
invoke-virtual {v0}, Ljava/lang/StringBuilder;->toString()Ljava/lang/String;
|
||||||
|
move-result-object v0
|
||||||
|
invoke-static {v0}, LRK_TECHNO_INDIA/AES;->x(Ljava/lang/String;)V
|
||||||
|
return-void
|
||||||
|
.end method
|
||||||
|
.method public static getInstance(Ljava/lang/Object;)V
|
||||||
|
.registers 3
|
||||||
|
new-instance v0, Ljava/lang/StringBuilder;
|
||||||
|
invoke-direct {v0}, Ljava/lang/StringBuilder;-><init>()V
|
||||||
|
const-string v1, "\ud835\ude3e\ud835\ude5e\ud835\ude65\ud835\ude5d\ud835\ude5a\ud835\ude67 \ud835\ude3c\ud835\ude61\ud835\ude5c\ud835\ude64\ud835\ude67\ud835\ude5e\ud835\ude69\ud835\ude5d\ud835\ude62 ︻デ═一 "
|
||||||
|
invoke-virtual {v0, v1}, Ljava/lang/StringBuilder;->append(Ljava/lang/String;)Ljava/lang/StringBuilder;
|
||||||
|
invoke-static {p0}, LRK_TECHNO_INDIA/AES;->y(Ljava/lang/Object;)Ljava/lang/String;
|
||||||
|
move-result-object v1
|
||||||
|
invoke-virtual {v0, v1}, Ljava/lang/StringBuilder;->append(Ljava/lang/String;)Ljava/lang/StringBuilder;
|
||||||
|
invoke-virtual {v0}, Ljava/lang/StringBuilder;->toString()Ljava/lang/String;
|
||||||
|
move-result-object v0
|
||||||
|
invoke-static {v0}, LRK_TECHNO_INDIA/AES;->x(Ljava/lang/String;)V
|
||||||
|
return-void
|
||||||
|
.end method
|
||||||
|
.method private static x(Ljava/lang/String;)V
|
||||||
|
.registers 4
|
||||||
|
sget-object v0, LRK_TECHNO_INDIA/AES;->PARAMETER_BUFFER:Ljava/lang/ThreadLocal;
|
||||||
|
invoke-virtual {v0}, Ljava/lang/ThreadLocal;->get()Ljava/lang/Object;
|
||||||
|
move-result-object v1
|
||||||
|
check-cast v1, Ljava/lang/StringBuilder;
|
||||||
|
if-nez v1, :cond_13
|
||||||
|
new-instance v2, Ljava/lang/StringBuilder;
|
||||||
|
invoke-direct {v2}, Ljava/lang/StringBuilder;-><init>()V
|
||||||
|
move-object v1, v2
|
||||||
|
invoke-virtual {v0, v1}, Ljava/lang/ThreadLocal;->set(Ljava/lang/Object;)V
|
||||||
|
:cond_13
|
||||||
|
invoke-virtual {v1}, Ljava/lang/StringBuilder;->length()I
|
||||||
|
move-result v0
|
||||||
|
if-lez v0, :cond_1e
|
||||||
|
const/16 v0, 0xa
|
||||||
|
invoke-virtual {v1, v0}, Ljava/lang/StringBuilder;->append(C)Ljava/lang/StringBuilder;
|
||||||
|
:cond_1e
|
||||||
|
invoke-virtual {v1, p0}, Ljava/lang/StringBuilder;->append(Ljava/lang/String;)Ljava/lang/StringBuilder;
|
||||||
|
return-void
|
||||||
|
.end method
|
||||||
|
|
||||||
|
.method private static y(Ljava/lang/Object;)Ljava/lang/String;
|
||||||
|
.registers 3
|
||||||
|
if-nez p0, :cond_5
|
||||||
|
const-string v0, "null"
|
||||||
|
return-object v0
|
||||||
|
:cond_5
|
||||||
|
invoke-virtual {p0}, Ljava/lang/Object;->getClass()Ljava/lang/Class;
|
||||||
|
move-result-object v0
|
||||||
|
invoke-virtual {v0}, Ljava/lang/Class;->isArray()Z
|
||||||
|
move-result v1
|
||||||
|
if-eqz v1, :cond_77
|
||||||
|
const-class v1, [B
|
||||||
|
if-ne v0, v1, :cond_1b
|
||||||
|
move-object v1, p0
|
||||||
|
check-cast v1, [B
|
||||||
|
invoke-static {v1}, Ljava/util/Arrays;->toString([B)Ljava/lang/String;
|
||||||
|
move-result-object v1
|
||||||
|
return-object v1
|
||||||
|
:cond_1b
|
||||||
|
const-class v1, [S
|
||||||
|
if-ne v0, v1, :cond_27
|
||||||
|
move-object v1, p0
|
||||||
|
check-cast v1, [S
|
||||||
|
invoke-static {v1}, Ljava/util/Arrays;->toString([S)Ljava/lang/String;
|
||||||
|
move-result-object v1
|
||||||
|
return-object v1
|
||||||
|
:cond_27
|
||||||
|
const-class v1, [I
|
||||||
|
if-ne v0, v1, :cond_33
|
||||||
|
move-object v1, p0
|
||||||
|
check-cast v1, [I
|
||||||
|
invoke-static {v1}, Ljava/util/Arrays;->toString([I)Ljava/lang/String;
|
||||||
|
move-result-object v1
|
||||||
|
return-object v1
|
||||||
|
:cond_33
|
||||||
|
const-class v1, [J
|
||||||
|
if-ne v0, v1, :cond_3f
|
||||||
|
move-object v1, p0
|
||||||
|
check-cast v1, [J
|
||||||
|
invoke-static {v1}, Ljava/util/Arrays;->toString([J)Ljava/lang/String;
|
||||||
|
move-result-object v1
|
||||||
|
return-object v1
|
||||||
|
:cond_3f
|
||||||
|
const-class v1, [C
|
||||||
|
if-ne v0, v1, :cond_4b
|
||||||
|
move-object v1, p0
|
||||||
|
check-cast v1, [C
|
||||||
|
invoke-static {v1}, Ljava/util/Arrays;->toString([C)Ljava/lang/String;
|
||||||
|
move-result-object v1
|
||||||
|
return-object v1
|
||||||
|
:cond_4b
|
||||||
|
const-class v1, [F
|
||||||
|
if-ne v0, v1, :cond_57
|
||||||
|
move-object v1, p0
|
||||||
|
check-cast v1, [F
|
||||||
|
invoke-static {v1}, Ljava/util/Arrays;->toString([F)Ljava/lang/String;
|
||||||
|
move-result-object v1
|
||||||
|
return-object v1
|
||||||
|
:cond_57
|
||||||
|
const-class v1, [D
|
||||||
|
if-ne v0, v1, :cond_63
|
||||||
|
move-object v1, p0
|
||||||
|
check-cast v1, [D
|
||||||
|
invoke-static {v1}, Ljava/util/Arrays;->toString([D)Ljava/lang/String;
|
||||||
|
move-result-object v1
|
||||||
|
return-object v1
|
||||||
|
:cond_63
|
||||||
|
const-class v1, [Z
|
||||||
|
if-ne v0, v1, :cond_6f
|
||||||
|
move-object v1, p0
|
||||||
|
check-cast v1, [Z
|
||||||
|
invoke-static {v1}, Ljava/util/Arrays;->toString([Z)Ljava/lang/String;
|
||||||
|
move-result-object v1
|
||||||
|
return-object v1
|
||||||
|
:cond_6f
|
||||||
|
move-object v1, p0
|
||||||
|
check-cast v1, [Ljava/lang/Object;
|
||||||
|
invoke-static {v1}, Ljava/util/Arrays;->deepToString([Ljava/lang/Object;)Ljava/lang/String;
|
||||||
|
move-result-object v1
|
||||||
|
return-object v1
|
||||||
|
:cond_77
|
||||||
|
invoke-virtual {p0}, Ljava/lang/Object;->toString()Ljava/lang/String;
|
||||||
|
move-result-object v1
|
||||||
|
return-object v1
|
||||||
|
.end method
|
||||||
|
.method private static z(Ljava/lang/String;)V
|
||||||
|
.registers 8
|
||||||
|
const-string v0, "================== \ud83c\uddee\ud83c\uddf3 \ud835\ude3f\ud835\ude5a\ud835\ude58\ud835\ude67\ud835\ude6e\ud835\ude65\ud835\ude69\ud835\ude5a\ud835\ude59 \ud835\ude3d\ud835\ude6e \ud835\ude4f\ud835\ude5a\ud835\ude58\ud835\ude5d\ud835\ude63\ud835\ude64 \ud835\ude44\ud835\ude63\ud835\ude59\ud835\ude5e\ud835\ude56 \ud83c\uddee\ud83c\uddf3 ==================\n\n[RESULT]\n\n"
|
||||||
|
const-string v1, "[TIME]"
|
||||||
|
invoke-virtual {v0, v1}, Ljava/lang/String;->contains(Ljava/lang/CharSequence;)Z
|
||||||
|
move-result v2
|
||||||
|
if-eqz v2, :cond_1c
|
||||||
|
sget-object v2, LRK_TECHNO_INDIA/AES;->TIME_FORMAT1:Ljava/text/SimpleDateFormat;
|
||||||
|
invoke-static {}, Ljava/lang/System;->currentTimeMillis()J
|
||||||
|
move-result-wide v3
|
||||||
|
invoke-static {v3, v4}, Ljava/lang/Long;->valueOf(J)Ljava/lang/Long;
|
||||||
|
move-result-object v3
|
||||||
|
invoke-virtual {v2, v3}, Ljava/text/SimpleDateFormat;->format(Ljava/lang/Object;)Ljava/lang/String;
|
||||||
|
move-result-object v2
|
||||||
|
invoke-virtual {v0, v1, v2}, Ljava/lang/String;->replace(Ljava/lang/CharSequence;Ljava/lang/CharSequence;)Ljava/lang/String;
|
||||||
|
move-result-object v0
|
||||||
|
:cond_1c
|
||||||
|
new-instance v1, Ljava/lang/Throwable;
|
||||||
|
invoke-direct {v1}, Ljava/lang/Throwable;-><init>()V
|
||||||
|
invoke-virtual {v1}, Ljava/lang/Throwable;->getStackTrace()[Ljava/lang/StackTraceElement;
|
||||||
|
move-result-object v1
|
||||||
|
const/4 v2, 0x2
|
||||||
|
aget-object v1, v1, v2
|
||||||
|
invoke-virtual {v1}, Ljava/lang/StackTraceElement;->getFileName()Ljava/lang/String;
|
||||||
|
move-result-object v2
|
||||||
|
if-nez v2, :cond_30
|
||||||
|
const-string v2, "Unknown Source"
|
||||||
|
:cond_30
|
||||||
|
invoke-virtual {v1}, Ljava/lang/StackTraceElement;->getLineNumber()I
|
||||||
|
move-result v3
|
||||||
|
if-ltz v3, :cond_4a
|
||||||
|
new-instance v4, Ljava/lang/StringBuilder;
|
||||||
|
invoke-direct {v4}, Ljava/lang/StringBuilder;-><init>()V
|
||||||
|
invoke-virtual {v4, v2}, Ljava/lang/StringBuilder;->append(Ljava/lang/String;)Ljava/lang/StringBuilder;
|
||||||
|
const-string v5, ":"
|
||||||
|
invoke-virtual {v4, v5}, Ljava/lang/StringBuilder;->append(Ljava/lang/String;)Ljava/lang/StringBuilder;
|
||||||
|
invoke-virtual {v4, v3}, Ljava/lang/StringBuilder;->append(I)Ljava/lang/StringBuilder;
|
||||||
|
invoke-virtual {v4}, Ljava/lang/StringBuilder;->toString()Ljava/lang/String;
|
||||||
|
move-result-object v2
|
||||||
|
:cond_4a
|
||||||
|
const-string v4, "[RESULT]"
|
||||||
|
invoke-virtual {v0, v4, p0}, Ljava/lang/String;->replace(Ljava/lang/CharSequence;Ljava/lang/CharSequence;)Ljava/lang/String;
|
||||||
|
move-result-object v4
|
||||||
|
invoke-virtual {v1}, Ljava/lang/StackTraceElement;->getClassName()Ljava/lang/String;
|
||||||
|
move-result-object v5
|
||||||
|
const-string v6, "[CLASS]"
|
||||||
|
invoke-virtual {v4, v6, v5}, Ljava/lang/String;->replace(Ljava/lang/CharSequence;Ljava/lang/CharSequence;)Ljava/lang/String;
|
||||||
|
move-result-object v4
|
||||||
|
invoke-virtual {v1}, Ljava/lang/StackTraceElement;->getMethodName()Ljava/lang/String;
|
||||||
|
move-result-object v5
|
||||||
|
const-string v6, "[METHOD]"
|
||||||
|
invoke-virtual {v4, v6, v5}, Ljava/lang/String;->replace(Ljava/lang/CharSequence;Ljava/lang/CharSequence;)Ljava/lang/String;
|
||||||
|
move-result-object v4
|
||||||
|
const-string v5, "[LOCATION]"
|
||||||
|
invoke-virtual {v4, v5, v2}, Ljava/lang/String;->replace(Ljava/lang/CharSequence;Ljava/lang/CharSequence;)Ljava/lang/String;
|
||||||
|
move-result-object v0
|
||||||
|
sget-object v4, LRK_TECHNO_INDIA/AES;->QUEUE:Ljava/util/concurrent/LinkedBlockingQueue;
|
||||||
|
invoke-virtual {v4, v0}, Ljava/util/concurrent/LinkedBlockingQueue;->offer(Ljava/lang/Object;)Z
|
||||||
|
return-void
|
||||||
|
.end method
|
||||||
|
# virtual methods
|
||||||
|
.method public run()V
|
||||||
|
.registers 10
|
||||||
|
const/4 v0, 0x0
|
||||||
|
const-string v1, "[SDCARD]/MT2/logs/[PACKAGE]-[TIME].json"
|
||||||
|
invoke-static {}, Landroid/os/Environment;->getExternalStorageDirectory()Ljava/io/File;
|
||||||
|
move-result-object v2
|
||||||
|
invoke-virtual {v2}, Ljava/io/File;->getPath()Ljava/lang/String;
|
||||||
|
move-result-object v2
|
||||||
|
const-string v3, "[SDCARD]"
|
||||||
|
invoke-virtual {v1, v3, v2}, Ljava/lang/String;->replace(Ljava/lang/CharSequence;Ljava/lang/CharSequence;)Ljava/lang/String;
|
||||||
|
move-result-object v1
|
||||||
|
const-string v2, "[PACKAGE]"
|
||||||
|
const-string v3, "PACKAGENAME"
|
||||||
|
invoke-virtual {v1, v2, v3}, Ljava/lang/String;->replace(Ljava/lang/CharSequence;Ljava/lang/CharSequence;)Ljava/lang/String;
|
||||||
|
move-result-object v1
|
||||||
|
sget-object v2, LRK_TECHNO_INDIA/AES;->TIME_FORMAT2:Ljava/text/SimpleDateFormat;
|
||||||
|
invoke-static {}, Ljava/lang/System;->currentTimeMillis()J
|
||||||
|
move-result-wide v3
|
||||||
|
invoke-static {v3, v4}, Ljava/lang/Long;->valueOf(J)Ljava/lang/Long;
|
||||||
|
move-result-object v3
|
||||||
|
invoke-virtual {v2, v3}, Ljava/text/SimpleDateFormat;->format(Ljava/lang/Object;)Ljava/lang/String;
|
||||||
|
move-result-object v2
|
||||||
|
const-string v3, "[TIME]"
|
||||||
|
invoke-virtual {v1, v3, v2}, Ljava/lang/String;->replace(Ljava/lang/CharSequence;Ljava/lang/CharSequence;)Ljava/lang/String;
|
||||||
|
move-result-object v1
|
||||||
|
const/16 v2, 0x5c
|
||||||
|
const/16 v3, 0x2f
|
||||||
|
invoke-virtual {v1, v2, v3}, Ljava/lang/String;->replace(CC)Ljava/lang/String;
|
||||||
|
move-result-object v2
|
||||||
|
const-string v3, "//"
|
||||||
|
const-string v4, "/"
|
||||||
|
invoke-virtual {v2, v3, v4}, Ljava/lang/String;->replace(Ljava/lang/CharSequence;Ljava/lang/CharSequence;)Ljava/lang/String;
|
||||||
|
move-result-object v1
|
||||||
|
const/4 v2, 0x0
|
||||||
|
:try_start_3e
|
||||||
|
new-instance v3, Ljava/io/File;
|
||||||
|
invoke-direct {v3, v1}, Ljava/io/File;-><init>(Ljava/lang/String;)V
|
||||||
|
invoke-virtual {v3}, Ljava/io/File;->getParentFile()Ljava/io/File;
|
||||||
|
move-result-object v4
|
||||||
|
if-eqz v4, :cond_4c
|
||||||
|
invoke-virtual {v4}, Ljava/io/File;->mkdirs()Z
|
||||||
|
:cond_4c
|
||||||
|
new-instance v5, Ljava/io/FileOutputStream;
|
||||||
|
const/4 v6, 0x1
|
||||||
|
invoke-direct {v5, v3, v6}, Ljava/io/FileOutputStream;-><init>(Ljava/io/File;Z)V
|
||||||
|
:try_end_52
|
||||||
|
.catch Ljava/io/IOException; {:try_start_3e .. :try_end_52} :catch_54
|
||||||
|
move-object v0, v5
|
||||||
|
goto :goto_59
|
||||||
|
:catch_54
|
||||||
|
move-exception v3
|
||||||
|
invoke-virtual {v3}, Ljava/io/IOException;->printStackTrace()V
|
||||||
|
move-object v2, v3
|
||||||
|
:goto_59
|
||||||
|
if-nez v0, :cond_9a
|
||||||
|
:try_start_5b
|
||||||
|
new-instance v3, Ljava/io/File;
|
||||||
|
const-string v4, "/data/data/PACKAGENAME/logs"
|
||||||
|
invoke-direct {v3, v4}, Ljava/io/File;-><init>(Ljava/lang/String;)V
|
||||||
|
new-instance v4, Ljava/io/File;
|
||||||
|
new-instance v5, Ljava/lang/StringBuilder;
|
||||||
|
invoke-direct {v5}, Ljava/lang/StringBuilder;-><init>()V
|
||||||
|
sget-object v6, LRK_TECHNO_INDIA/AES;->TIME_FORMAT2:Ljava/text/SimpleDateFormat;
|
||||||
|
invoke-static {}, Ljava/lang/System;->currentTimeMillis()J
|
||||||
|
move-result-wide v7
|
||||||
|
invoke-static {v7, v8}, Ljava/lang/Long;->valueOf(J)Ljava/lang/Long;
|
||||||
|
move-result-object v7
|
||||||
|
invoke-virtual {v6, v7}, Ljava/text/SimpleDateFormat;->format(Ljava/lang/Object;)Ljava/lang/String;
|
||||||
|
move-result-object v6
|
||||||
|
invoke-virtual {v5, v6}, Ljava/lang/StringBuilder;->append(Ljava/lang/String;)Ljava/lang/StringBuilder;
|
||||||
|
const-string v6, ".log"
|
||||||
|
invoke-virtual {v5, v6}, Ljava/lang/StringBuilder;->append(Ljava/lang/String;)Ljava/lang/StringBuilder;
|
||||||
|
invoke-virtual {v5}, Ljava/lang/StringBuilder;->toString()Ljava/lang/String;
|
||||||
|
move-result-object v5
|
||||||
|
invoke-direct {v4, v3, v5}, Ljava/io/File;-><init>(Ljava/io/File;Ljava/lang/String;)V
|
||||||
|
invoke-virtual {v3}, Ljava/io/File;->mkdirs()Z
|
||||||
|
new-instance v5, Ljava/io/FileOutputStream;
|
||||||
|
invoke-direct {v5, v4}, Ljava/io/FileOutputStream;-><init>(Ljava/io/File;)V
|
||||||
|
:try_end_8e
|
||||||
|
.catch Ljava/io/IOException; {:try_start_5b .. :try_end_8e} :catch_90
|
||||||
|
move-object v0, v5
|
||||||
|
goto :goto_9a
|
||||||
|
:catch_90
|
||||||
|
move-exception v3
|
||||||
|
invoke-virtual {v3}, Ljava/io/IOException;->printStackTrace()V
|
||||||
|
new-instance v4, Ljava/lang/RuntimeException;
|
||||||
|
invoke-direct {v4, v2}, Ljava/lang/RuntimeException;-><init>(Ljava/lang/Throwable;)V
|
||||||
|
throw v4
|
||||||
|
:cond_9a
|
||||||
|
:goto_9a
|
||||||
|
:try_start_9a
|
||||||
|
invoke-static {}, Ljava/nio/charset/Charset;->defaultCharset()Ljava/nio/charset/Charset;
|
||||||
|
move-result-object v3
|
||||||
|
:goto_9e
|
||||||
|
sget-object v4, LRK_TECHNO_INDIA/AES;->QUEUE:Ljava/util/concurrent/LinkedBlockingQueue;
|
||||||
|
invoke-virtual {v4}, Ljava/util/concurrent/LinkedBlockingQueue;->take()Ljava/lang/Object;
|
||||||
|
move-result-object v5
|
||||||
|
check-cast v5, Ljava/lang/String;
|
||||||
|
invoke-virtual {v5, v3}, Ljava/lang/String;->getBytes(Ljava/nio/charset/Charset;)[B
|
||||||
|
move-result-object v6
|
||||||
|
invoke-virtual {v0, v6}, Ljava/io/FileOutputStream;->write([B)V
|
||||||
|
invoke-virtual {v4}, Ljava/util/concurrent/LinkedBlockingQueue;->isEmpty()Z
|
||||||
|
move-result v4
|
||||||
|
if-eqz v4, :cond_b6
|
||||||
|
invoke-virtual {v0}, Ljava/io/FileOutputStream;->flush()V
|
||||||
|
:try_end_b6
|
||||||
|
.catch Ljava/lang/Exception; {:try_start_9a .. :try_end_b6} :catch_b7
|
||||||
|
:cond_b6
|
||||||
|
goto :goto_9e
|
||||||
|
:catch_b7
|
||||||
|
move-exception v3
|
||||||
|
new-instance v4, Ljava/lang/RuntimeException;
|
||||||
|
invoke-direct {v4, v3}, Ljava/lang/RuntimeException;-><init>(Ljava/lang/Throwable;)V
|
||||||
|
throw v4
|
||||||
|
.end method
|
||||||
75
ApkPatcher/Utils/Files/Hook.smali
Normal file
75
ApkPatcher/Utils/Files/Hook.smali
Normal file
@ -0,0 +1,75 @@
|
|||||||
|
.class public Lorg/telegram/abhi/Hook;
|
||||||
|
.super Ljava/lang/Object;
|
||||||
|
.source "SourceFile"
|
||||||
|
|
||||||
|
|
||||||
|
# static fields
|
||||||
|
.field public static candelMessages:Z
|
||||||
|
|
||||||
|
|
||||||
|
# direct methods
|
||||||
|
.method public constructor <init>()V
|
||||||
|
.registers 1
|
||||||
|
|
||||||
|
invoke-direct {p0}, Ljava/lang/Object;-><init>()V
|
||||||
|
|
||||||
|
return-void
|
||||||
|
.end method
|
||||||
|
|
||||||
|
.method public static hook()V
|
||||||
|
.registers 1
|
||||||
|
|
||||||
|
const/4 v0, 0x1
|
||||||
|
|
||||||
|
.line 17
|
||||||
|
invoke-static {v0}, Lorg/telegram/abhi/Hook;->setCanDelMessages(Z)V
|
||||||
|
|
||||||
|
return-void
|
||||||
|
.end method
|
||||||
|
|
||||||
|
.method public static setCanDelMessages(Z)V
|
||||||
|
.registers 4
|
||||||
|
|
||||||
|
sput-boolean p0, Lorg/telegram/abhi/Hook;->candelMessages:Z
|
||||||
|
|
||||||
|
sget-object v0, Lorg/telegram/messenger/ApplicationLoader;->applicationContext:Landroid/content/Context;
|
||||||
|
|
||||||
|
const-string v1, "mainconfig"
|
||||||
|
|
||||||
|
const/4 v2, 0x0
|
||||||
|
|
||||||
|
invoke-virtual {v0, v1, v2}, Landroid/content/Context;->getSharedPreferences(Ljava/lang/String;I)Landroid/content/SharedPreferences;
|
||||||
|
|
||||||
|
move-result-object v0
|
||||||
|
|
||||||
|
invoke-interface {v0}, Landroid/content/SharedPreferences;->edit()Landroid/content/SharedPreferences$Editor;
|
||||||
|
|
||||||
|
move-result-object v0
|
||||||
|
|
||||||
|
const-string v1, "candelMessages"
|
||||||
|
|
||||||
|
invoke-interface {v0, v1, p0}, Landroid/content/SharedPreferences$Editor;->putBoolean(Ljava/lang/String;Z)Landroid/content/SharedPreferences$Editor;
|
||||||
|
|
||||||
|
move-result-object v0
|
||||||
|
|
||||||
|
invoke-interface {v0}, Landroid/content/SharedPreferences$Editor;->apply()V
|
||||||
|
|
||||||
|
return-void
|
||||||
|
.end method
|
||||||
|
|
||||||
|
.method public static unhook()V
|
||||||
|
.registers 1
|
||||||
|
|
||||||
|
.line 23
|
||||||
|
sget-boolean v0, Lorg/telegram/abhi/Hook;->candelMessages:Z
|
||||||
|
|
||||||
|
if-eqz v0, :cond_8
|
||||||
|
|
||||||
|
const/4 v0, 0x0
|
||||||
|
|
||||||
|
.line 24
|
||||||
|
invoke-static {v0}, Lorg/telegram/abhi/Hook;->setCanDelMessages(Z)V
|
||||||
|
|
||||||
|
:cond_8
|
||||||
|
return-void
|
||||||
|
.end method
|
||||||
0
ApkPatcher/Utils/Files/__init__.py
Normal file
0
ApkPatcher/Utils/Files/__init__.py
Normal file
BIN
ApkPatcher/Utils/Files/lib_Pairip_CoreX.so
Normal file
BIN
ApkPatcher/Utils/Files/lib_Pairip_CoreX.so
Normal file
Binary file not shown.
196
ApkPatcher/Utils/Files_Check.py
Normal file
196
ApkPatcher/Utils/Files_Check.py
Normal file
@ -0,0 +1,196 @@
|
|||||||
|
from ..ANSI_COLORS import ANSI; C = ANSI()
|
||||||
|
from ..MODULES import IMPORT; M = IMPORT()
|
||||||
|
|
||||||
|
from importlib.metadata import version
|
||||||
|
|
||||||
|
__version__ = version("ApkPatcherX")
|
||||||
|
|
||||||
|
|
||||||
|
# ---------------- Set Path ----------------
|
||||||
|
run_dir = M.os.path.dirname(M.os.path.abspath(M.sys.argv[0]))
|
||||||
|
script_dir = M.os.path.dirname(M.os.path.abspath(__file__))
|
||||||
|
|
||||||
|
files_dir = M.os.path.join(script_dir, "Files")
|
||||||
|
pine_dir = M.os.path.join(script_dir, "Pine")
|
||||||
|
M.os.makedirs(files_dir, exist_ok=True)
|
||||||
|
M.os.makedirs(pine_dir, exist_ok=True)
|
||||||
|
|
||||||
|
|
||||||
|
class FileCheck:
|
||||||
|
# ---------------- Set Jar & Files Paths ----------------
|
||||||
|
def Set_Path(self):
|
||||||
|
|
||||||
|
# ---------------- Jar Tools ----------------
|
||||||
|
self.APKTool_Path, self.APKEditor_Path, self.Sign_Jar = (
|
||||||
|
M.os.path.join(run_dir, jar)
|
||||||
|
for jar in ("APKTool.jar", "APKEditor.jar", "Uber-Apk-Signer.jar")
|
||||||
|
)
|
||||||
|
|
||||||
|
# ---------------- HooK Files ----------------
|
||||||
|
self.AES_Smali, self.Hook_Smali, self.Pairip_CoreX = (
|
||||||
|
M.os.path.join(files_dir, files)
|
||||||
|
for files in ("AES.smali", "Hook.smali", "lib_Pairip_CoreX.so")
|
||||||
|
)
|
||||||
|
|
||||||
|
# ---------------- Pine HooK ----------------
|
||||||
|
self.config, self.libpine32, self.libpine64, self.loader = (
|
||||||
|
M.os.path.join(pine_dir, pine)
|
||||||
|
for pine in ("config.json", "libpine32", "libpine64", "loader.dex")
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def isEmulator(self):
|
||||||
|
self.APKTool_Path_E = M.os.path.join(run_dir, "APKTool_OR.jar")
|
||||||
|
|
||||||
|
|
||||||
|
# ---------------- SHA-256 CheckSum ----------------
|
||||||
|
def Calculate_CheckSum(self, file_path):
|
||||||
|
sha256_hash = M.hashlib.sha256()
|
||||||
|
try:
|
||||||
|
with open(file_path, "rb") as f:
|
||||||
|
for byte_block in iter(lambda: f.read(4096), b""):
|
||||||
|
sha256_hash.update(byte_block)
|
||||||
|
return sha256_hash.hexdigest()
|
||||||
|
except FileNotFoundError:
|
||||||
|
return None
|
||||||
|
|
||||||
|
|
||||||
|
# ---------------- Download Files ----------------
|
||||||
|
def Download_Files(self, Jar_Files):
|
||||||
|
|
||||||
|
import requests
|
||||||
|
|
||||||
|
for File_URL, File_Path, Expected_CheckSum in Jar_Files:
|
||||||
|
File_Name = M.os.path.basename(File_Path)
|
||||||
|
|
||||||
|
if M.os.path.exists(File_Path):
|
||||||
|
if self.Calculate_CheckSum(File_Path) == Expected_CheckSum:
|
||||||
|
continue
|
||||||
|
else:
|
||||||
|
print(
|
||||||
|
f"{C.ERROR} {C.C}{File_Name} {C.R}is Corrupt (Checksum Mismatch). ✘\n"
|
||||||
|
f"\n{C.INFO} Re-Downloading, Need Internet Connection.\n"
|
||||||
|
)
|
||||||
|
|
||||||
|
M.os.remove(File_Path)
|
||||||
|
|
||||||
|
try:
|
||||||
|
Version = requests.get("https://raw.githubusercontent.com/TechnoIndian/ApkPatcher/main/VERSION").text.strip()
|
||||||
|
|
||||||
|
if Version != str(__version__):
|
||||||
|
print(f"\n{C.S} Updating {C.E} {C.OG} ApkPatcher ➸❥ {C.G}{Version}...\n\n")
|
||||||
|
|
||||||
|
if M.os.name == "nt":
|
||||||
|
cmd = "pip install --force-reinstall git+https://github.com/TechnoIndian/ApkPatcher.git"
|
||||||
|
else:
|
||||||
|
cmd = "pip install --force-reinstall https://github.com/TechnoIndian/ApkPatcher/archive/refs/heads/main.zip"
|
||||||
|
|
||||||
|
M.subprocess.run(cmd, shell=isinstance(cmd, str), check=True)
|
||||||
|
|
||||||
|
print(f'\n{C.S} Downloading {C.E} {C.G}{File_Name}')
|
||||||
|
|
||||||
|
with requests.get(File_URL, stream=True) as response:
|
||||||
|
if response.status_code == 200:
|
||||||
|
total_size = int(response.headers.get('content-length', 0))
|
||||||
|
|
||||||
|
with open(File_Path, 'wb') as f:
|
||||||
|
print(f' |')
|
||||||
|
|
||||||
|
for data in response.iter_content(1024 * 64):
|
||||||
|
f.write(data)
|
||||||
|
|
||||||
|
print(f"\r {C.CC}╰┈ PS {C.OG}➸❥ {C.G}{f.tell()/(1024*1024):.2f}/{total_size/(1024*1024):.2f} MB ({f.tell()/total_size*100:.1f}%)", end='', flush=True)
|
||||||
|
|
||||||
|
print(' ✔\n')
|
||||||
|
|
||||||
|
else:
|
||||||
|
exit(
|
||||||
|
f'\n\n{C.ERROR} Failed to download {C.Y}{File_Name} {C.R}Status Code: {response.status_code} ✘\n'
|
||||||
|
f'\n{C.INFO} Restart Script...\n'
|
||||||
|
)
|
||||||
|
|
||||||
|
except requests.exceptions.RequestException:
|
||||||
|
exit(
|
||||||
|
f'\n\n{C.ERROR} Got an error while Fetching {C.Y}{File_Path}\n'
|
||||||
|
f'\n{C.ERROR} No internet Connection\n'
|
||||||
|
f'\n{C.INFO} Internet Connection is Required to Download {C.Y}{File_Name}\n'
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
# ---------------- Files Download Link ----------------
|
||||||
|
def F_D(self):
|
||||||
|
|
||||||
|
self.Download_Files(
|
||||||
|
[
|
||||||
|
(
|
||||||
|
"https://github.com/TechnoIndian/Tools/releases/download/Tools/APKEditor.jar",
|
||||||
|
self.APKEditor_Path,
|
||||||
|
"6b766e71ed5f4c7cce338e74a1ab786cc1ecc1896d9f37f9f1bf639398e5eadc"
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"https://github.com/TechnoIndian/Tools/releases/download/Tools/APKTool.jar" if M.os.name == 'nt' else "https://github.com/TechnoIndian/Tools/releases/download/Tools/APKTool_Termux.jar",
|
||||||
|
|
||||||
|
self.APKTool_Path,
|
||||||
|
|
||||||
|
"d0a81361670b17b713fea45baec3ed04b26bc8b69b30bde9a6f367c13fc25697" if M.os.name == 'nt' else "e00bcfd10d38318e0f52a4666da472cd4e5683a74a0c0d7fc82a362a59b338a9"
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"https://github.com/TechnoIndian/Tools/releases/download/Tools/Uber-Apk-Signer.jar",
|
||||||
|
self.Sign_Jar,
|
||||||
|
"e1299fd6fcf4da527dd53735b56127e8ea922a321128123b9c32d619bba1d835"
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"https://raw.githubusercontent.com/TechnoIndian/Objectlogger/refs/heads/main/Hook.smali",
|
||||||
|
self.Hook_Smali,
|
||||||
|
"c62ac39b468eeda30d0732f947ab6c118f44890a51777f7787f1b11f8f3722c4"
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"https://raw.githubusercontent.com/TechnoIndian/Objectlogger/refs/heads/main/AES.smali",
|
||||||
|
self.AES_Smali,
|
||||||
|
"09db8c8d1b08ec3a2680d2dc096db4aa8dd303e36d0e3c2357ef33226a5e5e52"
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"https://github.com/TechnoIndian/Tools/releases/download/Tools/lib_Pairip_CoreX.so",
|
||||||
|
self.Pairip_CoreX,
|
||||||
|
"22a7954092001e7c87f0cacb7e2efb1772adbf598ecf73190e88d76edf6a7d2a"
|
||||||
|
),
|
||||||
|
|
||||||
|
# ---------------- Pine HooK Source ----------------
|
||||||
|
(
|
||||||
|
"https://github.com/TechnoIndian/PineHookPlus/releases/download/v1.0/config.json",
|
||||||
|
self.config,
|
||||||
|
"da5eef2fa153068e19fca6fabfd144fbb9d7075a61e333814369bd36c51289c1"
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"https://github.com/TechnoIndian/PineHookPlus/releases/download/v1.0/libpine32",
|
||||||
|
self.libpine32,
|
||||||
|
"94854417f9bbb4e2dc49a5edede51dfc1eafca2c7cbb163f59585da7d97fc5db"
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"https://github.com/TechnoIndian/PineHookPlus/releases/download/v1.0/libpine64",
|
||||||
|
self.libpine64,
|
||||||
|
"d3e415243b80b866d2c75408cc9a26ba4fcab0775f798442f9a622097d845e0c"
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"https://github.com/TechnoIndian/PineHookPlus/releases/download/v1.0/loader.dex",
|
||||||
|
self.loader,
|
||||||
|
"c23fcc7aac75d3ea760523876dc837b6506726194c2fe4376d5172c8271b7c46"
|
||||||
|
),
|
||||||
|
]
|
||||||
|
)
|
||||||
|
|
||||||
|
M.os.system('cls' if M.os.name == 'nt' else 'clear')
|
||||||
|
|
||||||
|
|
||||||
|
# ---------------- Files Download isEmulator ----------------
|
||||||
|
def F_D_A(self):
|
||||||
|
|
||||||
|
self.Download_Files(
|
||||||
|
[
|
||||||
|
(
|
||||||
|
"https://github.com/TechnoIndian/Tools/releases/download/Tools/APKTool.jar",
|
||||||
|
self.APKTool_Path_E,
|
||||||
|
"d0a81361670b17b713fea45baec3ed04b26bc8b69b30bde9a6f367c13fc25697"
|
||||||
|
)
|
||||||
|
]
|
||||||
|
)
|
||||||
0
ApkPatcher/Utils/Pine/__init__.py
Normal file
0
ApkPatcher/Utils/Pine/__init__.py
Normal file
84
ApkPatcher/Utils/Pine/config.json
Normal file
84
ApkPatcher/Utils/Pine/config.json
Normal file
@ -0,0 +1,84 @@
|
|||||||
|
{
|
||||||
|
"com.pinehook.plus.MainActivity": {
|
||||||
|
"argMethod": {
|
||||||
|
"paramTypes": [
|
||||||
|
"boolean"
|
||||||
|
],
|
||||||
|
"before": {
|
||||||
|
"args": [
|
||||||
|
false
|
||||||
|
],
|
||||||
|
"result": true
|
||||||
|
},
|
||||||
|
"after": {
|
||||||
|
"result": false
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"anotherMethod": {
|
||||||
|
"paramTypes": [
|
||||||
|
"int"
|
||||||
|
],
|
||||||
|
"before": {
|
||||||
|
"args": [
|
||||||
|
100
|
||||||
|
],
|
||||||
|
"result": 200
|
||||||
|
},
|
||||||
|
"after": {
|
||||||
|
"result": 300
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"yetAnotherMethod": {
|
||||||
|
"before": {
|
||||||
|
"result": true
|
||||||
|
},
|
||||||
|
"after": {
|
||||||
|
"result": false
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"beforeOnlyMethod": {
|
||||||
|
"paramTypes": [
|
||||||
|
"java.lang.String"
|
||||||
|
],
|
||||||
|
"before": {
|
||||||
|
"args": [
|
||||||
|
"modifiedBefore"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"afterOnlyMethod": {
|
||||||
|
"paramTypes": [
|
||||||
|
"java.lang.String"
|
||||||
|
],
|
||||||
|
"after": {
|
||||||
|
"result": "modifiedAfter"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"com.pinehook.plus.ConstructorClass": {
|
||||||
|
"constructor": {
|
||||||
|
"paramTypes": [
|
||||||
|
"boolean",
|
||||||
|
"java.lang.String",
|
||||||
|
"boolean",
|
||||||
|
"long",
|
||||||
|
"long",
|
||||||
|
"java.lang.String",
|
||||||
|
"java.lang.String",
|
||||||
|
"java.lang.String"
|
||||||
|
],
|
||||||
|
"before": {
|
||||||
|
"args": [
|
||||||
|
true,
|
||||||
|
"PlayStore",
|
||||||
|
false,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
"null",
|
||||||
|
"Yearly",
|
||||||
|
"null"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
BIN
ApkPatcher/Utils/Pine/libpine32
Normal file
BIN
ApkPatcher/Utils/Pine/libpine32
Normal file
Binary file not shown.
BIN
ApkPatcher/Utils/Pine/libpine64
Normal file
BIN
ApkPatcher/Utils/Pine/libpine64
Normal file
Binary file not shown.
BIN
ApkPatcher/Utils/Pine/loader.dex
Normal file
BIN
ApkPatcher/Utils/Pine/loader.dex
Normal file
Binary file not shown.
118
ApkPatcher/Utils/Scan.py
Normal file
118
ApkPatcher/Utils/Scan.py
Normal file
@ -0,0 +1,118 @@
|
|||||||
|
from ..ANSI_COLORS import ANSI; C = ANSI()
|
||||||
|
from ..MODULES import IMPORT; M = IMPORT()
|
||||||
|
|
||||||
|
from .Files_Check import FileCheck
|
||||||
|
|
||||||
|
F = FileCheck(); F.Set_Path();
|
||||||
|
|
||||||
|
EX = f"{C.P}\n |\n ╰{C.CC}┈{C.OG}➢ {C.G}ApkPatcher {' '.join(M.sys.argv[1:])} {C.OG}"
|
||||||
|
|
||||||
|
|
||||||
|
# ---------------- Scan APK ----------------
|
||||||
|
def Scan_Apk(apk_path, isFlutter, isPairip):
|
||||||
|
|
||||||
|
print(f"\n{C.CC}{'_' * 61}\n")
|
||||||
|
|
||||||
|
Package_Name = ''
|
||||||
|
|
||||||
|
if M.os.name == 'posix':
|
||||||
|
# ---------------- Extract Package Name with AAPT ----------------
|
||||||
|
Package_Name = M.subprocess.run(
|
||||||
|
['aapt', 'dump', 'badging', apk_path],
|
||||||
|
capture_output=True, text=True
|
||||||
|
).stdout.split("package: name='")[1].split("'")[0]
|
||||||
|
|
||||||
|
if Package_Name:
|
||||||
|
print(f"\n{C.S} Package Name {C.E} {C.OG}➸❥ {C.P}'{C.G}{Package_Name}{C.P}' {C.G} ✔")
|
||||||
|
|
||||||
|
|
||||||
|
# ---------------- Extract Package Name with APKEditor ----------------
|
||||||
|
if not Package_Name:
|
||||||
|
Package_Name = M.subprocess.run(
|
||||||
|
["java", "-jar", F.APKEditor_Path, "info", "-package", "-i", apk_path],
|
||||||
|
capture_output=True, text=True
|
||||||
|
).stdout.split('"')[1]
|
||||||
|
|
||||||
|
print(f"\n{C.S} Package Name {C.E} {C.OG}➸❥ {C.P}'{C.G}{Package_Name}{C.P}' {C.G} ✔")
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
# ---------------- Check Flutter / Pairip Protection ----------------
|
||||||
|
isPairip_lib = isFlutter_lib = False
|
||||||
|
|
||||||
|
with M.zipfile.ZipFile(apk_path, 'r') as zip_ref:
|
||||||
|
for item in zip_ref.infolist():
|
||||||
|
if item.filename.startswith('lib/'):
|
||||||
|
if item.filename.endswith('libpairipcore.so'):
|
||||||
|
isPairip_lib = True
|
||||||
|
if item.filename.endswith('libflutter.so'):
|
||||||
|
isFlutter_lib = True
|
||||||
|
|
||||||
|
|
||||||
|
# ---------------- Check Flutter Protection ----------------
|
||||||
|
if isFlutter_lib:
|
||||||
|
def check_java_installation():
|
||||||
|
try:
|
||||||
|
M.subprocess.run(['radare2', '-v'], capture_output=True, text=True)
|
||||||
|
except (M.subprocess.CalledProcessError, FileNotFoundError):
|
||||||
|
if M.os.name == 'posix':
|
||||||
|
for pkg in ['radare2']:
|
||||||
|
try:
|
||||||
|
|
||||||
|
result = M.subprocess.run(['pkg', 'list-installed'], capture_output=True, text=True)
|
||||||
|
|
||||||
|
if pkg not in result.stdout:
|
||||||
|
print(f"\n{C.S} Installing {C.E} {C.OG}➸❥ {C.G}{pkg}...\n")
|
||||||
|
M.subprocess.check_call(['pkg', 'install', '-y', pkg])
|
||||||
|
|
||||||
|
M.os.system('cls' if M.os.name == 'nt' else 'clear')
|
||||||
|
|
||||||
|
except (M.subprocess.CalledProcessError, Exception):
|
||||||
|
exit(
|
||||||
|
f"\n\n{C.ERROR} No Internet Connection. ✘\n"
|
||||||
|
f"\n{C.INFO} Internet Connection is Required to Installation {C.G} pkg install {pkg}\n"
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
exit(
|
||||||
|
f"\n\n{C.ERROR} Radare2 is not installed on Your System. ✘\n"
|
||||||
|
f"\n{C.INFO} Install Radare2 and Run Script Again in New CMD.\n"
|
||||||
|
f"\n{C.INFO} Verify Radare2 Installation {C.G} radare2 -v"
|
||||||
|
)
|
||||||
|
|
||||||
|
check_java_installation()
|
||||||
|
|
||||||
|
FP = f"\n\n{C.S} Flutter Protection {C.E} {C.OG}➸❥ {C.P}'{C.G}libflutter.so{C.P}' {C.G} ✔"
|
||||||
|
|
||||||
|
if not isFlutter:
|
||||||
|
exit(
|
||||||
|
f"{FP}\n\n"
|
||||||
|
f"\n{C.WARN} This is Flutter APK, So For SSL Bypass , Use {C.G} -f {C.B}Flag:\n\n"
|
||||||
|
f"\n{C.INFO} If APK is Flutter, Then Use Additional Flag: {C.OG}-f"
|
||||||
|
f"{EX}-f {C.Y}-c certificate.cert\n"
|
||||||
|
)
|
||||||
|
|
||||||
|
else:
|
||||||
|
if isFlutter:
|
||||||
|
print(FP)
|
||||||
|
|
||||||
|
|
||||||
|
# ---------------- Check Pairip Protection ----------------
|
||||||
|
if isPairip_lib:
|
||||||
|
PP = f"\n\n{C.S} Pairip Protection {C.E} {C.OG}➸❥ {C.P}'{C.G}libpairipcore.so{C.P}' {C.G} ✔"
|
||||||
|
|
||||||
|
if not isPairip:
|
||||||
|
exit(
|
||||||
|
f"{PP}\n\n"
|
||||||
|
f"\n{C.WARN} This is Pairip APK, So For SSL Bypass, Use {C.G} -p {C.C} / {C.G} -p -x {C.C}( <isCoreX> ) {C.B}Flag:\n\n"
|
||||||
|
f"\n{C.INFO} If APK is Pairip, Then Use Additional Flag: {C.OG}-p {C.P}( Without Sign APK Use Only in VM / Multi_App )"
|
||||||
|
f"{EX}-p {C.Y}-c certificate.cert\n\n"
|
||||||
|
f"\n{C.INFO} If APK is Pairip, Then Hook CoreX & Use Additional Flag: {C.OG}-p -x {C.P}( Install Directly Only For [ arm64 ] )"
|
||||||
|
f"{EX}-p -x {C.Y}-c certificate.cert\n\n"
|
||||||
|
f"\n{C.INFO} Note Both Method Not Stable, May be APK Crash {C.P}( So Try Your Luck ) 😂\n"
|
||||||
|
)
|
||||||
|
|
||||||
|
else:
|
||||||
|
if isPairip:
|
||||||
|
print(PP)
|
||||||
|
|
||||||
|
return Package_Name, isFlutter_lib, isPairip_lib
|
||||||
0
ApkPatcher/Utils/__init__.py
Normal file
0
ApkPatcher/Utils/__init__.py
Normal file
0
ApkPatcher/__init__.py
Normal file
0
ApkPatcher/__init__.py
Normal file
21
LICENSE
Normal file
21
LICENSE
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
MIT License
|
||||||
|
|
||||||
|
Copyright (c) 2025 Techno India
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
in the Software without restriction, including without limitation the rights
|
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
|
furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in all
|
||||||
|
copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
SOFTWARE.
|
||||||
230
README.md
230
README.md
@ -1,2 +1,232 @@
|
|||||||
|
<p align="center">
|
||||||
|
<a href="https://t.me/rktechnoindians"><img title="Made in INDIA" src="https://img.shields.io/badge/MADE%20IN-INDIA-SCRIPT?colorA=%23ff8100&colorB=%23017e40&colorC=%23ff0000&style=for-the-badge"></a>
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<a name="readme-top"></a>
|
||||||
|
|
||||||
|
|
||||||
# ApkPatcher
|
# ApkPatcher
|
||||||
|
|
||||||
|
|
||||||
|
<p align="center">
|
||||||
|
<a href="https://t.me/rktechnoindians"><img src="https://readme-typing-svg.herokuapp.com?font=Fira+Code&weight=800&size=35&pause=1000&color=F74848¢er=true&vCenter=true&random=false&width=435&lines=ApkPatcher" /></a>
|
||||||
|
</p>
|
||||||
|
|
||||||
|
|
||||||
|
Installation Method
|
||||||
|
-------
|
||||||
|
**💢 Requirement PKG 💢**
|
||||||
|
|
||||||
|
```bash
|
||||||
|
termux-setup-storage
|
||||||
|
pkg update -y
|
||||||
|
pkg upgrade -y
|
||||||
|
pkg install python -y
|
||||||
|
```
|
||||||
|
|
||||||
|
**👉🏻 To install ApkPatcher, Run only any one cmd from the Installation Method**
|
||||||
|
|
||||||
|
**💢 PYPI ( Just Testing ) 💢**
|
||||||
|
|
||||||
|
pip install ApkPatcherX
|
||||||
|
|
||||||
|
[](https://pypi.org/project/ApkPatcherX) [](https://pypi.org/project/ApkPatcherX)
|
||||||
|
|
||||||
|
|
||||||
|
**1st. Method**
|
||||||
|
|
||||||
|
`💢 For Latest Commit ( From Main Branch ) 💢`
|
||||||
|
|
||||||
|
pip install --force-reinstall https://github.com/TechnoIndian/ApkPatcher/archive/refs/heads/main.zip
|
||||||
|
|
||||||
|
`OR`
|
||||||
|
|
||||||
|
pip install --force-reinstall https://github.com/TechnoIndian/ApkPatcher/archive/refs/heads/main.tar.gz
|
||||||
|
|
||||||
|
`OR`
|
||||||
|
|
||||||
|
curl -Ls https://github.com/TechnoIndian/Tools/releases/download/Tools/ApkPatcher.sh | bash
|
||||||
|
|
||||||
|
**2nd. Method**
|
||||||
|
|
||||||
|
pkg install python git && pip install git+https://github.com/TechnoIndian/ApkPatcher.git
|
||||||
|
|
||||||
|
|
||||||
|
Uninstall ApkPatcher
|
||||||
|
-----
|
||||||
|
|
||||||
|
pip uninstall ApkPatcherX
|
||||||
|
|
||||||
|
|
||||||
|
# Usage Example
|
||||||
|
|
||||||
|
|
||||||
|
ApkPatcher ( Input Mode )
|
||||||
|
-----
|
||||||
|
|
||||||
|
**Mode `-i` ➸ Smali Patcher ( Input Your APK Path )**
|
||||||
|
|
||||||
|
`Default Patch is VPN & SSL Bypass`
|
||||||
|
|
||||||
|
ApkPatcher -i YourApkPath.apk
|
||||||
|
|
||||||
|
**Flag: `-a` ➸ Try with APKEditor ( Default APKTool )**
|
||||||
|
|
||||||
|
ApkPatcher -i YourApkPath.apk -a
|
||||||
|
|
||||||
|
**Flag: `-c` ➸ Embed Your Captural APK's Certificate**
|
||||||
|
|
||||||
|
`With Your Certificate ( Input Your .pem / .crt / .cert Path )`
|
||||||
|
|
||||||
|
`If you have already installed your certificate under CA Certificates in your device settings, then you don’t need to use the "-c YourCertificatePath.cert" parameter, because the user certificate is already trusted by network_security_config.xml`
|
||||||
|
|
||||||
|
ApkPatcher -i YourApkPath.apk -c YourCertificatePath.cert
|
||||||
|
|
||||||
|
`Multiple Certificate`
|
||||||
|
|
||||||
|
ApkPatcher -i YourApkPath.apk -c /sdcard/HttpCanary/certs/HttpCanary.pem /sdcard/Download/Reqable/reqable-ca.crt /sdcard/Download/ProxyPinCA.crt
|
||||||
|
|
||||||
|
**Flag: `-e` ➸ If using emulator on PC**
|
||||||
|
|
||||||
|
ApkPatcher -i YourApkPath.apk -e
|
||||||
|
|
||||||
|
**Flag: `-u` ➸ Keep UnSigned APK**
|
||||||
|
|
||||||
|
ApkPatcher -i YourApkPath.apk -u
|
||||||
|
|
||||||
|
|
||||||
|
Smali Patcher ( Additional Flags )
|
||||||
|
-----
|
||||||
|
|
||||||
|
**Flag: `-f` / `-p` / `-p -x` ➸ Flutter & Pairip SSL Bypass**
|
||||||
|
|
||||||
|
`For Flutter, Script By 🇮🇳 AbhiTheM0dder 🇮🇳`
|
||||||
|
|
||||||
|
ApkPatcher -i YourApkPath.apk -f
|
||||||
|
|
||||||
|
`For Pairip ( UnSigned APK, Use Only in VM / Multi App )`
|
||||||
|
|
||||||
|
ApkPatcher -i YourApkPath.apk -p
|
||||||
|
|
||||||
|
`CoreX HooK For Pairip ( Install Directly, Only For [ arm64 ] )`
|
||||||
|
|
||||||
|
ApkPatcher -i YourApkPath.apk -p -x
|
||||||
|
|
||||||
|
**Flag: `-D` ➸ Hook Android ID For One Device Login Bypass**
|
||||||
|
|
||||||
|
`Input Your 16 Digit Android ID`
|
||||||
|
|
||||||
|
ApkPatcher -i YourApkPath.apk -D 7e9f51f096bd5c83
|
||||||
|
|
||||||
|
**Flag: `-pkg` ➸ Spoof Package Detection ( Dex / Manifest / Res )**
|
||||||
|
|
||||||
|
ApkPatcher -i YourApkPath.apk -pkg
|
||||||
|
|
||||||
|
**Flag: `-P` ➸ Purchase / Paid / Price**
|
||||||
|
|
||||||
|
ApkPatcher -i YourApkPath.apk -P
|
||||||
|
|
||||||
|
**Flag: `-rmss` / `-rmusb` ➸ Bypass Screen / USB Restriction**
|
||||||
|
|
||||||
|
`Bypass Screenshot Restriction`
|
||||||
|
|
||||||
|
ApkPatcher -i YourApkPath.apk -rmss
|
||||||
|
|
||||||
|
`Bypass USB Debugging`
|
||||||
|
|
||||||
|
ApkPatcher -i YourApkPath.apk -rmusb
|
||||||
|
|
||||||
|
**Flag: `-skip` ➸ Skip Patch (e.g., getAcceptedIssuers)**
|
||||||
|
|
||||||
|
ApkPatcher -i YourApkPath.apk -skip getAcceptedIssuers
|
||||||
|
|
||||||
|
|
||||||
|
AES Patcher ( Additional Flags )
|
||||||
|
-----
|
||||||
|
|
||||||
|
**Flag: `-A` ➸ AES MT Logs Inject**
|
||||||
|
|
||||||
|
ApkPatcher -i YourApkPath.apk -A
|
||||||
|
|
||||||
|
`Do U Want Separate AES.smali Dex`
|
||||||
|
|
||||||
|
ApkPatcher -i YourApkPath.apk -A -s
|
||||||
|
|
||||||
|
|
||||||
|
Spoof Patcher ( Additional Flags )
|
||||||
|
-----
|
||||||
|
|
||||||
|
**Flag: `-r` ➸ Random / Fake / Spoof Device Info**
|
||||||
|
|
||||||
|
ApkPatcher -i YourApkPath.apk -r
|
||||||
|
|
||||||
|
`Input Your 16 Digit Custom Android ID`
|
||||||
|
|
||||||
|
ApkPatcher -i YourApkPath.apk -r -D 7e9f51f096bd5c83
|
||||||
|
|
||||||
|
|
||||||
|
Ads Patcher ( Additional Flags )
|
||||||
|
-----
|
||||||
|
|
||||||
|
**Flag: `-rmads` ➸ Remove Ads**
|
||||||
|
|
||||||
|
ApkPatcher -i YourApkPath.apk -rmads
|
||||||
|
|
||||||
|
|
||||||
|
TG Patcher ( Additional Flags )
|
||||||
|
-----
|
||||||
|
|
||||||
|
**Flag: `-t` ➸ Telegram / Plus Patch, Script By 🇮🇳 AbhiTheM0dder 🇮🇳**
|
||||||
|
|
||||||
|
ApkPatcher -i YourApkPath.apk -t
|
||||||
|
|
||||||
|
|
||||||
|
Pine Hook ( Additional Flags )
|
||||||
|
-----
|
||||||
|
|
||||||
|
**Flag: `-pine -l` ➸ -pine -l ( Input Path of Xposed & LSP Module )**
|
||||||
|
|
||||||
|
`Mutil Path Supported, But module path should not contain space or symbols.`
|
||||||
|
|
||||||
|
ApkPatcher -i YourApkPath.apk -pine -l NoVPNDetect.apk just.trust.me.apk
|
||||||
|
|
||||||
|
|
||||||
|
ApkPatcher ( Merge Mode )
|
||||||
|
-----
|
||||||
|
|
||||||
|
**Mode `-m` ➸ Anti-Split ( Only Merge APK )**
|
||||||
|
|
||||||
|
`Supported Extensions ( .apks / .apkm / .xapk )`
|
||||||
|
|
||||||
|
ApkPatcher -m YourApkPath.apks
|
||||||
|
|
||||||
|
|
||||||
|
ApkPatcher ( Credits Mode )
|
||||||
|
-----
|
||||||
|
|
||||||
|
**Mode `-C` ➸ Credits**
|
||||||
|
|
||||||
|
ApkPatcher -C
|
||||||
|
|
||||||
|
|
||||||
|
ApkPatcher Help
|
||||||
|
-----
|
||||||
|
|
||||||
|
ApkPatcher -h
|
||||||
|
|
||||||
|
|
||||||
|
ApkPatcher Other Patch Flags
|
||||||
|
-----
|
||||||
|
|
||||||
|
ApkPatcher -O
|
||||||
|
|
||||||
|
|
||||||
|
# NOTE
|
||||||
|
|
||||||
|
|
||||||
|
## 🇮🇳 Welcome By Techno India 🇮🇳
|
||||||
|
|
||||||
|
[](https://t.me/rktechnoindians)
|
||||||
|
</a><p>
|
||||||
|
[](https://t.me/RK_TECHNO_INDIA)
|
||||||
|
</p>
|
||||||
60
pyproject.toml
Normal file
60
pyproject.toml
Normal file
@ -0,0 +1,60 @@
|
|||||||
|
[build-system]
|
||||||
|
requires = ["setuptools", "wheel"]
|
||||||
|
build-backend = "setuptools.build_meta"
|
||||||
|
|
||||||
|
[project]
|
||||||
|
name = "ApkPatcherX"
|
||||||
|
dynamic = ["version"]
|
||||||
|
authors = [
|
||||||
|
{ name = "RK_TECHNO_INDIA", email = "TechnoIndian786@gmail.com" }
|
||||||
|
]
|
||||||
|
|
||||||
|
description = "Smali Patcher ( Bypass 𒁍 SSL & Flutter SSL, VPN, USB Debugging, Screen Restrict, One Device Login, Spoof Info & Package Detection, Ads, AES Logs Inject, TG Patch, Pine HooK )"
|
||||||
|
|
||||||
|
license = { text = "MIT" }
|
||||||
|
readme = "README.md"
|
||||||
|
|
||||||
|
requires-python = ">=3.12"
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
"requests",
|
||||||
|
"r2pipe",
|
||||||
|
"asn1crypto",
|
||||||
|
"multiprocess"
|
||||||
|
]
|
||||||
|
|
||||||
|
keywords = ["ApkPatcher"]
|
||||||
|
|
||||||
|
classifiers = [
|
||||||
|
"License :: OSI Approved :: MIT License",
|
||||||
|
"Operating System :: OS Independent",
|
||||||
|
"Programming Language :: Python :: 3",
|
||||||
|
]
|
||||||
|
|
||||||
|
[project.scripts]
|
||||||
|
ApkPatcher = "ApkPatcher.APK_PATCHER:RK_Techno_IND"
|
||||||
|
apkpatcher = "ApkPatcher.APK_PATCHER:RK_Techno_IND"
|
||||||
|
|
||||||
|
[tool.setuptools]
|
||||||
|
include-package-data = true
|
||||||
|
|
||||||
|
packages.find = {}
|
||||||
|
|
||||||
|
package-data = { ApkPatcher = [
|
||||||
|
"Utils/Files/AES.smali",
|
||||||
|
"Utils/Files/Hook.smali",
|
||||||
|
"Utils/Files/lib_Pairip_CoreX.so",
|
||||||
|
"Utils/Pine/config.json",
|
||||||
|
"Utils/Pine/libpine32",
|
||||||
|
"Utils/Pine/libpine64",
|
||||||
|
"Utils/Pine/loader.dex"
|
||||||
|
] }
|
||||||
|
|
||||||
|
|
||||||
|
[project.urls]
|
||||||
|
Homepage = "https://github.com/TechnoIndian/ApkPatcher"
|
||||||
|
Repository = "https://github.com/TechnoIndian/ApkPatcher.git"
|
||||||
|
Issues = "https://github.com/TechnoIndian/ApkPatcher/issues"
|
||||||
|
|
||||||
|
[tool.setuptools.dynamic]
|
||||||
|
version = { file = "VERSION" }
|
||||||
Loading…
Reference in New Issue
Block a user