CT bypass prevents strip from handling the binary #19

Open
opened 2024-11-27 16:26:19 -06:00 by Pe13 · 3 comments
Pe13 commented 2024-11-27 16:26:19 -06:00 (Migrated from github.com)

Tested ChOma versions

Both on iOS (actually iPadOS) 16.6 M1

  • Roothide fastPathSign based on a custom ChOma
  • Upstream ChOma's ct_bypass (built on the iPad itself with theos iPhoneOS16.5 SDK and Procursus-roothide openssl-dev package)

Steps to reproduce

  1. Create a main.cpp file:
#include <iostream>

int main() {
  std::cout << "Not killed\n";
}
  1. Build it with clang++ and sign it with ldid (I used Procursus-roothide general.xml):
$ clang++ main.cpp && ldid -S/path/to/entitlements.xml a.out
  1. Check if strip works:
$ mkdir -p tmp && cp -a a.out tmp/a.out && strip tmp/a.out 
  1. Apply ct_bypass:
$ ct_bypass -i a.out -o tmp/a_ct.out
  1. Check if strip still works:
$ strip tmp/a_ct.out

Here you should get the error:

strip: fatal error: file not in an order that can be processed (link edit information does not fill the __LINKEDIT segment): /absolute/path/to/tmp/a_ct.out

This appears to be due to the fact that after the ct bypass, the __LINKEDIT segment is no longer 16 bytes aligned.

Why I care

I am trying to build Procursus(-roothide) packages directly on a device with Serotonine, and in order to make the compiler pass the tests of the various build systems (autotools, cmake, etc.) I wrote a wrapper for the compiler which once the binary is compiled, if it is an executable, applies the ct bypass to it.
In the installation phase, however, install -s is called on the binary, and this fails.
This problem can be circumvented by creating a wrapper for strip, but this greatly delays the process, since to make it as compatible as possible, you have to unsign the binary to be installed, install it, apply the ct_bypass to the installed file and also to the original one, all only if the file in question is a mach-o.

### Tested ChOma versions Both on iOS (actually iPadOS) 16.6 M1 - Roothide fastPathSign based on a custom [ChOma](https://github.com/roothide/Bootstrap-basebin/tree/main/ChOma-main) - Upstream ChOma's ct_bypass (built on the iPad itself with theos iPhoneOS16.5 SDK and Procursus-roothide openssl-dev package) ### Steps to reproduce 1. Create a `main.cpp` file: ```cpp #include <iostream> int main() { std::cout << "Not killed\n"; } ``` 2. Build it with `clang++` and sign it with ldid (I used [Procursus-roothide `general.xml`](https://github.com/roothide/Procursus-roothide/blob/main/build_misc/entitlements/general.xml)): ```shell $ clang++ main.cpp && ldid -S/path/to/entitlements.xml a.out ``` 3. Check if `strip` works: ```shell $ mkdir -p tmp && cp -a a.out tmp/a.out && strip tmp/a.out ``` 4. Apply ct_bypass: ```shell $ ct_bypass -i a.out -o tmp/a_ct.out ``` 5. Check if `strip` still works: ```shell $ strip tmp/a_ct.out ``` Here you should get the error: ```shell strip: fatal error: file not in an order that can be processed (link edit information does not fill the __LINKEDIT segment): /absolute/path/to/tmp/a_ct.out ``` [This appears to be due to the fact that after the ct bypass, the `__LINKEDIT` segment is no longer 16 bytes aligned.](https://discord.com/channels/1130859165942829106/1192297677619208323/1310604915101532222) ### Why I care I am trying to build Procursus(-roothide) packages directly on a device with Serotonine, and in order to make the compiler pass the tests of the various build systems (autotools, cmake, etc.) I wrote a wrapper for the compiler which once the binary is compiled, if it is an executable, applies the ct bypass to it. In the installation phase, however, `install -s` is called on the binary, and this fails. This problem can be circumvented by creating a wrapper for `strip`, but this greatly delays the process, since to make it as compatible as possible, you have to unsign the binary to be installed, install it, apply the ct_bypass to the installed file and also to the original one, all only if the file in question is a mach-o.
alfiecg24 commented 2024-11-28 03:19:24 -06:00 (Migrated from github.com)

I cannot access the link you've posted as to why you believe the segment not being 16-byte aligned is the issue. Could you explain, please?

I cannot access the link you've posted as to why you believe the segment not being 16-byte aligned is the issue. Could you explain, please?
Pe13 commented 2024-11-28 07:30:05 -06:00 (Migrated from github.com)

Sorry, it was a link to a message on roothide's discord server, I thought it was visible to everyone.
Actually I don't know much about it, mostly I reported roothider's words.
At first he thought the problem was that the file size was not aligned (comparing the binaries before me after the ct bypass).
Then looking at another executable we noticed that the condition was not on the size but only on the __LINKEDIT segment.
I attach screenshot of the chat (however the server should be public)
image

Sorry, it was a link to a message on roothide's discord server, I thought it was visible to everyone. Actually I don't know much about it, mostly I reported roothider's words. At first he thought the problem was that the file size was not aligned (comparing the binaries before me after the ct bypass). Then looking at another executable we noticed that the condition was not on the size but only on the __LINKEDIT segment. I attach screenshot of the chat (however the server should be public) ![image](https://github.com/user-attachments/assets/23f7997e-ab2e-4b12-b71c-645cbc3efe0b)
roothider commented 2024-11-28 13:55:00 -06:00 (Migrated from github.com)

some tools in cctools(e.g.strip) have the following requirements for macho:
__LINKEDIT segment:
offset+size = filesize

LC_CODE_SIGNATURE:
offset+size = filesize

some macho files processed by choma may not meet requirement 2, especially in the original macho file:
LC_CODE_SIGNATURE -> data_size != superblob->length

some tools in cctools(e.g.strip) have the following requirements for macho: __LINKEDIT segment: offset+size = filesize LC_CODE_SIGNATURE: offset+size = filesize some macho files processed by choma may not meet requirement 2, especially in the original macho file: LC_CODE_SIGNATURE -> data_size != superblob->length
Sign in to join this conversation.
No milestone
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
gh-opa334/ChOma#19
No description provided.