forked from pookjw/SidecarPatcher
-
Notifications
You must be signed in to change notification settings - Fork 1
/
main.swift
182 lines (152 loc) · 8.21 KB
/
main.swift
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
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
/*
SidecarPatcher - Version 13
Enabling Sidecar on old Mac (2015 or older)
But I don't have Sidecar-unsupported Mac so I don't know it works.
THIS SCRIPT DOESN'T MAKE SidecarCore BACKUP SO YOU HAVE TO DO THIS MANUALLY. PLEASE BACKUP /System/Library/PrivateFrameworks/SidecarCore.framework/Versions/A/SidecarCore. PLEASE. PLEASE. PLEASE.
And after patching SidecarCore, this script won't work until replacing to original one.
This script requires disabling SIP, and running as root.
*/
import Foundation
func shell(_ command: String) -> String{
let task = Process()
task.launchPath = "/bin/bash"
task.arguments = ["-c", command]
let pipe = Pipe()
task.standardOutput = pipe
task.launch()
let data = pipe.fileHandleForReading.readDataToEndOfFile()
let output: String = NSString(data: data, encoding: String.Encoding.utf8.rawValue)! as String
return output
}
// From https://gist.github.com/brennanMKE/a0a2ee6aa5a2e2e66297c580c4df0d66
fileprivate func directoryExistsAtPath(_ path: String) -> Bool {
var isDirectory = ObjCBool(true)
let exists = FileManager.default.fileExists(atPath: path, isDirectory: &isDirectory)
return exists && isDirectory.boolValue
}
func importCore(path: String) -> String{
return shell("xxd -p \"\(path)/SidecarCore\" | tr -d '\n'")
}
// idea from https://github.com/dfreniche/SwiftANSIColors
enum ANSIColors: String {
case black = "\u{001B}[0;30m"
case red = "\u{001B}[0;31m"
case green = "\u{001B}[0;32m"
case yellow = "\u{001B}[0;33m"
case blue = "\u{001B}[0;34m"
case magenta = "\u{001B}[0;35m"
case cyan = "\u{001B}[0;36m"
case white = "\u{001B}[0;37m"
case `default` = "\u{001B}[0;0m"
}
func + (left: ANSIColors, right: String) -> String {
return left.rawValue + right
}
func + (left: String, right: ANSIColors) -> String {
return left + right.rawValue
}
// end
func checkSystem(core: String, code: [String: PatchCode]) -> [PatchCode]{
var result: [PatchCode] = []
// Check OS
if #available(macOS 10.15, *){
()
}else{
assertionFailure(ANSIColors.red + "You're not using macOS 10.15 or later!" + ANSIColors.default)
}
// Check the system is patched (macModel and iPadModel)
for (_, value) in code{
if !core.contains(value.patched){
result.append(value)
}
}
if result.isEmpty{
assertionFailure(ANSIColors.red + "Already patched!" + ANSIColors.default)
}
// Check SidecarCore is damaged
for value in result{
if !core.contains(value.original){
assertionFailure(ANSIColors.red + "Not supported SidecarCore! or seems like damaged" + ANSIColors.default)
}
}
// Check SIP status
if !(shell("csrutil status") == "System Integrity Protection status: disabled.\n") && !(shell("csrutil status").contains("Filesystem Protections: disabled")){
assertionFailure(ANSIColors.red + "Filesystem Protections of System Integrity Protection is enabled" + ANSIColors.default)
}
// Check privilege
if !(shell("id -u") == "0\n"){
assertionFailure(ANSIColors.red + "Must be run as root" + ANSIColors.default)
}
// return patch code
return result
}
func patch(core: String, code: [PatchCode]) -> String{
var core = core
for value in code{
core.replaceSubrange(core.range(of: value.original)!, with: value.patched)
}
return core
}
func exportCore(core: String, path: String){
// Remove existing tmp dir
if directoryExistsAtPath("/tmp/SidecarPatcher"){
do {
try fileManager.removeItem(atPath: "/tmp/SidecarPatcher")
}
catch let error as NSError {
assertionFailure(ANSIColors.red + String("\(error)") + ANSIColors.default)
}
}
// Create temp dir
let temp_dir = URL(fileURLWithPath: "/tmp/").appendingPathComponent("SidecarPatcher").path
do{
try fileManager.createDirectory(atPath: temp_dir, withIntermediateDirectories: true, attributes: nil)
} catch let error as NSError {
assertionFailure(ANSIColors.red + String("\(error)") + ANSIColors.default)
}
// Export code
let output_path = URL(fileURLWithPath: "/tmp/SidecarPatcher").appendingPathComponent("output.txt")
do {
try core.write(to: output_path, atomically: true, encoding: String.Encoding.utf8)
} catch let error as NSError {
assertionFailure(ANSIColors.red + String("\(error)") + ANSIColors.default)
}
shell("xxd -r -p /tmp/SidecarPatcher/output.txt /tmp/SidecarPatcher/SidecarCore")
// Mount system (thanks to: https://github.com/pookjw/SidecarPatcher/issues/1)
shell("sudo mount -uw /")
// Remove existing original system file
if fileManager.fileExists(atPath: "\(path)/SidecarCore") {
do {
try fileManager.removeItem(atPath: "\(path)/SidecarCore")
}
catch let error as NSError {
assertionFailure(ANSIColors.red + String("\(error)") + ANSIColors.default)
}
}
// Copy system file
do {
try fileManager.copyItem(atPath: "/tmp/SidecarPatcher/SidecarCore", toPath: "\(path)/SidecarCore")
}
catch let error as NSError {
assertionFailure(ANSIColors.red + String("\(error)") + ANSIColors.default)
}
// codesign
shell("sudo codesign -f -s - \"\(path)/SidecarCore\"")
shell("sudo chmod 755 \"\(path)/SidecarCore\"")
}
struct PatchCode{
var original: String
var patched: String
}
let fileManager = FileManager()
let SidecarCorePath = "/System/Library/PrivateFrameworks/SidecarCore.framework/Versions/A"
var patchDictionary: [String: PatchCode] = [:]
patchDictionary["Mac"] = PatchCode(original: "694d616331332c3100694d616331332c3200694d616331332c3300694d616331342c3100694d616331342c3200694d616331342c3300694d616331342c3400694d616331352c3100694d616331362c3100694d616331362c32004d6163426f6f6b382c31004d6163426f6f6b416972352c31004d6163426f6f6b416972352c32004d6163426f6f6b416972362c31004d6163426f6f6b416972362c32004d6163426f6f6b416972372c31004d6163426f6f6b416972372c32004d6163426f6f6b50726f392c31004d6163426f6f6b50726f392c32004d6163426f6f6b50726f31302c31004d6163426f6f6b50726f31302c32004d6163426f6f6b50726f31312c31004d6163426f6f6b50726f31312c32004d6163426f6f6b50726f31312c33004d6163426f6f6b50726f31312c34004d6163426f6f6b50726f31312c35004d6163426f6f6b50726f31322c31004d61636d696e69362c31004d61636d696e69362c32004d61636d696e69372c31004d616350726f352c31004d616350726f362c31", patched: "694d616330302c3000694d616330302c3000694d616330302c3000694d616330302c3000694d616330302c3000694d616330302c3000694d616330302c3000694d616330302c3000694d616330302c3000694d616330302c30004d6163426f6f6b302c30004d6163426f6f6b416972302c30004d6163426f6f6b416972302c30004d6163426f6f6b416972302c30004d6163426f6f6b416972302c30004d6163426f6f6b416972302c30004d6163426f6f6b416972302c30004d6163426f6f6b50726f302c30004d6163426f6f6b50726f302c30004d6163426f6f6b50726f30302c30004d6163426f6f6b50726f30302c30004d6163426f6f6b50726f30302c30004d6163426f6f6b50726f30302c30004d6163426f6f6b50726f30302c30004d6163426f6f6b50726f30302c30004d6163426f6f6b50726f30302c30004d6163426f6f6b50726f30302c30004d61636d696e69302c30004d61636d696e69302c30004d61636d696e69302c30004d616350726f302c30004d616350726f302c30")
patchDictionary["iPad"] = PatchCode(original: "69506164342c310069506164342c320069506164342c330069506164342c340069506164342c350069506164342c360069506164342c370069506164342c380069506164342c390069506164352c310069506164352c320069506164352c330069506164352c340069506164362c31310069506164362c3132", patched: "69506164302c300069506164302c300069506164302c300069506164302c300069506164302c300069506164302c300069506164302c300069506164302c300069506164302c300069506164302c300069506164302c300069506164302c300069506164302c300069506164302c30300069506164302c3030")
print("SidecarPatcher (Version 13)")
print("GitHub : https://github.com/pookjw/SidecarPatcher") // don't erase this
let originalCore = importCore(path: SidecarCorePath) // get code
let patchToCode = checkSystem(core: originalCore, code: patchDictionary) // check availability and get patch code
let patchedCore = patch(core: originalCore, code: patchToCode) // patch code
exportCore(core: patchedCore, path: SidecarCorePath) // copy patched code to system
print("Reboot your macOS.")