在互联网找了很多相关的工具,可惜基本全都推荐用frida,其它的似乎没有一个能用的,除了不支持就是注入后程序崩溃,其中包括但不限于:

https://github.com/scen/osxinj

https://gist.github.com/vocaeq/fbac63d5d36bc6e1d6d99df9c92f75dc

但是frida我从来没有用过,感觉又脏又重,似乎还要依赖 ptrace,并且看到其它人基于它编写的工具都动不动几十MB。

于是我根据上面代码的思路并查阅一些相关资料后用rust编写了一个支持 M1/M2 的版本,它只是调用了一下 dlopen,所以也可以在已经被附加调试器的情况下注入。

它只有不到100KB(未主动优化文件大小的情况下),下载地址:https://github.com/kekeimiku/PointerSearcher-X/releases/download/v0.2.2/aarch64-apple-darwin-inject.tar.gz

使用方式很简单

1
./inject --pid 123 --path /xxx/xxx.dylib

rust 中编写一个测试用的 dylib 也很简单

Cargo.toml

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
[lib]
crate-type = ["cdylib"]

[profile.release]
opt-level = 3
lto = true
codegen-units = 1
panic = "abort"
strip = true
debug = false

lib.rs

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
use std::process::Command;

fn main() {
    Command::new("sh")
        .arg("-c")
        .arg("open -a Calculator")
        .output()
        .expect("sh exec error!");
}

#[used]
#[link_section = "__DATA,__mod_init_func"]
pub static INITIALIZE: fn() = main;

#[link_section = "__DATA,__mod_init_func"] 基本等同于在C中 __attribute__ ((constructor))