本文为看雪论坛优秀文章
看雪论坛作者ID:Ylarod
一
初遇
CANNOT LINK EXECUTABLE "/data/local/tmp/paylaod": library "libicu.so" not found: needed by /system/lib64/libharfbuzz_ng.so in namespace (default)
W linker : [ Android dynamic linker (64-bit) ]
W linker : [ Linking executable "/data/local/tmp/memexec" ]
W linker : [ Linking "[vdso]" ]
W linker : [ Reading linker config "/linkerconfig/ld.config.txt" ]
W linker : [ Using config section "**unrestricted**" ]
W linker : [ Linking "/data/local/tmp/memexec" ]
W linker : [ Linking "/system/lib64/liblog.so" ]
W linker : [ Linking "/apex/com.android.runtime/lib64/bionic/libm.so" ]
W linker : [ Linking "/apex/com.android.runtime/lib64/bionic/libdl.so" ]
W linker : [ Linking "/apex/com.android.runtime/lib64/bionic/libc.so" ]
W linker : [ Linking "/system/lib64/libc++.so" ]
W linker : [ Linking "/system/lib64/libnetd_client.so" ]
W linker : [ Linking "/system/lib64/libcutils.so" ]
W linker : [ Linking "/system/lib64/libbase.so" ]
W linker : [ CFI add 0x61abb23000 + 0x67000 ]
W linker : [ CFI add 0x77780d3000 + 0x1000 linux-vdso.so.1 ]
W linker : [ CFI add 0x7776c48000 + 0x10000 liblog.so ]
W linker : [ CFI add 0x7773d87000 + 0x37000 libm.so ]
W linker : [ CFI add 0x7773dc0000 + 0x5000 libdl.so ]
W linker : [ CFI add 0x7773a1e000 + 0x318000 libc.so ]
W linker : [ CFI add 0x7776cd2000 + 0xae000 libc++.so ]
W linker : [ CFI add 0x7773945000 + 0x2b000 libnetd_client.so: 0x777394a000 ]
W linker : [ CFI add 0x777391b000 + 0x12000 libcutils.so ]
W linker : [ CFI add 0x77738c4000 + 0x3b000 libbase.so ]
W linker : [ CFI add 0x777391b000 + 0x12000 libcutils.so ]
W linker : [ CFI add 0x77738c4000 + 0x3b000 libbase.so ]
W linker : [ Jumping to _start (0x61abb418e0)... ]
W linker : [ Android dynamic linker (64-bit) ]
W linker : [ Linking executable "/memfd:jit-cache (deleted)" ]
W linker : [ Linking "[vdso]" ]
W linker : [ Reading linker config "/linkerconfig/ld.config.txt" ]
W linker : [ Linking "/memfd:/jit-cache (deleted)" ]
F linker : CANNOT LINK EXECUTABLE "/data/local/tmp/payload": library "libicu.so" not found: needed by /system/lib64/libharfbuzz_ng.so in namespace (**default**)
相知
dir.system = /system/bin/
......
dir.unrestricted = /data/nativetest64/unrestricted
dir.isolated = /data/local/tmp/isolated
dir.product = /data/local/tests/product
dir.system = /data/local/tests/system
dir.unrestricted = /data/local/tests/unrestricted
dir.vendor = /data/local/tests/vendor
dir.unrestricted = /data/local/tmp
......
[system]
additional.namespaces = com_android_adbd,com_android_appsearch,com_android_art,com_android_conscrypt,com_android_i18n,com_android_media,com_android_neuralnetworks,com_android_os_statsd,com_android_resolv,com_android_runtime,com_android_tethering,rs,sphal,vndk,vndk_product
namespace.default.isolated = true
namespace.default.visible = true
namespace.default.search.paths = /system/${LIB}
......
# cat /proc/mounts | grep linkerconfig
tmpfs /linkerconfig tmpfs rw,seclabel,nosuid,nodev,noexec,relatime,size=5846680k,nr_inodes=1461670,mode=755 0 0
tmpfs /linkerconfig tmpfs rw,seclabel,nosuid,nodev,noexec,relatime,size=5846680k,nr_inodes=1461670,mode=755 0 0
以下使用 /data/adb/magisk/busybox vi /linkerconfig/ld.config.txt 编辑文件
dir.unrestricted = /memfd:
memfd_create(“/jit-cache”, MFD_CLOEXEC);
dir.unrestricted = /
WARNING: linker: /linkerconfig/ld.config.txt:1: warning: property value is empty (ignoring this line)
三
相识
由于aospxref服务最近不太稳定,我在看的时候刚好打不开,使用了android官方的源码在线浏览工具(https://cs.android.com/),然而这个玩意并不好用
if (access(value.c_str(), R_OK) != 0) {
if (errno == ENOENT) {
// no need to test for non-existing path. skip.
continue;
}
// If not accessible, don't call realpath as it will just cause
// SELinux denial spam. Use the path unresolved.
resolved_path = value;
}
// remove trailing '/'
while (!value.empty() && value.back() == '/') {
value.pop_back();
}
if (value.empty()) {
DL_WARN("%s:%zd: warning: property value is empty (ignoring this line)",
ld_config_file_path,
cp.lineno());
continue;
}
四
相杀
静态替换 linker
动态 hook
也许是我孤陋寡闻,如果有请务必告诉我。
给 /linkerconfig/ld.config.txt 添加 "dir.unrestricted = /memfd:/\n”
让 access 这个目录返回 0
bool mem_load(const std::string& image, char** argv, char** envp){
// 创建内存文件,设置这个参数会在exec后自动关闭这个文件
int fd = memfd_create("/jit-cache", MFD_CLOEXEC);
ftruncate(fd, (long)image.size()); // 设置文件长度
void *mem = mmap(nullptr, image.size(), PROT_WRITE, MAP_SHARED, fd, 0);
memcpy(mem, image.data(), image.size());
munmap(mem, image.size());
// 此时已经将ELF内容写入到内存文件里面
int pid = fork();
if (pid < 0) {
printf("mem_load failed\n"); // fork 失败
return false;
} else if (pid == 0) {
// 这里是子进程,使用 PTRACE_TRACEME 主动建立连接
ptrace(PTRACE_TRACEME);
fexecve(fd, argv, envp);
}
// 这里是父进程
int status;
struct user_regs_struct regs{};
struct iovec iov{};
iov.iov_base = ®s;
iov.iov_len = sizeof(user_regs_struct);
while(true){
wait(&status); // 等待子进程暂停
if(WIFEXITED(status)){
break; // 子进程退出
}
// 读取通用寄存器,系统调用号
ptrace(PTRACE_GETREGSET, pid, NT_PRSTATUS, &iov);
if (regs.regs[8] == __NR_faccessat){ // access函数使用的系统调用号
char path[] = "/memfd:";
long word;
// 注意,PTRACE_PEEKDATA 固定一次读取 sizeof(long) 字节长度的内容
word = ptrace(PTRACE_PEEKDATA, pid, regs.regs[1], NULL);
if (strcmp(path, (char*)&word) == 0){ // 判断是否是我们添加的目录
ptrace(PTRACE_SINGLESTEP, pid, NULL, NULL); // 单步执行,让系统调用执行完
wait(nullptr); // 等待系统调用执行完
ptrace(PTRACE_GETREGSET, pid, NT_PRSTATUS, &iov); // 读取寄存器
regs.regs[0] = 0; // 修改返回值为寄存器
ptrace(PTRACE_SETREGSET, pid, NT_PRSTATUS, &iov); // 修改寄存器
ptrace(PTRACE_DETACH, pid, NULL, NULL); // detach 进程
return true;
}
}
ptrace(PTRACE_SYSCALL, pid, NULL, NULL); // 执行到下一个系统调用时暂停
}
return false;
}
看雪ID:Ylarod
https://bbs.pediy.com/user-home-892096.htm
看雪2022KCTF秋季赛官网:https://ctf.pediy.com/game-team_list-18-29.htm
# 往期推荐
球分享
球点赞
球在看
点击“阅读原文”,了解更多!