2014-02-19 74 views
2

我想捕获后台服务的屏幕截图。它在ios6和ios7下工作正常,但在ios7视网膜下崩溃。IOMobileFramebufferGetLayerDefaultSurface无法在ios7上工作视网膜

这是我的代码

{ 

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运行(连接,0,& m_screenSurfaceRef)坠毁。

崩溃信息:

线#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

+0

似乎在64位+视网膜,而不仅仅是视网膜崩溃。你看到一样吗? – nevyn

+0

@nevyn谢谢,我构建的32位应用程序,它运作良好。 – joeykika

+0

这是一个不幸的,但也许是可以接受的解决方法。但是,我在下面提供的答案要好得多。你想接受它吗? – nevyn

回答

4

这是一个64位的问题与IOMobileFramebuffer.h的逆向工程。原型为

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 

} 

我们看到,第一个参数是间接引用,这意味着它必须是指针大小。在反转的头文件中,IOMobileFramebufferConnection被键入到io_connect_t中,这是对io_object_t的typedef'd,它是mach_port_t,它是__darwin_mach_port_t,它是__darwin_natural_t,它是无符号整型! Int恰好是32位的指针大小,但不是64位的,所以我们最终只是将指针的前32位发送到这个函数中,这显然会崩溃。

我的解决办法是刚刚重新的typedef为void *,像这样:

typedef void *IOMobileFramebufferConnection; 

完整的修正头可以在https://gist.github.com/nevyn/9486278找到。

相关问题