enable `su` in adb command line

This commit is contained in:
HappyZ 2018-11-18 04:38:34 -06:00
parent 15abfc1827
commit c02f389336
8 changed files with 214 additions and 38 deletions

View File

@ -0,0 +1,17 @@
#!/system/bin/sh
# If you're implementing this in a custom kernel/firmware,
# I suggest you use a different script name, and add a service
# to launch it from init.rc
# Launches SuperSU in daemon mode only on Android 4.3+.
# Nothing will happen on 4.2.x or older, unless SELinux+Enforcing.
# If you want to force loading the daemon, use "--daemon" instead
/system/xbin/daemonsu --auto-daemon &
# Some apps like to run stuff from this script as well, that will
# obviously break root - in your code, just search this file
# for "install-recovery-2.sh", and if present, write there instead.
/system/etc/install-recovery-2.sh

Binary file not shown.

Binary file not shown.

BIN
python_api/assets/su Normal file

Binary file not shown.

BIN
python_api/assets/supolicy Normal file

Binary file not shown.

View File

@ -123,6 +123,50 @@ class DPT():
cmd = "[[ -d {} ]] && echo 'YESS' || echo 'NONO'".format(folderp) cmd = "[[ -d {} ]] && echo 'YESS' || echo 'NONO'".format(folderp)
return 'YESS' in self.diagnosis_write(cmd) return 'YESS' in self.diagnosis_write(cmd)
def diagnosis_set_perm(self, fp, owner='0.0', perm='0777'):
'''
set permission of a file
'''
self.info_print('Set {0}: owner={1} perm={2}'.format(fp, owner, perm))
self.diagnosis_write('chown {0} {1}'.format(owner, fp))
self.diagnosis_write('chmod {0} {1}'.format(perm, fp))
def diagnosis_mkdir(self, folder):
'''
mkdir -p folder
'''
if not self.diagnosis_isfolder(folder):
self.info_print("{} already exist".format(folder))
return True
if not self.diagnosis_write('mkdir -p {}'.format(folder)):
self.err_print('Failed to create folder {}'.format(folder))
return False
return True
def diagnosis_ln(self, srcf, destf):
'''
ln -s srcfolder, targetfolder
'''
if not self.diagnosis_write('ln -s {0} {1}'.format(srcf, destf)):
self.err_print('Failed to link file')
return False
return True
def diagnosis_mount_system(self):
'''
mount system partition to mountpoint
'''
mountpoint = '/mnt/Lucifer'
if not self.diagnosis_mkdir(folder):
return ""
# umount first just in case
self.diagnosis_write('umount {}'.format(mountpoint))
# mount system partition (/dev/mmcblk0p9)
self.diagnosis_write('mount /dev/mmcblk0p9 {}'.format(mountpoint))
if self.diagnosis_isfolder('{}/xbin'.format(mountpoint)):
return mountpoint
return ""
def diagnosis_backup_boot(self): def diagnosis_backup_boot(self):
''' '''
back up boot partition to /tmp/ folder back up boot partition to /tmp/ folder
@ -149,8 +193,9 @@ class DPT():
''' '''
write cmd and read feedbacks write cmd and read feedbacks
''' '''
resp = ''
if self.serial is None: if self.serial is None:
return "" return resp
if 'less ' in cmd: if 'less ' in cmd:
self.err_print('do not support less/more') self.err_print('do not support less/more')
try: try:
@ -159,7 +204,10 @@ class DPT():
self.serial.write(cmd.encode() + b'\n') self.serial.write(cmd.encode() + b'\n')
# change timeout to (nearly) blocking first to read # change timeout to (nearly) blocking first to read
self.serial.timeout = timeout self.serial.timeout = timeout
resp = self.serial.read_until(b'# ') tmpresp = b''
while not '@FPX-' in resp:
tmpresp = self.serial.read_until(b'# ')
resp += tmpresp.decode("utf-8").replace("\r\r\n", '')
# change back the original timeout # change back the original timeout
self.serial.timeout = self.serialReadTimeout self.serial.timeout = self.serialReadTimeout
except serial.SerialTimeoutException as e: except serial.SerialTimeoutException as e:
@ -181,10 +229,8 @@ class DPT():
except BaseException as e: except BaseException as e:
self.err_print(str(e)) self.err_print(str(e))
return "" return ""
if echo: if not echo:
resp = resp.decode("utf-8").replace("\r\r\n", '') resp = resp.replace(cmd, '')
else:
resp = resp.decode("utf-8").replace("\r\r\n", '').replace(cmd, '')
self.dbg_print("len of {}; dbg: ".format(len(resp), resp.splitlines())) self.dbg_print("len of {}; dbg: ".format(len(resp), resp.splitlines()))
return resp return resp

View File

