1
1
/*
2
- * Copyright 2023 AeroStun
2
+ * Copyright 2023-2024 AeroStun
3
3
*
4
4
* Licensed under the Apache License, Version 2.0 (the "License");
5
5
* you may not use this file except in compliance with the License.
16
16
#include < cassert>
17
17
#include < cstddef>
18
18
#include < cstdint>
19
+ #include < cstring>
19
20
#include < map>
20
- #include < string>
21
21
22
22
#if defined(__linux__) && !defined(_GNU_SOURCE)
23
23
# define _GNU_SOURCE
38
38
39
39
#include < unistd.h>
40
40
41
- #include " dlhook.hxx "
41
+ #include " dlhook.h "
42
42
43
43
#if !defined(R_X86_64_JUMP_SLOT) && defined(R_X86_64_JMP_SLOT)
44
44
# define R_X86_64_JUMP_SLOT R_X86_64_JMP_SLOT
@@ -68,7 +68,7 @@ struct MaybeAddr {
68
68
using DlLinkMap = struct link_map ;
69
69
70
70
struct ObjectPltData {
71
- void * plt_addr_base{nullptr };
71
+ std:: uintptr_t plt_addr_base{0U };
72
72
73
73
const Elf64_Sym* dynsym{nullptr };
74
74
@@ -138,7 +138,7 @@ static const DlLinkMap* get_lmap_for_handle(void* const handle) {
138
138
}
139
139
140
140
template <class T >
141
- void force_write (T& dst, const T value) {
141
+ static void force_write (T& dst, const T value) {
142
142
#if defined(__linux__)
143
143
// Set new target using FOLL_FORCE
144
144
const int proc_self_mem = get_state ().proc_self_mem ;
@@ -170,7 +170,7 @@ void force_write(T& dst, const T value) {
170
170
static ObjectPltData inspect_object (DlLinkMap const * obj_lmap) {
171
171
ObjectPltData ret{};
172
172
173
- ret.plt_addr_base = reinterpret_cast <void * >(obj_lmap->l_addr );
173
+ ret.plt_addr_base = reinterpret_cast <std:: uintptr_t >(obj_lmap->l_addr );
174
174
175
175
// Locate symbol table
176
176
const Elf64_Dyn* dyn_symtab = find_dyn_by_tag (obj_lmap->l_ld , DT_SYMTAB);
@@ -242,15 +242,15 @@ static ObjectPltData inspect_object(DlLinkMap const* obj_lmap) {
242
242
243
243
template <class Callback >
244
244
static void foreach_plt_or_got (const ObjectPltData& obj, Callback&& callback) {
245
- auto filter_relas = [&](const auto & rela, const Elf64_Xword reloc_type) -> bool {
245
+ auto const filter_relas = [&](const auto & rela, const Elf64_Xword reloc_type) -> bool {
246
246
if (ELF64_R_TYPE (rela.r_info ) == reloc_type) {
247
247
// Sanity check of the symbol name's index
248
248
const std::size_t idx = obj.dynsym [ELF64_R_SYM (rela.r_info )].st_name ;
249
249
if (idx + 1 > obj.dynstr_size ) {
250
250
return false ;
251
251
}
252
252
253
- return callback (obj.dynstr + idx, *static_cast <void **>(obj.plt_addr_base + rela.r_offset ));
253
+ return callback (obj.dynstr + idx, *reinterpret_cast <void **>(obj.plt_addr_base + rela.r_offset ));
254
254
}
255
255
256
256
return true ;
@@ -275,7 +275,7 @@ static ObjectPltData get_object(const DlLinkMap* lmap) {
275
275
ObjectPltData object{};
276
276
if (it == obj_cache.end ()) {
277
277
object = inspect_object (lmap);
278
- if (object.plt_addr_base == nullptr ) {
278
+ if (object.plt_addr_base == 0U ) {
279
279
return {};
280
280
}
281
281
obj_cache.emplace (lmap, object);
@@ -286,20 +286,21 @@ static ObjectPltData get_object(const DlLinkMap* lmap) {
286
286
return object;
287
287
}
288
288
289
- static MaybeAddr dlhook_sym (const DlLinkMap* lmap, const std::string_view symbol, void * const hook) {
289
+ static MaybeAddr dlhook_sym (const DlLinkMap* lmap, const char * const symbol, void * const hook) {
290
290
if (lmap == nullptr ) {
291
291
return {};
292
292
}
293
293
294
+ auto const symbol_length = std::strlen (symbol);
295
+
294
296
MaybeAddr result{};
295
- const auto callback = [symbol, hook, &result](std::string_view name, void *& ptr) -> bool {
297
+ const auto callback = [symbol, symbol_length, hook, &result](const char * const name, void *& ptr) -> bool {
296
298
// if (!name.starts_with(symbol))
297
- if (name. substr ( 0 , symbol. size ()) != symbol ) {
299
+ if (std::strncmp (name , symbol, symbol_length) != 0 ) {
298
300
// Keep going
299
301
return true ;
300
302
}
301
- name.remove_prefix (symbol.size ());
302
- if (!name.empty () && name.front () != ' @' ) {
303
+ if (name[symbol_length] != ' \0 ' && name[symbol_length] != ' @' ) {
303
304
// Keep going
304
305
return true ;
305
306
}
@@ -318,13 +319,13 @@ static MaybeAddr dlhook_sym(const DlLinkMap* lmap, const std::string_view symbol
318
319
return result;
319
320
}
320
321
321
- void * dlhook_sym (void * const handle, const std::string_view symbol, void * const hook) {
322
+ extern " C " void * dlhook_sym (void * const handle, const char * const symbol, void * const hook) {
322
323
const auto result = dlhook_sym (get_lmap_for_handle (handle), symbol, hook);
323
324
assert (result.valid );
324
325
return result.addr ;
325
326
}
326
327
327
- void dlhook_sym_all (const std::string_view symbol, void * hook) {
328
+ extern " C " void dlhook_sym_all (const char * symbol, void * hook) {
328
329
for (auto it = _r_debug.r_map ; it != nullptr ; it = it->l_next ) {
329
330
const auto result = dlhook_sym (it, symbol, hook);
330
331
if (!result.valid ) {
@@ -338,7 +339,7 @@ static void dlhook_addr(const DlLinkMap* lmap, void* original, void* hook) {
338
339
return ;
339
340
}
340
341
341
- const auto callback = [original, hook](std::string_view , void *& ptr) -> bool {
342
+ const auto callback = [original, hook](const char * , void *& ptr) -> bool {
342
343
if (ptr != original) {
343
344
// Keep going
344
345
return true ;
@@ -352,9 +353,11 @@ static void dlhook_addr(const DlLinkMap* lmap, void* original, void* hook) {
352
353
foreach_plt_or_got (get_object (lmap), callback);
353
354
}
354
355
355
- void dlhook_addr (void * handle, void * original, void * hook) { dlhook_addr (get_lmap_for_handle (handle), original, hook); }
356
+ extern " C" void dlhook_addr (void * handle, void * original, void * hook) {
357
+ dlhook_addr (get_lmap_for_handle (handle), original, hook);
358
+ }
356
359
357
- void dlhook_addr_all (void * original, void * hook) {
360
+ extern " C " void dlhook_addr_all (void * original, void * hook) {
358
361
for (auto it = _r_debug.r_map ; it != nullptr ; it = it->l_next ) {
359
362
dlhook_addr (it, original, hook);
360
363
}
0 commit comments