frida将自己注入到Firefox中,hook了recv 和read函数
sudo /Users/snappyjack/Library/Python/3.8/bin/frida-trace -i "recv*" -i "read*" firefox
test in MacOS
cp /bin/cat /tmp/cat
/tmp/cat
在另一个终端运行如下python(macOS需关闭SIP)
import frida
def on_message(message, data):
print("[on_message] message:", message, "data:", data)
session = frida.attach("cat")
script = session.create_script("""
rpc.exports.enumerateModules = function () {
return Process.enumerateModules();
};
""")
script.on("message", on_message) # 这个暂时没有用
script.load()
print([m["name"] for m in script.exports.enumerate_modules()])
其中SIP状态查看如下
snappyjack@snappyjack /tmp % csrutil status
System Integrity Protection status: disabled.
输出的结果如下
snappyjack@snappyjack frida-morty % python3 example.py
['cat', 'libSystem.B.dylib', 'libcache.dylib', 'libcommonCrypto.dylib', 'libcompiler_rt.dylib', 'libcopyfile.dylib', 'libcorecrypto.dylib', 'libdispatch.dylib', 'libdyld.dylib', 'libkeymgr.dylib', 'liblaunch.dylib', 'libmacho.dylib', 'libquarantine.dylib', 'libremovefile.dylib', 'libsystem_asl.dylib', 'libsystem_blocks.dylib', 'libsystem_c.dylib', 'libsystem_collections.dylib', 'libsystem_configuration.dylib', 'libsystem_containermanager.dylib', 'libsystem_coreservices.dylib', 'libsystem_darwin.dylib', 'libsystem_dnssd.dylib', 'libsystem_featureflags.dylib', 'libsystem_info.dylib', 'libsystem_m.dylib', 'libsystem_malloc.dylib', 'libsystem_networkextension.dylib', 'libsystem_notify.dylib', 'libsystem_product_info_filter.dylib', 'libsystem_sandbox.dylib', 'libsystem_secinit.dylib', 'libsystem_kernel.dylib', 'libsystem_platform.dylib', 'libsystem_pthread.dylib', 'libsystem_symptoms.dylib', 'libsystem_trace.dylib', 'libunwind.dylib', 'libxpc.dylib', 'libc++abi.dylib', 'libobjc.A.dylib', 'liboah.dylib', 'libc++.1.dylib', 'dyld']
Functions
#include <stdio.h>
#include <unistd.h>
void
f (int n)
{
printf ("Number: %d\n", n);
}
int
main (int argc,
char * argv[])
{
int i = 0;
printf ("f() is at %p\n", f);
while (1)
{
f (i++);
sleep (1);
}
}
编译
gcc -Wall hello.c -o hello
运行后的效果如下
snappyjack@snappyjack frida-morty % ./hello
f() is at 0x1017aeee0
Number: 0
Number: 1
Number: 2
Number: 3
创建hook.py
from __future__ import print_function
import frida
import sys
session = frida.attach("hello")
script = session.create_script("""
Interceptor.attach(ptr("%s"), {
onEnter: function(args) {
send(args[0].toInt32());
}
});
""" % int(sys.argv[1], 16))#onEnter提供了args参数,可以用来读取参数列表
def on_message(message, data):
print(message)
script.on('message', on_message) # monitor for any messages from the injected process
script.load()
sys.stdin.read()
运行后如下
snappyjack@snappyjack frida-morty % python hook.py 0x106760ee0
{u'type': u'send', u'payload': 12}
{u'type': u'send', u'payload': 13}
{u'type': u'send', u'payload': 14}
{u'type': u'send', u'payload': 15}
{u'type': u'send', u'payload': 16}
{u'type': u'send', u'payload': 17}
或者这样
snappyjack@snappyjack ~ % sudo /Users/snappyjack/Library/Python/3.8/bin/frida-trace -i "f" hello
Password:
Instrumenting...
f: Auto-generated handler at "/Users/snappyjack/__handlers__/hello/f.js"
Started tracing 1 function. Press Ctrl+C to stop.
/* TID 0x307 */
711 ms f()
1712 ms f()
2715 ms f()
修改js
onEnter(log, args, state) {
log('f()');
send(args[0].toInt32());
},
结果如下
103338 ms f()
{'type': 'send', 'payload': 285}
104342 ms f()
{'type': 'send', 'payload': 286}
105345 ms f()
{'type': 'send', 'payload': 287}
106350 ms f()
{'type': 'send', 'payload': 288}
107352 ms f()
{'type': 'send', 'payload': 289}
108356 ms f()
{'type': 'send', 'payload': 290}
创建modify.py
import frida
import sys
session = frida.attach("hello")
script = session.create_script("""
Interceptor.attach(ptr("%s"), {
onEnter: function(args) {
args[0] = ptr("1337");
}
});
""" % int(sys.argv[1], 16)) #args[0] = ptr("1337")表示将1337指针赋予给args[0],达到修改参数的目的
script.load()
sys.stdin.read()
运行python modify.py 0x1042a0ee0
后效果如下
snappyjack@snappyjack frida-morty % ./hello
f() is at 0x1042a0ee0
Number: 0
Number: 1
Number: 2
Number: 3
Number: 4
Number: 5
Number: 6
Number: 7
Number: 8
Number: 1337
Number: 1337
Number: 1337
Number: 1337
或者
sudo /Users/snappyjack/Library/Python/3.8/bin/frida-trace -i "f" hello
修改js脚本
onEnter(log, args, state) {
log('f()');
send(args[0].toInt32());
args[0] = ptr("1337");
},
结果如下
Number: 53
Number: 54
Number: 1337
Number: 1337
Number: 1337
Number: 1337
Number: 1337
Number: 1337
Number: 1337
Number: 1337
创建call.py
import frida
import sys
session = frida.attach("hello")
script = session.create_script("""
var f = new NativeFunction(ptr("%s"), 'void', ['int']);
f(1911);
f(1911);
f(1911);
""" % int(sys.argv[1], 16)) #原型如下new NativeFunction(address, returnType, argTypes[, abi]),其中第一个参数是函数地址,第二个参数是返回值的类型,第三个参数是输入参数的类型
script.load()
运行后有如下效果
Number: 18
Number: 19
Number: 20
Number: 21
Number: 1911
Number: 1911
Number: 1911
Number: 22
Number: 23
Number: 24
Number: 25
Injecting Strings and Calling a Function
创建hi.c如下
#include <stdio.h>
#include <unistd.h>
int
f (const char * s)
{
printf ("String: %s\n", s);
return 0;
}
int
main (int argc,
char * argv[])
{
const char * s = "Testing!";
printf ("f() is at %p\n", f);
printf ("s is at %p\n", s);
while (1)
{
f (s);
sleep (1);
}
}
编译
gcc -Wall hi.c -o hi
运行如下
snappyjack@snappyjack frida-morty % ./hi
f() is at 0x10a3b6eb0
s is at 0x10a3b6f88
String: Testing!
String: Testing!
String: Testing!
同样建立stringhook.py
from __future__ import print_function
import frida
import sys
session = frida.attach("hi")
script = session.create_script("""
var st = Memory.allocUtf8String("TESTMEPLZ!");//在堆空间申请一块
var f = new NativeFunction(ptr("%s"), 'int', ['pointer']);//创建了一个方法
// In NativeFunction param 2 is the return value type,
// and param 3 is an array of input types
f(st);//执行了这个方法,并将之前TESTMEPLZ!地址传入其中
""" % int(sys.argv[1], 16))
def on_message(message, data):
print(message)
script.on('message', on_message)
script.load()
运行后结果如下
String: Testing!
String: Testing!
String: TESTMEPLZ!
String: Testing!
String: Testing!
String: Testing!
修改参数
snappyjack@snappyjack ~ % sudo /Users/snappyjack/Library/Python/3.8/bin/frida-trace -i "f" hi
Password:
Instrumenting...
f: Loaded handler at "/Users/snappyjack/__handlers__/hi/f.js"
onEnter(log, args, state) {
var buf = Memory.allocUtf8String('mystring');
this.buf = buf;
args[0] = buf;
},
结果如下
snappyjack@snappyjack frida-morty % ./hi
f() is at 0x10337beb0
s is at 0x10337bf88
String: Testing!
String: Testing!
String: Testing!
String: Testing!
String: Testing!
String: Testing!
String: Testing!
String: mystring
String: mystring
String: mystring
查看参数
修改js
sudo vim /Users/snappyjack/__handlers__/hi/f.js
onEnter(log, args, state) {
console.log("args[0]:",hexdump(args[0]));
console.log("args[1]:",args[0].readCString());
console.log("args[2]:",args[0].toInt32());
},
结果如下
args[0]: 0 1 2 3 4 5 6 7 8 9 A B C D E F 0123456789ABCDEF
105636f88 61 61 61 61 62 62 62 62 63 63 63 63 64 64 64 64 aaaabbbbccccdddd
105636f98 00 66 28 29 20 69 73 20 61 74 20 25 70 0a 00 73 .f() is at %p..s
105636fa8 20 69 73 20 61 74 20 25 70 0a 00 00 01 00 00 00 is at %p.......
105636fb8 1c 00 00 00 00 00 00 00 1c 00 00 00 00 00 00 00 ................
105636fc8 1c 00 00 00 02 00 00 00 b0 3e 00 00 34 00 00 00 .........>..4...
105636fd8 34 00 00 00 4a 3f 00 00 00 00 00 00 34 00 00 00 4...J?......4...
105636fe8 03 00 00 00 0c 00 01 00 10 00 01 00 00 00 00 00 ................
105636ff8 00 00 00 01 00 00 00 00 5c 82 60 20 ff 7f 00 00 ........\.` ....
105637008 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
105637018 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
105637028 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
105637038 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
105637048 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
105637058 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
105637068 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
105637078 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
args[1]: aaaabbbbccccdddd
args[2]: 90402696
sockaddr_in的一个案例
Client.c如下
#include <arpa/inet.h>
#include <errno.h>
#include <netdb.h>
#include <netinet/in.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <unistd.h>
int
main (int argc,
char * argv[])
{
int sock_fd, i, n;
struct sockaddr_in serv_addr;
unsigned char * b;
const char * message;
char recv_buf[1024];
if (argc != 2) // 验证参数
{
fprintf (stderr, "Usage: %s <ip of server>\n", argv[0]);
return 1;
}
printf ("connect() is at: %p\n", connect);
if ((sock_fd = socket (AF_INET, SOCK_STREAM, 0)) < 0) // 验证是否可以建立socket
{
perror ("Unable to create socket");
return 1;
}
bzero (&serv_addr, sizeof (serv_addr));
serv_addr.sin_family = AF_INET;
serv_addr.sin_port = htons (5000);
if (inet_pton (AF_INET, argv[1], &serv_addr.sin_addr) <= 0)//验证地址
{
fprintf (stderr, "Unable to parse IP address\n");
return 1;
}
printf ("\nHere's the serv_addr buffer:\n");
b = (unsigned char *) &serv_addr;
for (i = 0; i != sizeof (serv_addr); i++)
printf ("%s%02x", (i != 0) ? " " : "", b[i]);
printf ("\n\nPress ENTER key to Continue\n");
while (getchar () == EOF && ferror (stdin) && errno == EINTR)
;
if (connect (sock_fd, (struct sockaddr *) &serv_addr, sizeof (serv_addr)) < 0)
{
perror ("Unable to connect");
return 1;
}
message = "Hello there!";
if (send (sock_fd, message, strlen (message), 0) < 0)//发送一条
{
perror ("Unable to send");
return 1;
}
while (1)
{
n = recv (sock_fd, recv_buf, sizeof (recv_buf) - 1, 0);//接受数据并打印数据
if (n == -1 && errno == EINTR)
continue;
else if (n <= 0)
break;
recv_buf[n] = 0;
fputs (recv_buf, stdout);
}
if (n < 0)
{
perror ("Unable to read");
}
return 0;
}
编译如下
gcc -Wall client.c -o client
分别运行如下
snappyjack@snappyjack frida-morty % nc -l 5000
Hello there!
daf
aaa
bbb
ccc
snappyjack@snappyjack frida-morty % ./client 127.0.0.1
connect() is at: 0x7fff205d63dc
Here's the serv_addr buffer:
00 02 13 88 7f 00 00 01 00 00 00 00 00 00 00 00
Press ENTER key to Continue
daf
aaa
bbb
ccc
修改struct.py
from __future__ import print_function
import frida
import sys
session = frida.attach("client")
script = session.create_script("""
// First, let's give ourselves a bit of memory to put our struct in:
send('Allocating memory and writing bytes...');//首先发送一个字符串
var st = Memory.alloc(16); //然后申请一块空间
// Now we need to fill it - this is a bit blunt, but works...
st.writeByteArray([0x02, 0x00, 0x13, 0x89, 0x7F, 0x00, 0x00, 0x01, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30]);//将申请的空间填入一些数据
// Module.getExportByName() can find functions without knowing the source
// module, but it's slower, especially over large binaries! YMMV...
// 下面这句话是查找connect函数的地址,然后传入
Interceptor.attach(Module.getExportByName(null, 'connect'), {
onEnter: function(args) {
send('Injecting malicious byte array:');// 再发一个字符串
args[1] = st; // 修改connect的第一个参数
}
//, onLeave: function(retval) {
// retval.replace(0); // Use this to manipulate the return value
//}
});
""")
# Here's some message handling..
# [ It's a little bit more meaningful to read as output :-D
# Errors get [!] and messages get [i] prefixes. ]
def on_message(message, data):
if message['type'] == 'error':
print("[!] " + message['stack'])
elif message['type'] == 'send': # 如果种类是send,那么打印这个消息
print("[i] " + message['payload'])
else:
print(message) # 打印这个消息
script.on('message', on_message)
script.load()
sys.stdin.read()
运行如下命令
./client 127.0.0.1
nc -lp 5001
./struct_mod.py
可以看到端口已经被改成了5001
Messages
首先创建hello.c
#include <stdio.h>
#include <unistd.h>
void
f (int n)
{
printf ("Number: %d\n", n);
}
int
main (int argc,
char * argv[])
{
int i = 0;
printf ("f() is at %p\n", f);
while (1)
{
f (i++);
sleep (1);
}
}
创建一个send.py
from __future__ import print_function
import frida
import sys
session = frida.attach("hello")
script = session.create_script("send(1337);") # 创建一个script
def on_message(message, data):
print(message)
script.on('message', on_message)
script.load()
sys.stdin.read()
如果你将send(1337)改为send(a),将报如下错误
{u'type': u'error', u'description': u'ReferenceError: a is not defined', u'lineNumber': 1}
收取消息(异步的方式)
创建pingpong.py
from __future__ import print_function
import frida
import sys
session = frida.attach("hello")
script = session.create_script("""
recv('poke', function onMessage(pokeMessage) { send('pokeBack'); });
""")
def on_message(message, data):
print(message)
script.on('message', on_message) #打印 message
script.load()
script.post({"type": "poke"}) #应该是发了一个数据
sys.stdin.read()
阻塞的方式接受消息
from __future__ import print_function
import frida
import sys
session = frida.attach("hello")
script = session.create_script("""
Interceptor.attach(ptr("%s"), {
onEnter: function(args) {
send(args[0].toString()); //发送函数的参数
var op = recv('input', function(value) {
args[0] = ptr(value.payload);
});
op.wait(); //阻塞等待
}
});
""" % int(sys.argv[1], 16))
def on_message(message, data):
print(message) #打印发送过来的消息
val = int(message['payload'], 16) #获取发送过来的消息参数
script.post({'type': 'input', 'payload': str(val * 2)}) #将消息参数*2,发送给主程序
script.on('message', on_message)
script.load()
sys.stdin.read()
命令
Frida
snappyjack@snappyjack frida-morty % /usr/local/Cellar/python@3.9/3.9.2/Frameworks/Python.framework/Versions/3.9/bin/frida 计算器
____
/ _ | Frida 14.2.13 - A world-class dynamic instrumentation toolkit
| (_| |
> _ | Commands:
/_/ |_| help -> Displays the help system
. . . . object? -> Display information about 'object'
. . . . exit/quit -> Exit
. . . .
. . . . More info at https://www.frida.re/docs/home/
[Local::计算器]-> Object.keys(ObjC.classes).slice(0, 10)
[
"NSLeafProxy",
"Object",
"__NSGenericDeallocHandler",
"__NSAtom",
"_NSZombie_",
"__NSMessageBuilder",
"NSVB_AnimationFencingSupport",
"JSExport",
"NSProxy",
"FPFrameworkOverridesIterator"
]
frida-trace
snappyjack@snappyjack frida-morty % /usr/local/Cellar/python@3.9/3.9.2/Frameworks/Python.framework/Versions/3.9/bin/frida-trace --decorate -i "recv*" -i "send*" Firefox
Instrumenting...
...
...
sendUserActivityMsg: Auto-generated handler at "/Users/snappyjack/pycharmProjects/frida-morty/__handlers__/IOKit/sendUserActivityMsg.js"
sendAsyncReleaseMsg: Auto-generated handler at "/Users/snappyjack/pycharmProjects/frida-morty/__handlers__/IOKit/sendAsyncReleaseMsg.js"
Started tracing 24 functions. Press Ctrl+C to stop.
/* TID 0x993f */
2243 ms recvmsg(socket=0x86, message=0x70000d940af0, flags=0x80) [libsystem_kernel.dylib]
2243 ms recvmsg(socket=0x86, message=0x70000d940af0, flags=0x80) [libsystem_kernel.dylib]
其中--decorate
参数会自动添加类似如下方法
onEnter(log, args, state) {
log('memcpy()');
},
frida_ssl_logger(无法使用)
snappyjack@snappyjack frida_ssl_logger % python3 ssl_logger.py -verbose 22927
经过尝试
对wechat进行hook
下载class-dump:https://github.com/AloneMonkey/MonkeyDev/blob/master/bin/class-dump
首先生成头文件
class-dump -H /Applications/WeChat.app
结果如下
total 41864
drwxr-xr-x 4924 snappyjack staff 157568 3 1 16:31 .
drwx------@ 18 snappyjack staff 576 3 1 16:30 ..
-rw-r--r-- 1 snappyjack staff 1267 3 1 16:31 A2BlockInvocation.h
-rw-r--r-- 1 snappyjack staff 1112 3 1 16:31 A2DynamicBKURLConnectionInformalDelegate.h
-rw-r--r-- 1 snappyjack staff 820 3 1 16:31 A2DynamicClassDelegate.h
-rw-r--r-- 1 snappyjack staff 1667 3 1 16:31 A2DynamicDelegate.h
-rw-r--r-- 1 snappyjack staff 618 3 1 16:31 A2DynamicNSCacheDelegate.h
-rw-r--r-- 1 snappyjack staff 1446 3 1 16:31 A2DynamicNSURLConnectionDelegate.h
-rw-r--r-- 1 snappyjack staff 1739 3 1 16:31 ABTestItem.h
-rw-r--r-- 1 snappyjack staff 432 3 1 16:31 ABTestListWrap.h
-rw-r--r-- 1 snappyjack staff 729 3 1 16:31 AFCompoundResponseSerializer.h
-rw-r--r-- 1 snappyjack staff 1842 3 1 16:31 AFHTTPBodyPart.h
-rw-r--r-- 1 snappyjack staff 3858 3 1 16:31 AFHTTPRequestSerializer.h
-rw-r--r-- 1 snappyjack staff 1389 3 1 16:31 AFHTTPResponseSerializer.h
缩小查找范围
snappyjack@snappyjack wechathead % ls -al |grep Message|grep Service
-rw-r--r-- 1 snappyjack staff 5221 3 1 16:31 FTSFileMessageService.h
-rw-r--r-- 1 snappyjack staff 382 3 1 16:31 IMessageServiceAppExt-Protocol.h
-rw-r--r-- 1 snappyjack staff 980 3 1 16:31 IMessageServiceFileExt-Protocol.h
-rw-r--r-- 1 snappyjack staff 381 3 1 16:31 IMessageServiceFileReTransferExt-Protocol.h
-rw-r--r-- 1 snappyjack staff 755 3 1 16:31 IMessageServiceImageExt-Protocol.h
-rw-r--r-- 1 snappyjack staff 780 3 1 16:31 IMessageServiceVideoExt-Protocol.h
-rw-r--r-- 1 snappyjack staff 407 3 1 16:31 IMessageServiceVideoReTransferExt-Protocol.h
-rw-r--r-- 1 snappyjack staff 3144 3 1 16:31 MMFTSMessageService.h
-rw-r--r-- 1 snappyjack staff 20481 3 1 16:31 MessageService.h
查看MessageService.h
- (id)SendLocationMsgFromUser:(id)arg1 toUser:(id)arg2 withLatitude:(double)arg3 longitude:(double)arg4 poiName:(id)arg5 label:(id)arg6;
- (id)SendNamecardMsgFromUser:(id)arg1 toUser:(id)arg2 containingContact:(id)arg3;
- (id)SendStickerStoreEmoticonMsgFromUsr:(id)arg1 toUsrName:(id)arg2 md5:(id)arg3 productID:(id)arg4;
- (id)SendEmoticonMsgFromUsr:(id)arg1 toUsrName:(id)arg2 md5:(id)arg3 emoticonType:(unsigned int)arg4;
- (id)SendImgMessage:(id)arg1 toUsrName:(id)arg2 thumbImgData:(id)arg3 midImgData:(id)arg4 imgData:(id)arg5 imgInfo:(id)arg6;
- (id)SendTextMessage:(id)arg1 toUsrName:(id)arg2 msgText:(id)arg3 atUserList:(id)arg4;
- (id)SendAppMusicMessageFromUser:(id)arg1 toUsrName:(id)arg2 withTitle:(id)arg3 url:(id)arg4 description:(id)arg5 thumbnailData:(id)arg6;
- (id)SendAppURLMessageFromUser:(id)arg1 toUsrName:(id)arg2 withTitle:(id)arg3 url:(id)arg4 description:(id)arg5 thumbnailData:(id)arg6;
- (id)SendAppURLMessageFromUser:(id)arg1 toUsrName:(id)arg2 withTitle:(id)arg3 url:(id)arg4 description:(id)arg5 thumbUrl:(id)arg6 sourceUserName:(id)arg7 sourceDisp
尝试hook这些方法
sudo /Users/snappyjack/Library/Python/3.8/bin/frida-trace -m "-[MessageService Send*]" 微信
自动生成的js脚本如下
/*
* Auto-generated by Frida. Please modify to match the signature of -[MessageService SendTextMessageWithString:toUser:].
* This stub is currently auto-generated from manpages when available.
*
* For full API reference, see: https://frida.re/docs/javascript-api/
*/
{
/**
* Called synchronously when about to call -[MessageService SendTextMessageWithString:toUser:].
*
* @this {object} - Object allowing you to store state for use in onLeave.
* @param {function} log - Call this function with a string to be presented to the user.
* @param {array} args - Function arguments represented as an array of NativePointer objects.
* For example use args[0].readUtf8String() if the first argument is a pointer to a C string encoded as UTF-8.
* It is also possible to modify arguments by assigning a NativePointer object to an element of this array.
* @param {object} state - Object allowing you to keep state across function calls.
* Only one JavaScript function will execute at a time, so do not worry about race-conditions.
* However, do not use this to store function arguments across onEnter/onLeave, but instead
* use "this" which is an object for keeping state local to an invocation.
*/
onEnter(log, args, state) {
log(`-[MessageService SendTextMessageWithString:${args[2]} toUser:${args[3]}]`);
},
/**
* Called synchronously when about to return from -[MessageService SendTextMessageWithString:toUser:].
*
* See onEnter for details.
*
* @this {object} - Object allowing you to access state stored in onEnter.
* @param {function} log - Call this function with a string to be presented to the user.
* @param {NativePointer} retval - Return value represented as a NativePointer object.
* @param {object} state - Object allowing you to keep state across function calls.
*/
onLeave(log, retval, state) {
}
}
尝试发送几条数据后如下
Started tracing 18 functions. Press Ctrl+C to stop.
/* TID 0x307 */
115543 ms -[MessageService SendTextMessage:0x600001ff5560 toUsrName:0x9c2e0e36855403e1 msgText:0x9e0f1e68f7157201 atUserList:0x60000015f390]
134465 ms -[MessageService SendTextMessage:0x600001ff5560 toUsrName:0x9c2e0e36855403e1 msgText:0x600000214450 atUserList:0x6000002175a0]
修改onEnter信息如下
sudo vim /Users/snappyjack/__handlers__/MessageService/SendTextMessage_toUsrName_msgTex_34aa5a1f.js
onEnter(log, args, state) {
console.log(`-[我的消息测试 SendTextMessage:${args[2]} toUsrName:${args[3]} msgText:${args[4]} atUserList:${args[5]}]`);
console.log("arg[1] -> " + new ObjC.Object(args[2]))
console.log("arg[2] -> " + new ObjC.Object(args[3]))
console.log("arg[3] -> " + new ObjC.Object(args[4]))
console.log("arg[4] -> " + new ObjC.Object(args[5]))
},
运行如下
snappyjack@snappyjack ~ % sudo /Users/snappyjack/Library/Python/3.8/bin/frida-trace -m "-[MessageService SendTextMessage*]" 微信
结果如下
3541 ms -[MessageService SendTextMessage:0x600001c98f60 toUsrName:0xdc73374b7235993 msgText:0xfe6235eb6366d13 atUserList:0x600001e4a370]
-[我的消息测试 SendTextMessage:0x600001c98f60 toUsrName:0xdc73374b7235993 msgText:0xfe6235e85346f03 atUserList:0x60000005d680]
arg[1] -> wxid_6984249843912
arg[2] -> filehelper
arg[3] -> 333
arg[4] ->
修改发送的信息
onEnter(log, args, state) {
//log(`-[MessageService SendTextMessage:${args[2]} toUsrName:${args[3]} msgText:${args[4]} atUserList:${args[5]}]`);
//console.log(`-[我的消息测试 SendTextMessage:${args[2]} toUsrName:${args[3]} msgText:${args[4]} atUserList:${args[5]}]`);
console.log("arg[1] -> " + new ObjC.Object(args[2]));
console.log("arg[2] -> " + new ObjC.Object(args[3]));
console.log("arg[3] -> " + new ObjC.Object(args[4]));
args[4] = ObjC.classes.NSString.stringWithString_("MacOS微信分析")
},
主动调用信息,将一下信息保存为wechattest.js
console.log("init success");
function SendTextMessage(wxid, msg) {
var message = ObjC.chooseSync(ObjC.classes.MessageService)[0]
var username = ObjC.classes.CUtility.GetCurrentUserName();
console.log(username)
console.log("Type of arg[0] -> " + message)
var toUsrName = ObjC.classes.NSString.stringWithString_(wxid);
var msgText = ObjC.classes.NSString.stringWithString_(msg);
message["- SendTextMessage:toUsrName:msgText:atUserList:"](username, toUsrName, msgText, null);
}
SendTextMessage("filehelper","主动调用发送信息!")
运行/Users/snappyjack/Library/Python/3.8/bin/frida 微信 --debug --runtime=v8 --no-pause -l wechattest.js
,此时可以主动的发送消息
监听接收消息
/Users/snappyjack/Library/Python/3.8/bin/frida-trace -m "-[MessageService notifyAddMsgOnMainThread*]" 微信
直接修改js代码
var MessageData = new ObjC.Object(args[3]).$ivars;
console.log("fromUsrName -> " + MessageData.fromUsrName)
console.log("toUsrName -> " + MessageData.toUsrName)
console.log("msgContent -> " + MessageData.msgContent)
结果如下
Instrumenting...
-[MessageService notifyAddMsgOnMainThread:msgData:]: Loaded handler at "/Users/snappyjack/pycharmProjects/frida-morty/__handlers__/MessageService/notifyAddMsgOnMainThread_msgData_.js"
Started tracing 1 function. Press Ctrl+C to stop.
fromUsrName -> xxxx
toUsrName -> wxxxx
msgContent -> jxlxxxx7:
我记忆出现了混乱
/* TID 0x2c7f07 */
10044 ms -[MessageService notifyAddMsgOnMainThread:0x600002b925b0 msgData:0x7fa557609970]
fromUsrName -> 19xxxxm
toUsrName -> wxixxxx12
msgContent -> mxxxxxi:
外国明星名字太难记了
参考:https://bbs.pediy.com/thread-266041.htm