Fix lots of errors in unpinning patch application logic

This commit is contained in:
Tim Perry
2023-10-13 18:22:50 +02:00
parent 897bf0f58a
commit 5e094e2e6b
+56 -32
View File
@@ -113,7 +113,7 @@ const PINNING_FIXES = {
'android.security.net.config.NetworkSecurityConfig': [
{
methodName: '$init',
overloads: '*',
overload: '*',
replacement: () => {
const PinSet = Java.use('android.security.net.config.PinSet');
const EMPTY_PINSET = PinSet.EMPTY_PINSET.value;
@@ -366,66 +366,90 @@ setTimeout(function () {
Java.perform(function () {
if (DEBUG_MODE) console.debug('=== Disablig all recognized unpinning libraries ===');
Object.keys(PINNING_FIXES).forEach((targetClass) => {
const Cls = getJavaClassIfExists(targetClass);
if (!Cls) {
const classesToPatch = Object.keys(PINNING_FIXES);
classesToPatch.forEach((targetClassName) => {
const TargetClass = getJavaClassIfExists(targetClassName);
if (!TargetClass) {
// We skip patches for any classes that don't seem to be present. This is common
// as not all libraries we handle are necessarily used.
if (DEBUG_MODE) console.debug(`[ ] ${targetClass} *`);
if (DEBUG_MODE) console.debug(`[ ] ${targetClassName} *`);
return;
}
const patches = PINNING_FIXES[targetClass];
const patches = PINNING_FIXES[targetClassName];
let patchApplied = false;
patches.forEach(({ methodName, getMethod, overload, replacement }) => {
const namedTargetMethod = getMethod
? getMethod(targetClass)
: targetClass[methodName];
? getMethod(TargetClass)
: TargetClass[methodName];
const methodDescription = `${methodName}${
overload
overload === '*'
? '(*)'
: overload
? '(' + overload.map((argType) => {
// Simplify arg names to just the class name for simpler logs:
const argClassName = argType.split('.').slice(-1)[0];
if (argType.startsWith('[L')) return `${argClassName}[]`;
else return argClassName;
}).join(', ') + ')'
// No overload:
: ''
}`
const targetMethodImplementations = !namedTargetMethod
? [] // Method not found
: !overload
? [namedTargetMethod] // No overload specified
: overload === '*'
? namedTargetMethod.overloads // Targetting _all_ overloads
// Or targetting a specific overload:
: [namedTargetMethod.overload(...overload)];
let targetMethodImplementations = [];
try {
if (namedTargetMethod) {
if (!overload) {
// No overload specified
targetMethodImplementations = [namedTargetMethod];
} else if (overload === '*') {
// Targetting _all_ overloads
targetMethodImplementations = namedTargetMethod.overloads;
} else {
// Or targetting a specific overload:
targetMethodImplementations = [namedTargetMethod.overload(...overload)];
}
}
} catch (e) {
// Overload not present
}
// We skip patches for any methods that don't seem to be present. This is rarer, but does
// happen due to methods that only appear in certain library versions or whose signatures
// have changed over time.
if (targetMethodImplementations.length === 0) {
// We skip patches for any methods that don't seem to be present. This is
// rarer, but happens due to methods that only appear in certain library
// versions or whose signatures have changed over time.
if (DEBUG_MODE) console.debug(`[ ] ${targetClass} ${methodDescription}`);
if (DEBUG_MODE) console.debug(`[ ] ${targetClassName} ${methodDescription}`);
return;
}
try {
targetMethodImplementations.forEach((targetMethod) => {
targetMethodImplementations.forEach((targetMethod, i) => {
const patchName = `${targetClassName} ${methodDescription}${
targetMethodImplementations.length > 1 ? ` (${i})` : ''
}`;
try {
targetMethod.implementation = replacement(targetMethod);
if (DEBUG_MODE) console.debug(`[+] ${patchName} ${methodDescription}`);
})
patchApplied = true;
} catch (e) {
// In theory, errors like this should never happen - it means the patch is broken
// (e.g. an expected method doesn't exist at all)
console.warn(`[!] ERROR: ${patchName} failed: ${e}`);
}
if (DEBUG_MODE) console.debug(`[+] ${patchName}`);
patchApplied = true;
} catch (e) {
// In theory, errors like this should never happen - it means the patch is broken
// (e.g. some dynamic patch building fails completely)
console.error(`[!] ERROR: ${patchName} failed: ${e}`);
}
})
});
console.log(`[!] Matched class ${targetClass} but could not patch any methods`);
if (!patchApplied) {
console.log(`[!] Matched class ${targetClassName} but could not patch any methods`);
}
});
console.log('== Certificate unpinning completed ==');
});
});