前言

阅读了许多大佬文章
珍惜大佬的
正己大佬的
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隐藏。

缺点

只修改签名 代码不会检测出异常,但一改代码才会检测出来

实践测试

对市面上的大部分去签名软件测试 都能达到通杀!
附件没有混淆,欢迎大家学习!

上传的附件 app-debug.apk

最新回复:
哆啦噩梦 2024-06-28 18:03:18
这个好玩
mb_mmiqbqma 2024-06-29 00:39:56
貌似np管理器的fancybypass就可以过,原dex也可以放到文件夹里动态加载
NT10086 2024-06-29 08:44:51
我以为是教程
Eirv 2024-06-29 10:16:23
我只能说你找错地方了,除了读取apk,还有某个地方存储着dex数量和crc32
逆天而行 2024-06-29 10:29:54
Eirv 我只能说你找错地方了,除了读取apk,还有某个地方存储着dex数量和crc32
能说说还有什么地方啊?
逆天而行 2024-06-29 10:31:20
mb_mmiqbqma 貌似np管理器的fancybypass就可以过,原dex也可以放到文件夹里动态加载
的确可以,他的行为符合对抗原理
菱志漪 2024-07-01 09:43:30
Eirv 我只能说你找错地方了,除了读取apk,还有某个地方存储着dex数量和crc32
是说的DexCache不?我通过DexCache的实例确实可以拿到。不过我也遇到一个问题,就是DexCache的dexfile的指针和内存的似乎不一样
你瞒我瞒 2024-07-01 10:47:02
开了个demo,跑了一下上面给出的代码,if (strstr(buffer, "classes") && strstr(buffer, "base.apk")),请问这个判断有什么用途?base.apk是查找maps中自己apk的路径?我看到了/data/app/xxxxxx/base.apk的信息,但是这个判断一直不成立, classes的判断是为什么?在maps中没有找到classes和base.apk同时在一个行中。我用的是pixel3,Android12.
Eirv 2024-07-01 12:29:37
你瞒我瞒 开了个demo,跑了一下上面给出的代码,if (strstr(buffer, "classes") && strstr(buffer, "base.apk ...
这个是仅debug包才有,release包没有这个,debug包是直接加载的dex,所以所有方法都是解释运行