mirror of
https://github.com/kavishdevar/librepods.git
synced 2026-05-14 00:16:54 +00:00
android: format l2c_fcr_hook.cpp
This commit is contained in:
@@ -30,7 +30,7 @@
|
|||||||
#include "l2c_fcr_hook.h"
|
#include "l2c_fcr_hook.h"
|
||||||
|
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#include "xz.h"
|
#include "xz.h"
|
||||||
}
|
}
|
||||||
|
|
||||||
#define LOG_TAG "LibrePodsHook"
|
#define LOG_TAG "LibrePodsHook"
|
||||||
@@ -39,13 +39,13 @@ extern "C" {
|
|||||||
|
|
||||||
static HookFunType hook_func = nullptr;
|
static HookFunType hook_func = nullptr;
|
||||||
|
|
||||||
static uint8_t (*original_l2c_fcr_chk_chan_modes)(void*) = nullptr;
|
static uint8_t (*original_l2c_fcr_chk_chan_modes)(void *) = nullptr;
|
||||||
static tBTA_STATUS (*original_BTA_DmSetLocalDiRecord)(
|
|
||||||
tSDP_DI_RECORD*, uint32_t*) = nullptr;
|
static tBTA_STATUS (*original_BTA_DmSetLocalDiRecord)(tSDP_DI_RECORD *, uint32_t *) = nullptr;
|
||||||
|
|
||||||
static std::atomic<bool> enableSdpHook(false);
|
static std::atomic<bool> enableSdpHook(false);
|
||||||
|
|
||||||
uint8_t fake_l2c_fcr_chk_chan_modes(void* p_ccb) {
|
uint8_t fake_l2c_fcr_chk_chan_modes(void *p_ccb) {
|
||||||
LOGI("fake_l2c_fcr_chk_chan_modes called");
|
LOGI("fake_l2c_fcr_chk_chan_modes called");
|
||||||
uint8_t orig = 0;
|
uint8_t orig = 0;
|
||||||
if (original_l2c_fcr_chk_chan_modes)
|
if (original_l2c_fcr_chk_chan_modes)
|
||||||
@@ -55,13 +55,13 @@ uint8_t fake_l2c_fcr_chk_chan_modes(void* p_ccb) {
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
tBTA_STATUS fake_BTA_DmSetLocalDiRecord(
|
tBTA_STATUS fake_BTA_DmSetLocalDiRecord(tSDP_DI_RECORD *p_device_info, uint32_t *p_handle) {
|
||||||
tSDP_DI_RECORD* p_device_info,
|
|
||||||
uint32_t* p_handle) {
|
|
||||||
|
|
||||||
LOGI("fake_BTA_DmSetLocalDiRecord called");
|
LOGI("fake_BTA_DmSetLocalDiRecord called");
|
||||||
|
|
||||||
if (original_BTA_DmSetLocalDiRecord && enableSdpHook.load(std::memory_order_relaxed)) original_BTA_DmSetLocalDiRecord(p_device_info, p_handle);
|
if (original_BTA_DmSetLocalDiRecord &&
|
||||||
|
enableSdpHook.load(std::memory_order_relaxed))
|
||||||
|
original_BTA_DmSetLocalDiRecord(p_device_info, p_handle);
|
||||||
|
|
||||||
LOGI("fake_BTA_DmSetLocalDiRecord: modifying vendor to 0x004C, vendor_id_source to 0x0001");
|
LOGI("fake_BTA_DmSetLocalDiRecord: modifying vendor to 0x004C, vendor_id_source to 0x0001");
|
||||||
|
|
||||||
@@ -70,14 +70,15 @@ tBTA_STATUS fake_BTA_DmSetLocalDiRecord(
|
|||||||
p_device_info->vendor_id_source = 0x0001;
|
p_device_info->vendor_id_source = 0x0001;
|
||||||
}
|
}
|
||||||
|
|
||||||
LOGI("fake_BTA_DmSetLocalDiRecord: returning status %d", original_BTA_DmSetLocalDiRecord ? original_BTA_DmSetLocalDiRecord(p_device_info, p_handle) : BTA_FAILURE);
|
LOGI("fake_BTA_DmSetLocalDiRecord: returning status %d",
|
||||||
return original_BTA_DmSetLocalDiRecord ? original_BTA_DmSetLocalDiRecord(p_device_info, p_handle) : BTA_FAILURE;
|
original_BTA_DmSetLocalDiRecord ? original_BTA_DmSetLocalDiRecord(p_device_info, p_handle)
|
||||||
|
: BTA_FAILURE);
|
||||||
|
return original_BTA_DmSetLocalDiRecord ? original_BTA_DmSetLocalDiRecord(p_device_info,
|
||||||
|
p_handle)
|
||||||
|
: BTA_FAILURE;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool decompressXZ(
|
static bool decompressXZ(const uint8_t *input, size_t input_size, std::vector<uint8_t> &output) {
|
||||||
const uint8_t* input,
|
|
||||||
size_t input_size,
|
|
||||||
std::vector<uint8_t>& output) {
|
|
||||||
|
|
||||||
LOGI("decompressXZ called with input_size: %zu", input_size);
|
LOGI("decompressXZ called with input_size: %zu", input_size);
|
||||||
|
|
||||||
@@ -86,7 +87,7 @@ static bool decompressXZ(
|
|||||||
xz_crc64_init();
|
xz_crc64_init();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
struct xz_dec* dec = xz_dec_init(XZ_DYNALLOC, 64U << 20);
|
struct xz_dec *dec = xz_dec_init(XZ_DYNALLOC, 64U << 20);
|
||||||
if (!dec) {
|
if (!dec) {
|
||||||
LOGE("decompressXZ: xz_dec_init failed");
|
LOGE("decompressXZ: xz_dec_init failed");
|
||||||
return false;
|
return false;
|
||||||
@@ -106,7 +107,8 @@ static bool decompressXZ(
|
|||||||
|
|
||||||
LOGI("decompressXZ: entering decompression loop");
|
LOGI("decompressXZ: entering decompression loop");
|
||||||
while (true) {
|
while (true) {
|
||||||
LOGI("decompressXZ: xz_dec_run iteration, buf.in_pos: %zu, buf.out_pos: %zu", buf.in_pos, buf.out_pos);
|
LOGI("decompressXZ: xz_dec_run iteration, buf.in_pos: %zu, buf.out_pos: %zu", buf.in_pos,
|
||||||
|
buf.out_pos);
|
||||||
enum xz_ret ret = xz_dec_run(dec, &buf);
|
enum xz_ret ret = xz_dec_run(dec, &buf);
|
||||||
|
|
||||||
LOGI("decompressXZ: xz_dec_run returned %d", ret);
|
LOGI("decompressXZ: xz_dec_run returned %d", ret);
|
||||||
@@ -135,10 +137,10 @@ static bool decompressXZ(
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool getLibraryPath(const char* name, std::string& out) {
|
static bool getLibraryPath(const char *name, std::string &out) {
|
||||||
LOGI("getLibraryPath called with name: %s", name);
|
LOGI("getLibraryPath called with name: %s", name);
|
||||||
|
|
||||||
FILE* fp = fopen("/proc/self/maps", "r");
|
FILE *fp = fopen("/proc/self/maps", "r");
|
||||||
if (!fp) {
|
if (!fp) {
|
||||||
LOGE("getLibraryPath: fopen failed");
|
LOGE("getLibraryPath: fopen failed");
|
||||||
return false;
|
return false;
|
||||||
@@ -150,7 +152,7 @@ static bool getLibraryPath(const char* name, std::string& out) {
|
|||||||
while (fgets(line, sizeof(line), fp)) {
|
while (fgets(line, sizeof(line), fp)) {
|
||||||
if (strstr(line, name)) {
|
if (strstr(line, name)) {
|
||||||
LOGI("getLibraryPath: found line containing %s", name);
|
LOGI("getLibraryPath: found line containing %s", name);
|
||||||
char* path = strchr(line, '/');
|
char *path = strchr(line, '/');
|
||||||
if (path) {
|
if (path) {
|
||||||
out = path;
|
out = path;
|
||||||
out.erase(out.find('\n'));
|
out.erase(out.find('\n'));
|
||||||
@@ -166,10 +168,10 @@ static bool getLibraryPath(const char* name, std::string& out) {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
static uintptr_t getModuleBase(const char* name) {
|
static uintptr_t getModuleBase(const char *name) {
|
||||||
LOGI("getModuleBase called with name: %s", name);
|
LOGI("getModuleBase called with name: %s", name);
|
||||||
|
|
||||||
FILE* fp = fopen("/proc/self/maps", "r");
|
FILE *fp = fopen("/proc/self/maps", "r");
|
||||||
if (!fp) {
|
if (!fp) {
|
||||||
LOGE("getModuleBase: fopen failed");
|
LOGE("getModuleBase: fopen failed");
|
||||||
return 0;
|
return 0;
|
||||||
@@ -192,25 +194,23 @@ static uintptr_t getModuleBase(const char* name) {
|
|||||||
return base;
|
return base;
|
||||||
}
|
}
|
||||||
|
|
||||||
static uint64_t findSymbolOffsetDynsym(
|
static uint64_t
|
||||||
const std::vector<uint8_t>& elf,
|
findSymbolOffsetDynsym(const std::vector<uint8_t> &elf, const char *symbol_substring) {
|
||||||
const char* symbol_substring) {
|
|
||||||
|
|
||||||
LOGI("findSymbolOffsetDynsym called with %s", symbol_substring);
|
LOGI("findSymbolOffsetDynsym called with %s", symbol_substring);
|
||||||
|
|
||||||
auto* eh = reinterpret_cast<const Elf64_Ehdr*>(elf.data());
|
auto *eh = reinterpret_cast<const Elf64_Ehdr *>(elf.data());
|
||||||
auto* shdr = reinterpret_cast<const Elf64_Shdr*>(
|
auto *shdr = reinterpret_cast<const Elf64_Shdr *>(
|
||||||
elf.data() + eh->e_shoff);
|
elf.data() + eh->e_shoff);
|
||||||
|
|
||||||
const char* shstr =
|
const char *shstr = reinterpret_cast<const char *>(
|
||||||
reinterpret_cast<const char*>(
|
elf.data() + shdr[eh->e_shstrndx].sh_offset);
|
||||||
elf.data() + shdr[eh->e_shstrndx].sh_offset);
|
|
||||||
|
|
||||||
const Elf64_Shdr* dynsym = nullptr;
|
const Elf64_Shdr *dynsym = nullptr;
|
||||||
const Elf64_Shdr* dynstr = nullptr;
|
const Elf64_Shdr *dynstr = nullptr;
|
||||||
|
|
||||||
for (int i = 0; i < eh->e_shnum; ++i) {
|
for (int i = 0; i < eh->e_shnum; ++i) {
|
||||||
const char* secname = shstr + shdr[i].sh_name;
|
const char *secname = shstr + shdr[i].sh_name;
|
||||||
|
|
||||||
if (!strcmp(secname, ".dynsym"))
|
if (!strcmp(secname, ".dynsym"))
|
||||||
dynsym = &shdr[i];
|
dynsym = &shdr[i];
|
||||||
@@ -223,25 +223,23 @@ static uint64_t findSymbolOffsetDynsym(
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto* symbols = reinterpret_cast<const Elf64_Sym*>(
|
auto *symbols = reinterpret_cast<const Elf64_Sym *>(
|
||||||
elf.data() + dynsym->sh_offset);
|
elf.data() + dynsym->sh_offset);
|
||||||
|
|
||||||
const char* strings =
|
const char *strings = reinterpret_cast<const char *>(
|
||||||
reinterpret_cast<const char*>(
|
elf.data() + dynstr->sh_offset);
|
||||||
elf.data() + dynstr->sh_offset);
|
|
||||||
|
|
||||||
size_t count = dynsym->sh_size / sizeof(Elf64_Sym);
|
size_t count = dynsym->sh_size / sizeof(Elf64_Sym);
|
||||||
|
|
||||||
LOGI("findSymbolOffsetDynsym: scanning %zu symbols", count);
|
LOGI("findSymbolOffsetDynsym: scanning %zu symbols", count);
|
||||||
|
|
||||||
for (size_t i = 0; i < count; ++i) {
|
for (size_t i = 0; i < count; ++i) {
|
||||||
const char* name = strings + symbols[i].st_name;
|
const char *name = strings + symbols[i].st_name;
|
||||||
|
|
||||||
if (strstr(name, symbol_substring) &&
|
if (strstr(name, symbol_substring) && ELF64_ST_TYPE(symbols[i].st_info) == STT_FUNC) {
|
||||||
ELF64_ST_TYPE(symbols[i].st_info) == STT_FUNC) {
|
|
||||||
|
|
||||||
LOGI("findSymbolOffsetDynsym: matched %s @ 0x%lx",
|
LOGI("findSymbolOffsetDynsym: matched %s @ 0x%lx", name,
|
||||||
name, (unsigned long)symbols[i].st_value);
|
(unsigned long) symbols[i].st_value);
|
||||||
|
|
||||||
return symbols[i].st_value;
|
return symbols[i].st_value;
|
||||||
}
|
}
|
||||||
@@ -251,26 +249,23 @@ static uint64_t findSymbolOffsetDynsym(
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static uint64_t findSymbolOffset(
|
static uint64_t findSymbolOffset(const std::vector<uint8_t> &elf, const char *symbol_substring) {
|
||||||
const std::vector<uint8_t>& elf,
|
|
||||||
const char* symbol_substring) {
|
|
||||||
|
|
||||||
LOGI("findSymbolOffset called with symbol_substring: %s", symbol_substring);
|
LOGI("findSymbolOffset called with symbol_substring: %s", symbol_substring);
|
||||||
|
|
||||||
auto* eh = reinterpret_cast<const Elf64_Ehdr*>(elf.data());
|
auto *eh = reinterpret_cast<const Elf64_Ehdr *>(elf.data());
|
||||||
auto* shdr = reinterpret_cast<const Elf64_Shdr*>(
|
auto *shdr = reinterpret_cast<const Elf64_Shdr *>(
|
||||||
elf.data() + eh->e_shoff);
|
elf.data() + eh->e_shoff);
|
||||||
|
|
||||||
const char* shstr =
|
const char *shstr = reinterpret_cast<const char *>(
|
||||||
reinterpret_cast<const char*>(
|
elf.data() + shdr[eh->e_shstrndx].sh_offset);
|
||||||
elf.data() + shdr[eh->e_shstrndx].sh_offset);
|
|
||||||
|
|
||||||
const Elf64_Shdr* symtab = nullptr;
|
const Elf64_Shdr *symtab = nullptr;
|
||||||
const Elf64_Shdr* strtab = nullptr;
|
const Elf64_Shdr *strtab = nullptr;
|
||||||
|
|
||||||
LOGI("findSymbolOffset: parsing ELF sections");
|
LOGI("findSymbolOffset: parsing ELF sections");
|
||||||
for (int i = 0; i < eh->e_shnum; ++i) {
|
for (int i = 0; i < eh->e_shnum; ++i) {
|
||||||
const char* secname = shstr + shdr[i].sh_name;
|
const char *secname = shstr + shdr[i].sh_name;
|
||||||
if (!strcmp(secname, ".symtab"))
|
if (!strcmp(secname, ".symtab"))
|
||||||
symtab = &shdr[i];
|
symtab = &shdr[i];
|
||||||
if (!strcmp(secname, ".strtab"))
|
if (!strcmp(secname, ".strtab"))
|
||||||
@@ -283,23 +278,22 @@ static uint64_t findSymbolOffset(
|
|||||||
}
|
}
|
||||||
LOGI("findSymbolOffset: found symtab and strtab");
|
LOGI("findSymbolOffset: found symtab and strtab");
|
||||||
|
|
||||||
auto* symbols = reinterpret_cast<const Elf64_Sym*>(
|
auto *symbols = reinterpret_cast<const Elf64_Sym *>(
|
||||||
elf.data() + symtab->sh_offset);
|
elf.data() + symtab->sh_offset);
|
||||||
|
|
||||||
const char* strings =
|
const char *strings = reinterpret_cast<const char *>(
|
||||||
reinterpret_cast<const char*>(
|
elf.data() + strtab->sh_offset);
|
||||||
elf.data() + strtab->sh_offset);
|
|
||||||
|
|
||||||
size_t count = symtab->sh_size / sizeof(Elf64_Sym);
|
size_t count = symtab->sh_size / sizeof(Elf64_Sym);
|
||||||
|
|
||||||
LOGI("findSymbolOffset: scanning %zu symbols", count);
|
LOGI("findSymbolOffset: scanning %zu symbols", count);
|
||||||
for (size_t i = 0; i < count; ++i) {
|
for (size_t i = 0; i < count; ++i) {
|
||||||
const char* name = strings + symbols[i].st_name;
|
const char *name = strings + symbols[i].st_name;
|
||||||
|
|
||||||
if (strstr(name, symbol_substring) &&
|
if (strstr(name, symbol_substring) && ELF64_ST_TYPE(symbols[i].st_info) == STT_FUNC) {
|
||||||
ELF64_ST_TYPE(symbols[i].st_info) == STT_FUNC) {
|
|
||||||
|
|
||||||
LOGI("findSymbolOffset: matched symbol %s at 0x%lx", name, (unsigned long)symbols[i].st_value);
|
LOGI("findSymbolOffset: matched symbol %s at 0x%lx", name,
|
||||||
|
(unsigned long) symbols[i].st_value);
|
||||||
|
|
||||||
return symbols[i].st_value;
|
return symbols[i].st_value;
|
||||||
}
|
}
|
||||||
@@ -309,7 +303,7 @@ static uint64_t findSymbolOffset(
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool hookLibrary(const char* libname) {
|
static bool hookLibrary(const char *libname) {
|
||||||
LOGI("hookLibrary called with libname: %s", libname);
|
LOGI("hookLibrary called with libname: %s", libname);
|
||||||
|
|
||||||
if (!hook_func) {
|
if (!hook_func) {
|
||||||
@@ -336,19 +330,18 @@ static bool hookLibrary(const char* libname) {
|
|||||||
close(fd);
|
close(fd);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
LOGI("hookLibrary: opened file, size: %lld", (long long)st.st_size);
|
LOGI("hookLibrary: opened file, size: %lld", (long long) st.st_size);
|
||||||
|
|
||||||
std::vector<uint8_t> file(st.st_size);
|
std::vector<uint8_t> file(st.st_size);
|
||||||
read(fd, file.data(), st.st_size);
|
read(fd, file.data(), st.st_size);
|
||||||
close(fd);
|
close(fd);
|
||||||
|
|
||||||
auto* eh = reinterpret_cast<Elf64_Ehdr*>(file.data());
|
auto *eh = reinterpret_cast<Elf64_Ehdr *>(file.data());
|
||||||
auto* shdr = reinterpret_cast<Elf64_Shdr*>(
|
auto *shdr = reinterpret_cast<Elf64_Shdr *>(
|
||||||
file.data() + eh->e_shoff);
|
file.data() + eh->e_shoff);
|
||||||
|
|
||||||
const char* shstr =
|
const char *shstr = reinterpret_cast<const char *>(
|
||||||
reinterpret_cast<const char*>(
|
file.data() + shdr[eh->e_shstrndx].sh_offset);
|
||||||
file.data() + shdr[eh->e_shstrndx].sh_offset);
|
|
||||||
|
|
||||||
uint64_t chk_offset = 0;
|
uint64_t chk_offset = 0;
|
||||||
uint64_t sdp_offset = 0;
|
uint64_t sdp_offset = 0;
|
||||||
@@ -357,22 +350,16 @@ static bool hookLibrary(const char* libname) {
|
|||||||
if (!strcmp(shstr + shdr[i].sh_name, ".gnu_debugdata")) {
|
if (!strcmp(shstr + shdr[i].sh_name, ".gnu_debugdata")) {
|
||||||
LOGI("hookLibrary: found .gnu_debugdata section");
|
LOGI("hookLibrary: found .gnu_debugdata section");
|
||||||
|
|
||||||
std::vector<uint8_t> compressed(
|
std::vector<uint8_t> compressed(file.begin() + shdr[i].sh_offset,
|
||||||
file.begin() + shdr[i].sh_offset,
|
file.begin() + shdr[i].sh_offset + shdr[i].sh_size);
|
||||||
file.begin() + shdr[i].sh_offset + shdr[i].sh_size);
|
|
||||||
|
|
||||||
std::vector<uint8_t> decompressed;
|
std::vector<uint8_t> decompressed;
|
||||||
|
|
||||||
if (decompressXZ(
|
if (decompressXZ(compressed.data(), compressed.size(), decompressed)) {
|
||||||
compressed.data(),
|
|
||||||
compressed.size(),
|
|
||||||
decompressed)) {
|
|
||||||
|
|
||||||
chk_offset = findSymbolOffset(decompressed,
|
chk_offset = findSymbolOffset(decompressed, "l2c_fcr_chk_chan_modes");
|
||||||
"l2c_fcr_chk_chan_modes");
|
|
||||||
|
|
||||||
sdp_offset = findSymbolOffset(decompressed,
|
sdp_offset = findSymbolOffset(decompressed, "BTA_DmSetLocalDiRecord");
|
||||||
"BTA_DmSetLocalDiRecord");
|
|
||||||
} else {
|
} else {
|
||||||
LOGE("debugdata decompress failed");
|
LOGE("debugdata decompress failed");
|
||||||
}
|
}
|
||||||
@@ -383,14 +370,12 @@ static bool hookLibrary(const char* libname) {
|
|||||||
|
|
||||||
if (!chk_offset) {
|
if (!chk_offset) {
|
||||||
LOGI("fallback dynsym chk");
|
LOGI("fallback dynsym chk");
|
||||||
chk_offset = findSymbolOffsetDynsym(file,
|
chk_offset = findSymbolOffsetDynsym(file, "l2c_fcr_chk_chan_modes");
|
||||||
"l2c_fcr_chk_chan_modes");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!sdp_offset) {
|
if (!sdp_offset) {
|
||||||
LOGI("fallback dynsym sdp");
|
LOGI("fallback dynsym sdp");
|
||||||
sdp_offset = findSymbolOffsetDynsym(file,
|
sdp_offset = findSymbolOffsetDynsym(file, "BTA_DmSetLocalDiRecord");
|
||||||
"BTA_DmSetLocalDiRecord");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
uintptr_t base = getModuleBase(libname);
|
uintptr_t base = getModuleBase(libname);
|
||||||
@@ -400,25 +385,23 @@ static bool hookLibrary(const char* libname) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (chk_offset) {
|
if (chk_offset) {
|
||||||
void* target = reinterpret_cast<void*>(base + chk_offset);
|
void *target = reinterpret_cast<void *>(base + chk_offset);
|
||||||
hook_func(target,
|
hook_func(target, (void *) fake_l2c_fcr_chk_chan_modes,
|
||||||
(void*)fake_l2c_fcr_chk_chan_modes,
|
(void **) &original_l2c_fcr_chk_chan_modes);
|
||||||
(void**)&original_l2c_fcr_chk_chan_modes);
|
|
||||||
LOGI("hooked chk");
|
LOGI("hooked chk");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (sdp_offset) {
|
if (sdp_offset) {
|
||||||
void* target = reinterpret_cast<void*>(base + sdp_offset);
|
void *target = reinterpret_cast<void *>(base + sdp_offset);
|
||||||
hook_func(target,
|
hook_func(target, (void *) fake_BTA_DmSetLocalDiRecord,
|
||||||
(void*)fake_BTA_DmSetLocalDiRecord,
|
(void **) &original_BTA_DmSetLocalDiRecord);
|
||||||
(void**)&original_BTA_DmSetLocalDiRecord);
|
|
||||||
LOGI("hooked sdp");
|
LOGI("hooked sdp");
|
||||||
}
|
}
|
||||||
|
|
||||||
return chk_offset || sdp_offset;
|
return chk_offset || sdp_offset;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void on_library_loaded(const char* name, void*) {
|
static void on_library_loaded(const char *name, void *) {
|
||||||
LOGI("on_library_loaded called with name: %s", name);
|
LOGI("on_library_loaded called with name: %s", name);
|
||||||
|
|
||||||
if (strstr(name, "libbluetooth_jni.so")) {
|
if (strstr(name, "libbluetooth_jni.so")) {
|
||||||
@@ -432,20 +415,19 @@ static void on_library_loaded(const char* name, void*) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
extern "C"
|
extern "C" [[gnu::visibility("default")]]
|
||||||
[[gnu::visibility("default")]]
|
|
||||||
[[gnu::used]]
|
[[gnu::used]]
|
||||||
NativeOnModuleLoaded native_init(const NativeAPIEntries* entries) {
|
NativeOnModuleLoaded native_init(const NativeAPIEntries *entries) {
|
||||||
LOGI("native_init called with entries: %p", entries);
|
LOGI("native_init called with entries: %p", entries);
|
||||||
hook_func = (HookFunType)entries->hook_func;
|
hook_func = (HookFunType) entries->hook_func;
|
||||||
LOGI("LibrePodsNativeHook initialized, sdp hook enabled: %d", enableSdpHook.load(std::memory_order_relaxed));
|
LOGI("LibrePodsNativeHook initialized, sdp hook enabled: %d",
|
||||||
|
enableSdpHook.load(std::memory_order_relaxed));
|
||||||
return on_library_loaded;
|
return on_library_loaded;
|
||||||
}
|
}
|
||||||
|
|
||||||
extern "C"
|
extern "C" JNIEXPORT void JNICALL
|
||||||
JNIEXPORT void JNICALL
|
Java_me_kavishdevar_librepods_utils_NativeBridge_setSdpHook(JNIEnv *, jobject thiz,
|
||||||
Java_me_kavishdevar_librepods_utils_NativeBridge_setSdpHook(
|
jboolean enable) {
|
||||||
JNIEnv*, jobject thiz, jboolean enable) {
|
|
||||||
LOGI("setSdpHook called with enable: %d", enable);
|
LOGI("setSdpHook called with enable: %d", enable);
|
||||||
enableSdpHook.store(enable, std::memory_order_relaxed);
|
enableSdpHook.store(enable, std::memory_order_relaxed);
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user