0

I compile code below use library Cydia Substrate, and run on a test application, and it works Android 4.4, 5.1, 6.0, 7.0, 7.1. But on Android 8.0+ application does not work with this code, why is that? Why hook does not work in own process?

#include <jni.h>
#include <CydiaSubstrate.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

long baseAddr(char *soname) //find base address
{
    void *imagehandle = dlopen(soname, RTLD_LOCAL | RTLD_LAZY);
    if (soname == NULL)
        return NULL;
    if (imagehandle == NULL){
        return NULL;
    }
    uintptr_t * irc = NULL;
    FILE *f = NULL;
    char line[200] = {0};
    char *state = NULL;
    char *tok = NULL;
    char * baseAddr = NULL;
    if ((f = fopen("/proc/self/maps", "r")) == NULL)
        return NULL;
    while (fgets(line, 199, f) != NULL)
    {
        tok = strtok_r(line, "-", &state);
        baseAddr = tok;
        tok = strtok_r(NULL, "\t ", &state);
        tok = strtok_r(NULL, "\t ", &state); // "r-xp" field
        tok = strtok_r(NULL, "\t ", &state); // "0000000" field
        tok = strtok_r(NULL, "\t ", &state); // "01:02" field
        tok = strtok_r(NULL, "\t ", &state); // "133224" field
        tok = strtok_r(NULL, "\t ", &state); // path field

        if (tok != NULL) {
            int i;
            for (i = (int)strlen(tok)-1; i >= 0; --i) {
                if (!(tok[i] == ' ' || tok[i] == '\r' || tok[i] == '\n' || tok[i] == '\t'))
                    break;
                tok[i] = 0;
            }
            {
                size_t toklen = strlen(tok);
                size_t solen = strlen(soname);
                if (toklen > 0) {
                    if (toklen >= solen && strcmp(tok + (toklen - solen), soname) == 0) {
                        fclose(f);
                        return (long)strtoll(baseAddr,NULL,16);
                    }
                }
            }
        }
    }
    fclose(f);
    return NULL;
}

long location;

long RealOffset(long offset)
{
    if (location == 0)
    {

        location = baseAddr("/data/app/com.test.test-1/lib/arm/libtest.so");
        if (location == 0)
        {

            location = baseAddr("/data/app-lib/com.test.test-1/libtest.so");
        }
    }
    return location + offset;
}

void orig_func(void*);
void hook_func(void*){
    return;
}

__attribute__((constructor))
void main() {
    MSHookFunction((void *) RealOffset(0x1234C), (void *) &hook_func, (void **) &orig_func); //replace the function
}
5
  • Even if your goal is reverse engineering, the question as currently written is about software development, and is lacking specific information about the failure which would be required when posting a development debug question. Please consider putting in some logging to dump the maps file it is parsing to logcat and record the progress of your program. Mar 25 '19 at 21:46
  • The problem is in Android 8.0 :) There can not get root to check error records in logcat. And i have AMD, in Android Studio can't run Android above 7.1
    – Cly 4
    Mar 26 '19 at 11:28
  • Logcat does not require root Mar 26 '19 at 14:39
  • Yes, i checked, After Android 8.0 changed patch now: /data/app/com.test.test-dGVzdGV0ZXN0dA==/lib/arm/libtest.so And with each installation, this patch change.
    – Cly 4
    Apr 3 '19 at 13:47
  • You probably should not have hardcoded the expected path in the first place. There are java apis to get the app's data directory that you could pass down to your jni code. Or you can simply recognize the map entry where the actual filename matches rather than trying to match the directory name, which seems to include some sort of base64-like uniqueness or versioning. Apr 3 '19 at 16:12

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.