Conscrypt 调用栈 hook
🧩 hook Conscrypt 的 SSL 流包装类,在 SSL 收发时抓取 Java 调用栈。
📎 源码在线查看:
script.js(Conscrypt stack hook)
目的
Conscrypt 的 SSLOutputStream/SSLInputStream 在 write/read 时被 hook,那里抓栈赋值给全局 SSLstackwrite/SSLstackread,随后 Native 层 SSL_write/SSL_read 的 onEnter 再带进 message 里回传。这样就能定位到「是哪段 Java 代码触发了这次 SSL 收发」。
只抓栈不抓数据
注意
这里只抓栈不抓数据——数据由 Native 层 SSL_read/SSL_write hook 负责抓。Conscrypt 这层只负责把 Java 调用栈暂存到全局变量,供 Native hook 取用。
按版本分支
javascript
if (parseFloat(Java.androidVersion) > 8) {
// >8 用 ConscryptFileDescriptorSocket
Java.use("com.android.org.conscrypt.ConscryptFileDescriptorSocket$SSLOutputStream")
.write.overload('[B', 'int', 'int').implementation = function (b, i1, i2) {
var result = this.write(b, i1, i2);
SSLstackwrite = Java.use("android.util.Log").getStackTraceString(
Java.use("java.lang.Throwable").$new()).toString();
return result;
}
Java.use("com.android.org.conscrypt.ConscryptFileDescriptorSocket$SSLInputStream")
.read.overload('[B', 'int', 'int').implementation = function (b, i1, i2) {
var result = this.read(b, i1, i2);
SSLstackread = Java.use("android.util.Log").getStackTraceString(
Java.use("java.lang.Throwable").$new()).toString();
return result;
}
} else {
// <=8 用 OpenSSLSocketImpl
Java.use("com.android.org.conscrypt.OpenSSLSocketImpl$SSLOutputStream")...
Java.use("com.android.org.conscrypt.OpenSSLSocketImpl$SSLInputStream")...
}| Android 版本 | 类 |
|---|---|
| > 8(9+) | ConscryptFileDescriptorSocket$SSLOutputStream/SSLInputStream |
| ≤ 8(7、8) | OpenSSLSocketImpl$SSLOutputStream/SSLInputStream |
栈暂存到全局变量
javascript
SSLstackwrite = Java.use("android.util.Log").getStackTraceString(
Java.use("java.lang.Throwable").$new()).toString();new Throwable() + Log.getStackTraceString 拿当前调用栈字符串,存入模块级全局变量。Native 层 SSL_write 的 onEnter 紧随其后执行(同一调用链),读取该全局变量填入 message。
时序保证
Conscrypt SSLOutputStream.write 内部会调 Native SSL_write,所以:
App 调 SSLOutputStream.write
→ Conscrypt hook 抓栈 → SSLstackwrite = 栈
→ SSL_write (Native)
→ SSL_write onEnter: message.stack = SSLstackwrite ✔ 时序正确栈在 SSL_write 触发前已就绪。