@ -7,11 +7,50 @@ import subprocess
# import traceback # import traceback
def validate_required_files(dpt): '''
requiredFiles = [ Web Interface API Related
'python_api/shankerzhiwu_disableidcheck.pkg', '''
'python_api/shankerzhiwu_changepwd.pkg'
] def update_firmware(dpt):
'''
update firmware interface
'''
dpt.info_print(
'Please make sure you have charged your battery before this action.')
try:
resp = input('>>> Please enter the pkg file path: ')
if not os.path.isfile(resp):
dpt.err_print('File `{}` does not exist!'.format(resp))
return False
resp2 = input('>>> Pleae confirm {} is the pkg file to use [yes/no]: ')
if resp2 == 'yes':
if not dpt.update_firmware(open(resp, 'rb')):
dpt.err_print('Failed to upload pkg {}'.format(resp))
return False
dpt.info_print('Success!')
return True
elif resp == 'no':
dpt.info_print('Okay!')
else:
dpt.err_print('Unrecognized response: {}'.format(resp))
except BaseException as e:
dpt.err_print(str(e))
return False
def validate_required_files(dpt, purpose='diagnosis'):
if purpose == 'su-binary':
requiredFiles = [
'python_api/assets/su',
'python_api/assets/supolicy',
'python_api/assets/libsupol.so',
'python_api/assets/install-recovery.sh'
]
else:
requiredFiles = [
'python_api/assets/shankerzhiwu_disableidcheck.pkg',
'python_api/assets/shankerzhiwu_changepwd.pkg'
]
dpt.dbg_print('Checking required files...') dpt.dbg_print('Checking required files...')
for file in requiredFiles: for file in requiredFiles:
if not os.path.isfile(file): if not os.path.isfile(file):
@ -24,7 +63,7 @@ def disable_id_check(dpt):
''' '''
disable the id check (thanks to shankerzhiwu and his/her friend) disable the id check (thanks to shankerzhiwu and his/her friend)
''' '''
fp = 'python_api/shankerzhiwu_disableidcheck.pkg' fp = 'python_api/assets/shankerzhiwu_disableidcheck.pkg'
try: try:
resp = input('>>> Have you disabled the id check already? [yes/no]: ') resp = input('>>> Have you disabled the id check already? [yes/no]: ')
if resp == 'no': if resp == 'no':
@ -52,7 +91,7 @@ def reset_root_password(dpt):
''' '''
reset the root password (thanks to shankerzhiwu and his/her friend) reset the root password (thanks to shankerzhiwu and his/her friend)
''' '''
fp = 'python_api/shankerzhiwu_changepwd.pkg' fp = 'python_api/assets/shankerzhiwu_changepwd.pkg'
try: try:
if not dpt.update_firmware(open(fp, 'rb')): if not dpt.update_firmware(open(fp, 'rb')):
dpt.err_print('Failed to upload shankerzhiwu_changepwd pkg') dpt.err_print('Failed to upload shankerzhiwu_changepwd pkg')
@ -87,31 +126,9 @@ def obtain_diagnosis_access(dpt):
return True return True
def update_firmware(dpt): '''
''' Diagnosis Related
update firmware interface '''
'''
dpt.info_print(
'Please make sure you have charged your battery before this action.')
try:
resp = input('>>> Please enter the pkg file path: ')
if not os.path.isfile(resp):
dpt.err_print('File `{}` does not exist!'.format(resp))
return False
resp2 = input('>>> Pleae confirm {} is the pkg file to use [yes/no]: ')
if resp2 == 'yes':
if not dpt.update_firmware(open(resp, 'rb')):
dpt.err_print('Failed to upload pkg {}'.format(resp))
return False
dpt.info_print('Success!')
return True
elif resp == 'no':
dpt.info_print('Okay!')
else:
dpt.err_print('Unrecognized response: {}'.format(resp))
except BaseException as e:
dpt.err_print(str(e))
return False
def print_diagnosis_info(): def print_diagnosis_info():
@ -127,6 +144,7 @@ Supported commands:
`pull-file` -- transfer file from DPT `pull-file` -- transfer file from DPT
`backup-bootimg` -- backup the boot img and download it to local device `backup-bootimg` -- backup the boot img and download it to local device
`restore-bootimg` -- restore the boot img `restore-bootimg` -- restore the boot img
`get-su-bin` -- enable `su` (root) in adb (beta, not well tested)
`exit`/`quit` -- leave the tool `exit`/`quit` -- leave the tool
and many unix cmds (do not support less/head) and many unix cmds (do not support less/head)
""") """)
@ -315,6 +333,98 @@ def diagnosis_backup_bootimg(dpt):
return False return False
def diagnosis_get_su_bin(dpt):
'''
get sudo access in adb mode (so it would be much much eaiser to
make changes (no painful serial data transfer)
after doing this, adb should handle most necessary modifications
here we use system-method (push binary files to system)
'''
if not validate_required_files(dpt, purpose='su-binary'):
return False
dpt.info_print("Mounting /system partition..")
mountpoint = dpt.diagnosis_mount_system()
dpt.info_print("Mounted to {}".format(mountpoint))
if not mountpoint:
dpt.err_print("Nothing happened..")
return False
dpt.info_print("Uploading su file to /system/xbin..")
sufp = diagnosis_push_file(
dpt,
localfp='python_api/assets/su',
folder='{}/xbin'.format(mountpoint),
overwrite=True)
if sufp is None:
dpt.err_print("Due to previous failure, we stopped..")
return False
dpt.diagnosis_set_perm(sufp, owner='0.0', perm='0755')
daemonsufp = sufp[:-2] + 'daemonsu'
dpt.diagnosis_write('cp {0} {1}'.format(sufp, daemonsufp))
extfolder = "{}/bin/.ext".format(mountpoint)
dpt.diagnosis_mkdir(extfolder)
dpt.diagnosis_set_perm(extfolder, owner='0.0', perm='0777')
dpt.diagnosis_write('cp {0} {1}/su'.format(sufp, extfolder))
dpt.info_print("Uploading supolicy file to /system/xbin..")
supolicyfp = diagnosis_push_file(
dpt,
localfp='python_api/assets/supolicy',
folder='{}/xbin'.format(mountpoint),
overwrite=True)
if supolicyfp is None:
dpt.err_print("Due to previous failure, we stopped..")
return False
dpt.diagnosis_set_perm(supolicyfp, owner='0.0', perm='0755')
libsupolsofp = diagnosis_push_file(
dpt,
localfp='python_api/assets/libsupol.so',
folder='{}/lib'.format(mountpoint),
overwrite=True)
if libsupolsofp is None:
dpt.err_print("Due to previous failure, we stopped..")
return False
dpt.diagnosis_set_perm(libsupolsofp, owner='0.0', perm='0644')
dpt.info_print("Uploading install-recovery.sh to /system/bin..")
installrecfp = diagnosis_push_file(
dpt,
localfp='python_api/assets/install-recovery.sh',
folder='{}/bin'.format(mountpoint),
overwrite=True)
if installrecfp is None:
dpt.err_print("Due to previous failure, we stopped..")
return False
dpt.diagnosis_set_perm(installrecfp, owner='0.0', perm='0755')
dpt.info_print("Tweaking /system/bin/app_process..")
appprocessfp = '{0}/bin/app_process'.format(mountpoint)
dpt.diagnosis_write('mv {0} {0}_bak'.format(appprocessfp))
dpt.diagnosis_ln(daemonsufp, "/system/bin/app_process")
dpt.info_print("Tweaking /system/bin/app_process32..")
appprocess32fp = '{0}32'.format(appprocessfp)
if dpt.diagnosis_isfile("{}_original".format(appprocess32fp)):
dpt.diagnosis_remove_file(appprocess32fp)
else:
dpt.diagnosis_write("mv {0} {0}_original".format(appprocessfp))
dpt.diagnosis_ln(daemonsufp, "/system/bin/app_process32")
dpt.info_print("Tweaking /system/bin/app_process_init..")
if not dpt.diagnosis_isfile("{}_init".format(appprocessfp)):
dpt.diagnosis_write(
"cp {0}_ori {1}_init".format(appprocess32fp, appprocessfp))
dpt.diagnosis_set_perm(
"{}_init".format(appprocessfp), owner='0.2000', perm='0755')
dpt.info_print("Misc: add /system/etc/.installed_su_daemon")
miscfp = "{}/etc/.installed_su_daemon".format(mountpoint)
dpt.diagnosis_write("echo 1 > {}".format(miscfp))
dpt.diagnosis_set_perm(miscfp, owner='0.0', perm='0644')
dpt.info_print("Done!")
def diagnosis_restore_bootimg(dpt, usetmpfp=None, bootimgfp=None): def diagnosis_restore_bootimg(dpt, usetmpfp=None, bootimgfp=None):
''' '''
restore boot img restore boot img
@ -374,6 +484,9 @@ def diagnosis_cmd(dpt):
elif cmd == 'restore-bootimg': elif cmd == 'restore-bootimg':
diagnosis_restore_bootimg(dpt) diagnosis_restore_bootimg(dpt)
continue continue
elif cmd == 'get-su-bin':
diagnosis_get_su_bin(dpt)
continue
rawresp = dpt.diagnosis_write(cmd) rawresp = dpt.diagnosis_write(cmd)
# ignore first and last echos # ignore first and last echos
tmp = rawresp.splitlines() tmp = rawresp.splitlines()