Add injection support for dynamic-loading libraries 16/198316/4
authorVyacheslav Cherkashin <v.cherkashin@samsung.com>
Wed, 23 Jan 2019 16:27:55 +0000 (19:27 +0300)
committerVyacheslav Cherkashin <v.cherkashin@samsung.com>
Tue, 5 Feb 2019 11:10:04 +0000 (14:10 +0300)
Change-Id: I095ffe7ea03cb93bba7ff3f8a9580cfe25d1dba5
Signed-off-by: Vyacheslav Cherkashin <v.cherkashin@samsung.com>
src/core/common.h
src/core/injector.cpp
src/lsan/lsan_adapter.cpp

index bcf7136..5138b8c 100644 (file)
@@ -29,6 +29,10 @@ AutoRelease<T, R> make_auto_release(T t, R r)
 }
 
 
+template<class T, int N>
+constexpr int ARRAY_SIZE(T(&)[N]) { return N; }
+
+
 void die();
 
 } // namespace __swap
index 12edc13..62231ef 100644 (file)
@@ -2,6 +2,9 @@
 #include <sys/mman.h>
 #include "injector.h"
 #include "internal_libc.h"
+#include "internal_libdl.h"
+#include "common.h"
+#include "log.h"
 
 
 #if __WORDSIZE == 64
@@ -154,7 +157,7 @@ static int phdr_callback(dl_phdr_info *info, size_t /*size*/, void *data) noexce
     return 0;
 }
 
-void inject(injection_info info[], unsigned long size) noexcept
+static void do_inject(injection_info info[], unsigned long size) noexcept
 {
     const injection_data inject_data = {
         .info = info,
@@ -164,5 +167,50 @@ void inject(injection_info info[], unsigned long size) noexcept
     dl_iterate_phdr(phdr_callback, const_cast<injection_data *>(&inject_data));
 }
 
+
+// TODO: Add dlopen/dlsym()'s hooks support
+static void *dl_inject_dlopen(const char *filename, int flag) noexcept;
+static void *dl_inject_dlsym(void *handle, const char *symbol) noexcept;
+
+static struct injection_info dl_hooks_info[] = {
+    INJECTION_INFO_INIT("dlopen", dl_inject_dlopen),
+    INJECTION_INFO_INIT("dlsym", dl_inject_dlsym),
+};
+
+static struct injection_info *g_info;
+static unsigned long g_info_size;
+
+static void update_modules() noexcept
+{
+    do_inject(g_info, g_info_size);
+    do_inject(dl_hooks_info, ARRAY_SIZE(dl_hooks_info));
+}
+
+static void *dl_inject_dlopen(const char *filename, int flag) noexcept
+{
+    void *handle = internal::dlopen(filename, flag);
+
+    update_modules();
+    return handle;
+}
+
+static void *dl_inject_dlsym(void *handle, const char *symbol) noexcept
+{
+    for (unsigned long i = 0; i < g_info_size; ++i) {
+        if (internal::strcmp(symbol, g_info[i].name) == 0)
+            return (void *)g_info[i].addr;
+    }
+
+    return internal::dlsym(handle, symbol);
+}
+
+void inject(injection_info info[], unsigned long size) noexcept
+{
+    g_info = info;
+    g_info_size = size;
+
+    update_modules();
+}
+
 } // namespace injector
 } // namespace __swap
index 517ff8b..90c5310 100644 (file)
@@ -116,9 +116,6 @@ static struct injector::injection_info info[] = {
 */
 };
 
-template<class T, int N>
-constexpr int ARRAY_SIZE(T(&)[N]) { return N; }
-
 
 #define DLSYM_INIT_OR_RETURN(ret_value, handle, sym_name) \
     do { \