Skip to content

Instantly share code, notes, and snippets.

@sqrtrev
Created March 29, 2022 03:37
Show Gist options
  • Save sqrtrev/d3ab7d8dda67cf665ad0f5f7dae4c3cb to your computer and use it in GitHub Desktop.
Save sqrtrev/d3ab7d8dda67cf665ad0f5f7dae4c3cb to your computer and use it in GitHub Desktop.

(Written by c0m0r1)

Simple android app reversing w/ native library. just reversing the logic and running solver code in arm64-v8a CPU android phone with a given native library can solve it.

#include <fcntl.h>
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
#include <dlfcn.h>

#define __USE_GNU
#include <signal.h>


#define MEATBOX_OFFSET 0xCC0
#define SOULBOX_OFFSET 0xD80
#define GODBOX_OFFSET 0xD20
#define RES_ARR_OFFSET 0x47E8

typedef char *((*t_meatbox)(char *));
typedef char *((*t_soulbox)(char *));
typedef char *((*t_godbox)(char *));

/* Global symbols */
#define DEF(n) t_##n n = NULL

DEF(meatbox);
DEF(soulbox);
DEF(godbox);

#undef DEF

void print_hex(char * ptr, unsigned len){
    unsigned i;
    for(i = 0; i < len; i ++){
        if(!(i & 0xf)) printf("\n");
        printf("%x ", ptr[i]);
    }
}

void read_maps(){
    char buf[0x1000];

    int fd = open("/proc/self/maps", O_RDONLY);
    read(fd, buf, 0x1000);
    printf("%s", buf);
    close(fd);    
}

unsigned long long find_base(){
    char buf[0x1000];
    unsigned long long res = 0;

    FILE * fp = fopen("/proc/self/maps", "r");
    while(fgets(buf, 0x1000, fp) != NULL){
    if (!!strstr(buf, "libnative-lib.so")){
            *strchr(buf, '-') = '\0';
            res = strtoll(buf, NULL, 16);
            break;
        }
    }
    fclose(fp);
    return res;
}

static void *resolve(void *lib, const char *name) {
  void *sym;
  sym = dlsym(lib, name);
  printf("[D] Symbol %s is at %p\n", name, sym);
  return sym;
}

void handler(int sig, siginfo_t* siginfo, void* context)
{
    ucontext_t * uc;
    int i;

    uc = (ucontext_t *) context;

    printf("[-] signal %d\n", siginfo->si_signo);
    printf("[-] signal from %lx in %lx\n", uc->uc_mcontext.fault_address, uc->uc_mcontext.pc);
    for(i = 0; i < 31; i++){
        printf("r%d : 0x%llx\n", i, uc->uc_mcontext.regs[i]);
    }
    //dump_hex(uc->uc_mcontext.sp, 0x20);
    exit(1);
}


int main(int argc, char *argv[]){
    struct sigaction act;
	memset(&act, 0, sizeof(sigaction));
	act.sa_sigaction = handler;
	act.sa_flags = SA_SIGINFO;

    if (sigaction(SIGSEGV, &act, NULL) < 0) {
        printf("[-] signal handler register failed...");
        return 1;
    }

    char buf[3];
    int i,j;

    void *base = dlopen("./libnative-lib.so", RTLD_NOW); 

    char meat_table[0xff] = {0,};
    char soul_table[0xff] = {0,};
    char god_table[0xff] = {0,};
    
    if(!base){
        printf("[-] dlopen failed...");
        printf("[-] error: %s\n",  dlerror());
    }
    else{
        //why the fuck dlopen return gibberish???
        // fine i'll find it manually
        base = (void *)find_base();
        printf("[+] library base : %p\n", base);
    }

    //#define SYM(n) n = resolve(base, #n)
    //    SYM(meatbox);
    //    SYM(soulbox);
    //    SYM(godbox);
    //#undef SYM

    meatbox = (char *)base + MEATBOX_OFFSET;
    soulbox = (char *)base + SOULBOX_OFFSET;
    godbox = (char *)base + GODBOX_OFFSET;
    int * enc_vals = (char *)base + RES_ARR_OFFSET;

    read_maps();
    printf("[+] meatbox at %p\n", meatbox);
    printf("[+] soulbox at %p\n", soulbox);
    printf("[+] godbox at %p\n", godbox);

    printf("%p ", meatbox("1"));
    //print_hex(meatbox("1"), 0x8);

    for(i = 0; i < 0x100; i++){
        buf[0] = i;
        buf[1] = '\0';
        meat_table[i] = *(char *)(*meatbox)(buf);
    }
    for(i = 0; i < 0x100; i++){
        buf[0] = i;
        buf[1] = '\0';
        soul_table[i] = *(char *)(*soulbox)(buf);
    }
    for(i = 0; i < 0x100; i++){
        buf[0] = i;
        buf[1] = '\0';
        god_table[i] = *(char *)(*godbox)(buf);
    }

    for(i = 0 ; i < 153 ; i += 3){
        //printf("%x %x %x\n", enc_vals[i * 4], enc_vals[i * 4 + 1],enc_vals[i * 4 + 2]);
        for(j = 0; j < 0x100; j++){
            if (enc_vals[i] == meat_table[j] &&
                enc_vals[i + 1] ==  soul_table[j] &&
                enc_vals[i + 2] == god_table[j]){
                    printf("%c", j);
            }
        }
    }

    return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment