精华内容
下载资源
问答
  • dlopen
    2021-05-27 13:34:02

    前言

    Python项目Git上拉去下来,以后出现如下错误


    错误如下

    Traceback (most recent call last):
      File "/Users/cunweizhao/Desktop/desktop_health_sdk/desktop_health_sdk/websocketServerTest.py", line 12, in <module>
        from data_analysis import psychic_task
      File "/Users/cunweizhao/Desktop/desktop_health_sdk/desktop_health_sdk/data_analysis.py", line 11
    更多相关内容
  • A dlopen library that bypasses mobile system limitation dyOpen A dlopen library that bypasses mobile system limitation 简介 byOpen是一个绕过移动端系统限制的dlopen库。 支持特性 Android 支持...
  • node-dlopen 本地绑定到 libuv 的 uv_dlopen() 和朋友 该模块提供对 libuv 的dlopen() 、 dlclose() 、 dlsym()和dlerror()函数的访问。 还导出了一个高级面向对象的Library类。 安装 使用npm安装: $ npm ...
  • FlexDLL:Windows的类似于dlopen的API的实现介绍在Windows下,DLL()通常用于改善代码模块化和共享。 加载程序时,可以自动加载DLL(如果需要DLL)。 该程序还可以使用Win32 API中的函数,明确要求Windows在运行时...
  • A dlopen library that bypasses mobile system limitation 简介 byOpen是一个绕过移动端系统限制的增强版dlfunctions库。 支持特性 Android 支持App中加载和使用Android系统库接口(即使maps中还没有被加载也支持)...
  • shell自动生成dlopen接口脚本,gen_uni_dl.sh通过sed命令自动生成替换dlopen库接口并替换。
  • 看字面是找不到libsqlite.so 因为我用的是融云,其实类似的第三方的IM基本都用这玩意,比如还有个环信,也是 我百度许久后发现是因为7.0为了安全性,禁止访问系统内容,恰巧这货又是系统里的,所以就找不到了,将...
  • dlopen函数详解

    2021-05-11 10:37:50
    下面列出了这些API:- dlopen,打开一个库,并为使用该库做些准备。- dlsym,在打开的库中查找符号的值。- dlclose,关闭库。- dlerror,返回一个描述最后一次调用dlopen、dlsym,或dlclose的错误信息的字符串。...

    Linux提供了一套API来动态装载库。下面列出了这些API:

    - dlopen,打开一个库,并为使用该库做些准备。

    - dlsym,在打开的库中查找符号的值。

    - dlclose,关闭库。

    - dlerror,返回一个描述最后一次调用dlopen、dlsym,或dlclose的错误信息的字符串。

    C语言用户需要包含头文件dlfcn.h才能使用上述API。glibc还增加了两个POSIX标准中没有的API:

    - dladdr,从函数指针解析符号名称和所在的文件。

    - dlvsym,与dlsym类似,只是多了一个版本字符串参数。

    在Linux上,使用动态链接的应用程序需要和库libdl.so一起链接,也就是使用选项-ldl。但是,编译时不需要和动态装载的库一起链接。程序3-1是一个在Linux上使用dl*例程的简单示例。

    延迟重定位(Lazy Relocation)

    延迟重定位/装载是一个允许符号只在需要时才重定位的特性。这常在各UNIX系统上解析函数调用时用到。当一个和共享库一起链接的应用程序几乎不会用到该共享库中的函数时,该特性被证明是非常有用的。这种情况下,只有库中的函数被应用程序调用时,共享库才会被装载,否则不会装载,因此会节约一些系统资源。但是如果把环境变量LD_BIND_NOW设置成一个非空值,所有的重定位操作都会在程序启动时进行。也可以在链接器命令行通过使用-z now链接器选项使延迟绑定对某个特定的共享库失效。需要注意的是,除非重新链接该共享库,否则对该共享库的这种设置会一直有效。

    初始化(initializing)和终止化(finalizing)函数

    有时候,以前的代码可能用到了两个特殊的函数:_init和_fini。_init和_fini函数用在装载和卸载某个模块(注释14)时分别控制该模块的构造器和析构器(或构造函数和析构函数)。他们的C语言原型如下:

    void _init(void);

    void _fini(void);

    当一个库通过dlopen()动态打开或以共享库的形式打开时,如果_init在该库中存在且被输出出来,则_init函数会被调用。如果一个库通过dlclose()动态关闭或因为没有应用程序引用其符号而被卸载时,_fini函数会在库卸载前被调用。当使用你自己的_init和_fini函数时,需要注意不要与系统启动文件一起链接。可以使用GCC选项 -nostartfiles 做到这一点。

    但是,使用上面的函数或GCC的-nostartfiles选项并不是很好的习惯,因为这可能会产生一些意外的结果。相反,库应该使用__attribute__((constructor))和__attribute__((destructor))函数属性来输出它的构造函数和析构函数。如下所示:

    void __attribute__((constructor)) x_init(void)

    void __attribute__((destructor)) x_fini(void)

    构造函数会在dlopen()返回前或库被装载时调用。析构函数会在这样几种情况下被调用:dlclose()返回前,或main()返回后,或装载库过程中exit()被调用时。

    我们通过一个例子来讲解dlopen系列函数的使用和操作:

    主程序:

    #include

    #include

    #include

    //申明结构体

    typedef struct __test {

    int i;

    void (* echo_fun)(struct __test *p);

    }Test;

    //供动态库使用的注册函数

    void __register(Test *p) {

    p->i = 1;

    p->echo_fun(p);

    }

    int main(void) {

    void *handle = NULL;

    char *myso = "./mylib.so";

    if((handle = dlopen(myso, RTLD_NOW)) == NULL) {

    printf("dlopen - %sn", dlerror());

    exit(-1);

    }

    return 0;

    }

    动态库:

    #include

    #include

    //申明结构体类型

    typedef struct __test {

    int i;

    void (*echo_fun)(struct __test *p);

    }Test;

    //申明注册函数原型

    void __register(Test *p);

    static void __printf(Test *p) {

    printf("i = %dn", p->i);

    }

    //动态库申请一个全局变量空间

    //这种 ".成员"的赋值方式为c99标准

    static Test config = {

    .i = 0,

    .echo_fun = __printf,

    };

    //加载动态库的自动初始化函数

    void _init(void) {

    printf("initn");

    //调用主程序的注册函数

    __register(&config);

    }

    主程序编译: gcc test.c -ldl -rdynamic

    动态库编译: gcc -shared -fPIC -nostartfiles -o mylib.so mylib.c

    主程序通过dlopen()加载一个.so的动态库文件, 然后动态库会自动运行 _init() 初始化函数, 初始化函数打印一个提示信息, 然后调用主程序的注册函数给结构体重新赋值, 然后调用结构体的函数指针, 打印该结构体的值. 这样就充分的达到了主程序和动态库的函数相互调用和指针的相互传递.

    gcc参数-rdynamic 用来通知链接器将所有符号添加到动态符号表中(目的是能够通过使用 dlopen 来实现向后跟踪).

    gcc参数 -fPIC 作用: 当使用.so等类的库时,当遇到多个可执行文件共用这一个库时, 在内存中,这个库就不会被复制多份,让每个可执行文件一对一的使用,而是让多个可执行文件指向一个库文件,达到共用. 宗旨:节省了内存空间,提高了空间利用率.

    展开全文
  • 1. 说明Android 7.0 后使用 dlopen 函数无法获取 soinfo 对应,因此也无法使用 dlsym 函数去调用第三方的 so 内的函数。这里给出 dlopen() 函数的源码分析。2. 源码分析1. dlopen 函数函数调用会首先走到 dlfcn.cpp ...

    1. 说明

    Android 7.0 后使用 dlopen 函数无法获取 soinfo 对应,因此也无法使用 dlsym 函数去调用第三方的 so 内的函数。这里给出 dlopen() 函数的源码分析。

    2. 源码分析

    1. dlopen 函数

    函数调用会首先走到 dlfcn.cpp 类内的 dlopen 函数(/bionic/linker/dlfcn.cpp)

    85void* dlopen(const char* filename, int flags) {

    86 void* caller_addr = __builtin_return_address(0);

    87 return dlopen_ext(filename, flags, nullptr, caller_addr);

    88}

    69static void* dlopen_ext(const char* filename, int flags,

    70 const android_dlextinfo* extinfo, void* caller_addr) {

    71 ScopedPthreadMutexLocker locker(&g_dl_mutex);

    72 void* result = do_dlopen(filename, flags, extinfo, caller_addr); // 调到 linker.cpp 类内

    73 if (result == nullptr) {

    74 __bionic_format_dlerror("dlopen failed", linker_get_error_buffer());

    75 return nullptr;

    76 }

    77 return result;

    78}

    2. do_dlopen() 函数

    这个函数实现在 linker.cpp 类内。do_dlopen 函数会调用 find_library 函数返回 soinfo 对象,并最终调用 si->to_handle() 函数返回 handle_。(/bionic/linker/linker.cpp)

    2333void* do_dlopen(const char* name, int flags, const android_dlextinfo* extinfo,

    2334 void* caller_addr) {

    2335 soinfo* const caller = find_containing_library(caller_addr);

    2336

    2337 if ((flags & ~(RTLD_NOW|RTLD_LAZY|RTLD_LOCAL|RTLD_GLOBAL|RTLD_NODELETE|RTLD_NOLOAD)) != 0) {

    2338 DL_ERR("invalid flags to dlopen: %x", flags);

    2339 return nullptr;

    2340 }

    2341

    2342 android_namespace_t* ns = get_caller_namespace(caller);

    2343

    2344 if (extinfo != nullptr) {

    2345 if ((extinfo->flags & ~(ANDROID_DLEXT_VALID_FLAG_BITS)) != 0) {

    2346 DL_ERR("invalid extended flags to android_dlopen_ext: 0x%" PRIx64, extinfo->flags);

    2347 return nullptr;

    2348 }

    2349

    2350 if ((extinfo->flags & ANDROID_DLEXT_USE_LIBRARY_FD) == 0 &&

    2351 (extinfo->flags & ANDROID_DLEXT_USE_LIBRARY_FD_OFFSET) != 0) {

    2352 DL_ERR("invalid extended flag combination (ANDROID_DLEXT_USE_LIBRARY_FD_OFFSET without "

    2353 "ANDROID_DLEXT_USE_LIBRARY_FD): 0x%" PRIx64, extinfo->flags);

    2354 return nullptr;

    2355 }

    2356

    2357 if ((extinfo->flags & ANDROID_DLEXT_LOAD_AT_FIXED_ADDRESS) != 0 &&

    2358 (extinfo->flags & (ANDROID_DLEXT_RESERVED_ADDRESS | ANDROID_DLEXT_RESERVED_ADDRESS_HINT)) != 0) {

    2359 DL_ERR("invalid extended flag combination: ANDROID_DLEXT_LOAD_AT_FIXED_ADDRESS is not "

    2360 "compatible with ANDROID_DLEXT_RESERVED_ADDRESS/ANDROID_DLEXT_RESERVED_ADDRESS_HINT");

    2361 return nullptr;

    2362 }

    2363

    2364 if ((extinfo->flags & ANDROID_DLEXT_USE_NAMESPACE) != 0) {

    2365 if (extinfo->library_namespace == nullptr) {

    2366 DL_ERR("ANDROID_DLEXT_USE_NAMESPACE is set but extinfo->library_namespace is null");

    2367 return nullptr;

    2368 }

    2369 ns = extinfo->library_namespace;

    2370 }

    2371 }

    2372

    2373 ProtectedDataGuard guard;

    2374 soinfo* si = find_library(ns, name, flags, extinfo, caller); // 这里往下调用返回 soinfo 对象

    2375 if (si != nullptr) {

    2376 si->call_constructors();

    2377 return si->to_handle(); // 这里返回的是 调用 to_handle() 函数

    2378 }

    2379

    2380 return nullptr;

    2381}

    下面给处 find_library 函数的追踪:

    首先是 find_library 函数

    2159static soinfo* find_library(android_namespace_t* ns,

    2160 const char* name, int rtld_flags,

    2161 const android_dlextinfo* extinfo,

    2162 soinfo* needed_by) {

    2163 soinfo* si;

    2164

    2165 if (name == nullptr) {

    2166 si = somain;

    2167 } else if (!find_libraries(ns, needed_by, &name, 1, &si, nullptr, 0, rtld_flags,

    2168 extinfo, /* add_as_children */ false)) {

    2169 return nullptr;

    2170 }

    2171

    2172 return si;

    2173}

    接着是 find_libraries 函数,源码分析知道这个函数分为 4 步,暂未做具体分析

    1994static bool find_libraries(android_namespace_t* ns,

    1995 soinfo* start_with,

    1996 const char* const library_names[],

    1997 size_t library_names_count, soinfo* soinfos[],

    1998 std::vector* ld_preloads,

    1999 size_t ld_preloads_count, int rtld_flags,

    2000 const android_dlextinfo* extinfo,

    2001 bool add_as_children) {

    2002 // Step 0: prepare.

    2003 LoadTaskList load_tasks;

    2004 std::unordered_map readers_map;

    ...

    2053 if(!find_library_internal(ns, task, &zip_archive_cache, &load_tasks, rtld_flags)) {

    2054 return false;

    2055 }

    ...

    2156 return linked;

    2157}

    然后是 find_library_internal 函数

    1896static bool find_library_internal(android_namespace_t* ns,

    1897 LoadTask* task,

    1898 ZipArchiveCache* zip_archive_cache,

    1899 LoadTaskList* load_tasks,

    1900 int rtld_flags) {

    1901 soinfo* candidate;

    1902

    1903 if (find_loaded_library_by_soname(ns, task->get_name(), &candidate)) {

    1904 task->set_soinfo(candidate);

    1905 return true;

    1906 }

    1907

    1908 if (ns != &g_default_namespace) {

    1909 // check public namespace

    1910 candidate = g_public_namespace.find_if([&](soinfo* si) {

    1911 return strcmp(task->get_name(), si->get_soname()) == 0;

    1912 });

    1913

    1914 if (candidate != nullptr) {

    1915 ns->add_soinfo(candidate);

    1916 task->set_soinfo(candidate);

    1917 return true;

    1918 }

    1919 }

    1920

    1921 // Library might still be loaded, the accurate detection

    1922 // of this fact is done by load_library.

    1923 TRACE("[ \"%s\" find_loaded_library_by_soname failed (*candidate=%s@%p). Trying harder...]",

    1924 task->get_name(), candidate == nullptr ? "n/a" : candidate->get_realpath(), candidate);

    1925

    1926 if (load_library(ns, task, zip_archive_cache, load_tasks, rtld_flags)) {

    1927 return true;

    1928 } else {

    1929 // In case we were unable to load the library but there

    1930 // is a candidate loaded under the same soname but different

    1931 // sdk level - return it anyways.

    1932 if (candidate != nullptr) {

    1933 task->set_soinfo(candidate);

    1934 return true;

    1935 }

    1936 }

    1937

    1938 return false;

    1939}

    3. soinfo::to_handle() 函数

    (/bionic/linker/linker.cpp)

    do_dlopen 函数的最终返回是这个函数的返回,看下 这个函数的实现:

    3442void* soinfo::to_handle() {

    3443 if (get_application_target_sdk_version() <= 23 || !has_min_version(3)) {

    3444 return this;

    3445 }

    3446

    3447 return reinterpret_cast(get_handle());

    3448}

    然后调用了 get_handle() 函数。这个函数就是返回了 handle_

    3436uintptr_t soinfo::get_handle() const {

    3437 CHECK(has_min_version(3));

    3438 CHECK(handle_ != 0);

    3439 return handle_;

    3440}

    那 handle_ 的生成是在哪里呢?是在同目录下的 generate_handle 函数

    3450void soinfo::generate_handle() {

    3451 CHECK(has_min_version(3));

    3452 CHECK(handle_ == 0); // Make sure this is the first call

    3453

    3454 // Make sure the handle is unique and does not collide

    3455 // with special values which are RTLD_DEFAULT and RTLD_NEXT.

    3456 do {

    3457 arc4random_buf(&handle_, sizeof(handle_));

    3458 // the least significant bit for the handle is always 1

    3459 // making it easy to test the type of handle passed to

    3460 // dl* functions.

    3461 handle_ = handle_ | 1;

    3462 } while (handle_ == reinterpret_cast(RTLD_DEFAULT) ||

    3463 handle_ == reinterpret_cast(RTLD_NEXT) ||

    3464 g_soinfo_handles_map.find(handle_) != g_soinfo_handles_map.end());

    3465

    3466 g_soinfo_handles_map[handle_] = this;

    3467}

    由上可以看出, handle_ 是 arc4random_buf(&handle_, sizeof(handle_)); 函数生成的随机值。并将这个值放到 static std::unordered_map g_soinfo_handles_map 内,这个值与 soinfo 对应。

    4. soinfo 结构体

    soinfo 结构体就是 so 文件解析后的数据信息,解析处的 节信息,等等等等~~

    176struct soinfo {

    177 public:

    178 typedef LinkedList soinfo_list_t;

    179 typedef LinkedList android_namespace_list_t;

    180#if defined(__work_around_b_24465209__)

    181 private:

    182 char old_name_[SOINFO_NAME_LEN];

    183#endif

    184 public:

    185 const ElfW(Phdr)* phdr;

    186 size_t phnum;

    187 ElfW(Addr) entry;

    188 ElfW(Addr) base;

    189 size_t size;

    190

    191#if defined(__work_around_b_24465209__)

    192 uint32_t unused1; // DO NOT USE, maintained for compatibility.

    193#endif

    194

    195 ElfW(Dyn)* dynamic;

    196

    197#if defined(__work_around_b_24465209__)

    198 uint32_t unused2; // DO NOT USE, maintained for compatibility

    199 uint32_t unused3; // DO NOT USE, maintained for compatibility

    200#endif

    201

    202 soinfo* next;

    203 private:

    204 uint32_t flags_;

    205

    206 const char* strtab_;

    207 ElfW(Sym)* symtab_;

    208

    209 size_t nbucket_;

    210 size_t nchain_;

    211 uint32_t* bucket_;

    212 uint32_t* chain_;

    213

    214#if defined(__mips__) || !defined(__LP64__)

    215 // This is only used by mips and mips64, but needs to be here for

    216 // all 32-bit architectures to preserve binary compatibility.

    217 ElfW(Addr)** plt_got_;

    218#endif

    219

    220#if defined(USE_RELA)

    221 ElfW(Rela)* plt_rela_;

    222 size_t plt_rela_count_;

    223

    224 ElfW(Rela)* rela_;

    225 size_t rela_count_;

    226#else

    227 ElfW(Rel)* plt_rel_;

    228 size_t plt_rel_count_;

    229

    230 ElfW(Rel)* rel_;

    231 size_t rel_count_;

    232#endif

    233

    234 linker_function_t* preinit_array_;

    235 size_t preinit_array_count_;

    236

    237 linker_function_t* init_array_;

    238 size_t init_array_count_;

    239 linker_function_t* fini_array_;

    240 size_t fini_array_count_;

    241

    242 linker_function_t init_func_;

    243 linker_function_t fini_func_;

    244

    245#if defined(__arm__)

    246 public:

    247 // ARM EABI section used for stack unwinding.

    248 uint32_t* ARM_exidx;

    249 size_t ARM_exidx_count;

    250 private:

    251#elif defined(__mips__)

    252 uint32_t mips_symtabno_;

    253 uint32_t mips_local_gotno_;

    254 uint32_t mips_gotsym_;

    255 bool mips_relocate_got(const VersionTracker& version_tracker,

    256 const soinfo_list_t& global_group,

    257 const soinfo_list_t& local_group);

    258#if !defined(__LP64__)

    259 bool mips_check_and_adjust_fp_modes();

    260#endif

    261#endif

    262 size_t ref_count_;

    263 public:

    264 link_map link_map_head;

    265

    266 bool constructors_called;

    267

    268 // When you read a virtual address from the ELF file, add this

    269 // value to get the corresponding address in the process' address space.

    270 ElfW(Addr) load_bias;

    271

    272#if !defined(__LP64__)

    273 bool has_text_relocations;

    274#endif

    275 bool has_DT_SYMBOLIC;

    276

    277 public:

    278 soinfo(android_namespace_t* ns, const char* name, const struct stat* file_stat,

    279 off64_t file_offset, int rtld_flags);

    280 ~soinfo();

    281

    282 void call_constructors();

    283 void call_destructors();

    284 void call_pre_init_constructors();

    285 bool prelink_image();

    286 bool link_image(const soinfo_list_t& global_group, const soinfo_list_t& local_group,

    287 const android_dlextinfo* extinfo);

    288 bool protect_relro();

    289

    290 void add_child(soinfo* child);

    291 void remove_all_links();

    292

    293 ino_t get_st_ino() const;

    294 dev_t get_st_dev() const;

    295 off64_t get_file_offset() const;

    296

    297 uint32_t get_rtld_flags() const;

    298 uint32_t get_dt_flags_1() const;

    299 void set_dt_flags_1(uint32_t dt_flags_1);

    300

    301 soinfo_list_t& get_children();

    302 const soinfo_list_t& get_children() const;

    303

    304 soinfo_list_t& get_parents();

    305

    306 bool find_symbol_by_name(SymbolName& symbol_name,

    307 const version_info* vi,

    308 const ElfW(Sym)** symbol) const;

    309

    310 ElfW(Sym)* find_symbol_by_address(const void* addr);

    311 ElfW(Addr) resolve_symbol_address(const ElfW(Sym)* s) const;

    312

    313 const char* get_string(ElfW(Word) index) const;

    314 bool can_unload() const;

    315 bool is_gnu_hash() const;

    316

    317 bool inline has_min_version(uint32_t min_version __unused) const {

    318#if defined(__work_around_b_24465209__)

    319 return (flags_ & FLAG_NEW_SOINFO) != 0 && version_ >= min_version;

    320#else

    321 return true;

    322#endif

    323 }

    325 bool is_linked() const;

    326 bool is_linker() const;

    327 bool is_main_executable() const;

    328

    329 void set_linked();

    330 void set_linker_flag();

    331 void set_main_executable();

    332 void set_nodelete();

    333

    334 void increment_ref_count();

    335 size_t decrement_ref_count();

    336

    337 soinfo* get_local_group_root() const;

    338

    339 void set_soname(const char* soname);

    340 const char* get_soname() const;

    341 const char* get_realpath() const;

    342 const ElfW(Versym)* get_versym(size_t n) const;

    343 ElfW(Addr) get_verneed_ptr() const;

    344 size_t get_verneed_cnt() const;

    345 ElfW(Addr) get_verdef_ptr() const;

    346 size_t get_verdef_cnt() const;

    347

    348 bool find_verdef_version_index(const version_info* vi, ElfW(Versym)* versym) const;

    349

    350 uint32_t get_target_sdk_version() const;

    351

    352 void set_dt_runpath(const char *);

    353 const std::vector<:string>& get_dt_runpath() const;

    354 android_namespace_t* get_primary_namespace();

    355 void add_secondary_namespace(android_namespace_t* secondary_ns);

    356

    357 void set_mapped_by_caller(bool reserved_map);

    358 bool is_mapped_by_caller() const;

    359

    360 uintptr_t get_handle() const;

    361 void generate_handle();

    362 void* to_handle();

    363

    364 private:

    365 bool elf_lookup(SymbolName& symbol_name, const version_info* vi, uint32_t* symbol_index) const;

    366 ElfW(Sym)* elf_addr_lookup(const void* addr);

    367 bool gnu_lookup(SymbolName& symbol_name, const version_info* vi, uint32_t* symbol_index) const;

    368 ElfW(Sym)* gnu_addr_lookup(const void* addr);

    369

    370 bool lookup_version_info(const VersionTracker& version_tracker, ElfW(Word) sym,

    371 const char* sym_name, const version_info** vi);

    372

    373 void call_array(const char* array_name, linker_function_t* functions, size_t count, bool reverse);

    374 void call_function(const char* function_name, linker_function_t function);

    375 template

    376 bool relocate(const VersionTracker& version_tracker, ElfRelIteratorT&& rel_iterator,

    377 const soinfo_list_t& global_group, const soinfo_list_t& local_group);

    378

    379 private:

    380 // This part of the structure is only available

    381 // when FLAG_NEW_SOINFO is set in this->flags.

    382 uint32_t version_;

    383

    384 // version >= 0

    385 dev_t st_dev_;

    386 ino_t st_ino_;

    387

    388 // dependency graph

    389 soinfo_list_t children_;

    390 soinfo_list_t parents_;

    391

    392 // version >= 1

    393 off64_t file_offset_;

    394 uint32_t rtld_flags_;

    395 uint32_t dt_flags_1_;

    396 size_t strtab_size_;

    397

    398 // version >= 2

    399

    400 size_t gnu_nbucket_;

    401 uint32_t* gnu_bucket_;

    402 uint32_t* gnu_chain_;

    403 uint32_t gnu_maskwords_;

    404 uint32_t gnu_shift2_;

    405 ElfW(Addr)* gnu_bloom_filter_;

    406

    407 soinfo* local_group_root_;

    408

    409 uint8_t* android_relocs_;

    410 size_t android_relocs_size_;

    411

    412 const char* soname_;

    413 std::string realpath_;

    414

    415 const ElfW(Versym)* versym_;

    416

    417 ElfW(Addr) verdef_ptr_;

    418 size_t verdef_cnt_;

    419

    420 ElfW(Addr) verneed_ptr_;

    421 size_t verneed_cnt_;

    422

    423 uint32_t target_sdk_version_;

    424

    425 // version >= 3

    426 std::vector<:string> dt_runpath_;

    427 android_namespace_t* primary_namespace_;

    428 android_namespace_list_t secondary_namespaces_;

    429 uintptr_t handle_;

    430

    431 friend soinfo* get_libdl_info();

    432};

    展开全文
  • linux提供了加载和处理动态链接库的系统调用,非常方便。本文先从使用上进行总结,涉及到基本的操作方法,关于动态链接库的本质及如何加载进来
  • dlopen-dlsym-dlclose函数介绍,具体介绍该函数定义、使用等
  • dlopen函数使用示例

    2022-05-31 19:48:42
    cat dlopen.c #include <stdio.h> #include <dlfcn.h> int main(int argc, char *argv) { int index = -1; void *handle; int (*get_index)(int); int ret = -1; // 获取handle handle = ...

    cat dlopen.c

    #include <stdio.h>
    #include <dlfcn.h>
    
    int main(int argc, char *argv)
    {
            int index = -1;
            void *handle;
            int (*get_index)(int);
            int ret = -1;
    
    		// 获取handle
            handle = dlopen("./liba.so", RTLD_NOW);
            if (handle == NULL) {
                    printf("dlopen error!:%s\n", dlerror());
                    return -1;
            }
    
    		//获取函数,get_card_index为so中的实现函数,get_index指向该函数;
            get_index = dlsym(handle, "get_card_index");
            if (get_index == NULL) {
                    printf("dlsym error!\n");
                    dlclose(handle);
                    return -1;
            }
    
            ret = get_index(index);
            printf("ret:%d\n", ret);
    
    		// 关闭该handle
    		dlclose(handle);
            return 0;
    }
    

    cat test.c

    int get_card_index(int num)
    {
            return 123;
    }
    

    cat test.h

    int get_car_index(int num);
    

    编译和执行过程

    syli@lishengyu-pc:~/work/tmp$ gcc -fPIC -shared -o liba.so test.c
    syli@lishengyu-pc:~/work/tmp$ gcc dlopen.c -ldl
    syli@lishengyu-pc:~/work/tmp$ ./a.out 
    ret:123
    
    展开全文
  • C++ dlopen使用

    2022-02-13 10:55:04
    C++ dlopen使用 Loading Functions Loading Functions In C++ functions are loaded just like in C, with dlsym. The functions you want to load must be qualified as extern “C” to avoid the symbol name ...
  • dlopen系列函数详解

    千次阅读 2021-07-29 10:44:08
    下面列出了这些API: dlopen:该函数将打开一个新库,并把它装入内存。该函数主要用来加载库中的符号,这些符号在编译的时候是不知道的。这种机制使得在系统中添加或者删除一个模块时,都不需要重新进行编译。 ...
  • 显性调用,如果程序没有运行到dlopen,动态库文件xxx.so 是不需要拷贝到相关目录下的,程序只有在执行到dlopen时,才会检查该动态库,是一种插件形式,随用随调用。 显性调用,程序开始运行后,不会立刻读取动态库...
  • Android9.0中在activity的onCreate之前hook dlopen函数,如果需要返回值(即修改了LR寄存器),那么会触发:E/libEGL: EGL_ANDROID_blob_cache advertised, but unable to get eglSetBlobCacheFuncsANDROID。...
  • Android9.0中在activity的onCreate之前hook dlopen函数,如果需要返回值(即修改了LR寄存器),那么会触发:E/libEGL: EGL_ANDROID_blob_cache advertised, but unable to get eglSetBlobCacheFuncsANDROID。...
  • dlopen() dlopen()函数用来打开一个动态库,并将其加载到进程的地址空间,完成初始化过程,它的原型定义为: void *dlopen(const char *filename, int flags); 第一个参数是被加载动态库的路径,如果这个路径是绝对...
  • dlopen()

    千次阅读 2021-05-25 03:19:14
    4.1. dlopen()dlopen函数打开一个函数库然后为后面的使用做准备。C语言原形是:void * dlopen(const char *filename, int flag);如果文件名filename是以“/”开头,也就是使用绝对路径,那么dlopne就直接使用它,而...
  • dlopen

    千次阅读 2019-03-08 17:51:49
    编译时候要加入 -ldl (指定dl库) dlopen 基本定义
  • 背景 为了是不同的逻辑解耦,一般会把各个业务封装成动态库,然后主逻辑去调用各个插件。 demo 生产动态库 int add(int a,int b) { return (a + b); } ...int sub(int a, int b) ...void *dlopen(const char *
  • dlopen函数

    2021-07-24 11:44:11
    dlopen如果第一个参数是NULL,则表示打开当前进程的已经加载的符号表 如果第一个参数不是NULL,则表示打开目标文件so中符号表
  • : Error[java.lang.UnsatisfiedLinkError: dlopen failed: /data/app-lib/hecaiyun_CMCC/libFastKDCore.so: has text relocations 07-13 10:33:13.361 11237 11237 E Exception:: at java.lang.Runtime.loadLibrary0...
  • 前言[toc]对于自动化hook Il2cpp 的模块来说, dlopen 的hook相当于一个大门, 没有该大门口, 一切都是纸上谈兵在 armabi-v7a 上hook dlopen, 轻松的不要不要的, 甚至借用一下 virtual 系列app的 va++ 核心提供的 hook...
  • 目录 一、函数介绍 二、实现热更新 一、函数介绍 动态加载也就是运行时加载,即可以在程序运行时由我们决定...void *dlopen(const char *filename, int flags); // 通过句柄获取共享对象或可执行文件中符号的.
  • 采用dlopen、dlsym、dlclose加载动态链接库转载请标注,熬夜写的文章,挺辛苦 ...环境系统: 16.04.1-Ubuntu编译器: gnu 5.4.0python: 2.7.12参考dlopen、dlsym及dlclose 基本使用// file : add.cint add(int a, ...
  • Linux 下dlopen的使用

    2022-03-04 11:28:17
    dlopen() 功能:打开一个动态链接库 包含头文件: #include <dlfcn.h> 函数定义: void *dlopen(const char *pathname,int mode); 二、函数描述: dlopen()函数以指定模式打开指定的动态连接库文件,并...
  • - dlopen,打开一个库,并为使用该库作些准备。spa - dlsym,在打开的库中查找符号的值。命令行 - dlclose,关闭库。指针 - dlerror,返回一个描述最后一次调用dlopen、dlsym,或dlclose的错误信息的字符串。code...
  • Android NDK开发时,如果开启多线程加速,需要用到openMP库,一些版本的差异,会出现dlopen failed: library "libomp.so" not found的错误 网上github有很多讨论和解决方法,不过我试了很多个都
  • dlopen参数总结

    2021-03-24 20:13:15
    void * dlopen(const char *pathname, int mode); 返回一个void *类型的handle,否则返回NULL。 pathname就是所要打开的动态库,如果这个库声明链接了其它库,即对其它库有依赖关系,那么所有相关有依赖关系的库...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 21,894
精华内容 8,757
关键字:

dlopen