java层Socket抓包溯源
tcp java.net.SocketInputStream | ....... | java层 | socketRead0 (jni) | native层 java.net.SocketOutputStream | ....... | java层 | socketWrite0 (jni) | native层
function LogPrint(log) {
var theDate = new Date(); var hour = theDate.getHours(); var minute = theDate.getMinutes(); var second = theDate.getSeconds(); var mSecond = theDate.getMilliseconds(); hour < 10 ? hour = "0" + hour : hour; minute < 10 ? minute = "0" + minute : minute; second < 10 ? second = "0" + second : second; mSecond < 10 ? mSecond = "00" + mSecond : mSecond < 100 ? mSecond = "0" + mSecond : mSecond; var time = hour + ":" + minute + ":" + second + ":" + mSecond; var threadid = Process.getCurrentThreadId(); console.log("[" + time + "]" + "->threadid:" + threadid + "--" + log); } function printJavaStack(name) {
Java.perform(function () {
var Exception = Java.use("java.lang.Exception"); var ins = Exception.$new("Exception"); var straces = ins.getStackTrace(); if (straces != undefined && straces != null) {
var strace = straces.toString(); var replaceStr = strace.replace(/,/g, " \n "); LogPrint("=============================" + name + " Stack strat======================="); LogPrint(replaceStr); LogPrint("=============================" + name + " Stack end======================= \n "); Exception.$dispose(); } }); } function isprintable(value) {
if (value >= 32 && value <= 126) {
return true; } return false; } function hooktcp() {
Java.perform(function () {
var SocketClass = Java.use('java.net.Socket'); SocketClass.$init.overload('java.lang.String', 'int').implementation = function (arg0, arg1) {
console.log("[" + Process.getCurrentThreadId() + "]new Socket connection:" + arg0 + ",port:" + arg1); printJavaStack('tcp connect...') return this.$init(arg0, arg1); } var SocketInputStreamClass = Java.use('java.net.SocketInputStream'); //socketRead0 SocketInputStreamClass.socketRead0.implementation = function (arg0, arg1, arg2, arg3, arg4) {
var size = this.socketRead0(arg0, arg1, arg2, arg3, arg4); //console.log("[" + Process.getCurrentThreadId() + "]socketRead0:size:" + size + ",content:" + JSON.stringify(arg1)); var bytearray = Java.array('byte', arg1); var content = ''; for (var i = 0; i < size; i++) {
if (isprintable(bytearray[i])) {
content = content + String.fromCharCode(bytearray[i]); } } var socketimpl = this.impl.value; var address = socketimpl.address.value; var port = socketimpl.port.value; console.log("\naddress:" + address + ",port" + port + "\n" + JSON.stringify(this.socket.value) + "\n[" + Process.getCurrentThreadId() + "]receive:" + content); printJavaStack('socketRead0') return size; } var SocketOutPutStreamClass = Java.use('java.net.SocketOutputStream'); SocketOutPutStreamClass.socketWrite0.implementation = function (arg0, arg1, arg2, arg3) {
var result = this.socketWrite0(arg0, arg1, arg2, arg3); //console.log("[" + Process.getCurrentThreadId() + "]socketWrite0:len:" + arg3 + "--content:" + JSON.stringify(arg1)); var bytearray = Java.array('byte', arg1); var content = ''; for (var i = 0; i < arg3; i++) {
if (isprintable(bytearray[i])) {
content = content + String.fromCharCode(bytearray[i]); } } var socketimpl = this.impl.value; var address = socketimpl.address.value; var port = socketimpl.port.value; console.log("send address:" + address + ",port" + port + "[" + Process.getCurrentThreadId() + "]send:" + content); console.log("\n" + JSON.stringify(this.socket.value) + "\n[" + Process.getCurrentThreadId() + "]send:" + content); printJavaStack('socketWrite0') return result; } }) } function main() {
hooktcp(); } setImmediate(main)
udp java.net.DatagramSocket.send | PlainDatagramSockerImpl.send | IoBridge.sendto | java层 | libcore.io.Linux.sendtoBytes (jni) | native层 java.net.DatagramSocket.receive | .... | java层 | libcore.io.Linux.recvfromBytes (jni) | native层
java.net.DatagramSocket.send
function LogPrint(log) {
var theDate = new Date(); var hour = theDate.getHours(); var minute = theDate.getMinutes(); var second = theDate.getSeconds(); var mSecond = theDate.getMilliseconds(); hour < 10 ? hour = "0" + hour : hour; minute < 10 ? minute = "0" + minute : minute; second < 10 ? second = "0" + second : second; mSecond < 10 ? mSecond = "00" + mSecond : mSecond < 100 ? mSecond = "0" + mSecond : mSecond; var time = hour + ":" + minute + ":" + second + ":" + mSecond; var threadid = Process.getCurrentThreadId(); console.log("[" + time + "]" + "->threadid:" + threadid + "--" + log); } function printJavaStack(name) {
Java.perform(function () {
var Exception = Java.use("java.lang.Exception"); var ins = Exception.$new("Exception"); var straces = ins.getStackTrace(); if (straces != undefined && straces != null) {
var strace = straces.toString(); var replaceStr = strace.replace(/,/g, " \n "); LogPrint("=============================" + name + " Stack strat======================="); LogPrint(replaceStr); LogPrint("=============================" + name + " Stack end======================= \n "); Exception.$dispose(); } }); } function isprintable(value) {
if (value >= 32 && value <= 126) {
return true; } return false; } function hookudp() {
Java.perform(function () {
var LinuxClass = Java.use('libcore.io.Linux'); //private native int recvfromBytes(FileDescriptor fd, Object buffer, int byteOffset, int byteCount, int flags, InetSocketAddress srcAddress) throws ErrnoException, SocketException; LinuxClass.recvfromBytes.implementation = function (arg0, arg1, arg2, arg3, arg4, arg5) {
var size = this.recvfromBytes(arg0, arg1, arg2, arg3, arg4, arg5); var bytearray = Java.array('byte', arg1); var content = ""; for (var i = 0; i < size; i++) {
if (isprintable(bytearray[i])) {
content = content + String.fromCharCode(bytearray[i]); } } console.log("address:" + arg5 + " [" + Process.getCurrentThreadId() + "]recvfromBytes:size:" + size + ",content:" + JSON.stringify(arg1) + "---content," + content); printJavaStack('recvfromBytes'); return size; } //private native int sendtoBytes(FileDescriptor fd, Object buffer, int byteOffset, int byteCount, int flags, InetAddress inetAddress, int port) throws ErrnoException, SocketException; // private native int sendtoBytes(FileDescriptor fd, Object buffer, int byteOffset, int byteCount, int flags, SocketAddress address) throws ErrnoException, SocketException; LinuxClass.sendtoBytes.overload('java.io.FileDescriptor', 'java.lang.Object', 'int', 'int', 'int', 'java.net.InetAddress', 'int').implementation = function (arg0, arg1, arg2, arg3, arg4, arg5, arg6) {
var size = this.sendtoBytes(arg0, arg1, arg2, arg3, arg4, arg5, arg6); var bytearray = Java.array('byte', arg1); var content = ""; for (var i = 0; i < size; i++) {
if (isprintable(bytearray[i])) {
content = content + String.fromCharCode(bytearray[i]); } } console.log("address:" + arg5 + ",port" + arg6 + " [" + Process.getCurrentThreadId() + "]LinuxClass11.sendtoBytes:len:" + size + "--content:" + JSON.stringify(arg1) + "--content:" + content); printJavaStack('LinuxClass11.sendtoBytes') return size; } LinuxClass.sendtoBytes.overload('java.io.FileDescriptor', 'java.lang.Object', 'int', 'int', 'int', 'java.net.SocketAddress').implementation = function (arg0, arg1, arg2, arg3, arg4, arg5) {
var size = this.sendtoBytes(arg0, arg1, arg2, arg3, arg4, arg5); var bytearray = Java.array('byte', arg1); var content = ""; for (var i = 0; i < size; i++) {
if (isprintable(bytearray[i])) {
content = content + String.fromCharCode(bytearray[i]); } } console.log("address:" + arg5 + " [" + Process.getCurrentThreadId() + "]LinuxClass22.sendtoBytes:len:" + size + "--content:" + JSON.stringify(arg1) + ",content:" + content); printJavaStack('LinuxClass22.sendtoBytes') return size; } }) } function main() {
hookudp(); } setImmediate(main)
java层SSL抓包溯源
aosp默认使用okhttp
sslSocker->com.android.org.conscrypt.OpenSSLSocketImplWrapper 发送数据 com.android.org.conscrypt.OpenSSLSocketImpl$SSLSocketOutStream | write | com.android.org.conscrypt.NativeCrypto.SSL_write (jni,此时证书加密前的数据) | native层 接收数据 com.android.org.conscrypt.OpenSSLSocketImpl$SSLSocketInputStream | read | com.android.org.conscrypt.NativeCrypto.SSL_read (jni,此时证书解密后的数据) | native层
function LogPrint(log) {
var theDate = new Date(); var hour = theDate.getHours(); var minute = theDate.getMinutes(); var second = theDate.getSeconds(); var mSecond = theDate.getMilliseconds(); hour < 10 ? hour = "0" + hour : hour; minute < 10 ? minute = "0" + minute : minute; second < 10 ? second = "0" + second : second; mSecond < 10 ? mSecond = "00" + mSecond : mSecond < 100 ? mSecond = "0" + mSecond : mSecond; var time = hour + ":" + minute + ":" + second + ":" + mSecond; var threadid = Process.getCurrentThreadId(); console.log("[" + time + "]" + "->threadid:" + threadid + "--" + log); } function printJavaStack(name) {
Java.perform(function () {
var Exception = Java.use("java.lang.Exception"); var ins = Exception.$new("Exception"); var straces = ins.getStackTrace(); if (straces != undefined && straces != null) {
var strace = straces.toString(); var replaceStr = strace.replace(/,/g, " \n "); LogPrint("=============================" + name + " Stack strat======================="); LogPrint(replaceStr); LogPrint("=============================" + name + " Stack end======================= \n "); Exception.$dispose(); } }); } function getsocketdetail(fd) {
var result = ""; var type = Socket.type(fd); if (type != null) {
result = result + "type:" + type; var peer = Socket.peerAddress(fd); var local = Socket.localAddress(fd); result = result + ",address:" + JSON.stringify(peer) + ",local:" + JSON.stringify(local); } else {
result = "unknown"; } return result; } function printNativeStack(context, name) {
//Debug. var array = Thread.backtrace(context, Backtracer.ACCURATE); var first = DebugSymbol.fromAddress(array[0]); if (first.toString().indexOf('libopenjdk.so!NET_Send') < 0) {
var trace = Thread.backtrace(context, Backtracer.ACCURATE).map(DebugSymbol.fromAddress).join("\n"); LogPrint("-----------start:" + name + "--------------"); LogPrint(trace); LogPrint("-----------end:" + name + "--------------"); } } function isprintable(value) {
if (value >= 32 && value <= 126) {
return true; } return false; } function hookssl() {
Java.perform(function () {
var NativeCryptoClass = Java.use('com.android.org.conscrypt.NativeCrypto'); NativeCryptoClass.SSL_read.implementation = function (arg0, arg1, arg2, arg3, arg4, arg5, arg6) {
var size = this.SSL_read(arg0, arg1, arg2, arg3, arg4, arg5, arg6); var bytearray = Java.array('byte', arg3); var content = ''; for (var i = 0; i < size; i++) {
if (isprintable(bytearray[i])) {
content = content + String.fromCharCode(bytearray[i]); } } console.log("\n[" + Process.getCurrentThreadId() + "]ssl receive:" + content); printJavaStack('NativeCryptoClass.read') return size; } NativeCryptoClass.SSL_write.implementation = function (arg0, arg1, arg2, arg3, arg4, arg5, arg6) {
var result = this.SSL_write(arg0, arg1, arg2, arg3, arg4, arg5, arg6); var bytearray = Java.array('byte', arg3); var content = ''; for (var i = 0; i < arg5; i++) {
if (isprintable(bytearray[i])) {
content = content + String.fromCharCode(bytearray[i]); } } console.log("\n[" + Process.getCurrentThreadId() + "]ssl send:" + content); printJavaStack('NativeCryptoClass.SSL_write') return result; } }) } function enumerate() {
Java.perform(function () {
Java.enumerateLoadedClassesSync().forEach(function (classname) {
if (classname.indexOf("NativeCrypto") >= 0) {
console.log(classname); } }) }) } function main() {
//enumerate(); hookssl(); } setImmediate(main)
com.android.org.conscrypt.NativeCrypto.SSL_read 太深了,到上一层 com.android.org.conscrypt.OpenSSLSocketImpl$SSLSocketInputStream拿ip和端口的信息
function LogPrint(log) {
var theDate = new Date(); var hour = theDate.getHours(); var minute = theDate.getMinutes(); var second = theDate.getSeconds(); var mSecond = theDate.getMilliseconds(); hour < 10 ? hour = "0" + hour : hour; minute < 10 ? minute = "0" + minute : minute; second < 10 ? second = "0" + second : second; mSecond < 10 ? mSecond = "00" + mSecond : mSecond < 100 ? mSecond = "0" + mSecond : mSecond; var time = hour + ":" + minute + ":" + second + ":" + mSecond; var threadid = Process.getCurrentThreadId(); console.log("[" + time + "]" + "->threadid:" + threadid + "--" + log); } function printJavaStack(name) {
Java.perform(function () {
var Exception = Java.use("java.lang.Exception"); var ins = Exception.$new("Exception"); var straces = ins.getStackTrace(); if (straces != undefined && straces != null) {
var strace = straces.toString(); var replaceStr = strace.replace(/,/g, " \n "); LogPrint("=============================" + name + " Stack strat======================="); LogPrint(replaceStr); LogPrint("=============================" + name + " Stack end======================= \n "); Exception.$dispose(); } }); } function isprintable(value) {
if (value >= 32 && value <= 126) {
return true; } return false; } function hooksslsocket() {
Java.perform(function () {
var SSLInputStreamClass = Java.use('com.android.org.conscrypt.OpenSSLSocketImpl$SSLInputStream'); //public int read(byte[] buf, int offset, int byteCount) SSLInputStreamClass.read.overload().implementation = function () {
var value = this.read(); var sslsocketimplwrapper = this.this$0.value; console.log("SSLInputStreamClass.read 1obj->" + sslsocketimplwrapper); var socket = sslsocketimplwrapper.socket.value; console.log("SSLInputStreamClass.read 1socket->" + socket); //console.log("[" + Process.getCurrentThreadId() + "]SSLInputStreamClass.read:len:" + 4 + "--content:" + JSON.stringify(value)); console.log("[" + Process.getCurrentThreadId() + "]sslsocket read a int:" + value); printJavaStack('sslInputStream.read()') return value; } SSLInputStreamClass.read.overload('[B', 'int', 'int').implementation = function (arg0, arg1, arg2) {
var size = this.read(arg0, arg1, arg2); //内部类对象直接得到外部类对象的方法 var sslsocketimplwrapper = this.this$0.value; console.log("SSLInputStreamClass.read 2obj->" + sslsocketimplwrapper); var socket = sslsocketimplwrapper.socket.value; console.log("SSLInputStreamClass.read 2socket->" + socket); //console.log("[" + Process.getCurrentThreadId() + "]SSLInputStreamClass.read:len:" + size + "--content:" + JSON.stringify(arg0)); var bytearray = Java.array('byte', arg0); var content = ''; for (var i = 0; i < size; i++) {
if (isprintable(bytearray[i])) {
content = content + String.fromCharCode(bytearray[i]); } } /* var socketimpl = this.impl.value; var address = socketimpl.address.value; var port = socketimpl.port.value;*/ console.log("[" + Process.getCurrentThreadId() + "]sslsocket read:" + content); //console.log("\n" + JSON.stringify(this.socket.value) + "\n[" + Process.getCurrentThreadId() + "]send:" + content); printJavaStack('sslInputStream.read') return size; } var SSLOutputStreamClass = Java.use('com.android.org.conscrypt.OpenSSLSocketImpl$SSLOutputStream'); SSLOutputStreamClass.write.overload('int').implementation = function (arg0) {
var result = this.write(arg0); //通过内部类对象得到外部类对象 var sslsocketimplwrapper = this.this$0.value; console.log("SSLOutputStream 1obj->" + sslsocketimplwrapper); var socket = sslsocketimplwrapper.socket.value; console.log("SSLOutputStream 1socket->" + socket); /*SSLOutputStream 2obj->SSL socket over Socket[address=portal.meirishanglai.com/240.0.0.21,port=443,localPort=37563] SSLOutputStream 2socket->Socket[address=portal.meirishanglai.com/240.0.0.21,port=443,localPort=37563] */ console.log("[" + Process.getCurrentThreadId() + "]write(int):len:" + 4 + "--content:" + arg0); printJavaStack('sslOutputStream.write(int)') return result; } //public void write(byte[] buf, int offset, int byteCount) SSLOutputStreamClass.write.overload('[B', 'int', 'int').implementation = function (arg0, arg1, arg2) {
var result = this.write(arg0, arg1, arg2); var sslsocketimplwrapper = this.this$0.value; console.log("SSLOutputStream 2obj->" + sslsocketimplwrapper); var socket = sslsocketimplwrapper.socket.value; console.log("SSLOutputStream 2socket->" + socket); //console.log("[" + Process.getCurrentThreadId() + "]socketWrite0:len:" + arg2 + "--content:" + JSON.stringify(arg0)); var bytearray = Java.array('byte', arg0); var content = ''; for (var i = 0; i < arg2; i++) {
if (isprintable(bytearray[i])) {
content = content + String.fromCharCode(bytearray[i]); } } /* var socketimpl = this.impl.value; var address = socketimpl.address.value; var port = socketimpl.port.value;*/ console.log("[" + Process.getCurrentThreadId() + "]sslsocket send:" + content); //console.log("\n" + JSON.stringify(this.socket.value) + "\n[" + Process.getCurrentThreadId() + "]send:" + content); printJavaStack('sslOutputStream.write') return result; } }) } function main() {
hooksslsocket(); } setImmediate(main)
jni层Socker抓包溯源
tcp native层 libopenjdk.so - socketRead0 | NET_Read | libc.so - recvfrom | 系统调用(可以在自己的so中实现recvfrom,然后调用系统调用号) | 内核 libopenjdk.so - socketWrite0 | NET_Send | libc.so - sendto | 系统调用 | 内核
function LogPrint(log) {
var theDate = new Date(); var hour = theDate.getHours(); var minute = theDate.getMinutes(); var second = theDate.getSeconds(); var mSecond = theDate.getMilliseconds(); hour < 10 ? hour = "0" + hour : hour; minute < 10 ? minute = "0" + minute : minute; second < 10 ? second = "0" + second : second; mSecond < 10 ? mSecond = "00" + mSecond : mSecond < 100 ? mSecond = "0" + mSecond : mSecond; var time = hour + ":" + minute + ":" + second + ":" + mSecond; var threadid = Process.getCurrentThreadId(); console.log("[" + time + "]" + "->threadid:" + threadid + "--" + log); } function printNativeStack(context, name) {
//Debug. var array = Thread.backtrace(context, Backtracer.ACCURATE); var first = DebugSymbol.fromAddress(array[0]); if (first.toString().indexOf('libopenjdk.so!NET_Send') < 0) {
var trace = Thread.backtrace(context, Backtracer.ACCURATE).map(DebugSymbol.fromAddress).join("\n"); LogPrint("-----------start:" + name + "--------------"); LogPrint(trace); LogPrint("-----------end:" + name + "--------------"); } } function printJavaStack(name) {
Java.perform(function () {
var Exception = Java.use("java.lang.Exception"); var ins = Exception.$new("Exception"); var straces = ins.getStackTrace(); if (straces != undefined && straces != null) {
var strace = straces.toString(); var replaceStr = strace.replace(/,/g, " \n "); LogPrint("=============================" + name + " Stack strat======================="); LogPrint(replaceStr); LogPrint("=============================" + name + " Stack end======================= \n "); Exception.$dispose(); } }); } function isprintable(value) {
if (value >= 32 && value <= 126) {
return true; } return false; } function getsocketdetail(fd) {
var result = ""; var type = Socket.type(fd); if (type != null) {
result = result + "type:" + type; var peer = Socket.peerAddress(fd); var local = Socket.localAddress(fd); result = result + ",address:" + JSON.stringify(peer) + ",local:" + JSON.stringify(local); } else {
result = "unknown"; } return result; } function hooklibc() {
var libcmodule = Process.getModuleByName("libc.so"); var recvfrom_addr = libcmodule.getExportByName("recvfrom"); var sendto_addr = libcmodule.getExportByName("sendto"); console.log(recvfrom_addr + "---" + sendto_addr); //ssize_t recvfrom(int fd, void *buf, size_t n, int flags, struct sockaddr *addr, socklen_t *addr_len) Interceptor.attach(recvfrom_addr, {
onEnter: function (args) {
this.arg0 = args[0]; this.arg1 = args[1]; this.arg2 = args[2]; LogPrint("go into libc.so->recvfom"); printNativeStack(this.context, "recvfom"); }, onLeave(retval) {
var size = retval.toInt32(); if (size > 0) {
var result = getsocketdetail(this.arg0.toInt32()); console.log(result + "---libc.so->recvfrom:" + hexdump(this.arg1, {
length: size })); } LogPrint("leave libc.so->recvfom"); } }); //ssize_t sendto(int fd, const void *buf, size_t n, int flags, const struct sockaddr *addr, socklen_t addr_len) Interceptor.attach(sendto_addr, {
onEnter: function (args) {
this.arg0 = args[0]; this.arg1 = args[1]; this.arg2 = args[2]; LogPrint("go into libc.so->sendto"); printNativeStack(this.context, "sendto"); }, onLeave(retval) {
var size = ptr(this.arg2).toInt32(); if (size > 0) {
var result = getsocketdetail(this.arg0.toInt32()); console.log(result + "---libc.so->sendto:" + hexdump(this.arg1, {
length: size })); } LogPrint("leave libc.so->sendto"); } }); } function main() {
hooklibc(); } setImmediate(main);
udp libcore.io.Linux.sendtoBytes (jni) | libc.so - sendto libcore.io.Linux.recvfromBytes (jni) | libc.so - recvfrom
function LogPrint(log) {
var theDate = new Date(); var hour = theDate.getHours(); var minute = theDate.getMinutes(); var second = theDate.getSeconds(); var mSecond = theDate.getMilliseconds(); hour < 10 ? hour = "0" + hour : hour; minute < 10 ? minute = "0" + minute : minute; second < 10 ? second = "0" + second : second; mSecond < 10 ? mSecond = "00" + mSecond : mSecond < 100 ? mSecond = "0" + mSecond : mSecond; var time = hour + ":" + minute + ":" + second + ":" + mSecond; var threadid = Process.getCurrentThreadId(); console.log("[" + time + "]" + "->threadid:" + threadid + "--" + log); } function printNativeStack(context, name) {
//Debug. var array = Thread.backtrace(context, Backtracer.ACCURATE); var first = DebugSymbol.fromAddress(array[0]); if (first.toString().indexOf('libopenjdk.so!NET_Send') < 0) {
var trace = Thread.backtrace(context, Backtracer.ACCURATE).map(DebugSymbol.fromAddress).join("\n"); LogPrint("-----------start:" + name + "--------------"); LogPrint(trace); LogPrint("-----------end:" + name + "--------------"); } } function printJavaStack(name) {
Java.perform(function () {
var Exception = Java.use("java.lang.Exception"); var ins = Exception.$new("Exception"); var straces = ins.getStackTrace(); if (straces != undefined && straces != null) {
var strace = straces.toString(); var replaceStr = strace.replace(/,/g, " \n "); LogPrint("=============================" + name + " Stack strat======================="); LogPrint(replaceStr); LogPrint("=============================" + name + " Stack end======================= \n "); Exception.$dispose(); } }); } function isprintable(value) {
if (value >= 32 && value <= 126) {
return true; } return false; } function getsocketdetail(fd) {
var result = ""; var type = Socket.type(fd); if (type != null) {
result = result + "type:" + type; var peer = Socket.peerAddress(fd); var local = Socket.localAddress(fd); result = result + ",address:" + JSON.stringify(peer) + ",local:" + JSON.stringify(local); } else {
result = "unknown"; } return result; } function getip(ip_ptr) {
var result = ptr(ip_ptr).readU8() + "." + ptr(ip_ptr.add(1)).readU8() + "." + ptr(ip_ptr.add(2)).readU8() + "." + ptr(ip_ptr.add(3)).readU8() return result; } function getudpaddr(addrptr) {
var port_ptr = addrptr.add(2); var port = ptr(port_ptr).readU8() * 256 + ptr(port_ptr.add(1)).readU8(); var ip_ptr = addrptr.add(4); var ip_addr = getip(ip_ptr); return "peer:"+ip_addr+"--port:"+port; } function hooklibc() {
var libcmodule = Process.getModuleByName("libc.so"); var recvfrom_addr = libcmodule.getExportByName("recvfrom"); var sendto_addr = libcmodule.getExportByName("sendto"); console.log(recvfrom_addr + "---" + sendto_addr); //ssize_t recvfrom(int fd, void *buf, size_t n, int flags, struct sockaddr *addr, socklen_t *addr_len) Interceptor.attach(recvfrom_addr, {
onEnter: function (args) {
this.arg0 = args[0]; this.arg1 = args[1]; this.arg2 = args[2]; this.arg3 = args[3]; this.arg4 = args[4]; this.arg5 = args[5]; LogPrint("go into libc.so->recvfom"); printNativeStack(this.context, "recvfom"); }, onLeave(retval) {
var size = retval.toInt32(); if (size > 0) {
var result = getsocketdetail(this.arg0.toInt32()); if (result.indexOf('udp') >= 0) {
/*75struct sockaddr_in { 76 short sin_family; 77 u_short sin_port; 78 struct in_addr sin_addr; 79 char sin_zero[8]; 80};*/ var sockaddr_in_ptr = this.arg4; var sizeofsockaddr_in = this.arg5; //02 00 22 b8 c0 a8 05 96 00 00 00 00 00 00 00 00 console.log("this is a recvfrom udp!->" + getudpaddr(sockaddr_in_ptr) + "---" + sizeofsockaddr_in); } console.log(Process.getCurrentThreadId()+result + "---libc.so->recvfrom:" + hexdump(this.arg1, {
length: size })); } LogPrint("leave libc.so->recvfom"); } }); //ssize_t sendto(int fd, const void *buf, size_t n, int flags, const struct sockaddr *addr, socklen_t addr_len) Interceptor.attach(sendto_addr, {
onEnter: function (args) {
this.arg0 = args[0]; this.arg1 = args[1]; this.arg2 = args[2]; this.arg3 = args[3]; this.arg4 = args[4]; this.arg5 = args[5]; LogPrint("go into libc.so->sendto"); printNativeStack(this.context, "sendto"); }, onLeave(retval) {
var size = ptr(this.arg2).toInt32(); if (size > 0) {
var result = getsocketdetail(this.arg0.toInt32()); if (result.indexOf('udp') >= 0) {
/*75struct sockaddr_in { 76 short sin_family; 77 u_short sin_port; 78 struct in_addr sin_addr; 79 char sin_zero[8]; 80};*/ var sockaddr_in_ptr = this.arg4; var sizeofsockaddr_in = this.arg5; //02 00 22 b8 c0 a8 05 96 00 00 00 00 00 00 00 00 console.log("this is a sendto udp!->" + getudpaddr(sockaddr_in_ptr) + "---" + sizeofsockaddr_in); } console.log(Process.getCurrentThreadId()+"---"+result + "---libc.so->sendto:" + hexdump(this.arg1, {
length: size })); } LogPrint("leave libc.so->sendto"); } }); } function main() {
hooklibc(); } setImmediate(main);
jni层SSL抓包溯源
com.android.org.conscrypt.NativeCrypto.SSL_write (jni) | sslWrite | boringssl -> ssl_lib.c -> SSL_write | ssl3_write_app_data | do_ssl3_write (此时还是明文,之后被加密了) | ssl_write_pending | ssl_write_buffer_flush | dtls_write_buffer_flush/tls_write_buffer_flush | BIO_write | bio_io | libc.so - write com.android.org.conscrypt.NativeCrypto.SSL_read (jni) | libc.so - read
function hooklibc() {
var libcmodule = Process.getModuleByName("libc.so"); var read_addr = libcmodule.getExportByName("read"); var write_addr = libcmodule.getExportByName("write"); console.log(read_addr + "---" + write_addr); Interceptor.attach(read_addr, {
onEnter: function (args) {
this.arg0 = args[0]; this.arg1 = args[1]; this.arg2 = args[2]; this.socketinfo = getsocketdetail(this.arg0.toInt32()); LogPrint("go into libc.so->read_addr" + "---" + this.socketinfo); this.flag = false; if (this.socketinfo.indexOf("tcp") >= 0) {
this.flag = true; } if (this.flag) {
printNativeStack(this.context, Process.getCurrentThreadId() + "read"); } }, onLeave(retval) {
if (this.flag) {
var size = retval.toInt32(); if (size > 0) {
console.log(Process.getCurrentThreadId() + "---libc.so->read:" + hexdump(this.arg1, {
length: size })); } } LogPrint("leave libc.so->read"); } }); Interceptor.attach(write_addr, {
onEnter: function (args) {
this.arg0 = args[0]; this.arg1 = args[1]; this.arg2 = args[2]; this.socketinfo = getsocketdetail(this.arg0.toInt32()); LogPrint("go into libc.so->write" + "---" + this.socketinfo); this.flag = false; if (this.socketinfo.indexOf("tcp") >= 0) {
this.flag = true; } if (this.flag) {
printNativeStack(this.context, Process.getCurrentThreadId() + "write"); } }, onLeave(retval) {
if (this.flag) {
var size = ptr(this.arg2).toInt32(); if (size > 0) {
console.log(Process.getCurrentThreadId() + "---libc.so->write:" + hexdump(this.arg1, {
length: size })); } } LogPrint("leave libc.so->write"); } }); }
自编译openssl库抓包溯源
hook 自编译 ssl so中的所有导出函数(有符号)
function hookallssl() {
var libsslmodule = Process.getModuleByName("libssl.so"); var SSL_get_rfd_ptr = libsslmodule.getExportByName('SSL_get_rfd'); var SSL_get_rfd = new NativeFunction(SSL_get_rfd_ptr, 'int', ['pointer']); Process.enumerateModules().forEach(function (module) {
module.enumerateExports().forEach(function (symbol) {
var name = symbol.name; if (name == 'SSL_read') {
LogPrint(JSON.stringify(module) + JSON.stringify(symbol)); } if (name == 'SSL_write') {
LogPrint(JSON.stringify(module) + JSON.stringify(symbol)); Interceptor.attach(symbol.address, {
onEnter: function (args) {
this.arg0 = args[0]; this.arg1 = args[1]; this.arg2 = args[2]; LogPrint("go into " + Process.getCurrentThreadId() + "---" + JSON.stringify(module) + "---" + JSON.stringify(symbol)); printNativeStack(this.context, Process.getCurrentThreadId() + "---" + JSON.stringify(module) + "---" + JSON.stringify(symbol)); var size = ptr(this.arg2).toInt32(); if (size > 0) {
var sockfd = SSL_get_rfd(this.arg0); var socketdetail = getsocketdetail(sockfd); console.log(socketdetail + "---" + Process.getCurrentThreadId() + "---" + JSON.stringify(module) + "---" + JSON.stringify(symbol) + hexdump(this.arg1, {
length: size })); } }, onLeave(retval) {
LogPrint("leave " + Process.getCurrentThreadId() + "---" + JSON.stringify(module) + "---" + JSON.stringify(symbol)); } }); } }) }) }
发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/214331.html原文链接:https://javaforall.net
