Exactly 3 months and a day after placing an advise by a Romanian Apple reseller, I in the end received my 14-stir M1 Max. Effectively, in reality.. I first received the depraved configuration (unpleasant mannequin as a replacement of CTO), needed to advance it to them after wasting a day on migrating my data to it, they despatched my cash aid by mistake, needed to pay them again, and after many calls and emails later the righteous computer arrived.
As soon as these gadgets had been in the fingers of users, requests started coming in for Lunar to provide an risk to fetch previous the 500 nits limit for each day usage
Over the closing week I tried my most attention-grabbing to determine the fashion to invent this, but it no doubt’s both impossible to boost the nits limit from userspace, or I fair don’t accept as true with the foremost skills.
I’ll fragment some crucial parts that I realized while reverse engineering my ability by the macOS part that handles brightness. I first started by playing this HDR take a look at video (launch it in most recent Chrome or Safari for most attention-grabbing results): hdr-take a look at-pattern.webm
Which resulted in a blinding white at 1600 nits:
This generated the following logs in Console.app: After atmosphere the cloak brightness to max, I might well well gaze in the logs that SDR (Fashioned Dynamic Fluctuate) became being capped at 400 nits:
Colorful a flashlight right this moment into the Ambient Gentle Sensor allowed SDR to soar as much as 500 nits:
Since Mountainous Sur, macOS transitioned from having the frameworks on the disk as separate binaries, to having a single file containing your entire scheme libraries, called a Browsing for keywords from the above logs surfaced most optimistic the dyld cache as expected.
I weak dyld-shared-cache-extractor to fall the separate binaries on disk, then did one other search there.
This surfaced up After taking a learn about by the QuartzCore binary with Ghidra and finding some iOS headers for it on limneos.ranking, I created a pattern Swift project to are trying to utilize a pair of of the exported capabilities from it: monitorpanel – principal.swift
Essentially based completely on some launch-sourced iOS jailbreak tweaks, I seen that builders weak the Unfortunately, The use of the below code, I succeeded in producing the code from principal.swift
While taking a learn about by Ghidra, I seen that Unfortunately, your entire perhaps righteous symbols are now not exported and making an strive to link against them would consequence in the Adding the personal symbols in the CoreBrightness.tbd file doesn’t abet on this case.
I knew from earlier work on window administration that the SkyLight exports slightly a pair of symbols, and happily I had a edifying example on the fashion to utilize them inner yabai, a macOS window supervisor equivalent to i3 and bspwm.
But again, nothing righteous is exported.
The characteristic While discussing this topic with István Tóth, the developer of BetterDummy, he got right here up with a mesmerizing thought.
The streaming part already works in the most fresh Beta of BetterDummy and looks quite quickly as effectively. But adding tone mapping might well well trigger this to be too resource intensive to be weak.
I ponder linking might well well be completed against private symbols utilizing memory offsets, I be mindful doing one thing like that 8 years previously at BitDefender, while making an strive to utilize the unexported But the If anyone has any thought how this might well well be accomplished, I’d feel free must that that it is possible you’ll well perhaps ship me a marginally by the Contact page.
Featured Content Ads
add advertising here
Featured Content Ads
add advertising here# Attempting out the scheme
# Playing a HDR video
Featured Content Ads
add advertising here
1
2
3
WindowServer Drawl 1 atmosphere nits to 888.889
corebrightnessd SDR - perceptual ramp clocked: 227.095169 -> 252.268112 - 49.169426% (239.142059 Nits)
WindowServer Drawl 1 commitBrightness sdr: 211.603, headroom: 4.20075, ambient: 4.3396, filtered ambient: 13.6333, limit: 1600
# SDR cap in customary lighting
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
WindowServer Drawl 1 atmosphere nits to 1600
WindowServer Drawl 1 atmosphere cloak headroom hint to 7.56866
WindowServer Drawl 1 commitBrightness sdr: 216.548, headroom: 7.38865, ambient: 4.24854, filtered ambient: 13.3472, limit: 1600
corebrightnessd PCC: Situation PCC: Part:=1.0496 CabalFactor:=0.0033 time=2.000000 Lux:=13.6080 Nits:=229.1757 consequence=1 error=(null)
WindowServer Drawl 1 commitBrightness sdr: 301.188, headroom: 5.3123, ambient: 4.24854, filtered ambient: 13.3472, limit: 1600
WindowServer Drawl 1 atmosphere nits to 1602.03
corebrightnessd levelPercentage 0.334298, diploma = 4.967383 (nits/pwm), lux = 15.000000
WindowServer Drawl 1 commitBrightness sdr: 301.571, headroom: -1, ambient: 4.79275, filtered ambient: 15.0569, limit: -1
WindowServer Drawl 1 atmosphere cloak headroom hint to 5.27556
WindowServer Drawl 1 commitBrightness sdr: 321.478, headroom: 4.97701, ambient: 4.79275, filtered ambient: 15.0569, limit: 1600
WindowServer Drawl 1 commitBrightness sdr: 340.675, headroom: 4.69655, ambient: 4.79275, filtered ambient: 15.0569, limit: 1600
WindowServer Drawl 1 commitBrightness sdr: 377.322, headroom: 4.24041, ambient: 4.79275, filtered ambient: 15.0569, limit: 1600
corebrightnessd PCC: Situation PCC: Part:=1.0340 CabalFactor:=0.0023 time=2.000000 Lux:=15.0569 Nits:=377.3223 consequence=1 error=(null)
WindowServer Drawl 1 atmosphere nits to 1600
WindowServer Drawl 1 atmosphere cloak headroom hint to 4
WindowServer Drawl 1 commitBrightness sdr: 400, headroom: -1, ambient: 4.96577, filtered ambient: 15.6004, limit: -1
# SDR cap in declare sunlight hours
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
WindowServer Drawl 1 commitBrightness sdr: 400, headroom: -1, ambient: 322.204, filtered ambient: 1012.24, limit: -1
WindowServer Drawl 1 commitBrightness sdr: 400.484, headroom: 1, ambient: 322.204, filtered ambient: 1012.24, limit: 400.484
WindowServer Drawl 1 atmosphere nits to 400.484
WindowServer Drawl 1 commitBrightness sdr: 401.15, headroom: 1, ambient: 322.204, filtered ambient: 1012.24, limit: 401.15
WindowServer Drawl 1 atmosphere nits to 401.15
WindowServer Drawl 1 commitBrightness sdr: 401.223, headroom: 1, ambient: 322.204, filtered ambient: 1012.24, limit: 401.224
WindowServer Drawl 1 atmosphere nits to 401.223
WindowServer Drawl 1 commitBrightness sdr: 401.223, headroom: -1, ambient: 370.814, filtered ambient: 1164.95, limit: -1
WindowServer Drawl 1 commitBrightness sdr: 401.552, headroom: 1, ambient: 370.814, filtered ambient: 1164.95, limit: 401.552
corebrightnessd PCC: Situation PCC: Part:=1.7464 CabalFactor:=0.0498 time=2.000000 Lux:=1164.9467 Nits:=401.5517 consequence=1 error=(null)
WindowServer Drawl 1 atmosphere nits to 401.552
WindowServer Drawl 1 commitBrightness sdr: 402.219, headroom: 1, ambient: 370.814, filtered ambient: 1164.95, limit: 402.219
WindowServer Drawl 1 atmosphere nits to 402.219
WindowServer Drawl 1 commitBrightness sdr: 402.885, headroom: 1, ambient: 370.814, filtered ambient: 1164.95, limit: 402.885
WindowServer Drawl 1 atmosphere nits to 402.885
... heaps of same logs ...
WindowServer Drawl 1 atmosphere nits to 495.458
WindowServer Drawl 1 commitBrightness sdr: 496.125, headroom: 1, ambient: 810.176, filtered ambient: 2545.24, limit: 496.125
WindowServer Drawl 1 atmosphere nits to 496.125
WindowServer Drawl 1 commitBrightness sdr: 496.791, headroom: 1, ambient: 810.176, filtered ambient: 2545.24, limit: 496.792
WindowServer Drawl 1 atmosphere nits to 496.791
WindowServer Drawl 1 commitBrightness sdr: 497.458, headroom: 1, ambient: 810.176, filtered ambient: 2545.24, limit: 497.458
WindowServer Drawl 1 atmosphere nits to 497.458
WindowServer Drawl 1 commitBrightness sdr: 498.125, headroom: 1, ambient: 810.176, filtered ambient: 2545.24, limit: 498.125
WindowServer Drawl 1 atmosphere nits to 498.125
WindowServer Drawl 1 commitBrightness sdr: 498.791, headroom: 1, ambient: 810.176, filtered ambient: 2545.24, limit: 498.792
WindowServer Drawl 1 atmosphere nits to 498.791
WindowServer Drawl 1 commitBrightness sdr: 499.458, headroom: 1, ambient: 810.176, filtered ambient: 2545.24, limit: 499.458
WindowServer Drawl 1 atmosphere nits to 499.458
WindowServer Drawl 1 commitBrightness sdr: 500, headroom: 1, ambient: 810.176, filtered ambient: 2545.24, limit: 500
WindowServer Drawl 1 atmosphere nits to 500
WindowServer Drawl 1 commitBrightness sdr: 500, headroom: -1, ambient: 987.858, filtered ambient: 3103.45, limit: -1
# Dissecting the scheme
dyld_shared_cache
.
QuartzCore
because the single space the achieve that string might well well be realized.
# Making an strive to abuse QuartzCore
CAWindowServer
class to interface with the cloak and HID parts right this moment. The class became accessible right here so I tried to invent the identical on macOS.
CAWindowServer.serverIfRunning
always returns nil
and while CAWindowServer.server(withOptions: nil)
returns a reputedly tremendous server, all exterior displays are forcefully disconnected when that server is created.
commitBrightness
log line in Console, but nothing in reality changed.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
func setToMax(_ d: CAWindowServerDisplay) {
d.setBrightnessLimit(1600)
d.setHeadroom(1)
d.maximumBrightness = 1000.0
d.setSDRBrightness(600)
d.maximumHDRLuminance = 1600
d.maximumReferenceLuminance = 1600
d.maximumSDRLuminance = 1000
d.distinction = 1.1
d.commitBrightness(1)
// d.change() // segfault
}
let ws: CAWindowServer? = (CAWindowServer.server(withOptions: nil) as? CAWindowServer) // disconnects exterior displays
if let ws = ws,
let displays = ws.displays as? [CAWindowServerDisplay],
let d = displays.first(the achieve: { $0.deviceName == "principal" })
{
setToMax(d)
}
commitBrightness
log line
1
monitorpanel Drawl 1 commitBrightness sdr: 600, headroom: 1, ambient: -1, filtered ambient: -1, limit: 1600
# CoreBrightness
QuartzCore
in the end calls into CoreBrightness
capabilities to boost the nits limit, so I took a learn about on the exported symbols on that binary.
undefined symbols
error.
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
// Dull Exported Symbols
_OBJC_CLASS_$_BrightnessSystem
_OBJC_CLASS_$_BrightnessSystemClient
_OBJC_CLASS_$_BrightnessSystemClientInternal
_OBJC_CLASS_$_CBAdaptationClient
_OBJC_CLASS_$_CBBlueLightClient
_OBJC_CLASS_$_CBClient
_OBJC_CLASS_$_CBKeyboardPreferencesManager
_OBJC_CLASS_$_CBTrueToneClient
_OBJC_CLASS_$_DisplayServicesClient
_OBJC_CLASS_$_KeyboardBrightnessClient
// Attention-grabbing No longer Exported Symbols
-[CBBrightnessProxySKL brightnessNotificationRequestEDR]
-[CBBrightnessProxySKL brightnessRequestEDRHeadroom]
-[CBBrightnessProxySKL brightnessRequestRampDuration]
-[CBBrightnessProxySKL commitBrightness:]
-[CBBrightnessProxySKL initWithSLSBrightnessControl:]
-[CBBrightnessProxySKL setAmbient:]
-[CBBrightnessProxySKL setBrightnessLimit:]
-[CBBrightnessProxySKL setHeadroom:]
-[CBBrightnessProxySKL setNotificationQueue:]
-[CBBrightnessProxySKL setPotentialHeadroom:]
-[CBBrightnessProxySKL setSDRBrightness:]
-[CBBrightnessProxySKL setWhitePoint:rampDuration:error:]
-[CBBrightnessProxySKL unregisterNotificationBlocks]
-[CBDisplayModuleSKL configureEDRSecPerStop]
-[CBDisplayModuleSKL configurePCCDefaults]
-[CBDisplayModuleSKL getBrightnessLimit]
-[CBDisplayModuleSKL getDynamicSliderAdjustedNits:]
-[CBDisplayModuleSKL getDynamicSliderAdjustedSDRNits]
-[CBDisplayModuleSKL getLinearBrightnessForNits:]
-[CBDisplayModuleSKL getLinearBrightness]
-[CBDisplayModuleSKL getMaxNitsAdjusted]
-[CBDisplayModuleSKL getMaxNitsEDR]
-[CBDisplayModuleSKL getMaxPanelNits]
-[CBDisplayModuleSKL getNitsForLinearBrightness:]
-[CBDisplayModuleSKL getNitsForUserBrightness:]
-[CBDisplayModuleSKL getPerceptualBrightness]
-[CBDisplayModuleSKL getSDRBrightnessCurrent]
-[CBDisplayModuleSKL getSDRBrightnessTarget:]
-[CBDisplayModuleSKL getSDRNitsCapped]
-[CBDisplayModuleSKL getUserBrightnessForNits:]
-[CBDisplayModuleSKL getUserBrightnessSloperExtended]
-[CBDisplayModuleSKL getUserBrightness]
-[CBDisplayModuleSKL handleBrightnessCapOverride:]
-[CBDisplayModuleSKL initialiseEDR]
-[CBDisplayModuleSKL initialiseSDR]
-[CBDisplayModuleSKL luminanceToPerceptual:]
-[CBDisplayModuleSKL panelMaxNitsOverride:]
-[CBDisplayModuleSKL perceptualToLuminance:]
-[CBDisplayModuleSKL rampDynamicSlider:withLength:]
-[CBDisplayModuleSKL rampEDRHedroom:withLength:]
-[CBDisplayModuleSKL rampFactor:withLength:]
-[CBDisplayModuleSKL rampManagerUpdateHandling]
-[CBDisplayModuleSKL rampNitsCap:]
-[CBDisplayModuleSKL rampSDRBrightness:withLength:properties:]
-[CBDisplayModuleSKL requestEDRHeadroomImmediate:]
-[CBDisplayModuleSKL requestEDRHeadroomTransition:withLength:]
-[CBDisplayModuleSKL requestEDRHeadroomTransitionStop]
-[CBDisplayModuleSKL requestFactorImmediate:]
-[CBDisplayModuleSKL requestFactorTransition:withLength:]
-[CBDisplayModuleSKL requestFactorTransitionStop]
-[CBDisplayModuleSKL requestSDRBrightnessTransition:]
-[CBDisplayModuleSKL requestSDRBrightnessTransition:withLength:properties:]
-[CBDisplayModuleSKL requestSDRBrightnessTransitionStop]
-[CBDisplayModuleSKL supportsDynamicSlider]
-[CBDisplayModuleSKL supportsEDR]
-[CBDisplayModuleSKL supportsSDRBrightness]
-[CBDisplayModuleSKL updateAmbient]
-[CBDisplayModuleSKL updateAutoBrightnessState:]
-[CBDisplayModuleSKL updateBrightnessState]
-[CBDisplayModuleSKL updateContrastEnhancerState:]
-[CBDisplayModuleSKL updateDynamicSliderAmbient]
-[CBDisplayModuleSKL updateDynamicSliderAutoBrightness]
-[CBDisplayModuleSKL updateDynamicSliderChargerState]
-[CBDisplayModuleSKL updateDynamicSliderScaler:]
-[CBDisplayModuleSKL updateEDRAmbient]
-[CBDisplayModuleSKL updateSDRBrightness:]
-[CBDisplayModuleSKL updateSDRNits:]
-[CBEDR appliedCompensation]
-[CBEDR availableHeadroom]
-[CBEDR brightnessCap]
-[CBEDR cappedHeadroomFromUncapped:]
-[CBEDR copyStatusInfo]
-[CBEDR description]
-[CBEDR initWithRampPolicy:potentialHeadroom:andReferenceHeadroom:]
-[CBEDR maxHeadroom]
-[CBEDR panelMax]
-[CBEDR referenceHeadroom]
-[CBEDR sanityCheck]
-[CBEDR sdrBrightness]
-[CBEDR secondsPerStop]
-[CBEDR setAppliedCompensation:]
-[CBEDR setBrightnessCap:]
-[CBEDR setPanelMax:]
-[CBEDR setSdrBrightness:]
-[CBEDR setSecondsPerStop:]
-[CBEDR shouldUpdateEDRForRequestedHeadroom:targetHeadroom:rampTime:]
-[CBEDR stopsFromHeadroomRatio:]
-[CBNVRAM backlightNitsDefault]
-[CBNVRAM backlightNitsMax]
-[CBNVRAM backlightNitsMin]
-[CBNVRAM dealloc]
-[CBNVRAM init]
-[CBNVRAM readBacklightNits]
-[CBNVRAM setBacklightNitsMax:]
-[CBNVRAM writeBacklightNits:]
# SkyLight
SkyLight
framework is carefully linked to the WindowServer so I took a learn about at that too.
kSLSBrightnessRequestEDRHeadroom
seemed promising but I always received a SIGBUS
when making an strive to name it. I will’t fetch its implementation so I don’t know what parameters I must pass. I fair guessed the main one might well well be a cloak ID.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
@import Darwin;
@import Foundation;
// clang -fmodules -F/Arrangement/Library/PrivateFrameworks -framework SkyLight -o headroom headroom.m && ./headroom
extern int SLSMainConnectionID(void);
extern CFTypeRef SLSDisplayGetCurrentHeadroom(int did);
extern void kSLSBrightnessRequestEDRHeadroom(int did, CFTypeRef headroom);
const int MAIN_DISPLAY_ID = 1;
int principal(int argc, char argv)
{
int cid = SLSMainConnectionID();
NSLog(@"SLSMainConnectionID: %d", cid);
CFTypeRef headroom = SLSDisplayGetCurrentHeadroom(MAIN_DISPLAY_ID);
kSLSBrightnessRequestEDRHeadroom(MAIN_DISPLAY_ID, headroom);
return 0;
}
# Diversified tips
# Streaming to a dummy
CGVirtualDisplay
with the identical size because the built-in cloakCGDisplayStream
that video to the virtual cloak# The use of personal symbols
_decrypt
and _generate_domain
suggestions of some DGA malware.
dyld_shared_cache
mannequin of macOS is one thing new to me and I don’t accept as true with enough details to be in a hassle to invent that fair now.
NOW WITH OVER +8500 USERS. other folks can Be part of Knowasiak for free. Register on Knowasiak.com
Read More