三國kill字串密碼編譯演算法分析,kill字串密碼編譯演算法
三國kill字串密碼編譯演算法分析
【文章標題】:三國kill字串密碼編譯演算法
【文章作者】: Ericky
【作者部落格】: http://blog.csdn.net/hk9259
【】: 百度下載
【保護方式】: 字串加密
【作者聲明】: 本人水平有限,若有不足錯誤之處請各位大俠指正
0x1 前言
據說這款遊戲的老版本是可以直接修改其中相應的字串來進行狸貓換太子,從而繞過檢驗並且達到內購破解的效果,如今時隔一年,該遊戲為了防止被篡改或者其他,加強了對自身的加密,尤其把一些關鍵字符串所保護,強度是否值得起時間的考驗,我們來一探究竟。
0x2 定位
開啟libgame.so,按照以前的思路,在浩瀚的字串中找到加密的字串如下:
定位到紅色框框中的類如下:
0x3 分析
分析
繼續向下分析:
跟進後如下:
Base64為標準的解密方式。
而下面的函數為Xor編碼函數,不用管我們繼續往下跟進:
這裡是一個迴圈解密,關鍵函數為70004C。
跟進去再繼續跟來到SUB_7BE950這個函數:
然後進行解密,解密出來的字串用於so裡面的調用。
0x4 寫解密加密程式
還原加密代碼如下:
//加密字串 BYTE arry[] = "classes.dea";//加密KEYconst uint32_t Key = 0x9f;//初始化unsigned char XorOut[100] =""; char Base64Out[100]="";const size_t lens = sizeof(arry); for (size_t i = 0 ; i < lens - 1; i++) { XorOut[i] = arry[i] ^ (Key+i);}base64_encode( XorOut, Base64Out, lens-1 );printf("%s\n", Base64Out); char * base64_encode( const unsigned char * bindata, char * base64, int binlength ){ int i, j; unsigned char current; for ( i = 0, j = 0 ; i < binlength ; i += 3 ) { current = (bindata[i] >> 2) ; current &= (unsigned char)0x3F; base64[j++] = base64char[(int)current]; current = ( (unsigned char)(bindata[i] << 4 ) ) & ( (unsigned char)0x30 ) ; if ( i + 1 >= binlength ) { base64[j++] = base64char[(int)current]; base64[j++] = '='; base64[j++] = '='; break; } current |= ( (unsigned char)(bindata[i+1] >> 4) ) & ( (unsigned char) 0x0F ); base64[j++] = base64char[(int)current]; current = ( (unsigned char)(bindata[i+1] << 2) ) & ( (unsigned char)0x3C ) ; if ( i + 2 >= binlength ) { base64[j++] = base64char[(int)current]; base64[j++] = '='; break; } current |= ( (unsigned char)(bindata[i+2] >> 6) ) & ( (unsigned char) 0x03 ); base64[j++] = base64char[(int)current]; current = ( (unsigned char)bindata[i+2] ) & ( (unsigned char)0x3F ) ; base64[j++] = base64char[(int)current]; } base64[j] = '\0'; return base64;}
還原解密代碼如下:
//*******************解密//KEYconst uint32_t Key2 = 0X9f;//解密字串const char Base64In[]="7cXSzdbWxsPUhsbf3w==";const size_t lens2 = (sizeof(Base64In)- 1)*3/4 -2;//Base64解密後存放unsigned char XorIn[] =""; //Base64解密base64_decode( Base64In, XorIn);//Xor解密後存放char Base64Outd[100] = "";//Xor解密for (size_t i = 0 ; i < lens2; i++) { Base64Outd[i] = XorIn[i] ^ (Key2+i);}printf("%s\n", Base64Outd); int base64_decode( const char * base64, unsigned char * bindata ){ int i, j; unsigned char k; unsigned char temp[4]; for ( i = 0, j = 0; base64[i] != '\0' ; i += 4 ) { memset( temp, 0xFF, sizeof(temp) ); for ( k = 0 ; k < 64 ; k ++ ) { if ( base64char[k] == base64[i] ) temp[0]= k; } for ( k = 0 ; k < 64 ; k ++ ) { if ( base64char[k] == base64[i+1] ) temp[1]= k; } for ( k = 0 ; k < 64 ; k ++ ) { if ( base64char[k] == base64[i+2] ) temp[2]= k; } for ( k = 0 ; k < 64 ; k ++ ) { if ( base64char[k] == base64[i+3] ) temp[3]= k; } bindata[j++] = ((unsigned char)(((unsigned char)(temp[0] << 2))&0xFC)) | ((unsigned char)((unsigned char)(temp[1]>>4)&0x03)); if ( base64[i+2] == '=' ) break; bindata[j++] = ((unsigned char)(((unsigned char)(temp[1] << 4))&0xF0)) | ((unsigned char)((unsigned char)(temp[2]>>2)&0x0F)); if ( base64[i+3] == '=' ) break; bindata[j++] = ((unsigned char)(((unsigned char)(temp[2] << 6))&0xF0)) | ((unsigned char)(temp[3]&0x3F)); } return j;}
0x5 測試結果
7cXSzdbWxsPUhsbf3w== ——–> resources.out
88nDjcLWyMPGysCFx8XPyc7d1JzA2w== ——–> lib/armeabi/libgame.so
88nDjcLWyMPGysCH3ZvMgcPZ09XS2dCYxNc= ——–> lib/armeabi-v7a/libgame.so
/MzA0dDB1ojDzdE= ——–> classes.dex
0x6總結
需要十足的耐心來分析演算法,很鍛煉人,睡覺。
2015.7.26
By Ericky
著作權聲明:本文為博主原創文章,未經博主允許不得轉載。