我想从后台服务捕获屏幕截图。在ios6和ios7下工作正常,但在ios7 retina下崩溃。
这是我的代码
{
IOMobileFramebufferConnection connect;
kern_return_t result;
m_screenSurfaceRef = NULL;
io_service_t framebufferService = IOServiceGetMatchingService(kIOMasterPortDefault, IOServiceMatching("AppleH1CLCD"));
if(!framebufferService)
framebufferService = IOServiceGetMatchingService(kIOMasterPortDefault, IOServiceMatching("AppleM2CLCD"));
if(!framebufferService)
framebufferService = IOServiceGetMatchingService(kIOMasterPortDefault, IOServiceMatching("AppleCLCD"));
#pragma unused(result)
result = IOMobileFramebufferOpen(framebufferService, mach_task_self(), 0, &connect);
result = IOMobileFramebufferGetLayerDefaultSurface(connect, 0, &m_screenSurfaceRef);
}
在视网膜上运行时,IOMobileFramebufferGetLayerDefaultSurface(connect, 0, &m_screenSurfaceRef) 崩溃。
崩溃信息:
thread #1: tid = 0x1dfe9, 0x000000018ea2c270 IOMobileFramebuffer
IOMobileFramebufferGetLayerDefaultSurface + 4, queue = 'com.apple.main-thread, stop reason = EXC_BAD_ACCESS (code=1, address=0x5e06dc28) frame #0: 0x000000018ea2c270 IOMobileFramebuffer
IOMobileFramebufferGetLayerDefaultSurface + 4
最佳答案
这是 IOMobileFramebuffer.h 逆向工程的 64 位问题。原型(prototype)为
IOMobileFramebufferReturn IOMobileFramebufferGetLayerDefaultSurface(IOMobileFramebufferConnection connection, int surface, CoreSurfaceBufferRef *ptr);
...不正确,因为 IOMobileFramebufferConnection 的 typedef 不正确。如果看一下 IOMobileFramebufferGetLayerDefaultSurface 的反汇编和部分反编译:
IOMobileFramebufferReturn IOMobileFramebufferGetLayerDefaultSurface(Connection *connection, int surface, IOSurfaceRef *ptr)
{
if(connection) { // 0x18f95026c: cbz x0, 0x18f95027c
long tmp = connection->unk2; // 0x18f950270: ldr x3, [x0, #552] // <== Crash!
if(tmp) { // 0x18f950274: cbz x3, 0x18f95027c
goto tmp; // 0x18f950278: br x3
}
}
//0x18f95027c: movn w0, #8191, lsl #16
//0x18f950280: movk w0, #706
//0x18f950284: ret lr
}
我们看到第一个参数被取消引用,这意味着它必须是指针大小的。在反向 header 中,IOMobileFramebufferConnection 被 typedef'd 为 io_connect_t,io_connect_t 被 typedef'd 为 io_object_t,即 mach_port_t,即 __darwin_mach_port_t,即 __darwin_natural_t,即 unsigned int! Int 在 32 位上恰好是指针大小,但不在 64 位以下,因此我们最终只是将指针的前 32 位发送到该函数中,这显然会崩溃。
我的解决方案是将 typedef 重新定义为 void*,如下所示:
typedef void *IOMobileFramebufferConnection;
完整的更正标题可以在 https://gist.github.com/nevyn/9486278 找到。 .
关于ios7 - IOMobileFramebufferGetLayerDefaultSurface 不适用于 ios7 视网膜,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21870667/