Skip to content
GitLab
Projects Groups Snippets
  • /
  • Help
    • Help
    • Support
    • Community forum
    • Submit feedback
    • Contribute to GitLab
  • Sign in / Register
  • D dynamorio
  • Project information
    • Project information
    • Activity
    • Labels
    • Members
  • Repository
    • Repository
    • Files
    • Commits
    • Branches
    • Tags
    • Contributors
    • Graph
    • Compare
  • Issues 1,467
    • Issues 1,467
    • List
    • Boards
    • Service Desk
    • Milestones
  • Merge requests 44
    • Merge requests 44
  • CI/CD
    • CI/CD
    • Pipelines
    • Jobs
    • Schedules
  • Deployments
    • Deployments
    • Environments
    • Releases
  • Packages and registries
    • Packages and registries
    • Package Registry
    • Infrastructure Registry
  • Monitor
    • Monitor
    • Incidents
  • Analytics
    • Analytics
    • Value stream
    • CI/CD
    • Repository
  • Wiki
    • Wiki
  • Snippets
    • Snippets
  • Activity
  • Graph
  • Create a new issue
  • Jobs
  • Commits
  • Issue Boards
Collapse sidebar
  • DynamoRIO
  • dynamorio
  • Issues
  • #3543
Closed
Open
Issue created Apr 15, 2019 by Administrator@rootContributor

Private loading not working on Android 9

Created by: summershrimp

The Bionic library for Android 9 have changes from Android 6 that fails dynamorio.

Below is a small trick to get it working, but not a perfectly way.

In order to running dynamorio on android9-arm64, we change privload_call_lib_func

diff --git a/core/unix/loader.c b/core/unix/loader.c
index 89d5d31c..00c3519e 100644
--- a/core/unix/loader.c
+++ b/core/unix/loader.c
@@ -911,7 +911,7 @@ privload_call_lib_func(fp_t func)
      */
     dummy_argv[0] = dummy_str;
     dummy_argv[1] = NULL;
-    func(1, dummy_argv, our_environ);
+    //func(1, dummy_argv, our_environ);
 }

 bool

Firstly, we thought programs with init or init_array would behave abnormal, but a few testcases shows that It's working perfectly. Then we thought the module load callback would behave abnormal, but it also works.

The question is, what's really happening when call init functions from dynamorio privload? What would failed if we don't call init functions from dynamorio privload?

PS. Testing with libinscount.so with patch below.

+++ b/api/samples/inscount.cpp
@@ -85,6 +85,14 @@ static dr_emit_flags_t
 event_app_instruction(void *drcontext, void *tag, instrlist_t *bb, instr_t *inst,
                       bool for_trace, bool translating, void *user_data);

+static void
+event_module_load(void *drcontext, const module_data_t *info, bool loaded)
+{
+    const char *module_name = dr_module_preferred_name(info);
+    dr_fprintf(STDOUT, "Module Name: %s\n", module_name);
+
+}
+
 DR_EXPORT void
 dr_client_main(client_id_t id, int argc, const char *argv[])
 {
@@ -108,6 +116,7 @@ dr_client_main(client_id_t id, int argc, const char *argv[])
     dr_register_exit_event(event_exit);
     drmgr_register_bb_instrumentation_event(event_bb_analysis, event_app_instruction,
                                             NULL);
+    drmgr_register_module_load_event(event_module_load);

     /* make it easy to tell, by looking at log file, which client executed */
     dr_log(NULL, DR_LOG_ALL, 1, "Client 'inscount' initializing\n");

Testing program:

bad_case.cpp:

// g++ bad_case.cpp -o bad_case.so -fPIC -shared 
#include <cassert>
#include <cstdio>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>

unsigned long global_magic;

__attribute__((constructor)) static void initall(){
    global_magic = 0xdead0000;
    printf("global_magic: %lx\n", global_magic);
}

__attribute__((destructor))  static void deinitall(){
    global_magic = 0;
    printf("global_magic: %lx\n", global_magic);
}


class BadClass{
public:
    BadClass() {
        this->magic_number = global_magic;
        this->add_number = 0xbeef;
        this->magic_number = this->magic_number + this->add_number;
    }

    bool isOK(){
        printf("%lx\n", this->magic_number);
        return this->magic_number == 0xdeadbeef;
    }

    ~BadClass() {
        printf("deconstruct\n");
        this->magic_number = 0;
    }

private:
    unsigned long magic_number;
    unsigned long add_number;
};

BadClass globalbad;
extern "C"{
int bad_case(void) {
    char tmp[4096];
    int cnt;
    assert(globalbad.isOK());
    int fd = open("/proc/self/maps", O_RDONLY);
    while((cnt = read(fd, tmp, 4096)) != 0)
        write(1, tmp, cnt);
    return 0;
}
}

main.c:

// gcc main.c -o main -fPIE -pie -ldl
#include <dlfcn.h>
#include <stdlib.h>
int (*bad_case)(void);

int main(void){
    void* handle = dlopen("./bad_case.so", RTLD_LAZY);
    if(!handle) {
        perror("dlopen");
        exit(-1);
    }
    bad_case = dlsym(handle, "bad_case");
    if(!bad_case) {
        perror("dlsym");
        exit(-1);
    }

    bad_case();
}
Assignee
Assign to
Time tracking