5 ms·
Objective-C is a real object oriented programming language. Everything is messages. Reverse engineering ObjC as a security engineer over the years has been a tr
by bitexploder 6y ago
Objective-C is a real object oriented programming language. Everything is messages. Reverse engineering ObjC as a security engineer over the years has been a treat. The runtime is a breeze to work with and the language itself made substantial usability improvements over C. It’s phased out over Swift now, but I really have no complaints over my time with the language, a rare thing in tech. I didn’t know you, Mr. Cox, but I enjoyed your work.
- userbinator 6y agoCoincidentally, I've been doing RE for many years, starting in the days of DOS and then moving into Windows, but it was only very recently --- less than a week ago --- that I had my first look at an app written in ObjC, and the first thing I noticed was the amount of information in the binary that seemed to almost give away most of its source: method, field, and class names everywhere. When I saw a method named something like checkLicenseSignature, I almost thought it was misdirection. The second thing that I found astonishing was that these strings were actually being used by the runtime to determine what to call, i.e. something that in basically every other native language I've seen would be a direct or indirect call to an address or vtable offset. All this in an application that has no exported functions. I can definitely see how it would make RE extremely straightforward! Efficiency, on the other hand...
- saagarjha 6y agoObjective-C, at least these days, is plenty fast, with a the cost of a message send being comparable to a virtual function call. The fast path of objc_msgSend is just over a dozen instructions.
- nielsbot 6y agoPlus for critical sections you can obtain method pointers which are just C functions.
- why_only_15 6y agoas i recall, `libobjc` is ~25% of app launch time. `objc_msgSend` is quite expensive when you're making hundreds of thousands to millions of calls per second.
- pjmlp 6y agoAlthough Swift has the spotlight, Objective-C keeps being improved. "Advancements in the Objective-C runtime" https://developer.apple.com/videos/play/wwdc2020/10163/ https://developer.apple.com/videos/play/wwdc2020/10163/
- jcfields 6y agoSwift uses the Objective-C runtime.
- microtherion 6y agoSwift is tiptoeing between static and dynamic typing, preferring the former when feasible, but often needing some of the latter when dealing with the UI.
- pjmlp 6y agoSwift can uses the Objective-C runtime for interoperability with Objective-C code, just like .NET uses COM on Windows. They need to interoperate with the rest of the platform.
- AJRF 6y agoThe compiler does some very fancy stuff with objc_msgSend to make it fast, and the selectors are interned. https://www.mikeash.com/pyblog/objc_msgsends-new-prototype.html https://www.mikeash.com/pyblog/objc_msgsends-new-prototype.h...
- donarb 6y agoObjective-C had an IMP pointer, essentially a function pointer. If you needed to send a message to an object in a tight loop, you could extract the pointer before the loop and use it inside.
- bitexploder 6y agoThe M1 chip has specialized paths on it just to make the message sending even faster. That’s part of the M1 magic.
- saagarjha 6y agoTo be fair I think the extent of this specialization is a branch hint
- bitexploder 6y agoIt’s still a kind of neat trick. One of those paths where even a little optimization goes a long way due to it being so hot.
- DaiPlusPlus 6y ago> these strings were actually being used by the runtime to determine what to call Fortunately it doesn't do a full string comparison - it just compares the value of the string pointers, I understand.
- saagarjha 6y agoYes: selectors are interned.
- sorbits 6y ago> All this in an application that has no exported functions This is not strictly true: On macOS/iOS the OS/frameworks/plug-ins may call your methods, likewise with support for services, input managers, distributed objects, etc. The responder chain is a good example of this dynamism: The input manager (responsible for interpreting key strokes) translate the user’s input into a message, e.g. “copy” or “insert A” and then finds the first object in the chain of objects that responds to this message. This chain of objects may consist of standard framework objects (like a text view) or it may be your custom objects (like a view controller subclass). In most other environments, you would have to create special interfaces for stuff you want to make public, this means only that stuff suffers the performance overhead, but you generally pay the cost in code complexity, see e.g. Window’s Component Object Model.