逆向分析某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)