Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Unicode path handling #14

Closed
FlavSec opened this issue Aug 22, 2017 · 7 comments
Closed

Unicode path handling #14

FlavSec opened this issue Aug 22, 2017 · 7 comments
Labels

Comments

@FlavSec
Copy link
Contributor

FlavSec commented Aug 22, 2017

Yet another path-related bug. Non-ASCII characters in the name of the app bundle appear to cause gruesome issues with insert_dylib. I can try and dig into this further - as a quick workaround, I've found extracting the .ipa, renaming the offending .app folder and binary, and updating the Info.plist to have an ASCII-only name will allow the process to work.

NetSPI:Desktop netspi$ objection patchipa -s unicode.ipa -c XXXXXXXX
Using Gadget version: 10.5.1
<snip>
Working with app: Test®†µ˚¬.app
Bundle identifier is: XXXXXXX.test
Injecting the load library to /var/folders/1k/mw7w1kfd4c96jkvkw5mp3qfm0000gn/T/Payload/Test┬«ΓÇá┬╡╦Ü┬¼.app/Test®†µ˚¬ might have failed.

/var/folders/1k/mw7w1kfd4c96jkvkw5mp3qfm0000gn/T/Payload/Test┬«ΓÇá┬╡╦Ü┬¼.app/Test®†µ˚¬: No such file or directory

Codesigning 11 .dylib's with signature XXXXXXXXX
Code signing: libswiftRemoteMirror.dylib
Code signing: FridaGadget.dylib
Code signing: libswiftCore.dylib
Code signing: libswiftCoreGraphics.dylib
Code signing: libswiftCoreImage.dylib
Code signing: libswiftDarwin.dylib
Code signing: libswiftDispatch.dylib
Code signing: libswiftFoundation.dylib
Code signing: libswiftObjectiveC.dylib
Code signing: libswiftQuartzCore.dylib
Code signing: libswiftUIKit.dylib
Creating new archive with patched contents...
Codesigning patched IPA...

Copying final ipa from /var/folders/1k/mw7w1kfd4c96jkvkw5mp3qfm0000gn/T/unicode-frida-codesigned.ipa to current directory...
Cleaning up temp files...
@leonjza
Copy link
Member

leonjza commented Aug 23, 2017

Thanks. I imagine this is going to be a problem with certain locales as well. Is this IPA one you can share with me?

@FlavSec
Copy link
Contributor Author

FlavSec commented Aug 23, 2017

Sure! It's just a quick test app I threw together in xcode. Should be attached to this comment.
unicode.ipa.zip

@FlavSec
Copy link
Contributor Author

FlavSec commented Aug 23, 2017

So I jumped down the rabbit hole - it's an issue with zipfile.ZipFile() guessing the wrong encoding for the extracted filenames. We'll see how GitHub handles the below output, hopefully it's legible:

NetSPIs-MacBook-Pro:test netspi$ unzip unicode.ipa
Archive:  unicode.ipa
<snip>
NetSPIs-MacBook-Pro:test netspi$ ls
Payload
NetSPIs-MacBook-Pro:test netspi$ cd Payload/
NetSPIs-MacBook-Pro:Payload netspi$ ls
Test®†µ˚¬.app # <- Correct name of app bundle, as set in Xcode.
NetSPIs-MacBook-Pro:test netspi$
NetSPIs-MacBook-Pro:test netspi$ python3
Python 3.6.2 (v3.6.2:5fd33b5926, Jul 16 2017, 20:11:06) 
[GCC 4.2.1 (Apple Inc. build 5666) (dot 3)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> import zipfile
>>> file = zipfile.ZipFile('/Users/netspi/Desktop/test/unicode.ipa','r')
>>> file
<zipfile.ZipFile filename='/Users/netspi/Desktop/test/unicode.ipa' mode='r'>
>>> file.namelist()[1]
'Payload/Test®†µ˚¬.app/' # <- WRONG representation of filename
>>> file.namelist()[1].encode('cp437') # <- The deep corners of the internet suggested code page 437 is commonly used as a default encoding with the zip format
b'Payload/Test\xc2\xae\xe2\x80\xa0\xc2\xb5\xcb\x9a\xc2\xac.app/' #
>>> file.namelist()[1].encode('cp437').decode('utf-8')
'Payload/Test®†µ˚¬.app/' # <- Sure enough, reversing the cp437 decoding and re-decoding as UTF8 fixes the problem.

So! I found a few python issue tickets (such as https://bugs.python.org/issue28080), but it doesn't look like there's a simple way to programmatically guess the encoding of the zip file.

The errors I initially posted in this issue stem from the fact that we use

self.app_binary = os.path.join(self.app_folder, info_plist['CFBundleExecutable'])

which gets the properly-encoded name from the plist file, regardless of how the actual filename is decoded from the zip file. If the filename decodes properly from the zip file, this will work. If it doesn't, the binary referenced by the above won't be present in the unzipped archive. Additionally, re-packaging an IPA with incorrectly encoded filenames will cause a similar mismatch when a user tries to install or run a modified IPA.

I'm not sure of the best way to proceed here. Compare the filename in the plist with the extracted filename, perhaps, and use that as a way to determine valid encodings?

@leonjza
Copy link
Member

leonjza commented Aug 24, 2017

Thanks for looking into this. You rock! 🤘
I guess we can always fall back to using a delegator and unzip combo if that is going to make life easier.

I will also try a few things to see if I can find a way to handle unicode better.

@pachoo
Copy link

pachoo commented Mar 27, 2018

@leonjza I fixed this in a local branch by using system's unzip instead of the zipfile module to extract the IPA. In my case, the problem was that the IPA had UTF-8 filenames in it, but the zip flag for that wasn't set for those entries, so zipfile encoded/munged the pathname as cp437 (e.g. https://github.com/python/cpython/blob/master/Lib/zipfile.py#L1305 ).

@leonjza
Copy link
Member

leonjza commented Mar 28, 2018

Excellent @pachoo. Do you want to create a PR for those changes?

@leonjza
Copy link
Member

leonjza commented Feb 17, 2021

Closing due to age.

@leonjza leonjza closed this as completed Feb 17, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

3 participants