前言
阅读了许多大佬文章
珍惜大佬的
正己大佬的
mt去签名原理
等等。
总结前辈经验,不难发现常规签名校验的原理:
都是对本地存储的apk文件进行检测
大多数软件并没有对载入内存的文件进行检测
我也搜索的很多资料
并没有对内存上校验有过多的论述
所以我分享我实现的一种方法:
dex内存校验
实现原理
通过maps 对内存中的dex进行校验
实现步骤
1.通过maps获取内存的dex
2.遍历每个dex.header.signature
3.将获取的signature 进行比对
实现代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 | bool isMyDexSignaures(){ char path[1024]; sprintf(path,"/proc/%d/maps",getpid()); FILE * f = fopen(path,"r"); if(f == NULL){ log("error fopen!"); }; char buffer[4096]; string sig=""; while(fgets(buffer,sizeof (buffer),f)){ if(strstr(buffer,"classes")&& strstr(buffer,"base.apk")){ log("%s",buffer); char *temp = strtok(buffer,"-"); long addr= strtoul(temp,NULL,16); log("dex 头部magic: %s",(char *)addr); log("dex特征打印:%s",getsignature((char *)addr).c_str()); sig.append(getsignature((char *)addr)); } } log("signature: %s",sig.c_str()); return strcmp("5ebbcf832fb69feb3703021e2989839c7b3fffafa7f7e55c6f0204d50e7fb7988a9d2efcc1064122bcb722c16c9987a8e3a09a1048a6303a0db1a76568511675af3d5bc146ea17dfeaa9c545369ad757",sig.c_str())==0;} |
1 2 3 4 5 6 7 8 9 10 11 | string getsignature(char *addr){ addr+=12; //偏移到signature char buffer[50]= {0}; int index = 0; for(int i=0;i<20;i++){ sprintf(buffer+index,"%02x",(unsigned char)*((unsigned char *)(addr+i))); index+=2; } return string(buffer);} |
将代码复制到自己的项目运行一遍 获取日志中的signature 添加到strcmp函数中。每次修改过java代码都要修改!
提高强度
1.将open改成svc实现的代码,不懂可以买珍惜的课 里面有svc的内容
2.自己实现字符串匹配函数
3.结合其他签名检测函数 事半功倍!
4.ollvm
对抗原理
1.hook maps 再申请的假dex内存 达到欺骗的效果。
2.不修改原本dex,用自己的dex文件hook程序,再把自己的dex隐藏。
缺点
只修改签名 代码不会检测出异常,但一改代码才会检测出来
实践测试
对市面上的大部分去签名软件测试 都能达到通杀!
附件没有混淆,欢迎大家学习!