i learned a lot about lldb debugging when i went spelunking through system service process memory. eventually i got too distracted learning about runtime introspection in Swift and obj-c and ended up building a dynamic object explorer/debugger instead of accomplishing my original goal. obj-c runtime dynamism is fascinating. it’s like, “what if we make C as dynamic as Ruby”. you can invent new classes at runtime, swap method implementations, create a new class that extends a specific existing object. you can even change what class an object is.
Swift is a lot less dynamic and a lot less introspectable at runtime :-( (there is a swift reflection api called Mirror but i struggled to do anything interesting with it)
Well thats because objc and ruby are cousins. Both are sort of the only two smalltalk based languages out there
I'm sure you can trace connections, at least in ideas, but I think Ruby is way more Perl-based than Smalltalk-based.
For the GP, in most languages the dot or arrow operator is field access. If that field is a function reference, parenthesis are used to invoke it.
From outside of the object, neither Ruby or Objective-C allow direct access to object fields or functions. The dot operator sends the object a message that be bound to anything, and even rebound at runtime for specific instances. There is no difference between access and property and calling a function - it’s all messages. Smalltalk and Objective-C (before dot operators) don’t even have different syntax for data fields and functions calls. Ruby’s no arg messages are similar.
Most of the time that distinction doesn’t matter. But writing things like wrappers and proxies becomes trivial. A object can forward any message it receives, and if it sees on it wants to intercept, it can do that easily. Most of the time modifying existing programs and frameworks can be as easy as rebinding some logic to something that wasn’t part of the original program.
This comes at the cost of some runtime performance, and possibly some complexity. The elegance outweighs those, imho.
For example, until a decade ago, macOS was extremely scriptable and consistent. IB was flexible, but approachable. There were few specialized frameworks, but a lot was possible with just Cocoa. Now it seems like dynamism at the programming level is frowned upon, scripting and automation require constant user permission, Swift seems to favor performance over dynamism, and it seems like any new concepts are now all relegated to their own framework.
That never existed in iOS and as UIKit was merged into macOS that old support was never added back in. AFAIK the Shortcuts system uses a totally different automation mechanism for scripting applications.
For a lot of applications, especially ones that started life in the classic MacOS days, AppleScript automation was pretty amazing. You could easily tie very disparate applications together.
The application level automation was orthogonal to the use of Objective-C or even Cocoa.
Source: I was at Apple from 2004-2020 and did a lot with automation over the years while there.
Seems a better choice to just parse the files than using private APIs as I couldn't see much of the documentation for them (or rather reversed APIs in various projects) + image handling is weirdly complicated in macOS generally so I want to avoid that.
Currently I've experimented by just recreating the graphics from scratch using vector rendering but it's quite cumbersome.
Other libraries, such as Qt, try to draw the native widgets into offscreen image but it's extremely hacky way prone to GUI breaking with any OS update. Java has their own Apple blessed way, but seems quite limited to me and don't want to depend on that either.
> not related to Apple CarPlay
The article is well worth reading even without ingesting the specifics in order to follow the author's reverse engineering process.
> This knowledge could be useful for security research and building developer tools that does not rely on Xcode or Apple’s proprietary tools.
Yes it could be. But if you developed it for such altruistic purposes, why tease the code?
> I’m considering open-sourcing these tools, but no promises yet!
Maybe OOP is thinking of selling their reverse engineering tools? Seems like that’s still a proprietary tool, I’m just paying someone else for it
Is that WinDOS shit?
Anyway, compiling to WASM is smart. Apple can't kill your tools if they're not on the app store. And you don't have to pay Apple tax for giving access to a free tool. Cool project!
Don't use binary formats when it isn't absolutely needed.
Also, it's a format designed to hold binary data. JSON can't do that without hacks like base64 encoding.
Binary file stores like this are very common in highly optimized software, which operating systems tend to be, especially if you go looking at the older parts. Windows has a similar format embedded in EXE/DLL files. Same concept: a kind of pseudo-filesystem used to hold app icons and other resources.
For application file formats that require storing binary blob data such as images, bitmaps, etc , many in the industry have settled on "SQLite db as a file format": (https://www.sqlite.org/appfileformat.html)
Examples include Mozilla Firefox using sqlite db for favicons, Apple iOS using sqlite to store camera photos, Kodi media player uses sqlite for binary metadata, Microsoft Visual C++ IDE stores source code browsing data in sqlite, etc.
Sqlite db would usually be a better choice rather than binary blobs encoded as Base64 and being stuffed into json.gzip files. One of the areas where the less efficient gzipped JSON might be better than Sqlite is web-server-to-web-browser data transfers because the client's Javascript engine has builtin gzip decompress and JSON manipulation functions.
I personally subscribe to the Unix philosophy. There are really two options, binary or plain text (readable binary due to a agreed standard formatting). All other formats are a variation of the two.
Additional a binary format suits makes sense when the format is to be used for mobile devices which may not have much storage or bandwidth.
Sane for 3rd party devs
JSON in particular isn't very good [0] but I'd also argue that text formats in general aren't great. Isn't it a lot better that an int32_t always takes exactly 4 bytes instead of anywhere between one and eleven bytes (-2147483648)?
Using JSON / HTTP for backend communication (i.e. microservices) is madness when you consider how much overhead there is and how little value having it be human-readable delivers.
Why not have both options? .gltf and .glb being possible for assets been more than helpful to me more than once, having the option gives you the best of both worlds :)
Working with binary files really isn't that hard. If Apple documented the .car format, writing your own parser wouldn't be difficult. It's not like it's a complicated format. Still, Apple clearly doesn't intend for people to make their own .car generators; to them, ease of reverse engineering is a bug, not a feature.
Computers need to do it a bunch for every program launch for every single user of macOS for decades. The developer just needed to write a generator and a parser for the format once.
Would it have been a bit easier to write a parser for a format that's based around a zip file with a manifest.json? I don't know, maybe. You'd end up with some pretty huge dependencies (a zip file reader, a JSON parser), but maybe it'd be slightly easier. Is it worth it?
obj-c sendmsg use makes it more similar to understanding minified JS than decompiling static c because it literally calls many methods by string name.
EDIT - someone needs to crack open x86 OPENSTEP and do some grepping for 'RATC'...