基本原理: 通过读取apk文件(实际就是zip)中的特征文件,来判断应用是否加固。开源的APKID中主要使用pyhon和yara规则,比我这个更加全面
1, 编译zlib和minizip
bash
#buid zilb
cd YOUR_PATH
git clone https://gitclone.com/github.com/madler/zlib.git
mv zlib zlib-src
cd zlib-src/
./configure --prefix=${YOUR_PATH}/zlib/out
make
make test
make install
#build minizip
cd contrib/minizip/
make
cp -raf *.h ../../out/include/
cp -raf ioapi.o ../../out/lib/libioapi.a
cp -raf unzip.o ../../out/lib/libunzip.a
cp -raf zip.o ../../out/lib/libzip.a
最后得到库文件
bash
#show file
zlib-src/out$ ls include/
crypt.h ioapi.h iowin32.h mztools.h unzip.h zconf.h zip.h zlib.h
zlib-src/out$ ls lib/
libioapi.a libunzip.a libz.a libzip.a libz.so libz.so.1 libz.so.1.3.0.1-motley pkgconfig
2,编写主程序
先将已经编译好的zlib和minizip拷贝到代码目录
bash
#main code
cd YOUR_PATH
cp -raf zlib-src/out ./zlib-out
编写main.cpp
bash
#include <iostream>
#include <string>
#include "zip.h"
#include "unzip.h"
bool debug = true;
std::string IsAndroidApkProtect(std::string &fileName)
{
std::string EncryptType;
std::string temp = fileName;
if("libtup.so" == temp || "libexec.so" == temp || "libshell.so" == temp || "mix.dex" == temp)
{
EncryptType = "腾讯";
return EncryptType;
}
else if("libsgmain.so" == temp || "aliprotect.dat" == temp || "libsgsecuritybody.so" == temp || "libmobisec.so" == temp)
{
EncryptType = "阿里聚安全";
return EncryptType;
}
else if("libchaosvmp.so" == temp || "libddog.so" == temp || "libfdog.so" == temp )
{
EncryptType = "娜迦";
return EncryptType;
}
else if("libkwscmm.so" == temp || "libkwscr.so" == temp || "libkwslinker.so" == temp)
{
EncryptType = "几维安全";
return EncryptType;
}
else if("libtosprotection.x86.so"== temp || "libtosprotection.armeabi-v7a.so" == temp || "libtosprotection.armeabi.so" == temp)
{
EncryptType = "腾讯御安全";
return EncryptType;
}
else if("libsecexe.so" == temp || "libtosprotection.armeabi-v7a.so" == temp || "libtosprotection.armeabi.so" == temp)
{
EncryptType = "梆梆免费版";
return EncryptType;
}
else if("libDexHelper.so" == temp || "libDexHelper-x86.so" == temp )
{
EncryptType = "梆梆企业版";
return EncryptType;
}
else if("libexec.so" == temp || "libexecmain.so" == temp || "ijiami.dat" == temp )
{
EncryptType = "爱加密免费版";
return EncryptType;
}
else if("libprotectClass.so" == temp || "libjiagu.so" == temp || "libjiagu_art.so" == temp || "libjiagu_x86.so" == temp)
{
EncryptType = "360";
return EncryptType;
}
else if("libegis.so" == temp || "libNSaferOnly.so" == temp )
{
EncryptType = "通付盾";
return EncryptType;
}
else if("ijiami.ajm" == temp )
{
EncryptType = "爱加密企业版";
return EncryptType;
}
else if("libedog.so" == temp )
{
EncryptType = "娜迦企业版";
return EncryptType;
}
else if("libnqshield.so" == temp )
{
EncryptType = "网秦";
return EncryptType;
}
else if("librsprotect.so" == temp )
{
EncryptType = "瑞星";
return EncryptType;
}
else if("libbaiduprotect.so" == temp )
{
EncryptType = "百度";
return EncryptType;
}
else if("libapssec.so" == temp )
{
EncryptType = "盛大加密";
return EncryptType;
}
else if("libx3g.so" == temp )
{
EncryptType = "顶像科技";
return EncryptType;
}
else if("libAPKProtect.so" == temp )
{
EncryptType = "APKProtect";
return EncryptType;
}
else if("libnesec.so" == temp )
{
EncryptType = "网易易盾";
return EncryptType;
}
EncryptType = "";
return EncryptType;
}
bool checkApkProtect(const std::string& apkPath) {
bool isProctected = false;
unzFile zipFile = unzOpen(apkPath.c_str());
if (zipFile == NULL) {
std::cerr << "Cannot open " << apkPath << std::endl;
return false;
}
if (unzGoToFirstFile(zipFile) != UNZ_OK) {
unzClose(zipFile);
std::cerr << "Cannot read files from " << apkPath << std::endl;
return false;
}
std::string libPath = "lib/";
do {
char filename[256];
unzGetCurrentFileInfo(zipFile, NULL, filename, sizeof(filename), NULL, 0, NULL, 0);
std::string fileStr(filename);
// 检查文件是否在lib目录下,并且是.so文件
if (fileStr.substr(0, libPath.size()) == libPath && fileStr.size() > 3 &&
fileStr.substr(fileStr.size() - 3) == ".so") {
size_t lastHashPos = fileStr.find_last_of('/');
std::string temp = fileStr.substr(lastHashPos + 1);
if(debug){
std::cout << "Found .so file: " << temp << std::endl;
}
std::string resultStr = IsAndroidApkProtect(temp);
if(!resultStr.empty()){
std::cout << "Protect Result: " << resultStr << std::endl;
isProctected = true;
break;
}
}
if (unzGoToNextFile(zipFile) != UNZ_OK) {
break;
}
} while (true);
unzClose(zipFile);
if(!isProctected)
std::cout << "未检测到加固" << std::endl;
return isProctected;
}
int main(int argc, char* argv[]) {
if (argc < 2) {
std::cerr << "Usage: " << argv[0] << " <apk_file_path>" << std::endl;
return 1;
}
std::string apkFilePath = argv[1];
checkApkProtect(apkFilePath);
return 0;
}
3,编写Makefile
g++ main.cpp -o main -I xxx/include/ -L xxx/lib/ -l ioapi -l unzip -l zip -lz
定义编译器
CC := g++
ZIP_DEPS_PATH := ./zlib-out/
ZIP_INCLUDE := $(ZIP_DEPS_PATH)/include
ZIP_LIB :=$(ZIP_DEPS_PATH)/lib
定义编译选项
CFLAGS=-Wall -Wextra -std=c++11 -I $(ZIP_INCLUDE) -L $(ZIP_LIB) -l ioapi -l unzip -l zip -lz
目标文件
TARGET=apk_protect_detector
源文件
SRCS=main.cpp
目标文件
OBJS=$(patsubst %.cpp, %.o, $(SRCS))
默认目标
all: $(TARGET)
链接目标
$(TARGET): $(OBJS)
$(CC) $(CFLAGS) -o $@ $^
从.cpp文件生成.o文件
%.o: %.cpp
$(CC) $(CFLAGS) -c $< -o $@
清理编译生成的文件
clean:
rm -f $(OBJS) $(TARGET)
声明伪目标
.PHONY: all clean
4, 编译
make
g++ -Wall -Wextra -std=c++11 -I ./zlib-out//include -L ./zlib-out//lib -l ioapi -l unzip -l zip -lz -c main.cpp -o main.o
g++ -Wall -Wextra -std=c++11 -I ./zlib-out//include -L ./zlib-out//lib -l ioapi -l unzip -l zip -lz -o apk_protect_detector main.o
5, 测试
./apk_protect_detector yizhifu-10.88.10.apk
Found .so file: libapm_bitmaps.so
Found .so file: libijkengine-mp3.so
Found .so file: libjitdealer.so
Found .so file: libAlipayBitmapNative.so
Found .so file: libutility.so
Found .so file: libdatabase_sqlcrypto.so
Found .so file: libarthook.so
Found .so file: libsgnocaptchaso-5.5.8.so
Found .so file: libv8worker-native.so
Found .so file: libgetuiext3.so
Found .so file: libwind.so
Found .so file: libmpaas_crypto.so
Found .so file: libc++_shared.so
Found .so file: libjsengine-api.so
Found .so file: libhoks.so
Found .so file: libjsengine-platform.so
Found .so file: libnllvm1624349491.so
Found .so file: libAPMUOCPLIB.so
Found .so file: libandfix.so
Found .so file: libjdcard.so
Found .so file: libcrashsdk.so
Found .so file: libCryptoOperAd.so
Found .so file: libdexpatch_x86.so
Found .so file: libbestpaysheild.so
Found .so file: libturbojpeg.so
Found .so file: libDexHelper-x86.so
Protect Result: 梆梆企业版
总结:
目前代码只是一个基础,正确性还需要验证,后期还需要优化执行速度