Skip to content

Releases: 0cyn/ktool

Release 2.0.0

10 Jan 23:29
Compare
Choose a tag to compare

This has been a long time coming, I wanted to keep something stable on pip while I
didn't really have the time to get things to that point. I have been really busy with work, and given its work in a field related to this project I
didn't work on it a lot. This resulted in 2 years of me pushing updates every now and then and not actually putting anything
on pip.

So I am doing that now. There may be regressions. Please inform me.

I am mainly getting this out because I made a HUGE improvement to the chained fixup stuff.
It was bad and implemented 1/12th of the spec and now it is good and does everything :)

  • ACTUAL chained fixup processing. Full device/arch/system coverage.
  • Including Rebase Opcode processing even though we have no use for them in the CLI, just in case you need to check your own parser.
  • Huge refactor. Re-did a LOT of stuff I wanted to get fixed.
  • armv7 / arm64_32 support
  • MachOImageHeader.replace_load_command
  • MachOImageHeader iterator
  • VM.detranslate
  • --force-misaligned-vm
  • util.detect_filetype
  • Expanded Swift Support. We're not "there" yet, but there's more now than there was.
  • Unit test improvements and fixes
  • Fix rpath re-serialization
  • Restructure the sublibraries.
  • Disable mmaped IO by default.
  • Bitfield Struct Support
  • Union Support
  • Better memory map fallback support
  • Better VM mapping structure
  • Hotfixes for Queue bugs and the legacy setup.py installation method.
  • Fix windows-curses dep

Way more that I didn't mention here, this is 2 years worth of commits I'm not going to dig through currently. Enjoy!

1.3.0 - Insert fixes + refactor

14 May 22:08
Compare
Choose a tag to compare

Class Renames:
Dyld -> MachOImageLoader
ImageHeader -> MachOImageHeader

LD64 class was removed
insert_load_cmd(load_command, index=-1, suffix=None) and remove_load_command(index) added to MachOImageHeader which supports adding and removing all types of load commands now.

ktool.dyld module renamed to ktool.loader, now contains only code relevant specifically to loading the Image class from a standard MachO
Image class and a few others moved to new image.py, in which contained code is a non-platform-specific abstraction not tied to MachO.

Fixes:

  • Rewritten load command injection should fix issues with round-tripping and producing bad patches. A ton of unit testing for this area was added to try and maintain this.
  • Fix for some issues on certain weird linux environments

Improvements:

  • ktool no longer tries to guess the property getter/setter; it decodes it from the actual standard attr_string or generates it from the property name if none is specified. This avoids potential false positives and also clarifies when non-standard ones are used. We also decode whether a property is @ dynamic but do not encode that in the header yet.
  • json output for properties now embeds attr_string, getter, and setter.
  • More unit tests

1.2.1 - Bugfix update, mostly

01 May 20:59
Compare
Choose a tag to compare

New

  • ImageHeader can now be created from arbitrarily values (ImageHeader.from_values())
  • New Constructable LoadCommand + Segment currently used in tandem with old Segment wrapper.
  • Unit tests!
  • --fdec flag for dump, which forward declares private class imports

Fixes

  • BytesIO fixes
  • Fix lc insertion
  • Fix with mmaped IO loader
  • Program no longer crashes on unimplemented load commands
  • Better VM segment input verification
  • Properly null pad strings in structs
  • Minor fixes in help messages
  • Fix a crash with the codesign parser
  • Fix (one) missing Chained Fixup structure.
  • Fix relative method list parsing when relative addresses are negative
  • Much better error handling in objc parsing
  • Better info on bad load commands

1.2.0

30 Mar 17:53
Compare
Choose a tag to compare
  • Added entitlement parsing
  • Added Codesign information to GUI.
  • Added json dumping for all mach-o/obj-c metadata
  • Fixed an issue with Slice.find() on 32 bit files
  • Further sped up struct loading substantially.
  • Fixed issues with the patcher.

