1. 程式人生 > >針對cocos2d圖片資源自定義加密的解密

針對cocos2d圖片資源自定義加密的解密

http://zhaoxiaodan.com/cocos2dx/%E9%92%88%E5%AF%B9cocos2d%E5%9B%BE%E7%89%87%E8%B5%84%E6%BA%90%E8%87%AA%E5%AE%9A%E4%B9%89%E5%8A%A0%E5%AF%86%E7%9A%84%E8%A7%A3%E5%AF%86.html

發現某遊戲其assets目錄的圖片開啟是雪花, 而且用二進位制開啟檢視檔案, 找魔數啊什麼的, 都沒發定義, 是新的檔案格式? 還是被加密了?

google到這篇文章 破解TexturePacker加密資源 - 使用IDA才想起來, 可以使用ida進行反編譯.(除錯後發現, 該遊戲並不是使用TexturePacker提供的加密方式)

在哪裡解密的?

雖然遊戲沒有原始碼, 但是cocos2dx是有原始碼的, 參考進行除錯, 還是蠻簡單的, 而且記得一句話, 不管你怎麼加密, 最後你在記憶體裡, 肯定有一份解密之後的資料.

好, 按這個思路, 那我首先看, 這個解密之後的資料到底放在哪裡?

根據以前的經驗, cocos2dx的圖片資源載入, 是在Image::initWithImageData(const unsigned char * data, ssize_t dataLen) 函式, 按照函式名稱顧名思義:用資料初始化Image, 好了, 在ida 給這個函式下個斷點, 先看看這個傳進來的data

可以看到, data這個記憶體地址是debug148:797363E8

, 而且這個地址的內容跟上面開啟看到的完全不一樣, 再再而且, 前4個位元組就是png檔案的魔數!.png

那也就是說, 圖片檔案是在被讀入記憶體之後, 在被初始化之前就解密了;

那圖片在哪裡被讀入?

cocos2dx的圖片資源載入, 一般都是從TextureCache::addImage(const std::string &path) 這個函式開始的, 參考原始碼

