Objective C binaries often contain constant CFStrings in the __cfstring sections which eventually refer to the actual string data in __cstring. This for example gets generated when the code uses a function like NSLog() which takes NSString * with a constant string.
florian-macbook:test florian$ rz bins/mach0/hello-objc-osx
-- This code was intentionally left blank, try 'e asm.arch=ws'
[0x100000bbc]> iz
[Strings]
nth paddr vaddr len size section type string
――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――
(...)
3 0x00000d6d 0x100000d6d 5 6 2.__TEXT.__cstring ascii Hahha
4 0x00000d73 0x100000d73 12 13 2.__TEXT.__cstring ascii Hello World
(...)
3 0x100001058 0x100001058 5 6 ascii cstr.Hahha
4 0x100001078 0x100001078 12 13 ascii cstr.Hello World
[0x100000bbc]>
Knowing the addrs of these strings can be very useful since code will refer to them instead of the raw string data, so to get meaningful xrefs to the string, you should use the cstr. ones.
But these are only shown in iz, not in izz, which is what Cutter uses, so they are not shown there.
There are different ways to approach this:
Make Cutter optionally also show iz only. This could be useful in general since izz can sometimes also be very bloated.
Find a better way to analyze for these strings in Rizin, e.g.
Make izz in Rizin also emit these strings with the same dirty workaround
Have them in the mach0 plugin (then it's only mach-o specific though, not sure if relevant for other plugins)
or detect them in analysis and make xrefs point just to the raw string (might be confusing and error-prone)
or detect them in analysis and make a single xref from the CFString struct to the raw string (Then getting xrefs to a string will be two-stepped, probably inconvenient)
or detect them in analysis and let that set up strings and everything (currently not possible since strings there are static)
To Reproduce
Steps to reproduce the behavior:
Open bins/mach0/hello-objc-osx with default analysis
Go into the strings widget and look for "Hello World"
Only the raw "Hello World" string is shown, which has 0 xrefs to it
Expected behavior
Either both "cstr.Hello World" and "Hello World" should be shown, or "Hello World" should have meaningful xrefs
Environment information
Describe the bug
Objective C binaries often contain constant
CFString
s in the__cfstring
sections which eventually refer to the actual string data in__cstring
. This for example gets generated when the code uses a function likeNSLog()
which takesNSString *
with a constant string.Rizin has kind of a dirty workaround to detect such strings: https://github.com/rizinorg/rizin/blob/bdface85a24a52d1c4a8cf2daa00dc6099e5db51/librz/bin/bfile.c#L777 With this you can see both the raw strings and the
CStrings
prefixed withcstr.
:Knowing the addrs of these strings can be very useful since code will refer to them instead of the raw string data, so to get meaningful xrefs to the string, you should use the
cstr.
ones. But these are only shown iniz
, not inizz
, which is what Cutter uses, so they are not shown there.There are different ways to approach this:
iz
only. This could be useful in general sinceizz
can sometimes also be very bloated.izz
in Rizin also emit these strings with the same dirty workaroundTo Reproduce
Steps to reproduce the behavior:
bins/mach0/hello-objc-osx
with default analysisExpected behavior
Either both "cstr.Hello World" and "Hello World" should be shown, or "Hello World" should have meaningful xrefs
Additional context
CFString source: https://opensource.apple.com/source/CF/CF-1153.18/CFString.c.auto.html