Skip to main content

Manually Decrypt Executable

You will need to install a debugger on to the device. I would suggest installing lldb which should be available in the package manager.

With lldb installed on the jailbroken device, change into the application bundle directory. Query the app Info.plist for the name of the executable.

cd /private/var/containers/Bundle/Application/{UUID}/App.app

plutil Info.plist | grep CFBundleExecutable
CFBundleExecutable = NetGopher;

Save off the entitlements of the NetGopher binary since we will need to re-sign the app after modifications.

# still in the $APP directory on the device:
jtool2 --ent NetGopher >> entitlements.xml

Read the LC_ENCRYPTION_INFO_64 data from the executable.

iPhone7-JB:~ root# otool -l Gopher| grep -A 5 LC_ENC
cmd LC_ENCRYPTION_INFO_64
cmdsize 24
cryptoff 49152
cryptsize 4096
cryptid 1
pad 0

Make a note of cryptsize & cryptoff values.

Launch the Gopher application with lldb:

# launch the app executable:
lldb NetGopher

# press "r" to run the binary:
(lldb) r

# get the offset value from the binary using "image list":
(lldb) image list NetGopher
[ 0] A3900C75-743B-3460-80F9-0B08C6388A76 0x0000000100ad8000 /private/var/containers/Bundle/Application/BA340945-2DDE-4790-85EC-63FE5195C211/NetGopher.app/NetGopher

# example command to read and extract memory:
(lldb) memory read --force --outfile extractedbin --binary --count <cryptsize> <dynamic offset>+<cryptoff>

# real example:
(lldb) memory read --force --outfile extractedbin --binary --count 4096 100ad8000+49152
4096 bytes written to 'extractedbin'

# quit:
exit
Quitting LLDB will kill one or more processes. Do you really want to proceed: [Y/n] Y

Write the extractedbin file into the $BINARY:

iPhone7-JB:~ root# dd seek=49152 bs=1 conv=notrunc if=bin of=NetGopher 
4096+0 records in
4096+0 records out
4096 bytes (4.1 kB, 4.0 KiB) copied, 0.060556 s, 67.6 kB/s

After writing the extracted data back into the binary, you will need to re-sign the app:

ldid -Sentitlements.xml NetGopher

Full Walk-Through for Gopher Application

Here is a full walk-through of this entire process:

iPhone7-JB: # cd /private/var/containers/Bundle/Application/BA340945-2DDE-4790-85EC-63FE5195C211/NetGopher.app

iPhone7-JB: # plutil Info.plist | grep Executable
CFBundleExecutable = NetGopher;

iPhone7-JB: # lldb NetGopher
(lldb) target create "NetGopher"
Current executable set to '/private/var/containers/Bundle/Application/BA340945-2DDE-4790-85EC-63FE5195C211/NetGopher.app/NetGopher' (arm64).

(lldb) r
Process 1230 launched: '/private/var/containers/Bundle/Application/BA340945-2DDE-4790-85EC-63FE5195C211/NetGopher.app/NetGopher' (arm64)

This generally means that another instance of this process was already running or is hung in the debugger.
Process 1230 stopped
* thread #1, queue = 'com.apple.main-thread', stop reason = signal SIGABRT
frame #0: 0x00000001b61c195c libsystem_kernel.dylib`__pthread_kill + 8
libsystem_kernel.dylib`__pthread_kill:
-> 0x1b61c195c <+8>: b.lo 0x1b61c1978 ; <+36>
0x1b61c1960 <+12>: stp x29, x30, [sp, #-0x10]!
0x1b61c1964 <+16>: mov x29, sp
0x1b61c1968 <+20>: bl 0x1b619f1dc ; cerror_nocancel

(lldb) image list NetGopher
[ 0] A3900C75-743B-3460-80F9-0B08C6388A76 0x0000000104344000 /private/var/containers/Bundle/Application/BA340945-2DDE-4790-85EC-63FE5195C211/NetGopher.app/NetGopher

(lldb) memory read --force --outfile gopherBin --binary --count 4096 0x0000000104344000+49152
4096 bytes written to 'gopherBin'

(lldb) exit
Quitting LLDB will kill one or more processes. Do you really want to proceed: [Y/n] Y

iPhone7-JB: # dd seek=49152 bs=1 conv=notrunc if=gopherBin of=NetGopher
4096+0 records in
4096+0 records out
4096 bytes (4.1 kB, 4.0 KiB) copied, 0.059492 s, 68.8 kB/s

iPhone7-JB: # ldid -Sent.xml NetGopher