DynamoRIO / DynamoRIO/dynamorio
Private loading not working on Android 9
- Dominant language
- C
- Stars
- 3.2k
- Forks
- 629
- Avg merge
- 2d 18h
- Merged PRs (30d)
- 30
Description
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`
```patch
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.
```patch
+++ 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:
``` C++
// g++ bad_case.cpp -o bad_case.so -fPIC -shared
#include
#include
#include
#include
#include
#include
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:
```C
// gcc main.c -o main -fPIE -pie -ldl
#include
#include
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();
}
```
Contributor guide
Research direction
Start in core/unix/loader.c at privload_call_lib_func and compare its behavior on Android 9 with the supplied workaround. Review api/samples/inscount.cpp and reproduce the loader behavior using bad_case.cpp and main.c. Done means identifying why initialization callbacks fail and defining a tested, correct handling strategy rather than relying on the workaround.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- c, cpp
- Domain
- operating-systems
- Issue type
- Bug
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Stale
- Clarity
- Needs clarification
- Newbie friendliness
- 25/100