針對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
.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)返回