|
| 1 | +import Foundation |
| 2 | +import ApplicationServices |
| 3 | + |
| 4 | +typealias notAPrivateAPI0 = @convention(c) () -> CInt |
| 5 | +typealias notAPrivateAPI1 = @convention(c) (CInt, CInt, CFString, CFTypeRef) -> CGError |
| 6 | + |
| 7 | +// JS: f = (n, s) => `[${[...s].map((x, i) => x.charCodeAt(0) + i + n).join(', ')}]` |
| 8 | +let unsuspiciousArrayOfIntsThatDoNotObfuscateAnything: [[Int]] = [ |
| 9 | + // https://en.wikipedia.org/wiki/Leet |
| 10 | + [1, 3, 3, 7], |
| 11 | + // Framework path |
| 12 | + [84, 123, 118, 120, 106, 115, 54, 84, 114, 108, 125, 109, 127, 135, 62, 86, 131, 115, 128, 121, 140, 133, 137, 131, 140, 73, 92, 140, 141, 138, 136, 131, 130, 150, 140, 147, 147, 121, 140, 154, 159, 147, 142, 145, 160, 92, 149, 162, 146, 159, 152, 171, 164, 168, 162, 103, 122, 170, 171, 168, 166, 161, 160, 180, 170, 177, 177, 151, 170, 184, 189, 177, 172, 175, 190], |
| 13 | + // _CGSDefaultConnection |
| 14 | + [97, 70, 75, 88, 74, 108, 110, 106, 127, 119, 128, 80, 125, 125, 126, 118, 117, 135, 125, 132, 132], |
| 15 | + // CGSSetConnectionProperty |
| 16 | + [70, 75, 88, 89, 108, 124, 76, 121, 121, 122, 114, 113, 131, 121, 128, 128, 99, 134, 132, 134, 124, 138, 141, 147] |
| 17 | +] |
| 18 | + |
| 19 | +func aFnThatDoesNotObfuscateAnythingAtAll(_ i: Int, _ ints: [Int]) -> String { |
| 20 | + return String(ints.enumerated().map({ Character(UnicodeScalar($0.element + i - $0.offset + 1)!) })) |
| 21 | +} |
| 22 | + |
| 23 | +let anInconspicuousListOfPointersThatDoNotPointToPrivateAPIs: [UnsafeMutableRawPointer] = { |
| 24 | + var list = [UnsafeMutableRawPointer]() |
| 25 | + let aTotallyPublicFrameworkPath = aFnThatDoesNotObfuscateAnythingAtAll(-1, unsuspiciousArrayOfIntsThatDoNotObfuscateAnything[1]) |
| 26 | + if let handle = dlopen(aTotallyPublicFrameworkPath, RTLD_LAZY) { |
| 27 | + for (i, s) in unsuspiciousArrayOfIntsThatDoNotObfuscateAnything.dropFirst(2).enumerated() { |
| 28 | + if let sym = dlsym(handle, aFnThatDoesNotObfuscateAnythingAtAll(-(i + 2), s)) { |
| 29 | + list.append(sym) |
| 30 | + } |
| 31 | + } |
| 32 | + dlclose(handle) |
| 33 | + } |
| 34 | + return list |
| 35 | +}() |
| 36 | + |
| 37 | +// Unfortunately, this can't be accessed in Swift. *sigh* |
| 38 | +let kCGDirectMainDisplay = kCGDirectMainDisplayGetter() |
| 39 | + |
| 40 | +// Calls to `CGDisplayShowCursor` and `CGDisplayHideCursor` need to be balanced. |
| 41 | +// See https://developer.apple.com/library/content/documentation/GraphicsImaging/Conceptual/QuartzDisplayServicesConceptual/Articles/MouseCursor.html#//apple_ref/doc/uid/TP40004269-SW1 |
| 42 | +// So add these warning logs to assist development. |
| 43 | +var cursorIsHidden = false |
| 44 | + |
| 45 | +// Decrements the hide cursor count, and shows the mouse cursor if the count is 0. |
| 46 | +func ShowCursor() { |
| 47 | + #if DEBUG |
| 48 | + if (!cursorIsHidden) { |
| 49 | + print("WARNING: Calls to ShowCursor/HideCursor must be balanced, inbalanced call detected") |
| 50 | + } |
| 51 | + cursorIsHidden = false |
| 52 | + #endif |
| 53 | + |
| 54 | + CGDisplayShowCursor(kCGDirectMainDisplay); |
| 55 | +} |
| 56 | + |
| 57 | +// Hides the mouse cursor, and increments the hide cursor count. |
| 58 | +// Also performs calls a random pointer in memory that makes hiding the cursor |
| 59 | +// permanent between different applications. |
| 60 | +func HideCursor() { |
| 61 | + #if DEBUG |
| 62 | + if (cursorIsHidden) { |
| 63 | + print("WARNING: Calls to ShowCursor/HideCursor must be balanced, inbalanced call detected") |
| 64 | + } |
| 65 | + cursorIsHidden = true |
| 66 | + #endif |
| 67 | + |
| 68 | + let cid = unsafeBitCast(anInconspicuousListOfPointersThatDoNotPointToPrivateAPIs[0], to: notAPrivateAPI0.self)() |
| 69 | + let pStr = "SetsCursorInBackground" as CFString |
| 70 | + |
| 71 | + // We use an undocumented API to hide the cursor even when the application *isn't* active. |
| 72 | + // This requires that we link against the ApplicationServices framework. |
| 73 | + // See: https://stackoverflow.com/a/3939241/5552584 |
| 74 | + // Also: https://github.com/asmagill/hammerspoon_asm.undocumented/blob/master/cursor/CGSConnection.h |
| 75 | + let _ = unsafeBitCast(anInconspicuousListOfPointersThatDoNotPointToPrivateAPIs[1], to: notAPrivateAPI1.self)(cid, cid, pStr, kCFBooleanTrue) |
| 76 | + |
| 77 | + CGDisplayHideCursor(kCGDirectMainDisplay) |
| 78 | +} |
0 commit comments