Texture2D * TextureCache::addImage(const std::string &path)
{
    //cache中是否已經有這個圖片
    auto it = _textures
.find(fullpath); if( it != _textures.end() ) texture = it->second; //沒有 if (! texture) { do { image = new (std::nothrow) Image(); CC_BREAK_IF(nullptr == image); //初始化image bool bRet = image->initWithImageFile(fullpath); CC_BREAK_IF(!bRet); texture = new (std::nothrow) Texture2D(); //再用image初始化texture if( texture && texture->initWithImage(image) ) { //hold 住 _textures.insert( std::make_pair(fullpath, texture) ); } else { CCLOG("cocos2d: Couldn't create texture for file:%s in TextureCache", path.c_str()); } } while (0); } CC_SAFE_RELEASE(image); return texture; }

然後追到

bool Image::initWithImageFile(const std::string& path)
{
    ...

    //從檔案讀入資料
    Data data = FileUtils::getInstance()->getDataFromFile(_filePath);

    ...
}

其實也就是CCFileUtils.cpp中的Data FileUtils::getDataFromFile(const std::string& filename)

這個CCFileUtils.cpp是平臺相關的, 每個平臺有每個平臺的具體實現. android的版本是CCFileUtils-android.cpp檔案

Data FileUtilsAndroid::getData(const std::string& filename, bool forString)
{
    ...
    //上面一大堆, 主要就是先判斷這個filename是絕對目錄還是assets目錄,    //如果是assets目錄則用AssetManager 來開啟並讀取,再做些分配記憶體什麼的事情
    //
   int bytesread = AAsset_read(asset, (void*)data, fileSize);
   size = bytesread;

   AAsset_close(asset);

    ...
}

在ida中找到相應的程式碼檢視

發現在AAsset_read 之後多了一個FileUtils::xxxxxxxxx函式的呼叫, 並且,v10這個指標指向的就是檔案讀入後的記憶體, 傳給了這個函式.

進到函式看一眼:

哦? 記憶體每4個位元組位與一個數再存回去? 得了, 基本是解密函式無疑. 驗證下

在115行也就是AAsset_read之後下個斷

看到檔案被讀入記憶體, 並且記憶體中的資料跟檔案是一致的

再在FileUtils::xxxxxxxxx之後下個斷

看到, v10 這個記憶體變化了, 出現了png的魔數.png

那麼FileUtils::xxxxxxxxx函式就是解密函式無疑

知道解密演算法了, 怎麼把圖還原出來?

很簡單, 照著這個函式寫一個c函式, 讀檔案進記憶體, 調這個函式解密, 就可以了

#include <stdio.h>
#include <stdlib.h>
void xxxxx(unsigned char* fileData, int fileSize)
{
    int v5,v6,v7,v8,v9,i;
    v5=0x00000000;
    v6=0;
    while(1)
    {
        v7=v6+v5;
        if( v6 >= fileSize / 4)
            break;
        v8= 4 * v6;
        v9 = *(int *)&fileData[4 * v6++];
        *(int *)&fileData[v8] = v7 ^ v9;
    }
    for ( i = 0; ; *(&fileData[fileSize] + i) = *(&fileData[fileSize] + i) ^ 0xCC )
    {
        --i;
        if ( ~i >= fileSize % 4 )
            break;
    }
}

int main(int argc,char** args)
{
    if(argc <= 2){
        printf("paramters wrong\n");
        return 1;
    }
    char* filePath = args[1];
    char* savePath = args[2];
    printf("%s => %s\n",filePath,savePath);

    FILE *fp = fopen(filePath, "r");
    if(!fp)
    {
        printf("read file %s fail !!\n",filePath);
        return 1;
    }
    fseek(fp,0,SEEK_END);
    size_t size = ftell(fp);
    fseek(fp,0,SEEK_SET);
    unsigned char* buffer = (unsigned char*)malloc(sizeof(unsigned char) * size);
    size_t readsize = fread(buffer, sizeof(unsigned char), size, fp);
    fclose(fp);
    xxxxx(buffer,readsize);

    FILE *pFile = fopen(savePath, "w");
    if(!pFile)
    {
        printf("write file %s fail !!\n",savePath);
        return 1;
    }
    fwrite (buffer , sizeof(char), readsize, pFile);
    fclose (pFile);

    return 0;
}

相關推薦

針對cocos2d圖片資源定義加密解密

http://zhaoxiaodan.com/cocos2dx/%E9%92%88%E5%AF%B9cocos2d%E5%9B%BE%E7%89%87%E8%B5%84%E6%BA%90%E8%87%AA%E5%AE%9A%E4%B9%89%E5%8A%A0%E5%AF%8

python 定義加密解密

import tkinter import webbrowser import re #本程式是一箇中文字元和中文檢測工具 #中文字元自己新增,我只添加了一點 #輸入字串,點選檢查文字即可判斷有沒有中文字元 # qianxiao996精心製作 #部落格地址:h

java 加密演算法 base64 以及 定義解密

import sun.misc.BASE64Decoder; public class Base64Utils {    public static String getBASE64(byte[] b) {   String s = null;   if (b !=

Android 如何讀取本地圖片或者資源圖片定義大小

摘要:將圖片資源設定到控制元件的src屬性並且要求全屏,且不丟失內容時,我們需要對原始的圖片進行處理,改變大小來適應螢幕,尤其是對包含虛擬鍵盤的Android裝置,需要手動增加圖片的高度來實現虛擬鍵盤消

java 圖片定義大小

ipa apach logger private idt except clas 取圖 ont java 小功能,進行圖片的自定義大小 package com.project.video.controller; import java.awt.Color; import

Enjoy! 多達400多萬的動態搞笑,愛情,友情。。。。表情下載 表情表情定義表情表情圖片下載 定義QQ表情使用方法完全圖解

分享一下我老師大神的人工智慧教程!零基礎,通俗易懂!http://blog.csdn.net/jiangjunshow 也歡迎大家轉載本篇文章。分享知識,造福人民,實現我們中華民族偉大復興!        

Android應用--簡 美音樂播放器獲取專輯圖片定義列表介面卡)

分享一下我老師大神的人工智慧教程!零基礎,通俗易懂!http://blog.csdn.net/jiangjunshow 也歡迎大家轉載本篇文章。分享知識,造福人民,實現我們中華民族偉大復興!        

圖片銜接定義類序列化

#include <fstream> // include headers that implement a archivein simple text format #include<boost/archive/text_oarchive.hpp> #inclu

7.Vue-Quill-Editor圖片插入定義

Vue-Quill-Editor圖片插入自定義 前言: 因為在專案中前端採用了Vue來實現,正好用到了富文字編輯器這一塊,於是,經過技術上的選擇,決定使用Vue-Quill-Editor。 使用的過程相對簡單,但是圖片插入時,保留的是base64二進位制形式,會導致資料庫欄位太長,儲存不易。 所以再三

加密解密傳輸&kaptcha驗證碼使用次數限制思路

序:       剛來第一天環境剛搞好,svn剛裝完,賬號都還沒有,員工手冊還沒有學習完,就被要求開始擼程式碼。還好同事之間溝通狠順暢,直接可以找到人問東西。      今天主要比較緊急的待修復

iOS-儲存圖片到(定義)相簿步驟

p.p1 { margin: 0.0px 0.0px 0.0px 0.0px; font: 14.0px "Yuanti SC"; color: #000000; background-color: #ffffff } 儲存到相簿步驟: 1.儲存圖片到【相機膠捲】 2.擁有一個【自定義相簿】 3.將剛

Django框架(十六:上傳圖片定義目錄下)

如何將圖片上傳到自定義目錄下 upload_to: 在根目錄下(MEDIA_ROOT)要生成的目錄 MEDIA_ROOT: 只要上傳圖片,肯定要設定,用於指定圖片上傳的根目錄。可以設定在static下(static目錄的搜尋路徑,已經通過STATICFILES_

scrapy爬取圖片定義圖片名字

  前言      Scrapy使用ImagesPipeline類中函式get_media_requests下載到圖片後,預設的圖片命名為圖片下載連結的雜湊值,例如:它的下載連結是,雜湊值為7710759a8e3444c8d28ba81a4421ed,那麼最終的圖片下載到指定路徑後名稱為771075

iOS中設定百度地圖定義標註圖片定義泡泡

#pragma mark - BMKMapViewDelegate // 根據anntation生成對應的View - (BMKAnnotationView *)mapView:(BMKMapView *)mapView viewForAnnotation:(id &l

使用點陣圖字型工具BMFont從圖片生成定義字型

本篇講解如何利用美工提供的字元圖形來生成自定義字型。 美術提供的字型經常是下面這樣的: 或者這樣的: 這時候我們就要藉助BMFont了,首先針對真彩色的圖形,我們要做一些設定,點選"Options"->“Export options”: 在彈出的視窗中,注意

Android仿微信朋友圈九宮格圖片展示定義控制元件,支援縮放動畫~

一直對微信朋友圈九宮格圖片顯示控制元件比較好奇,找到一篇介紹相關騷操作的部落格 部落格雖好但是不夠完美,缺少點選圖片預覽頁面和縮放動畫,作為一個不斷追求完美主義的人,我想把這個控制元件結合到專案中而不是單純作為一個控制元件。 下面是我的實現效果圖: (

Vue2.0圖片上傳及圖片壓縮定義H5圖片上傳元件

最近公司要求圖片上傳需要壓縮,以前直接使用元件不能滿足使用了,於是決定自定義個圖片上傳元件。可以實現動態傳入url,設定壓縮率,接收回傳引數。 壓縮也質量還不錯。先上效果圖效果如下壓縮質量還不錯,4.37M到550k 壓縮率更是達到了87% ,這省了不少流量和伺服器硬碟啊,哈

程式碼藝術-Android針對帶有複雜動畫定義view的程式碼設計

Android自定義view有時需要完成一些複雜的動畫,這時後會發現程式碼看起來還是蠻複雜的,如何實現讓程式碼結構清晰,對提供程式碼穩定性以及對程式碼修改有著非常大的幫助。下面是我提供的一種思路。 思路原理: 我們知道一個動畫其實是有固定流程的,比如一個走動的

C++ 筆記——字串定義加密處理

根據慣例,先放定義。加密,是以某種特殊的演算法改變原有的資訊資料,使得未授權的使用者即使獲得了已加密的資訊,但因不知解密的方法,仍然無法瞭解資訊的內容。 加密演算法非常多,常見的加密演算法有MD5、AES、Base64、DES等等。但是此篇部落格記錄的加密演算法和上述加密演算法無關,主要

CAS定義加密方式和定義登入驗證

先搭建一個CAS服務:搭建教程 本專案中的自定義加和登入驗證中的加密方法使用了shiro,記得加shiro-all-XXX.jar。 原始碼下載 一、自定義加密 實現PasswordEncoder介面,public String encode(String password)返回