Skip to content

Instantly share code, notes, and snippets.

@miticollo
Created May 9, 2023 01:07
Show Gist options
  • Save miticollo/7a9f460f8e219f59c6e8ec336274cd85 to your computer and use it in GitHub Desktop.
Save miticollo/7a9f460f8e219f59c6e8ec336274cd85 to your computer and use it in GitHub Desktop.
A frida agent to reset all permissions on specific app. This work is based on https://github.com/FouadRaheb/AppData.
#!/usr/bin/env python3
import json
import frida
from frida.core import Device, Session, Script, ScriptExportsSync
compiler: frida.Compiler = frida.Compiler()
compiler.on("diagnostics", lambda diag: print(f"on_diagnostics: {diag}"))
bundle: str = compiler.build('permissions.ts', compression='terser')
device: Device = frida.get_usb_device()
session: Session = device.attach('Springboard')
script: Script = session.create_script(source=bundle)
script.load()
api: ScriptExportsSync = script.exports_sync
# Third-party app
information: dict = json.loads(api.get_permissions('ru.odnoklassniki.messenger'))
print('TamTam has ' + str(len(information)) + ' permission(s): ')
print(json.dumps(information, indent="\t"))
# Preinstalled app
information = json.loads(api.get_permissions('com.apple.AppStore'))
print('App Store has ' + str(len(information)) + ' permission(s).')
information: dict = json.loads(api.get_permissions('com.apple.iMessageAppsViewService'))
print('com.apple.iMessageAppsViewService has ' + str(len(information)) + ' permission(s).')
api.reset_all_app_permissions('ru.odnoklassniki.messenger')
const {LSApplicationProxy} = ObjC.classes;
const kCFAllocatorDefault: NativePointer = Module.getExportByName('CoreFoundation', 'kCFAllocatorDefault').readPointer();
const CFBundleCreate = new NativeFunction(
Module.getExportByName('CoreFoundation', 'CFBundleCreate'),
'pointer',
[
'pointer', // allocator
'pointer', // url
]);
const TCCAccessResetForBundle = new NativeFunction(
Module.getExportByName('/System/Library/PrivateFrameworks/TCC.framework/TCC', 'TCCAccessResetForBundle'),
'int',
[
'pointer', // service
'pointer', // url
]);
const TCCAccessCopyInformationForBundle = new NativeFunction(
Module.getExportByName('/System/Library/PrivateFrameworks/TCC.framework/TCC', 'TCCAccessCopyInformationForBundle'),
'pointer',
[
'pointer', // url
]);
const CFRelease = new NativeFunction(
Module.getExportByName('CoreFoundation', 'CFRelease'),
'void',
[
'pointer', // cf
]);
function nsArray2JSObject(nsArray: ObjC.Object): { [key: string]: string }[] {
const array = [];
const count = nsArray.count().valueOf();
for (let i = 0; i !== count; i++) {
const element: { [key: string]: string } = {};
const obj: ObjC.Object = nsArray.objectAtIndex_(i);
const enumerator = obj.keyEnumerator();
for (let key: string; (key = enumerator.nextObject()) !== null;)
element[key] = obj.objectForKey_(key).toString();
array[i] = element;
}
return array;
}
rpc.exports = {
// https://github.com/FouadRaheb/AppData/blob/eebc09cfb17375f04f5df08796754738d60b5e13/AppData/Classes/Model/ADAppData.m#L292-L300
resetAllAppPermissions: function (bundleIdentifier: string): void {
const appProxy = LSApplicationProxy.applicationProxyForIdentifier_(bundleIdentifier);
const bundleURL = appProxy.$ivars["_bundleURL"];
const bundle: NativePointer = CFBundleCreate(kCFAllocatorDefault, bundleURL);
if (!bundle.isNull()) {
const kTCCServiceAll = ObjC.classes.NSString.stringWithString_("kTCCServiceAll");
TCCAccessResetForBundle(kTCCServiceAll, bundle);
CFRelease(bundle);
}
// Reset location permission
const { CLLocationManager } = ObjC.classes;
CLLocationManager.setAuthorizationStatusByType_forBundleIdentifier_(0, bundleIdentifier)
},
// https://github.com/FouadRaheb/AppData/blob/eebc09cfb17375f04f5df08796754738d60b5e13/AppData/Classes/Model/ADAppData.m#L272-L279
getPermissions: function (bundleIdentifier: string): string | null {
const appProxy = LSApplicationProxy.applicationProxyForIdentifier_(bundleIdentifier);
const bundleURL = appProxy.$ivars["_bundleURL"];
const bundle: NativePointer = CFBundleCreate(kCFAllocatorDefault, bundleURL);
if (!bundle.isNull()) {
const array: ObjC.Object = new ObjC.Object(TCCAccessCopyInformationForBundle(bundle));
CFRelease(bundle);
return JSON.stringify(nsArray2JSObject(array));
}
return null;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment