BlackFeather'S Blog

首页 | |

某个sqlcrypto的算法概要

逆向分析某app的本地存储是发现其平台下所有APP都是利用了同一个基于sqlite的加密库,网上没有搜索到任何有用信息,猜测是自己定制的(文件名:libdatabase_sqlcrypto.so,内部名是alibaba.sqlcrypto)。


ps:如果有人觉得此文不妥,立即联系博主处理(我发现了一些事情,表示你们响应速度还蛮快的)。


于是逆向分析了下其加密算法,然后参考着sqlite的加密接口重写了此库。


关键函数很少:

#include "sqlite3.c"
#include "aes.h"

#define KEYLENGTH 16

typedef struct _codec_ctx
{
char *pszPass;
int nPassLen;

aes_ctx m_ctxde;
aes_ctx m_ctxen;

Btree*        m_bt; /* Pointer to B-tree used by DB */

}codec_ctx;



void* sqlite3Codec(void *iCtx, void *data, Pgno pgno, int mode)
{
codec_ctx *ctx = (codec_ctx *) iCtx;
unsigned char *pData = (unsigned char *) data;
int pageSize = sqlite3BtreeGetPageSize(ctx->m_bt);
int nBlock = pageSize / 16;
int i;
unsigned char szTmp[16];

switch(mode) {
case 0: /* decrypt */
case 2:
case 3:
for (i = 0; i < nBlock; i++)
{
aes_decrypt(&pData[i * 16], szTmp, &ctx->m_ctxde);
memcpy(&pData[i * 16], szTmp, 16);
}
break;

case 6: /* encrypt */
for (i = 0; i < nBlock; i++)
{
aes_encrypt(&pData[i * 16], szTmp, &ctx->m_ctxen);
memcpy(&pData[i * 16], szTmp, 16);
}
break;

case 7: /* Encrypt a page for the journal file */
for (i = 0; i < nBlock; i++)
{
aes_encrypt(&pData[i * 16], szTmp, &ctx->m_ctxde);
memcpy(&pData[i * 16], szTmp, 16);
}
break;
}

return data;
}


void sqlite3FreeCodecArg(void *pCodecArg) 
{
codec_ctx *ctx = (codec_ctx *)pCodecArg;
if(pCodecArg == NULL) 
return;

sqlite3_free(ctx->pszPass);
memset(ctx, 0, sizeof(codec_ctx));
sqlite3_free(ctx);
}


int sqlite3CodecAttach(sqlite3* db, int nDb, const void* zKey, int nKey)
{
struct Db *pDb = &db->aDb[nDb];

if(nKey && zKey && pDb->pBt)
{
codec_ctx *ctx = sqlite3Malloc(sizeof(codec_ctx));

aes_decrypt_key128((const unsigned char *)zKey, &ctx->m_ctxde);
aes_encrypt_key128((const unsigned char *)zKey, &ctx->m_ctxen);

ctx->m_bt = pDb->pBt; /* assign pointer to database btree structure */
ctx->pszPass = (char *)sqlite3Malloc(nKey + 1);
memcpy(ctx->pszPass, zKey, nKey);
ctx->pszPass[nKey] = '\0';
ctx->nPassLen = nKey;

sqlite3PagerSetCodec(sqlite3BtreePager(pDb->pBt), sqlite3Codec, NULL, sqlite3FreeCodecArg, (void *) ctx);

}

return SQLITE_OK;
}


void sqlite3pager_get_codec(Pager *pPager, void **ctx) 
{
*ctx = pPager->pCodec;
}


void sqlite3CodecGetKey(sqlite3* db, int nDb, void** zKey, int* nKey)
{
struct Db *pDb = &db->aDb[nDb];

if( pDb->pBt ) {
codec_ctx *ctx;
sqlite3pager_get_codec(pDb->pBt->pBt->pPager, (void **) &ctx);

if(ctx) 
{
*zKey = ctx->pszPass;
*nKey = ctx->nPassLen;

else 
{
*zKey = NULL;
*nKey = 0;
}
}
}

void sqlite3_activate_see(const char *info)
{
//啥也不用做
}

int sqlite3_rekey(sqlite3 *db, const void *zKey, int nKey)
{
//懒得写了。。。好烦
return SQLITE_ERROR;
}

int sqlite3_key(sqlite3 *db, const void *zKey, int nKey)
{
/* The key is only set for the main database, not the temp database  */
return sqlite3CodecAttach(db, 0, zKey, nKey);
}


没错。。就这么多,测试可用。

2015/12/24 | Tags:sqlite,sqlcrypto | C/C++代码 | 查看评论(5)

相关文章:

Powered By Z-Blog  触屏版 | WAP版 | 电脑版