int main() { crazy_context_t* context = crazy_context_create(); crazy_library_t* library; // Expect to find the library in the same directory than this executable. crazy_context_add_search_path_for_address(context, (void*)&main); crazy_context_set_java_vm(context, kJavaVM, JNI_VERSION_1_2); // Load libjni_lib.so, this should invoke its JNI_OnLoad() function // automatically. setenv(VARNAME, "INIT", 1); if (!crazy_library_open(&library, kJniLibName, context)) Panic("Could not open library: %s\n", crazy_context_get_error(context)); const char* env = getenv(VARNAME); if (strcmp(env, "LOADED")) Panic("JNI_OnLoad() hook was not called! %s is %s\n", VARNAME, env); crazy_library_close(library); env = getenv(VARNAME); if (strcmp(env, "UNLOADED")) Panic("JNI_OnUnload() hook was not called! %s is %s\n", VARNAME, env); // Now, change the minimum JNI version to JNI_VERSION_1_6, which should // prevent loading the library properly, since it only supports 1.2. crazy_context_set_java_vm(context, kJavaVM, JNI_VERSION_1_6); setenv(VARNAME, "INIT", 1); if (crazy_library_open(&library, kJniLibName, context)) Panic("Could load the library with JNI_VERSION_1_6 > JNI_VERSION_1_2."); // Disable the feature, this shall load the library, but not call the // JNI_OnLoad() hook. crazy_context_set_java_vm(context, NULL, 0); setenv(VARNAME, "INIT", 1); if (!crazy_library_open(&library, kJniLibName, context)) Panic("Could not load the library without a JavaVM handle !?\n"); env = getenv(VARNAME); if (strcmp(env, "INIT")) Panic("JNI_OnLoad() was called, %s is %s (expected INIT)\n", VARNAME, env); crazy_library_close(library); env = getenv(VARNAME); if (strcmp(env, "INIT")) Panic( "JNI_OnUnload() was called, %s is %s (expected INIT)\n", VARNAME, env); crazy_context_destroy(context); return 0; }
int main() { String exe_path = GetCurrentExecutableDirectory(); TempDirectory temp_dir_1; TempDirectory temp_dir_2; // List of symbols in original libfoo.so and libfoo2.so, respectively. static const char* const kFooSymbols[] = {"Foo", NULL}; static const char* const kFoo2Symbols[] = {"Foo2", NULL}; // Copy libfoo.so to $TMPDIR1/libfoo.so CopyFile("libfoo.so", exe_path.c_str(), "libfoo.so", temp_dir_1.path()); // Copy libfoo2.so to $TMPDIR2/libfoo.so CopyFile("libfoo2.so", exe_path.c_str(), "libfoo.so", temp_dir_2.path()); // Create a new context object. crazy_context_t* context = crazy_context_create(); crazy_library_t* library; // Reset search paths to a non-existing directory. Check that the library // can't be loaded. setenv("LD_LIBRARY_PATH", "/this-directory-does-not-exist", 1); crazy_context_reset_search_paths(context); CheckLibraryCantLoad("libfoo.so", context); // Add the search path to the current executable, this should load the // original // libfoo.so. crazy_context_add_search_path_for_address(context, (void*)&main); CheckLibrary("libfoo.so", kFooSymbols, kFoo2Symbols, context); // Reset search paths to use $TMPDIR2 then $TMPDIR1 setenv("LD_LIBRARY_PATH", temp_dir_1.path(), 1); crazy_context_reset_search_paths(context); crazy_context_add_search_path(context, temp_dir_2.path()); // Check that the copy of libfoo2.so is loaded. CheckLibrary("libfoo.so", kFoo2Symbols, kFooSymbols, context); // Reset search paths to use only $TMPDIR1 crazy_context_reset_search_paths(context); // Check that the copy of libfoo.so is loaded. CheckLibrary("libfoo.so", kFooSymbols, kFoo2Symbols, context); crazy_context_destroy(context); return 0; }
int main() { crazy_context_t* context = crazy_context_create(); crazy_library_t* library; putenv("TEST_VAR=INIT"); // DEBUG crazy_context_set_load_address(context, 0x20000000); // Load libfoo.so if (!crazy_library_open( &library, "libfoo_with_static_constructor.so", context)) { Panic("Could not open library: %s\n", crazy_context_get_error(context)); } const char* env = getenv("TEST_VAR"); if (!env || strcmp(env, "LOADED")) Panic( "Constructors not run when loading libfoo_with_static_constructor.so"); // Find the "Foo" symbol. FunctionPtr foo_func; if (!crazy_library_find_symbol( library, "Foo", reinterpret_cast<void**>(&foo_func))) { Panic("Could not find 'Foo' in libfoo.so\n"); } // Call it. (*foo_func)(); // Close the library. printf("Closing libfoo_with_static_constructor.so\n"); crazy_library_close(library); env = getenv("TEST_VAR"); if (!env || strcmp(env, "UNLOADED")) Panic( "Destructors not run when unloading libfoo_with_static_constructor.so"); crazy_context_destroy(context); return 0; }
int main() { crazy_context_t* context = crazy_context_create(); crazy_library_t* library; // DEBUG crazy_context_set_load_address(context, 0x20000000); // Load libbar.so if (!crazy_library_open(&library, "libbar.so", context)) { Panic("Could not open library: %s\n", crazy_context_get_error(context)); } // Find the "Bar" symbol. FunctionPtr bar_func; if (!crazy_library_find_symbol( library, "Bar", reinterpret_cast<void**>(&bar_func))) { Panic("Could not find 'Bar' in libbar.so\n"); } // Call it. (*bar_func)(); // Find the "Foo" symbol from libbar.so FunctionPtr foo_func; if (!crazy_library_find_symbol( library, "Foo", reinterpret_cast<void**>(&foo_func))) { Panic("Could not find 'Foo' from libbar.so\n"); } // Close the library. printf("Closing libbar.so\n"); crazy_library_close(library); crazy_context_destroy(context); return 0; }
int main() { crazy_context_t* context = crazy_context_create(); RelroLibrary foo; int pipes[2]; if (socketpair(AF_UNIX, SOCK_STREAM, 0, pipes) < 0) Panic("Could not create socket pair: %s", strerror(errno)); pid_t child = fork(); if (child < 0) Panic("Could not fork test program!"); if (child == 0) { // In the child. crazy_context_set_load_address(context, CHILD_ADDRESS); foo.Init("libfoo_with_relro.so", context); printf("Child waiting for foo relro fd\n"); foo.ReceiveRelroInfo(pipes[0]); foo.UseSharedRelro(context); printf("RELRO used in child process\n"); CheckRelroMaps(1); FunctionPtr foo_func; if (!crazy_library_find_symbol( foo.library, "Foo", reinterpret_cast<void**>(&foo_func))) Panic("Could not find 'Foo' in library"); printf("Calling Foo()\n"); (*foo_func)(); printf("Foo called, exiting\n"); exit(0); } else { // In the parent. // Load at fixed address to simplify testing. crazy_context_set_load_address(context, PARENT_ADDRESS); foo.Init("libfoo_with_relro.so", context); printf("Library loaded\n"); printf("Parent enabling foo RELRO sharing\n"); foo.CreateSharedRelro(context, CHILD_ADDRESS); foo.SendRelroInfo(pipes[1]); printf("Relocated RELRO sent to child\n"); CheckRelroMaps(0); printf("Parent waiting for child\n"); // Wait for child to complete. int status; waitpid(child, &status, 0); if (WIFSIGNALED(status)) Panic("Child terminated by signal!!\n"); else if (WIFEXITED(status)) { int child_status = WEXITSTATUS(status); if (child_status != 0) Panic("Child terminated with status=%d\n", child_status); } else Panic("Child exited for unknown reason!!\n"); } crazy_context_destroy(context); return 0; }