从 Swift 调用 getsectiondata
Calling getsectiondata from Swift
这个问题和答案描述了如何在现代 OS X/macOS 版本上使用 Objective-C 从 Mach-O 部分读取数据:
描述的答案有效。我正在尝试用 Swift 实现同样的事情。我做不到。
我在 "Other linker flags" 中有以下内容:-Wl,-sectcreate,__LOCALIZATIONS,__base,en.lproj/Localizable.strings,-segprot,__LOCALIZATIONS,r,r
。
这段 Swift 代码为我提供了一个指向嵌入数据的指针,直到我尝试 运行 Xcode 之外的代码并且 ASLR 破坏了它:
var size: UInt = 0
let _localizationSection = getsectdata(
"__LOCALIZATIONS",
"__base",
&size)
为了解决 ASLR 问题,根据上述问题和答案,并根据我自己的测试,我应该改用 getsectiondata
。它在 Objective-C 中运行良好,但我在 Swift 中运气不佳。以下是我唯一设法通过编译器的东西,但它 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
的第一个参数会导致编译错误。
我正在使用 Swift 3.0,运行在 macOS 10.12.
上安装我的代码
linked-toObjective-C代码的区别
void *ptr = getsectiondata(&_mh_execute_header, ...);
和您的 Swift 翻译
var header = _mh_execute_header
let localizationSection = getsectiondata(&header, ...)
是后者传递了全局的一个copy的地址
_mh_execute_header
函数的变量,显然
不被接受。如果将Objective-C代码修改为
struct mach_header_64 header = _mh_execute_header;
void *ptr = getsectiondata(&header, ...);
然后它也失败了(实际上在我的测试中崩溃了)。
现在的问题是 _mh_execute_header
暴露给 Swift
作为 常数:
public let _mh_execute_header: mach_header_64
并且不能获取 Swift 中常量的地址。一种可能
解决方法是定义
#import <mach-o/ldsyms.h>
static const struct mach_header_64 *mhExecHeaderPtr = &_mh_execute_header;
在桥接头文件中,然后作为
使用
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)
// ...
}
}
这个问题和答案描述了如何在现代 OS X/macOS 版本上使用 Objective-C 从 Mach-O 部分读取数据:
描述的答案有效。我正在尝试用 Swift 实现同样的事情。我做不到。
我在 "Other linker flags" 中有以下内容:-Wl,-sectcreate,__LOCALIZATIONS,__base,en.lproj/Localizable.strings,-segprot,__LOCALIZATIONS,r,r
。
这段 Swift 代码为我提供了一个指向嵌入数据的指针,直到我尝试 运行 Xcode 之外的代码并且 ASLR 破坏了它:
var size: UInt = 0
let _localizationSection = getsectdata(
"__LOCALIZATIONS",
"__base",
&size)
为了解决 ASLR 问题,根据上述问题和答案,并根据我自己的测试,我应该改用 getsectiondata
。它在 Objective-C 中运行良好,但我在 Swift 中运气不佳。以下是我唯一设法通过编译器的东西,但它 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
的第一个参数会导致编译错误。
我正在使用 Swift 3.0,运行在 macOS 10.12.
上安装我的代码linked-toObjective-C代码的区别
void *ptr = getsectiondata(&_mh_execute_header, ...);
和您的 Swift 翻译
var header = _mh_execute_header
let localizationSection = getsectiondata(&header, ...)
是后者传递了全局的一个copy的地址
_mh_execute_header
函数的变量,显然
不被接受。如果将Objective-C代码修改为
struct mach_header_64 header = _mh_execute_header;
void *ptr = getsectiondata(&header, ...);
然后它也失败了(实际上在我的测试中崩溃了)。
现在的问题是 _mh_execute_header
暴露给 Swift
作为 常数:
public let _mh_execute_header: mach_header_64
并且不能获取 Swift 中常量的地址。一种可能 解决方法是定义
#import <mach-o/ldsyms.h>
static const struct mach_header_64 *mhExecHeaderPtr = &_mh_execute_header;
在桥接头文件中,然后作为
使用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)
// ...
}
}