__attribute__((constructor))
void detectfrida() {
char *filePaths[NUM_LIBS];
parse_proc_maps_to_fetch_path(filePaths);
for (int i = 0; i < NUM_LIBS; i++) {
fetch_checksum_of_library(filePaths[i], &elfSectionArr[i]);
if (filePaths[i] != NULL)
free(filePaths[i]);
}
pthread_t t;
pthread_create(&t, NULL, (void *) detect_frida_loop, NULL);
}
void detect_frida_loop(void *pargs) {
struct timespec timereq;
timereq.tv_sec = 5;
timereq.tv_nsec = 0;
while (1) {
// ...
detect_frida_memdiskcompare();
my_nanosleep(&timereq, NULL);
}
}
(source)
The code above computes checksum of loaded binaries in the APK and creates a thread that it's job is constantly checking if the checksums did not change.
You would also notice the use of my_nanosleep, which is because it uses a system call instead of calling the function, making it harder to be hooked. system calls are direct instructions and hooking them
would require traversing the instructions in the binraries and placing custom code that might not guarentee working on all cases.
if we look at the open function before hooking, we would notice it's setup bytes:
sub sp, sp, #0x130
stp x29, x30, [sp, #0xe0]
str x28, [sp, #0xf0]
Before Hook
sub sp, sp, #0x130
br x16
adrp x0, #0x7a6a570000
After Hook
You can notice the first 3 instructions, which are 12 bytes, have changed.
The new instructions simply jump to frida core handler
bool IsDebuggerPresent() {
return ptrace(PTRACE_TRACEME, 0, 1, 0) < 0;
}
ptrace is a system call that is used to trace a process, but one process can trace another at a time!
Thus, if it returns -1, it means
debugger is attached.
A common technique is used to distribute mods is by changing package name to make it possible to install it without having to uninstall the original APK, and this can be checked by simply getting package name from application context on onCreate method:
@Override
public void onCreate(Bundle instance) {
super.onCreate(instance);
setContentView(R.layout.main);
PACKAGE_NAME = getApplicationContext().getPackageName();
}
Distributed APKs are modified, although apk signature can be easily spoofed, it does not hurt to be added and could stop some:
Signature[] sig = context.getPackageManager()
.getPackageInfo(context.getPackageName(), PackageManager.GET_SIGNATURES)
.signatures;
// verify signatures ...