Tool

  • Added ktool cs for interacting with codesigning info
  • Added ktool json for dumping metadata as json
  • Implemented ktool -V

Library

Documentation has been mostly updated to reflect new additions

Codesign Info

  • Added CodesignInfo class, accessible via image.codesign_info
    • Entitlements accessible via codesign_info.entitlements

Serialization

The majority of objects containing relevant/important metadata about the image now contain a .serialize() function, which returns json-formattable dictionaries containing relevant metadata.

Struct Parser

  • Redid the method in which .raw bytes are generated, eliminating the bottleneck created by that feature
  • Added support for field "sizes" being another Struct type

File Backing

  • Added a BackingFile class to further abstract out the direct file reads
  • Added a SlicedBackingFile class to even further abstract out slices within a file. This fixed a confusing issue with the Slice.find() search utility in 32 bit files. This also abstracts out the patching functionality in order to keep that code more sane.

Patcher

  • Refactored the majority of the LD64 class and its patching methods to now rebuild the entire header and write it via a single slice.patch()

Parsing of more codesign related information, along with adding more relevant data to json dumps to come.

1.1.4

15 Mar 02:52
Compare
Choose a tag to compare

Nothing too crazy, a lot of cleanup/refactoring, a few additions

GUI

  • Structs will now be rendered with an indentation for readability
  • Scrolling now supports PGUP + PGDOWN

Image

.vm_realign() - Computes image alignment (after the imageheader has been loaded) and sets up (or re-sets-up) the proper VM translator for the image.

Slice

CPU subtype now masks out the ABI bits.

VM Address Translation

Added a new VM translator, based on how low-level memory paging works. It is up to 2x faster than the old manual translator.

It falls back to the legacy method whenever images cannot be mapped to 16k/4k pages.

  • Refactor: -> get_file_address() -> translate()
  • New Attribute: .detag_kern_64 - Set this to automatically detag 64 bit kernel pointers being translated
  • New Attribute: .detag_64 - Set this to detag 64 bit pointers (remove chained fixup data)

ObjC

A lot more fallback/safe failure stuff. You can now load a binary extracted using the default dyld_extractor.bundle (although objc data will still not be processable, as the offsets are entirely junk and likely irreperable without access to the entire cache).

Structs

.render_indented() - Return a string similar to str(struct_instance) but with linebreaks and indentation.

Internal:

Struct sizes now actually contain two values; the high 2 bytes represent the type of the field, and the low 2 bytes represent the size of the data in that field.

loading a field as bytes uses the size type_bytes | <size>. loading a field as a string is done with char_t[size]. Unsigned ints now internally use the 0x10000 mask instead of being represented by -<size>

kcache parsing:

  • Added version string parsing
    image

1.1.3

06 Mar 04:18
Compare
Choose a tag to compare

watchOS kcache extraction + minor bug fixes

TUI

  • Add support for --no-mmap flag (needed on windows) in open command
  • Only detag kext addresses on 64 bit kcaches

ktool.macho

MachOFile -

  • Fix an issue where 32 bit little endian files wouldn't be recognized.

ktool.kcache -

  • Add support for armv7k kernelcaches

1.1.1

05 Mar 11:16
Compare
Choose a tag to compare

This release builds on the baseline kernelcache processing shipped with 1.1.0

  • Added a modified version of the python stdlib plistlib that actually works in ktool.kplistlib
  • Added the kcache stuff to the help strings.

GUI

  • Temporarily dropped the non-implemented title menus
  • Added a new one named "Help", and moved the old default info text to that

GUI Kernel Cache Loader

  • Added a full Loader specifically for KernelCaches
  • Info specific to Kernel Caches
  • Creates a View listing kexts and allow browsing their attributes and prelink info

ktool.kcache

KernelCache

Added Attributes:

  • .prelink_info -> prelink info dict for the Mach Kernel psuedoextension
  • .version -> Release Version (semantic) of the kernel

