2018-09-25 MonkeyDev hook glTexImage2D (성공)

4532 단어
  • MonkeyDev
  • IPA는 셸을 벗겨야 함
  • fishhook

  • 코드를 MDTestDylib.m에 추가하세요.
    // glTexImage2D
    #include 
    #include 
    #include 
    static void saveImageToPNG(const char *path, int _width, int _height, unsigned char * _data) {
        bool needToCopyPixels = false;
        int bitsPerComponent = 8;
        int bitsPerPixel = 32;
        {
    //        bitsPerPixel = 24;
        }
        
        
        int bytesPerRow    = (bitsPerPixel/8) * _width;
        int myDataLength = bytesPerRow * _height;
    
        unsigned char *pixels    = _data;
        
        if (bitsPerPixel == 24)
        {
            pixels = (unsigned char*) malloc(sizeof(unsigned char) *myDataLength);
            
            for (int i = 0; i < _height; ++i)
            {
                for (int j = 0; j < _width; ++j)
                {
                    pixels[(i * _width + j) * 3] = _data[(i * _width + j) * 4];
                    pixels[(i * _width + j) * 3 + 1] = _data[(i * _width + j) * 4 + 1];
                    pixels[(i * _width + j) * 3 + 2] = _data[(i * _width + j) * 4 + 2];
                }
            }
            
            needToCopyPixels = true;
        }
    
        // make data provider with data.
        CGBitmapInfo bitmapInfo = kCGBitmapByteOrderDefault;
        {
    //        bitmapInfo |= kCGImageAlphaPremultipliedLast;
        }
        CGDataProviderRef provider        = CGDataProviderCreateWithData(0, pixels, myDataLength, 0);
        CGColorSpaceRef colorSpaceRef     = CGColorSpaceCreateDeviceRGB();
        CGImageRef iref                   = CGImageCreate(_width, _height,
                                                           bitsPerComponent, bitsPerPixel, bytesPerRow,
                                                           colorSpaceRef, bitmapInfo, provider,
                                                           0, false,
                                                           kCGRenderingIntentDefault);
    
        UIImage* image                    = [[UIImage alloc] initWithCGImage:iref];
    
        CGImageRelease(iref);
        CGColorSpaceRelease(colorSpaceRef);
        CGDataProviderRelease(provider);
    
        NSData *data;
        
    //    if (saveToPNG)
        {
            data = UIImagePNGRepresentation(image);
        }
    //    else
    //    {
    //        data = UIImageJPEGRepresentation(image, 1.0f);
    //    }
        
        [data writeToFile:[NSString stringWithUTF8String:path] atomically:YES];
        
        if (needToCopyPixels) free(pixels);
    }
    
    static void (*orig_glTexImage2D)( GLenum target,
                                    GLint level,
                                    GLint internalFormat,
                                    GLsizei width,
                                    GLsizei height,
                                    GLint border,
                                    GLenum format,
                                    GLenum type,
                                     const GLvoid * data);
    void my_glTexImage2D(GLenum target,
                         GLint level,
                         GLint internalFormat,
                         GLsizei width,
                         GLsizei height,
                         GLint border,
                         GLenum format,
                         GLenum type,
                         const GLvoid * data)
    {
    
        static int fileIndex = 0;
        ++fileIndex;
        NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
        NSString *documentsDirectory = [paths objectAtIndex:0];
    
        char fullNamebuf[128];
        snprintf(fullNamebuf, 128, "%s/%d.png", [documentsDirectory UTF8String], fileIndex);
    
        NSLog(@" >>>>>>>>>>>>>>>>>>> %s", fullNamebuf);
        saveImageToPNG(fullNamebuf, width, height, data);
        return orig_glTexImage2D(target, level, internalFormat, width, height, border, format, type, data);
    }
    
    CHConstructor{
        NSLog(INSERT_SUCCESS_WELCOME);
    
    #define M 3
        rebind_symbols((struct rebinding[M]){
            {"close", my_close, (void *)&orig_close},
            {"open", my_open, (void *)&orig_open},
            {"glTexImage2D", my_glTexImage2D, (void*)&orig_glTexImage2D}
        }, M);
    #undef M
    

    단점이 뚜렷하다. 모든 자원을 한쪽으로 돌려야만 대응하는 자원을 얻을 수 있다.
    UP: 2018.09.25에saveImageTopNG 간략한 버전을 첨부하여 압축된 것이 없기 때문에 생성된 그림이 약간 크고 4배가 넘는다.
    #define STB_IMAGE_WRITE_IMPLEMENTATION
    #include "stb_image_write.h"
    
    static void saveImageToPNG(const char *path, int _width, int _height, unsigned char * _data) {
        stbi_write_png(path, _width, _height, 4, _data, _width * 4);
    }

    좋은 웹페이지 즐겨찾기