废话不多说, 注入方式自己提供,这里只讲hook方法
hook框架为substrate
//入口函数
void entry(hook* ptr_hook, void *handle)
{
do
{
// 符号区分是什么动态库
if (by_dlsym(handle, "_ZN7cocos2d14cocos2dVersionEv"))
{
// 这里判定为cocos的动态库
cocos_entry(ptr_hook, handle);
break;
}
if (by_dlsym(handle, "il2cpp_init") || by_dlsym(handle, "mono_init"))
{
unity_entry(ptr_hook, handle);
break;
}
LOGE("[-] [%s] not find symbol", __FUNCTION__);
test_entry(ptr_hook, handle);
} while (0);
}
// xxtea hook函数
void decrypt_xxtea(hook* ptr_hook, void *handle)
{
remove_file(CRACK_XXTEA_FILE);
do {
// hook符号 有的符号改了的需要自己找
hook_pointer pointers[] = {
MS_Pointer("xxtea_decrypt", xxtea_decrypt),
MS_Pointer("_Z13xxtea_decryptPhjS_jPj", xxtea_decrypt),
MS_Pointer("_Z25xxtea_decrypt_in_cocos2dxPhjS_jPj", xxtea_decrypt),
MS_Pointer("_Z8_byds_d_PhjS_jPj", xxtea_decrypt)
};
MS_HookSymbols(handle, pointers);
} while (0);
LOGD("[+] [%s] hook finish", __FUNCTION__);
}
// 这是函数原型
//unsigned char *xxtea_decrypt(unsigned char *data, xxtea_long data_len, unsigned char *key, xxtea_long key_len, xxtea_long *ret_length);
// 这里的key就是xxtea的key了
// 拿到key的地址和长度就可以拿出字符串或者十六进制了
HOOK_DEF(unsigned char *, xxtea_decrypt, unsigned char *data, unsigned int data_len, unsigned char *key, unsigned int key_len, unsigned int *ret_length) {
LOGD("[+] [%s] key[%s] key_len[%d]", __FUNCTION__, key, key_len);
const char *mode = "a+";
FILE *fp = NULL;
char buff[512] = { 0 };
char keybuff[128] = { 0 };
std::string package = g_ptr_hook->get_pack_name();
size_t len;
memcpy(keybuff, key, key_len);
snprintf(buff, sizeof(buff), "[+] package[%s] xxtea key[%s] key_len[%d]\n", package.c_str(), keybuff, key_len);
len = strlen(buff);
// 这里做了个输出保存了key到本地方便查看
do {
if ((fp = fopen(CRACK_XXTEA_FILE, "a+")) == NULL)
break;
if (fwrite(buff, sizeof(char), len, fp) <= 0)
break;
} while (0);
if (fp)
fclose(fp);
return old_xxtea_decrypt(data, data_len, key, key_len, ret_length);
}
以上非常简单就能拿到xxtea的key了