从Swift调用getsectiondata [英] Calling getsectiondata from Swift
问题描述
此问答描述了如何在现代OS X/macOS版本上使用Objective-C从Mach-O部分读取数据:
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
所描述的答案有效.我正在尝试用Swift来实现同样的事情.我无法使其正常工作.
The described answer works. I'm trying to implement the same thing with Swift. I can't make it work.
我在其他链接器标志"中具有以下内容:-Wl,-sectcreate,__LOCALIZATIONS,__base,en.lproj/Localizable.strings,-segprot,__LOCALIZATIONS,r,r
.
I have the following in "Other linker flags": -Wl,-sectcreate,__LOCALIZATIONS,__base,en.lproj/Localizable.strings,-segprot,__LOCALIZATIONS,r,r
.
这个Swift代码为我提供了一个指向嵌入式数据的指针,直到我尝试在Xcode之外运行代码并且ASLR破坏了它:
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)
要解决ASLR问题,根据上述问答,并根据我自己的测试,我应该改用getsectiondata
.它在Objective-C中效果很好,但是在Swift中我没有运气.以下是我设法通过编译器的唯一一件事,但它返回nil:
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)
是否正在复制_mh_execute_header
问题,有什么办法可以避免它?我需要一个UnsafePointer<mach_header_64>
,但是使用&_mh_execute_header
作为getsectiondata
的第一个参数会导致编译错误.
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.
我正在使用Swift 3.0,并在macOS 10.12上运行我的代码.
I'm using Swift 3.0, and running my code on macOS 10.12.
推荐答案
链接到Objective-C代码之间的区别
The difference between the linked-to Objective-C code
void *ptr = getsectiondata(&_mh_execute_header, ...);
和您的Swift翻译
var header = _mh_execute_header
let localizationSection = getsectiondata(&header, ...)
是后者通过了全局变量的副本的地址
_mh_execute_header
函数的变量,显然
不被接受.如果您将Objective-C代码修改为
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 to
struct mach_header_64 header = _mh_execute_header;
void *ptr = getsectiondata(&header, ...);
然后它也失败了(实际上在我的测试中崩溃了.)
then it fails as well (and actually crashed in my test).
现在的问题是_mh_execute_header
暴露给Swift
作为常量:
Now the problem is that _mh_execute_header
is exposed to Swift
as a constant:
public let _mh_execute_header: mach_header_64
,并且不能使用Swift中的常量地址.一种可能 解决方法是定义
and one cannot take the address of a constant in Swift. One possible workaround is to define
#import <mach-o/ldsyms.h>
static const struct mach_header_64 *mhExecHeaderPtr = &_mh_execute_header;
在桥接头文件中,然后将其用作
in the bridging header file, and then use it as
let localizationSection = getsectiondata(mhExecHeaderPtr, ...)
在Swift中.
另一种选择是通过dlopen
/dlsym
import MachO
if let handle = dlopen(nil, RTLD_LAZY) {
defer { dlclose(handle) }
if let ptr = dlsym(handle, MH_EXECUTE_SYM) {
let mhExecHeaderPtr = ptr.assumingMemoryBound(to: mach_header_64.self)
var size: UInt = 0
let localizationSection = getsectiondata(
mhExecHeaderPtr,
"__LOCALIZATIONS",
"__base",
&size)
// ...
}
}
这篇关于从Swift调用getsectiondata的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!