Define DTrace compatible structs for Objective-C objects

烂漫一生 提交于 2019-12-13 15:50:21

问题


I'm trying to write a DTrace script that will show me the parameter passed to -[NSURLConnection sendSynchronousRequest:returningResponse:error:] and I can't find a struct that works for extracting the string out of the passed in NSString parameter. This question has an answer that works for OS X applications, but it does not work for my application which is using the iOS simulator.

Although I'm looking for a solution to this specific example, I'm much more interested in learning the best way to define / discover the underlying memory structure for any given Objective-C object. As you can see from the OS X test app I wrote, an NSString parameter does not always have the raw string data in the same place. In the case where it's __NSCFString is appears to be located (length prefixed) at 16 bytes in. In the case where it's a __NSCFConstant string it's somewhere else that's not immediately obvious looking at the raw memory dump.

If there are structs defined in system headers that will show me what I'm looking for that would be good first step but I'm thinking that LLDB ought to be able to show me useful hints as well.


回答1:


In theory, Class-dump should be able to examine a Mach-O file and report the declarations for your Objective C classes.

When I last tried to use Class-dump I didn't have any success; I can't remember exactly why but I now see that there's a possible alternative, namely Hopper. In any case, after reading the article Abusing the Objective C runtime, I used gdb to inspect the address space; unlike you, I used DTrace to stop a process on entry to a method and then examined the memory addressed by arg2. If, in your case, you can't see a reasonable string then I suggest that you look for pointers and follow them.

Note that your question used the phrase "DTrace-compatible". That raises an interesting point: dtrace(1) is a compiler and it is not obliged to pack structures in the same way as whatever was used to build your victim. On Solaris, dtrace(1) conforms to the ABI of the given platform, be it SPARC or x86. I haven't investigated its behaviour on MacOS but it might be different, so bear this in mind, particularly if dtrace gives you unexpected results.




回答2:


The compiler can make virtually everything with ObjC code as long as it conforms to public definition of objective c runtime.

I think you've chosen wrong object to start your study: NSString (along with NSNumber) has multiple versions which are chosen depending on your usage. E.g. your compile-time constant NSString is likely represented as:

struct __builtin_NSString {
    const int *isa; // point to __NSConstantStringClassReference
    const char *str; // point to some byte array under __cfstring segment
    unsigned int length; // size of that byte array
};

You can also find your constant NSString (or CFString) by checking the __cfstring segment, e.g. via otool otool -s __DATA __cfstring.

I don't know of any method that would allow you to decompile any ObjC object into C-struct form. My suggestion is to look how various fields of the objects are accessed by disassembling your program. E.g. you could add breakpoint to setters and getters of your properties.

If you feel comfortable, you may also study source code of the compiler responsible for making high level code into intermediate (in case of LLVM based compiler) representation: CGObjCMac, CGObjC, CGObjCRuntime.



来源:https://stackoverflow.com/questions/19622839/define-dtrace-compatible-structs-for-objective-c-objects

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!