├── README.md ├── com.apple.system.logging.plist └── img ├── plist_creation.png ├── private_search.png ├── private_usage.png └── unredacted.png /README.md: -------------------------------------------------------------------------------- 1 | ## Unredacting `` `os_log()` messages on iOS. 2 | 3 | **tldr:** Save `com.apple.system.logging.plist` inside of `/Library/Preferences/Logging/` and execute `killall logd`. 4 | 5 | *rootless path:* `/private/var/preferences/Logging/com.apple.system.logging.plist` 6 | 7 | #### Discovery 8 | The motivation for finding this came while working on a project that deals with resigning applications and installing them to a device. When trying to install an application that holds invalid entitlements, `installd` would produce the following log message: 9 | `entitlement has value not permitted by provisioning profile `. Seeing the real contents of this message would greatly reduce the amount of time I spent debugging entitlements. 10 | 11 | `logd` seems like the obvious first place to start looking. Pull the binary off of a jailbroken iOS device and throw it in a disassembler. The goal is to remove ``; searching for string references of `private` shows promising results, specifically `Enable-Private-Data`. 12 | 13 | ![private search results](img/private_search.png) 14 | 15 | 16 | It has only 1 cross-reference, a function located at `0x100009648`. This function is a part of the initialization of the system's default logger. The usage of the string hints at it being a preference key. 17 | 18 | ![private usage](img/private_usage.png) 19 | 20 | `Enable-Private-Data` is loaded into register `x1` from address `0x10001e775`, to be used as the second argument in a branch to function `xpc_dictionary_get_bool()`. The result is used later on in the continued creation of the default logger. We need to set this key to `TRUE` to enable logging of `` items. 21 | 22 | 23 | Looking into the documentation for `xpc_dictionary_get_bool()`, the first argument is the dictionary containing the target key: 24 | `bool xpc_dictionary_get_bool(xpc_object_t xdict, const char *key);` 25 | 26 | Directly before the branch to this function, register `x0` is populated from `x19`, which we can assume contains the `xpc_object_t` representation of the dictionary that we need to modify. How does this get created? 27 | 28 | ![plist creation](img/plist_creation.png) 29 | 30 | It's easier to read what this is doing backwards, from the bottom to the top. `x19` is populated via a branch to `_os_trace_read_plist_at()`, using the return value of the `snprintf_chk()` branch performed at `0x1000096e8`. At `0x1000096cc` we can see the format string to be used, `%s/%s.plist`. Just above that are the values to be used to populate it: the return value of ` _os_trace_prefsdir_path()` and the string `com.apple.system.logging`. `_os_trace_prefsdir_path()` is implemented in `libSystem.dylib` and returns string `/Library/Preferences/Logging/`. 31 | 32 | With this, this full plist path can be constructed: `/Library/Preferences/Logging/com.apple.system.logging.plist`. It seems all we need to do is create a plist file at this path, containing a bool key `Enable-Private-Data` with value of `TRUE`. Could it be that simple? 33 | 34 | ![unredacted](img/unredacted.png) 35 | 36 | Yep. 37 | -- 38 | Some problems can only be solved by reverse engineering, but that doesn't mean they aren't simple. 39 | -------------------------------------------------------------------------------- /com.apple.system.logging.plist: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EthanArbuckle/unredact-private-os_logs/544cc65d32f8e9700cda00bf51d0beb1db2d4bdc/com.apple.system.logging.plist -------------------------------------------------------------------------------- /img/plist_creation.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EthanArbuckle/unredact-private-os_logs/544cc65d32f8e9700cda00bf51d0beb1db2d4bdc/img/plist_creation.png -------------------------------------------------------------------------------- /img/private_search.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EthanArbuckle/unredact-private-os_logs/544cc65d32f8e9700cda00bf51d0beb1db2d4bdc/img/private_search.png -------------------------------------------------------------------------------- /img/private_usage.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EthanArbuckle/unredact-private-os_logs/544cc65d32f8e9700cda00bf51d0beb1db2d4bdc/img/private_usage.png -------------------------------------------------------------------------------- /img/unredacted.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EthanArbuckle/unredact-private-os_logs/544cc65d32f8e9700cda00bf51d0beb1db2d4bdc/img/unredacted.png --------------------------------------------------------------------------------