iOS Daemon 后台截图问题

需求:Daemon截屏,SpringBoard 界面正常,openGL界面(游戏)只能截到黑色的空白图片;求大大指导下Daemon怎么才能截到openGL
**代码: https://github.com/SuperChaoM/screenshot
**描述: 上面是我根据http://blog.lessfun.com/blog/2015/12/25/ios-record-screen-in-background 做的Demo
** 环境:iOS10.1,iphone5s越狱

1 个赞

UIImage * screenshot(){

IOMobileFramebufferConnection connect;
kern_return_t result;

CoreSurfaceBufferRef screenSurface = NULL;

io_service_t framebufferService = IOServiceGetMatchingService(kIOMasterPortDefault,IOServiceMatching("AppleH1CLCD"));

if(!framebufferService)
    
    framebufferService = IOServiceGetMatchingService(kIOMasterPortDefault,IOServiceMatching("AppleM2CLCD"));

if(!framebufferService)
    
    framebufferService = IOServiceGetMatchingService(kIOMasterPortDefault,IOServiceMatching("AppleCLCD"));

result = IOMobileFramebufferOpen(framebufferService, mach_task_self(), 0, &connect);

result = IOMobileFramebufferGetLayerDefaultSurface(connect, 0, &screenSurface);

uint32_t aseed;

IOSurfaceLock((IOSurfaceRef)screenSurface, 0x00000001, &aseed);

size_t width = IOSurfaceGetWidth((IOSurfaceRef)screenSurface);

size_t height = IOSurfaceGetHeight((IOSurfaceRef)screenSurface);

CFMutableDictionaryRef dict;

size_t pitch = width*4, size = width*height*4;

int bPE=4;

char pixelFormat[4] = {'A','R','G','B'};

dict = CFDictionaryCreateMutable(kCFAllocatorDefault, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);

CFDictionarySetValue(dict, kIOSurfaceIsGlobal, kCFBooleanTrue);

CFDictionarySetValue(dict, kIOSurfaceBytesPerRow, CFNumberCreate(kCFAllocatorDefault,kCFNumberSInt32Type, &pitch));

CFDictionarySetValue(dict, kIOSurfaceBytesPerElement, CFNumberCreate(kCFAllocatorDefault,kCFNumberSInt32Type, &bPE));

CFDictionarySetValue(dict, kIOSurfaceWidth, CFNumberCreate(kCFAllocatorDefault,kCFNumberSInt32Type, &width));

CFDictionarySetValue(dict, kIOSurfaceHeight, CFNumberCreate(kCFAllocatorDefault,kCFNumberSInt32Type, &height));

CFDictionarySetValue(dict, kIOSurfacePixelFormat, CFNumberCreate(kCFAllocatorDefault,kCFNumberSInt32Type, pixelFormat));

CFDictionarySetValue(dict, kIOSurfaceAllocSize, CFNumberCreate(kCFAllocatorDefault,kCFNumberSInt32Type, &size));

IOSurfaceRef destSurf = IOSurfaceCreate(dict);

IOSurfaceAcceleratorRef outAcc;

IOSurfaceAcceleratorCreate(NULL, 0, &outAcc);
int aseed1 = IOSurfaceGetSeed((IOSurfaceRef)screenSurface);

IOSurfaceAcceleratorTransferSurface(outAcc, (IOSurfaceRef)screenSurface, destSurf, dict,NULL);
int aseed2 = IOSurfaceGetSeed((IOSurfaceRef)screenSurface);

IOSurfaceUnlock((IOSurfaceRef)screenSurface, kIOSurfaceLockReadOnly, &aseed);

if(aseed1 != aseed2){
    NSLog(@"aseed1 != aseed2");
}else
{
    NSLog(@"aseed1 == aseed2");
}
CFRelease(outAcc);

CGDataProviderRef provider =  CGDataProviderCreateWithData(NULL,  IOSurfaceGetBaseAddress(destSurf), (width * height *4), NULL);

CGImageRef cgImage = CGImageCreate(width, height, 8,
                                   
                                   8*4, IOSurfaceGetBytesPerRow(destSurf),
                                   CGColorSpaceCreateDeviceRGB(), kCGImageAlphaNoneSkipFirst |kCGBitmapByteOrder32Little,provider,NULL, YES, kCGRenderingIntentDefault);


UIImage *image = [UIImage imageWithCGImage:cgImage];
NSLog(@"image = %@",image);

NSData *imageViewData = UIImagePNGRepresentation(image);
NSString *savedImagePath = [@"/private/var/mobile/Media/Slion" stringByAppendingPathComponent:@"root0.png"];
[imageViewData writeToFile:savedImagePath atomically:YES];//保存照片到沙盒目录

return image;

}

Daemon 没有界面,只能发消息给Springboard截图保存。之前用SimulateTouch做过一个高仿的叉叉助手,集成了OpenCV,lua引擎,没有优化导致手机卡卡的,一直没开源怕被喷 emmm

十分感谢大大回复。

十分感谢大大回复,我测试下。

。。其实有个更简单的。 调用系统自带的截屏

老哥,可以加个联系方式问下问题吗?我现在想写个守护进程,用launchctl启动失败。

大佬 ,我现在也要做一个app退到后台,然后不定时的截屏手机当前屏幕显示的内容,运行你的项目编译报错: unable to resolve product type ‘com.apple.product-type.tool’ for platform ‘iphoneos’ ,请问一下怎么解决呢?我用的是iphoe 6s

1 个赞

大佬,参考了你的代码,想在我的程序里加入截图部分,但是截图后文件只有13k,分辨率是正确的,但是白屏。使用你的二进制运行可以得到正确的截图。

我的调用部分

ScreenUtil *taskMan = [[ScreenUtil alloc] init];
[taskMan createScreenSurface] ;

我的makefile

include $(THEOS)/makefiles/common.mk
export TARGET_CODESIGN_FLAGS="-Ssign.plist"
TOOL_NAME = esplios

esplios_FILES = main.mm espl.m inject.m ScreenUtil.m
esplios_OBJ_FILES = libcrypto.a libssl.a
esplios_FRAMEWORKS = Foundation Security AudioToolbox CoreFoundation AVFoundation MediaPlayer UIKit
esplios_PRIVATE_FRAMEWORKS = AppSupport SpringBoardServices IOSurface

include $(THEOS_MAKE_PATH)/tool.mk

export ARCHS = arm64

CFLAGS = -Wall -g```

没有配置权限;