Since making two Tweak: Wechattweak-Macos and QQTweak-macOS, I found a common problem: The above two applications both adopted the sandbox mechanism of macOS, and the signature was removed when the dynamic library was inserted, resulting in the failure of the sandbox. As a procrastination, I finally repaired it during the National Day holiday and recorded the process.

0x00 For example

The following application will cause sandbox failure after Tweak is installed, causing files such as chat logs to fail to load and file paths to be corrupted. Sorry in fact…

  1. WeChat
    • Failed to load historical chat records
    • ~/DocumentsAppear under directoryMMappedKVFolder. reference# 19
    • ~/DocumentsAppear under directoryJietuSDKStat.plist. reference# 21
    • ~/DocumentsAppear under directory.rdqFolder.
  2. QQ
    • Failed to load historical chat records
    • ~/DocumentsThe catalogue was beyond recognition

0 x01 sandbox

Sandbox

For those interested, check out Apple’s official documentation: About App Sandbox.

So the original sandbox path for QQ should be like this:

It can be seen that the sandbox is actually a folder with the same directory structure as the ~ directory under ~/Library/Containers/{bundleid}/Data, in order to limit the access of the application, and at the same time, directories or files with many soft links can be seen. The main ones are the Documents and Library directories.

0x02 Recovery Plan

Static analysis of the above two applications using Hopper Disassembler to search for keywords such as path, location and folder name, etc.

All of the path-related methods I found by looking at them use the same function, Final positioning methods NSSearchPathForDirectoriesInDomains (NSSearchPathDirectory directory, NSSearchPathDomainMask domainMask, BOOL expandTilde).

0 x04 pit

Found NSSearchPathForDirectoriesInDomains this is a Global Function, however, is not some of the Objective – C class object methods, Therefore, Method Swizzling will not work if Hook Method is needed.

This article will introduce another magic device: Fishhook, which is implemented by Facebook open source dynamic modification C language functions, specifically to solve all kinds of difficult Hook framework, detailed introduction and source code or go to GitHub.

Resources: Dynamic modification of C language function implementation

0 x05 Tweak

Declare a function pointer with the same signature as the original function and the new function:

/ / the original method static NSArray < > nsstrings * * (* original_NSSearchPathForDirectoriesInDomains) (NSSearchPathDirectory directory, NSSearchPathDomainMask domainMask, BOOL expandTilde); / / replace method NSArray < > nsstrings * * tweak_NSSearchPathForDirectoriesInDomains (NSSearchPathDirectory directory, NSSearchPathDomainMask domainMask, BOOL expandTilde) {} // here will return application sandbox path}Copy the code
Static void __attribute__((constructor)) tweak(void) {// Wrap the rebindin structure as an array, rebind the original symbol open, 1 to the array size rebind_symbols (struct rebinding [1]) {{" NSSearchPathForDirectoriesInDomains ", tweak_NSSearchPathForDirectoriesInDomains, (void *)&original_NSSearchPathForDirectoriesInDomains } }, 1); }Copy the code

⚠️ Note: the application signature is not affected by debugging with the DYLD_INSERT_LIBRARIES command, so the sandbox is fine. You can debug after removing the signature by using the command codesign –remove-signature.

0x06 Final Effect

Of course sandbox path access is working. Updating your App through the App Store, Tweak installation/uninstallation, etc will not affect sandbox path access.