Kext

Added Attributes:
Note: Do not rely on any of these not being empty

  • .prelink_info -> Dict[str, Any] with info for this kext pulled straight from the plist in __PRELINK_INFO:__info.
  • .development_region
  • .executable_name
  • .id -> will always be the same as .name
  • .bundle_name -> Plaintext readable proper name of the bundle (like, "Libkern Extension")
  • .package_type -> Always KEXT
  • .info_string -> Informative (maybe) string describing the kext
  • .version_str -> (Probably) the same as .version

1.1.0

05 Mar 03:06
Compare
Choose a tag to compare

This release mainly adds merged-type kernelcache parsing.

kmacho module

  • Added support for LC_THREAD, LC_UNIXTHREAD, and LC_MAIN
  • Added mapping for LC_LOAD_UPWARD_DYLIB

ktool module

New! ktool.kcache

KernelCache class:
.mach_kernel: Image -> Image representing the Mach Kernel itself
.kexts: List[Kext] -> List of Kext objects embedded in this kernel

Kext class:
.name -> kext name
.version: str -> kext version
.mach_header -> Mach-O Header of the Kext
.image -> Image representing this Kext

_VirtualMemoryMap
  • Added support (and detagging) for 64 bit kernel address space.
Image
  • added .entry_point attribute, which points to the address (in VM Space) of the program's entry point, if an LC_THREAD, LC_UNIXTHREAD, or LC_MAIN was in the header
  • added .thread_state attribute, which holds the entry thread state if an LC_THREAD/LC_UNIXTHREAD was defined
GUI
  • Fix: Window wont crash when a view is empty

Release 1.0.0

01 Mar 06:17
Compare
Choose a tag to compare

🎉 🎉 🎉 🎉

This release includes the changelog from 1.0.0rc0

Changes

  • Terminal Output is now highlighted
  • Table rendering in terminal output now has ansi support
  • Added --class flag to dump
  • Chained Fixup Support! iOS 15 binaries, etc can now have their imports processed. It's rudimentary, but damnit, it works :)
  • Fixed ENCRYPTION_INFO_COMMAND handling
  • Function Starts table processing
  • Remove unneeded packaging dependency in favor of just hackily using setuptools's vendored version. This is a hack, but reportedly, procursus (an iOS bootstrap) cant handle building one of packaging's build dependencies, so this makes that work.
  • heavily improved non-mmap implementation

Swift

Extremely Rudimentary swift processing. It's just the groundwork, and shouldn't really be counted as a feature yet, but binaries with swift wont break it anymore, and it can read some basic info about swift types (and list swift types)

Structs

  • Rewrite it again to handle signed int field processing automatically
  • Rewrite it again again so my IDE properly recognizes the fields exist, without slowing down processing too much

Internal Stuff

  • Migrated the entire project to poetry and refactored some of the project layout.

Release 1.0.0 RC 0

24 Feb 02:15
Compare
Choose a tag to compare

🎉 🎉 🎉 🎉

Changes

  • Chained Fixup Support! iOS 15 binaries, etc can now have their imports processed. It's rudimentary, but damnit, it works :)
  • Fixed ENCRYPTION_INFO_COMMAND handling
  • Function Starts table processing
  • Remove unneeded packaging dependency in favor of just hackily using setuptools's vendored version. This is a hack, but reportedly, procursus (an iOS bootstrap) cant handle building one of packaging's build dependencies, so this makes that work.
  • heavily improved non-mmap implementation

Swift

Extremely Rudimentary swift processing. It's just the groundwork, and shouldn't really be counted as a feature yet, but binaries with swift wont break it anymore, and it can read some basic info about swift types (and list swift types)

Structs

  • Rewrite it again to handle signed int field processing automatically
  • Rewrite it again again so my IDE properly recognizes the fields exist, without slowing down processing too much