将壳拖入AK中分析,入口点已经修改成了StubApplication
调用了方法attachBaseContext
这个方法比onCreate调用的更早,很多壳会在这个方法中对原始程序进行还原
除此之外还加载了mobisec.so,查看lib文件夹下的so文件可以找到这个so文件
用IDA打开libmobisec后找到Jni_Onload,导入jni.h中的结构体,F5后重新注释Jni_Onload。
可以看到函数调用了FindClass方法,这个方法是在动态注册时使用的,用于找到class
要找的class名为com/ali/mobisecenance/StubApplication
有了class,就可以对其内部的方法进行注册
static int registerNativeMethods(JNIEnv* env,
const char* className,
JNINativeMethod *gMethods,
int numMethods)
{
jclass clazz;
clazz = env->FindClass(className);
if(clazz == NULL) {
return JNI_FALSE;
}
if(env->RegisterNatives(clazz, gMethods, numMethods) < 0) {
return JNI_FALSE;
}
return JNI_TRUE;
}
在函数的后半段看到off_54010,跳转过去查看
看到几个jar,怀疑是原始文件数据,壳通过这几个文件将原始程序在内存中进行还原
查看assets文件夹发现cls.jar和fak.jar
除此之外还看到了对attachBaseContext和onCreate进行了动态注册
跳转到sub_24d3c+1处查看attachBaseContext方法,主要函数有以下几个:
1.init_classes函数主要对加载器等进行初始化,然后一堆存储地址之类的操作
2.parse_dex是对dex文件进行解码然后调用
内部会调用openWithHeader,并将cls.jar传进去
openWithHeader内部主要是对dex文件进行解密操作
执行完以后,v53指向解密的dex文件
此时将这一块内存dump出来就是解密的dex文件了
运行脚本
static main(void)
{
auto i,begin,end,len,fp;
fp = fopen("e:\\dump.dex","wb");
begin = 0xa98a3010;
len = 0x941fc;
end = begin + len;
for(i=begin;i<end;i++)
fputc(Byte(i),fp);
}
dump文件的长度通过dex文件格式可知,0xa98a3030处是fileSize
把dump出来的文件使用JEB打开,都没有问题
如果发现dump出来的dex文件反编译没有代码,只有函数声明,说明没有dump完整,碰到这种情况,通常是后面对dex文件进行了patch,也就是说需要dump的是后面解析出来的dex文件。如果dump出来发现dex文件无法识别,需要对dex进行修复,这种情况一般是dump的长度不够,通过在IDA中ctrl+s找到dex后面的段,计算总长度重新dump即可。
将dex文件反编译,覆盖到反编译后apk的smali文件夹下(原来的文件需要删除),将AndroidManifest.xml中的壳入口删除,重新编译,即可运行。
可能是apk过于久远,所以在加壳状态下程序无法运行,可见加过壳的程序的稳定性是个问题,脱壳后重新编译的apk可以正常运行。
样本:
链接:https://pan.baidu.com/s/13cBpJ9pUo5Wc9yq4mwmmtg
提取码:8r28