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

how do i add a load command? #42

Open
DetachHead opened this issue May 22, 2022 · 3 comments
Open

how do i add a load command? #42

DetachHead opened this issue May 22, 2022 · 3 comments

Comments

@DetachHead
Copy link

i have no idea what i'm doing, so forgive me if i'm doing something (or everything) wrong.

context

even though i don't have a mac and know nothing about iOS development, i'm trying to fix a framework for a .ipa file that seems to have been compiled wrong. i get this error when trying to upload it to testflight:

ERROR ITMS-90125: "The binary is invalid. The encryption info in the LC_ENCRYPTION_INFO load command is either missing or invalid, or the binary is already encrypted. This binary does not seem to have been built with Apple's linker."

i used lipo as mentioned here to remove unused architectures but it didn't work. as far as i can tell that wasn't the only issue because i don't see the ITMS-90087 and ITMS-90209 errors

running out of options i decided to try and see if i can just add the load command to the binary manually. using both otool and this library i was able to verify that this framework does not contain the LC_ENCRYPTION_INFO command.

code

from macholib.mach_o import LC_ENCRYPTION_INFO_64, encryption_info_command_64
from macholib.MachO import MachO, load_command

mach_o_path = "Payload/foo.app/Frameworks/foo.framework/binary"

mach_o = MachO(mach_o_path)

mach_o.headers[-1].commands.append(
    (
        load_command(LC_ENCRYPTION_INFO_64, 24),
        encryption_info_command_64(
            cryptid=0, cryptoff=16384, cryptsize=27344896, pad=0
        ),
        b"",
    )
)

mach_o.write(open(mach_o_path, "wb"))

error

i don't get any errors when writing to the file but attempting to read the binary again after making that change cause the following error:

Traceback (most recent call last):
  File "c:\Users\amogus\asdf.py", line 9, in <module>
    mach_o = MachO(mach_o_path)
  File "C:\Users\amogus\.venv\lib\site-packages\macholib\MachO.py", line 122, in __init__
    self.load(fp)
  File "C:\Users\amogus\.venv\lib\site-packages\macholib\MachO.py", line 137, in load
    self.load_header(fh, 0, size)
  File "C:\Users\amogus\.venv\lib\site-packages\macholib\MachO.py", line 171, in load_header
    raise ValueError("Unknown Mach-O header: 0x%08x in %r" % (header, fh))
ValueError: Unknown Mach-O header: 0x00000000 in <_io.BufferedReader name='Payload/foo.app/Frameworks/foo.framework/binary'>
@ronaldoussoren
Copy link
Owner

Good questions, and I don't have a good answer at the moment.

The code currently cannot add or remove load commands, it just has limited support for changing existing load commands as long as those changes don't change the size of those commands. I have a use case for other changes to the load commands (in particular removing some load commands and moving around other load commands to redistribute "free" space to be able to grow some payloads), but that will require some research on my side.

@ronaldoussoren
Copy link
Owner

What I don't understand is why you're trying to use macholib for making these changes. Your question seems to indicate that there's something wrong with the build of an app bundle and IMHO that should be fixed at the source instead of trying to fix it during the upload to Apple.

@jvolkman
Copy link

It's pretty straightforward and you're close. You're missing:

  1. Make sure there's actually space: assert macho_header.low_offset - macho_header.total_size >= new_load_command.cmdsize
  2. pass the appropriate endianness to your new structs: load_command(..., _endian_= macho_header.endian) (same for encryption_info_command_64)
  3. macho_header.header.ncmds += 1
  4. macho_header.changeHeaderSizeBy(new_load_command.cmdsize)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants