日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > Android >内容正文

Android

android 禁用dlsym_Android 7.0 dlopen 函数分析

發布時間:2023/12/19 Android 28 豆豆
生活随笔 收集整理的這篇文章主要介紹了 android 禁用dlsym_Android 7.0 dlopen 函数分析 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

1. 說明

Android 7.0 后使用 dlopen 函數無法獲取 soinfo 對應,因此也無法使用 dlsym 函數去調用第三方的 so 內的函數。這里給出 dlopen() 函數的源碼分析。

不同點可參考:https://blog.csdn.net/u011247544/article/details/75262360

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_mapreaders_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_mapg_soinfo_handles_map 內,這個值與 soinfo 對應。

4. soinfo 結構體

soinfo 結構體就是 so 文件解析后的數據信息,解析處的 節信息,等等等等~~

176struct soinfo {

177 public:

178 typedef LinkedListsoinfo_list_t;

179 typedef LinkedListandroid_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& 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 template376 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::vectordt_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};

總結

以上是生活随笔為你收集整理的android 禁用dlsym_Android 7.0 dlopen 函数分析的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。

主站蜘蛛池模板: 波多野结衣简介 | 欧洲三级在线 | 免费日韩欧美 | 啦啦啦免费高清视频在线观看 | 国产亚洲欧美一区 | 中国国产毛片 | 日韩va在线观看 | 国产又粗又大又黄 | 粉嫩av.com| 91精品国产aⅴ一区 黄色a网 | 成年人视频免费在线观看 | 免费看的黄色 | 日日撸视频 | 亚洲av人人澡人人爽人人夜夜 | 91成人在线观看喷潮动漫 | 欧美在线视频免费播放 | 琪琪女色窝窝777777 | 亚洲视频手机在线观看 | 久色99| 非洲黑寡妇性猛交视频 | 精品国产欧美一区二区三区成人 | 中文字幕一区二区人妻痴汉电车 | 99视频网站 | 深夜影院在线观看 | www.污在线观看 | 日本黄色三级网站 | 手机看片久久久 | 国产片91 | 91视频网址入口 | 久久美女免费视频 | 超级碰在线观看 | 在线看片 | 国产精品毛片久久久久久 | 男女黄床上色视频免费的软件 | 亚洲妇女av | 日日摸日日碰夜夜爽av | 免费看黄在线网站 | 国产精品综合久久久 | 中文字幕亚洲无线码在线一区 | 国产成人精品无码免费看81 | 最新福利在线 | 亚洲男人网 | 久久人人精 | 久久午夜视频 | 欧美视频免费在线观看 | 黄色免费在线观看视频 | 欧美一区二区三区网站 | 啪网址| 天天干夜夜爱 | 亚洲精品少妇久久久久久 | 亚洲欧洲成人精品久久一码二码 | 激情午夜天 | 国产免费激情 | 已满18岁免费观看电视连续剧 | 狠狠入| 专业操老外 | 日韩精品视频播放 | 欧美在线一级视频 | 最新日韩av| 日韩免费视频一区 | 国产精品果冻传媒潘 | 在线不卡中文字幕 | 牛牛精品一区二区 | 国产在线伊人 | 奇米影| 黄色片免费看 | 久久久久久久久免费看无码 | 中文字幕在线视频免费播放 | 天天干天天拍 | 成av人片在线观看www | 日本高清不卡码 | 天天综合网天天综合 | 日韩欧美在线观看视频 | 妞妞影视| 亚洲AV无码成人精品一区 | 日本免费精品视频 | 东方成人av | 亚洲色妞 | 午夜不卡在线观看 | 波多野吉衣在线观看视频 | 日本午夜精品 | 国产伦精品一区二区三 | 日韩乱码人妻无码系列中文字幕 | www.桃色av嫩草.com | 插插看看 | 国产精品永久 | 欧美激情久久久 | 天天射日日| 麻豆精品视频在线观看 | 中文字幕15页 | xxxx国产| sese综合| 日本a级大片 | wwwxxx黄色片 | 米奇久久 | 亚洲av无码久久精品狠狠爱浪潮 | 日韩毛片大全 | 91禁在线看 | 99精品影视 |