看雪论坛作者ID:GitRoy
样本:很老的x度加固
分析工具:ida、jeb、010、apktool
NativeHook:基于Substrate的Nativehook
Android系统:4.4
int new_debug() {
return 0;
}
if (old_debug == NULL) {
elfHook("libdvm.so", "_Z25dvmDbgIsDebuggerConnectedv", (void *) new_debug,
(void **) &old_debug);
}
char *new_fgets(char *buf, int bufsize, FILE *stream) {
char *trace = "TracerPid:t1";
if (strstr(buf, trace) != NULL) {
strcpy(buf, "TracerPid:t0");
}
return old_fgets(buf, bufsize, stream);
}
jint new_JNI_OnLoad(JavaVM *vm, void *reserved) {
log("%s", "jni on load");
while (!debug){
}
log("%s", "in jni onload");
debug = true;
return old_JNI_OnLoad(vm, reserved);
}
修复dexdump后的文件
if (old_findDex == NULL) {
elf_hook("libdvm.so", "_Z12dexFindClassPK7DexFilePKc", (void *) &new_dexFindClass,
(void **) &old_findDex);
}
void *new_dexFindClass(const void *pDexFile, const char *descriptor) {}
char *file_name = "/data/data/com.qsq.qianshengqian/1.dex";
FILE *dex_file = fopen(file_name, "wb+");
fwrite(dexFile->pHeader, dexFile->pHeader->fileSize, 1, dex_file);
fclose(dex_file);
u4 *off = &(pDef->annotationsOff);<br>*off = 0;
void *new_dexFindClass(const void *pDexFile, const char *descriptor) {
DexFile *dexFile = (DexFile *) pDexFile;
if (dexFile->pHeader->fileSize == 5573376 && a == 0 ) {
log("%s","start dump");
a = 1;
size_t size = dexFile->pHeader->fileSize;
DexClassDef *pDef = dexFile->pClassDefs;
// log("class def size is %d", dexFile->pHeader->classDefsSize);
int classDefSize = dexFile->pHeader->classDefsSize;
log("%d",classDefSize);
//2.dex保留classdef。
FILE *pFile = fopen("/data/data/com.qsq.qianshengqian/2.dex", "wb+");
u4 currentLength =dexFile->pHeader->fileSize;
for (int i = 0; i < classDefSize; ++i) {
if (pDef->classDataOff != 0) {
const u1 *start = dexGetClassData(dexFile, pDef);
DexClassData *pData = ReadClassData(&start);
int len = 0;
u4 f_off = currentLength + len;
uint8_t *string = EncodeClassData(pData, len);
fwrite(string, 1, len, pFile);
currentLength = currentLength + len;
//重置偏移,
if (i<4495) {
u4 *def_off = &(pDef->classDataOff);
*def_off = f_off;
}
}
//重置annotation
u4 *off = &(pDef->annotationsOff);
*off = 0;
pDef++;
}
log("%s","write compete");
fclose(pFile);
char *file_name = "/data/data/com.qsq.qianshengqian/1.dex";
FILE *dex_file = fopen(file_name, "wb+");
fwrite(dexFile->pHeader, dexFile->pHeader->fileSize, 1, dex_file);
fclose(dex_file);
}
return old_findDex(pDexFile, descriptor);
}
修复onCreate001
jint new_JNI_OnLoad(JavaVM *vm, void *reserved) {
vm->GetEnv((void **) &jniEnv, JNI_VERSION_1_4);
//0x35c为RegisterNatives偏移地址
elf_hook_Direct((void *) *(unsigned int *) ((*(unsigned int *) jniEnv) + 0x35C),
(void *) &myRegisterNatives, (void **) &oldRegisterNatives);
return old_JNI_OnLoad(vm, reserved);
}
//修复函数
void new_d(JNIEnv *env, jclass c, jstring js) {
log("%s",env->GetStringUTFChars(js, false));
return old_d(env,c,js);
}
void (*old_e)(JNIEnv *env, jclass c,jstring js);
//还原函数
void new_e(JNIEnv *env, jclass c, jstring js) {
//这里直接拦截它恢复
// log("%s", "run new e");
// log("%s",env->GetStringUTFChars(js, false));
// return old_e(env,c,js);
}
void on_native_reg(JNIEnv *env, jclass c, const JNINativeMethod *m, jint n) {
for (int i = 0; i < n; i++) {
if (strcmp(m[i].name, "d") == 0) {
elf_hook_Direct(m[i].fnPtr, (void *) &new_d, (void **) &old_d);
}
if (strcmp(m[i].name, "e") == 0) {
elf_hook_Direct(m[i].fnPtr, (void *) &new_e, (void **) &old_e);
}
}
}
void *new_dexFindClass(const void *pDexFile, const char *descriptor) {
DexFile *dexFile = (DexFile *) pDexFile;
char *aim = "Lcom/qsq/qianshengqian/LoginActivity;";
int cmp = strcmp(descriptor, aim);
if (dexFile->pHeader->fileSize == 5573376 && a == 0 && cmp) {
log("%s","start dump");
a = 1;
size_t size = dexFile->pHeader->fileSize;
DexClassDef *pDef = dexFile->pClassDefs;
// log("class def size is %d", dexFile->pHeader->classDefsSize);
int classDefSize = dexFile->pHeader->classDefsSize;
log("%d",classDefSize);
//2.dex保留classdef。
FILE *pFile = fopen("/data/data/com.qsq.qianshengqian/2.dex", "wb+");
u4 currentLength =dexFile->pHeader->fileSize;
for (int i = 0; i < classDefSize; ++i) {
if (pDef->classDataOff != 0) {
const u1 *start = dexGetClassData(dexFile, pDef);
DexClassData *pData = ReadClassData(&start);
int len = 0;
u4 f_off = currentLength + len;
uint8_t *string = EncodeClassData(pData, len);
fwrite(string, 1, len, pFile);
currentLength = currentLength + len;
//重置偏移,
if (i<4495) {
u4 *def_off = &(pDef->classDataOff);
*def_off = f_off;
}
}
//重置annotation
u4 *off = &(pDef->annotationsOff);
*off = 0;
pDef++;
}
log("%s","write compete");
fclose(pFile);
char *file_name = "/data/data/com.qsq.qianshengqian/1.dex";
FILE *dex_file = fopen(file_name, "wb+");
fwrite(dexFile->pHeader, dexFile->pHeader->fileSize, 1, dex_file);
fclose(dex_file);
}
return old_findDex(pDexFile, descriptor);
}
然后我们就用1.dex与Fix_2.dex组合成一个新的dex,再将Fix_1.dex中的code_item覆盖到1.dex的code_item。可以看到已经修复成功了,到此为止这个样本完成了,样本以及代码资源奉上(原文附件中)。
[2023春季班]《看雪安卓高级研修班(网课)》招生!
《安卓高级研修班(网课)》
火热招生中!
为了更加针对性、更高效地培养安全人才,为企业的发展和壮大赋能,提高企业在招聘活动中及人才在求职过程中的对接效率,结合看雪自身在安全圈的深厚技术积累沉淀,看雪正式针对《安卓高级研修班》学员推出《看雪安卓应用安全能力认证》。
有一定基础的初、中级安卓逆向研究员,迫切希望提高自身能力、学习能力强,升职加薪意愿强烈、学习意愿强烈。
-
上述列出的两大计划、各八大专题及其包含的二十四个细目; -
专属班主任,敦促学习、鼓励士气;良好的抱团学习的氛围;
-
可以参加《安卓高级研修班》线下班,鼓励线下交流,与大佬谈笑风生;
-
注意2W班和3W班是完全独立噢,没有交集;
开班时间:2022年6月开班
PS:以上为总体服务计划,具体课程时间(段)安排以最终合同约定的课程表为准。
高研网课 |
就业班 |
强化班 |
月薪三万计划 |
16999元 |
8599元 |
月薪两万计划 |
11199元 |
5599元 |
-
就业班附带包就业服务(须达到合同规定的毕业标准),签合同保证就业及薪资,达不到退全款;
-
就业班有入学考核,缴费成功后进入考核流程,考核不通过退全款;
-
考核流程会包括简历筛选、班主任和老师(电话)面试等环节;
-
强化班仅去除包就业服务,并且无入学考核,其余与就业班完全相同;
-
就业班与强化班一起授课,合计35人一个班,教学上不做任何区分。
-
《安卓高级研修班》全系列无任何金融计划,纯预付;无任何金融套路。
-
网络课程为虚拟商品,购买之前可以观看下述试看内容,购买成功之后不接受退款。
网课月薪三万计划:
https://www.kanxue.com/book-brief-84.htm
扫码立即报名!
试看地址:
3W:《ida trace分析非标准算法》
3W:《Fart&frida》
扫码免费试看
扫码免费试看
课程顾问微信:r0ysue(备注“安卓高研网课”)
免责条款
以上所有宣传稿件内容均不作为服务承诺,最终以实际签订培训合同为准。
课程大纲与细目会根据教学反馈不断优化、调整与更新,实际授课可能与宣传主题略有不同;
Q:有优惠么?!有优惠么?!有优惠么?!重要的事情说三遍!!
-
一部pixel手机(sailfish)(安卓8脱壳镜像)
-
安卓源码开发编译调试环境SSD移动硬盘500G
A:月薪三万计划的内容与线下班的内容是一样的,我们在线下班沉淀大家的切实的需求和疑问,重新编排和制作内容作为网课与大家分享。月薪两万计划的内容由三万计划的讲师全新制作,充分体现工作场景一线的需求,更加贴近实战、实用,有用、好用。
Q:网课内容与线下班内容一样么?
A:目前针对ollvm和vmp,任何所谓的自动化,都是带很多前提和条件限制的;目前最快的还原ollvm或vmp的方法,还是手动分析,一般快则两三日、慢则一两周,基本上可以还原出来。
A:月薪两万计划推荐至少有实际安卓安全岗位工作经验一年以上为宜。初学者可以先看我们安卓版主非虫大佬的《Android软件安全权威指南》等安卓安全书籍进行入门,在看雪论坛看帖发帖提升自身水平,本套课程建议有工作经验的老手前来充电学习。
月薪三万计划视大家实际需求而定,一般看得懂目录及想要学习的人自己就懂,大家不用盲目跟风。如果看不懂目录及不理解目录的具体含义及意义,建议先从两万计划学起,多积累技术和经验。
A:不需要,互相独立的。月薪两万计划的定位更加偏向工作岗位一线逆向需求,月薪三万计划则更加偏向于高级调试技巧,二者互为补充,相辅相成。有非常多地大佬两个计划一起报名了,我们也会确保直播时间不会冲突。
A:其实推荐两个班一起报,有好几位大佬就是两个班全报的。因为首先价格真心不贵,其实我们会将直播的时间错开,方便大家同时进修三万和两万计划,学习自己想要学习的、心仪的知识。
A:每一场直播都有回放,在看雪课程中可以观看。
A:就业班是需要考核的。考核流程是先缴费报名,然后开始。会经过简历、(远程)一面和二面。通过之后补差价,不通过退全款。
# 十一月
# 十月
《dexvmp后的算法逆向分析和还原》
《使用unicorn对ollvm字符串进行解密》
《Frida追踪定Socket接口自吐游戏APK的服务器IP和地址》
Frida hook Java/Native与init_array 自吐最终方案 》
# 九月
《macOS安装调试llvm入门》
《fart的理解和分析过程》
《使用ollvm自定义简单的字符串加密》
《使用ida trace来还原ollvm混淆的非标准算法》
# 八月
# 七月
# 六月
从三道题目入手入门frida
单纯使用Frida书写类抽取脱壳工具的一些心路历程和实践
某聊天app的音视频通话逆向
# 五月
初试IDA&FRIDA联合调试简单ollvm保护的加密函数源码
# 四月
某抽取壳的原理简析
frida辅助脱壳
# 三月
报 名 地 址
网课月薪三万计划:
https://www.kanxue.com/book-brief-84.htm
扫码立即报名!
课程顾问微信:r0ysue(备注“安卓高研网课”)
看雪ID:GitRoy
https://bbs.pediy.com/user-home-762912.htm
https://www.kanxue.com/book-leaflet-84.htm
# 往期推荐
球分享
球点赞
球在看
点击“阅读原文”,了解更多!
原文始发于微信公众号(看雪学苑):脱壳成长之路之二代壳进阶:绕过反调试、函数体回填并修复onCreate