|
import argparse |
|
import os |
|
import re |
|
import lief |
|
from adb_shell.adb_device import AdbDeviceTcp,_AdbTransactionInfo |
|
from adb_shell.auth.sign_pythonrsa import PythonRSASigner |
|
from adb_shell.auth.keygen import keygen |
|
|
|
def get_device(port,host): |
|
adb_device = AdbDeviceTcp(host, port) |
|
adbkey = "adbkey" |
|
if not os.path.isfile(adbkey): |
|
keygen(adbkey) |
|
with open(adbkey) as f: |
|
priv = f.read() |
|
with open(adbkey + '.pub') as f: |
|
pub = f.read() |
|
signer = PythonRSASigner(pub, priv) |
|
adb_device.connect(rsa_keys=[signer], auth_timeout_s=0.1) |
|
try: |
|
print("attempting to get root access") |
|
# adb_device._service(b'root', b'') |
|
adb_device.root() |
|
print(f"USER:{adb_device.shell('whoami')}") |
|
except Exception as e : |
|
print("failed to get root , run script again ? adb-shell bug??") |
|
return False |
|
return adb_device |
|
|
|
def get_library_folder(adb_device, package_name): |
|
command = f'pm dump {package_name} | grep -i legacyNativeLibraryDir | awk -F "legacyNativeLibraryDir=" \'{{print $2}}\'' |
|
result = adb_device.shell(command).strip() |
|
legacy_native_library_dir = result |
|
print(f"[*]Lib folder set to {legacy_native_library_dir}") |
|
|
|
command = f'pm dump {package_name} | grep -i primaryCpuAbi | awk -F "=" \'{{print $2}}\'' |
|
result = adb_device.shell(command).strip() |
|
print(f"[*]arch set to {result}") |
|
arch = 'arm' if 'armeabi-v7a' in result else 'arm64' |
|
package_name = f"{legacy_native_library_dir}/{arch}" |
|
print(f"[*]full path to lib folder set to {package_name}") |
|
return package_name, arch |
|
|
|
def inject_library(adb_device, package_name, gadget_folder, target_lib): |
|
lib_folder, arch = get_library_folder(adb_device, package_name) |
|
script_dir = os.path.dirname(os.path.realpath(__file__)) |
|
pattern = fr'/data/app/.*{re.escape(package_name)}.*' |
|
if not re.search(pattern, lib_folder): |
|
print(f"failed to get path for package : {package_name} is it installed??") |
|
return |
|
gadget_file = os.path.join(gadget_folder, [file for file in os.listdir(gadget_folder) if f"-{arch}." in file][0]) |
|
injected_lib = os.path.join(script_dir, target_lib) |
|
adb_device.pull(rf'{lib_folder}/{target_lib}', injected_lib) |
|
binary = lief.parse(injected_lib) |
|
binary.add_library("libgadget.so") |
|
binary.write(injected_lib) |
|
# adb_device.shell('su') |
|
# adb_device.root(timeout_s=10) |
|
adb_device.push(rf'{injected_lib}', rf'{lib_folder}/{target_lib}') |
|
adb_device.push(gadget_file, rf'{lib_folder}/libgadget.so') |
|
adb_device.push(os.path.join(gadget_folder, 'libgadget.config.so'), rf'{lib_folder}/libgadget.config.so') |
|
|
|
adb_device.shell(f'chmod 777 {lib_folder}/libgadget.so') |
|
adb_device.shell(f'chmod 777 {lib_folder}/libgadget.config.so') |
|
adb_device.shell(f'chmod 777 {lib_folder}/{target_lib}') |
|
|
|
print("Done!") |
|
|
|
if __name__ == '__main__': |
|
parser = argparse.ArgumentParser(description='Inject a shared library into an input binary using LIEF') |
|
parser.add_argument('--package_name', help='package name') |
|
parser.add_argument('--gadget_folder', help='Path to the gadgets folder') |
|
parser.add_argument('--target_lib', help='Name of injected library') |
|
parser.add_argument('--host', default='127.0.0.1', help='ADB host (default: 127.0.0.1)') |
|
parser.add_argument('--port', type=int, default=5555, help='ADB port (default: 5555)') |
|
args = parser.parse_args() |
|
|
|
device = get_device(args.port,args.host) |
|
if device: |
|
inject_library(device, args.package_name, args.gadget_folder, args.target_lib) |
|
else: |
|
print("failed to get device!") |