This question and answer describe how to read data from a Mach-O section with Objective-C on modern OS X/macOS versions: Crash reading bytes from getsectbyname
The described answer works. I'm trying to implement the same thing with Swift. I can't make it work.
I have the following in "Other linker flags": -Wl,-sectcreate,__LOCALIZATIONS,__base,en.lproj/Localizable.strings,-segprot,__LOCALIZATIONS,r,r
.
This Swift code gets me the a pointer to the embedded data, until I try to run the code outside Xcode and ASLR breaks it:
var size: UInt = 0
let _localizationSection = getsectdata(
"__LOCALIZATIONS",
"__base",
&size)
To get around the ASLR problem, according to the above question and answer, and based on my own testing, I should be using getsectiondata
instead. It works great in Objective-C, but I'm having no luck in Swift. The following is the only thing I've managed to get past the compiler, but it returns nil:
var size: UInt = 0
var header = _mh_execute_header
let localizationSection = getsectiondata(
&header,
"__LOCALIZATIONS",
"__base",
&size)
Is taking a copy of _mh_execute_header
the problem and is there any way to avoid it? I need an UnsafePointer<mach_header_64>
, but using &_mh_execute_header
as the first parameter to getsectiondata
causes a compilation error.
I'm using Swift 3.0, and running my code on macOS 10.12.
The difference between the linked-to Objective-C code
and your Swift translation
is that the latter passes the address of a copy of the global
_mh_execute_header
variable to the function, and apparently that is not accepted. If you modify the Objective-C code tothen it fails as well (and actually crashed in my test).
Now the problem is that
_mh_execute_header
is exposed to Swift as a constant:and one cannot take the address of a constant in Swift. One possible workaround is to define
in the bridging header file, and then use it as
in Swift.
Another option is to lookup the symbol via
dlopen
/dlsym