Open paulo-raca opened 5 years ago
I've been trying to reproduce it as a unit tests, and so far I got this:
@Test
public void hookBinder() throws Exception {
BinderHook.doTransaction();
Assert.assertEquals(0, BinderHook.hookCount);
Assert.assertEquals(0, BinderHook.backupCount);
//------------------------ AFTER HOOKING --------------------------------
HookMain.backupAndHook(
Class.forName("android.os.BinderProxy").getDeclaredMethod("transactNative", int.class, Parcel.class, Parcel.class, int.class),
BinderHook.class.getDeclaredMethod("transactNativeHook", Object.class, int.class, Parcel.class, Parcel.class, int.class),
BinderHook.class.getDeclaredMethod("transactNativeBackup", Object.class, int.class, Parcel.class, Parcel.class, int.class));
BinderHook.doTransaction();
Assert.assertEquals(1, BinderHook.hookCount);
Assert.assertEquals(0, BinderHook.backupCount);
}
static class BinderHook {
static int hookCount;
static int backupCount;
public static boolean transactNativeHook(Object thiz, int code, Parcel data, Parcel reply, int flags) throws RemoteException {
Log.i(TAG, "transactNativeHook");
hookCount++;
return transactNativeBackup(thiz, code, data, reply, flags);
}
public static boolean transactNativeBackup(Object thiz, int code, Parcel data, Parcel reply, int flags) throws RemoteException {
Log.i(TAG, "transactNativeBackup");
backupCount++;
throw new UnsupportedOperationException("Stub!");
}
public static void doTransaction() throws Exception {
Context ctx = InstrumentationRegistry.getContext();
ctx.getPackageManager().getNameForUid(Process.myUid());
}
}
Interestingly, the errors I describe do not happen when I run this as a stand-alone unit tests. However, it crashes on API23:
03-01 02:52:29.832 6216-6226/lab.galaxy.yahfa.test A/libc: Fatal signal 11 (SIGSEGV), code 1, fault addr 0x7ff6016f9500 in tid 6226 (HeapTaskDaemon)
03-01 02:52:30.052 1334-1334/? A/DEBUG: *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***
03-01 02:52:30.052 1334-1334/? A/DEBUG: Build fingerprint: 'Android/sdk_google_phone_x86_64/generic_x86_64:6.0/MASTER/5056751:userdebug/test-keys'
03-01 02:52:30.052 1334-1334/? A/DEBUG: Revision: '0'
03-01 02:52:30.052 1334-1334/? A/DEBUG: ABI: 'x86_64'
03-01 02:52:30.060 1334-1334/? A/DEBUG: pid: 6216, tid: 6226, name: HeapTaskDaemon >>> lab.galaxy.yahfa.test <<<
03-01 02:52:30.060 1334-1334/? A/DEBUG: signal 11 (SIGSEGV), code 1 (SEGV_MAPERR), fault addr 0x7ff6016f9500
03-01 02:52:30.261 1334-1334/? A/DEBUG: rax 7ff5c02b4e08bf48 rbx 000000004e08bf48 rcx 00007ff5b366d5c0 rdx 0000000077ff0000
03-01 02:52:30.262 1334-1334/? A/DEBUG: rsi 00007ff5bb104030 rdi 00007ff5c383e200
03-01 02:52:30.262 1334-1334/? A/DEBUG: r8 000000004e08be98 r9 000000000000001f r10 0000000000000001 r11 000000000000001f
03-01 02:52:30.262 1334-1334/? A/DEBUG: r12 0000000000000000 r13 00007ff5bae16298 r14 0000000000000000 r15 0000000000000000
03-01 02:52:30.262 1334-1334/? A/DEBUG: cs 0000000000000033 ss 000000000000002b
03-01 02:52:30.262 1334-1334/? A/DEBUG: rip 00007ff5c355e354 rbp 00007ff5b3dc75c0 rsp 00007ff5b3dc7460 eflags 0000000000010246
03-01 02:52:30.348 1334-1334/? A/DEBUG: backtrace:
03-01 02:52:30.351 1334-1334/? A/DEBUG: #00 pc 0000000000511354 /system/lib64/libart.so (art::StackVisitor::WalkStack(bool)+212)
03-01 02:52:30.351 1334-1334/? A/DEBUG: #01 pc 00000000005205d4 /system/lib64/libart.so (art::Thread::VisitRoots(art::RootVisitor*)+1444)
03-01 02:52:30.352 1334-1334/? A/DEBUG: #02 pc 0000000000282790 /system/lib64/libart.so (art::gc::collector::CheckpointMarkThreadRoots::Run(art::Thread*)+112)
03-01 02:52:30.353 1334-1334/? A/DEBUG: #03 pc 000000000053cbc1 /system/lib64/libart.so (art::ThreadList::RunCheckpoint(art::Closure*)+529)
03-01 02:52:30.353 1334-1334/? A/DEBUG: #04 pc 00000000002818bc /system/lib64/libart.so (art::gc::collector::MarkSweep::MarkRootsCheckpoint(art::Thread*, bool)+108)
03-01 02:52:30.354 1334-1334/? A/DEBUG: #05 pc 000000000028746d /system/lib64/libart.so (art::gc::collector::MarkSweep::MarkingPhase()+589)
03-01 02:52:30.354 1334-1334/? A/DEBUG: #06 pc 0000000000287b01 /system/lib64/libart.so (art::gc::collector::MarkSweep::RunPhases()+721)
03-01 02:52:30.355 1334-1334/? A/DEBUG: #07 pc 0000000000278f1a /system/lib64/libart.so (art::gc::collector::GarbageCollector::Run(art::gc::GcCause, bool)+330)
03-01 02:52:30.355 1334-1334/? A/DEBUG: #08 pc 00000000002af297 /system/lib64/libart.so (art::gc::Heap::CollectGarbageInternal(art::gc::collector::GcType, art::gc::GcCause, bool)+2295)
03-01 02:52:30.355 1334-1334/? A/DEBUG: #09 pc 00000000002b0dd1 /system/lib64/libart.so (art::gc::Heap::ConcurrentGCTask::Run(art::Thread*)+145)
03-01 02:52:30.355 1334-1334/? A/DEBUG: #10 pc 00000000002e532e /system/lib64/libart.so (art::gc::TaskProcessor::RunAllTasks(art::Thread*)+62)
03-01 02:52:30.356 1334-1334/? A/DEBUG: #11 pc 0000000072107549 /data/dalvik-cache/x86_64/system@framework@boot.oat (offset 0x1ed6000)
03-01 02:52:30.631 1334-1334/? A/DEBUG: Tombstone written to: /data/tombstones/tombstone_01
I'm trying to intercept all Binder transactions coming in/out of a process.
While hooking them works fine, calling the backup method does not (Except for Android P, where it works fine)
My (simplified) hooks look like this:
While the hook is called as expected, it crashes when trying to call the backup methods, each with a distinct error:
As far as I can tell, both have the same issue: Apparently, the backup method receives all the metadata from the target method and fails runtime verifications, instead of simply replacing it's implementation.
I still didn't have success reproducing this problem as a small unit test, but I'll try again tomorrow