-
Notifications
You must be signed in to change notification settings - Fork 5
/
Tweak.x
146 lines (113 loc) · 5.39 KB
/
Tweak.x
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
/* How to Hook with Logos
Hooks are written with syntax similar to that of an Objective-C @implementation.
You don't need to #include <substrate.h>, it will be done automatically, as will
the generation of a class list and an automatic constructor.
%hook ClassName
// Hooking a class method
+ (id)sharedInstance {
return %orig;
}
// Hooking an instance method with an argument.
- (void)messageName:(int)argument {
%log; // Write a message about this call, including its class, name and arguments, to the system log.
%orig; // Call through to the original function with its original arguments.
%orig(nil); // Call through to the original function with a custom argument.
// If you use %orig(), you MUST supply all arguments (except for self and _cmd, the automatically generated ones.)
}
// Hooking an instance method with no arguments.
- (id)noArguments {
%log;
id awesome = %orig;
[awesome doSomethingElse];
return awesome;
}
// Always make sure you clean up after yourself; Not doing so could have grave consequences!
%end
*/
#import <Foundation/Foundation.h>
#import "CPTManager.h"
CPTManager* cptManager;
// https://theos.dev/docs/logos-syntax#hookf
%group TX
// libPCITransport.dylib
// pci::transport::th::writeAsync(unsigned char const*, unsigned int, void (*)(void*))
// Handles all outgoing ARI & QMI packets
// Source: https://dev.seemoo.tu-darmstadt.de/apple/iphone-qmi-wireshark/-/tree/main/agent
%hookf(int, WriteAsync, void *instance, unsigned char *data, unsigned int length, void *callback) {
// Copy the data buffer into a NSData object
// See: https://developer.apple.com/documentation/foundation/nsdata/1547231-datawithbytes?language=objc
NSData *objData = [NSData dataWithBytes:data length:length];
// NSLog(@"Hey, we're hooking ARI & QMI send stuff %@", objData);
[cptManager addData:objData :@"OUT"];
// Call the original implementation of this function
return %orig;
}
%end
%group QMI
// libATCommandStudioDynamic.dylib
// QMux::State::handleReadData(unsigned char const*, unsigned int)
// Handles all incoming QMI packets
// Source: https://dev.seemoo.tu-darmstadt.de/apple/iphone-qmi-wireshark/-/tree/main/agent
%hookf(int, HandleReadData, void *instance, unsigned char *data, unsigned int length) {
// Copy the data buffer into a NSData object
// See: https://developer.apple.com/documentation/foundation/nsdata/1547231-datawithbytes?language=objc
NSData *objData = [NSData dataWithBytes:data length:length];
// NSLog(@"Hey, we're hooking QMI read stuff %@", objData);
[cptManager addData:objData :@"IN"];
// Call the original implementation of this function
return %orig;
}
%end
%group ARI
// libARIServer.dylib
// AriHostRt::InboundMsgCB(unsigned char*, unsigned long)
// Handles all incoming ARI packets
// Source: https://github.com/seemoo-lab/aristoteles/blob/master/tools/frida_ari_functions.js
%hookf(int, InboundMsgCB, unsigned char *data, unsigned int length) {
// Copy the data buffer into a NSData object
// See: https://developer.apple.com/documentation/foundation/nsdata/1547231-datawithbytes?language=objc
NSData *objData = [NSData dataWithBytes:data length:length];
// NSLog(@"Hey, we're hooking ARI read stuff %@", objData);
[cptManager addData:objData :@"IN"];
// Call the original implementation of this function
return %orig;
}
%end
%ctor {
NSString* programName = [NSString stringWithUTF8String: argv[0]];
if ([programName isEqualToString:@"/System/Library/Frameworks/CoreTelephony.framework/Support/CommCenter"]) {
// Only enable the tweak for the process CommCenter
NSLog(@"Happy hooking from the CapturePackets tweak in %@", programName);
cptManager = [CPTManager manager];
// Collect the references to the two libraries to increase the speed of function finding
// See: https://github.com/theos/logos/issues/67#issuecomment-682242010
// See: http://www.cydiasubstrate.com/api/c/MSGetImageByName/
MSImageRef libATCommandStudioDynamicImage = MSGetImageByName("/usr/lib/libATCommandStudioDynamic.dylib");
MSImageRef libPCITransportImage = MSGetImageByName("/usr/lib/libPCITransport.dylib");
// The two underscores in front of the function names are important for MSFindSymbol to work
// See: http://www.cydiasubstrate.com/api/c/MSFindSymbol/
%init(TX, WriteAsync = MSFindSymbol(libPCITransportImage, "__ZN3pci9transport2th10writeAsyncEPKhjPFvPvE"));
// We can always hook this function and on ARI iPhone it is never called.
%init(QMI, HandleReadData = MSFindSymbol(libATCommandStudioDynamicImage, "__ZN4QMux5State14handleReadDataEPKhj"));
NSLog(@"Our CapturePackets tweak hooks QMI packets");
// libARIServer is not directly loaded into the CommCenter process.
// We have to wait a bit for it to be available.
// The library is only loaded on ARI iPhones.
// 1s = 10^9s
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, 1 * NSEC_PER_SEC), dispatch_get_main_queue(), ^{
MSImageRef libARIServer = MSGetImageByName("/usr/lib/libARIServer.dylib");
// Only initialize the hook for incoming ARI messages as the library is only loaded on ARI iPhones.
if (libARIServer != NULL) {
%init(ARI, InboundMsgCB = MSFindSymbol(libARIServer, "__ZN9AriHostRt12InboundMsgCBEPhm"));
// NSLog(@"libARIServer: %p - InboundMsg: %p", libARIServer, MSFindSymbol(libARIServer, "__ZN9AriHostRt12InboundMsgCBEPhm"));
NSLog(@"Our CapturePackets tweak also hooks ARI packets");
}
});
[cptManager listen:33067];
}
}
%dtor {
if (cptManager != NULL) {
[cptManager close];
}
}