diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..1fa8dbf
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,3 @@
+*.pyc
+*~
+#*#
\ No newline at end of file
diff --git a/AnalysisCSN/CSN.py b/AnalysisCSN/CSN.py
index 369790f..a419ad2 100644
--- a/AnalysisCSN/CSN.py
+++ b/AnalysisCSN/CSN.py
@@ -3,7 +3,16 @@
import os
from hashlib import md5, sha1, sha256
from base64 import b64encode
-from core.chilkatCert.win32 import chilkat
+from platform import system, architecture
+
+SYS = system()
+if SYS == "Darwin":
+ from core.chilkatCert.mac import chilkat
+if SYS == "Windows":
+ if architecture()[0] == "32bit":
+ from core.chilkatCert.win32 import chilkat
+ elif architecture()[0] == "64bit":
+ from core.chilkatCert.win64 import chilkat
BLACK_LIST_CSN = [
('936eacbe07f201df', 'Google测试证书(打包党)'),
diff --git a/ApkDetecter.py b/ApkDetecter.py
index 6344c02..c470af6 100644
--- a/ApkDetecter.py
+++ b/ApkDetecter.py
@@ -8,6 +8,7 @@
import hashlib
import thread
import shutil
+import subprocess
from PyQt4 import QtCore, QtGui
from AnalysisXML.AXML import AXML
from DexInfo import DexInfoForm
@@ -16,7 +17,7 @@
from CheckProtect import CheckProtect
from AnalysisCSN.CSN import CSN
from GUI.apkdetecter_ui import Ui_APKDetecter
-
+from platform import system
@@ -27,8 +28,7 @@ def __init__(self, parent = None):
self._want_to_close = True
self.dexheader = {}
self.loadfile_path = ""
- #self.unpackDir = tempfile.mktemp()
- self.unpackDir = ur"d:\APK"
+ self.unpackDir = tempfile.mkdtemp()
self.ui = Ui_APKDetecter()
self.ui.setupUi(self)
@@ -37,9 +37,19 @@ def __init__(self, parent = None):
self.ui.apk_info.clicked.connect(self.apkinfo_dialog)
self.ui.extend_info.clicked.connect(self.extendinfo_dialog)
+ self.apkinfo = None
+ self.dexinfo = None
+
def closeEvent(self, evnt):
if self._want_to_close:
super(ApkDetecterForm, self).closeEvent(evnt)
+
+ # Clean up UI if present
+ if self.apkinfo and self.apkinfo.isVisible():
+ self.apkinfo.close()
+ if self.dexinfo and self.dexinfo.isVisible():
+ self.dexinfo.close()
+
self.clearfiles(self.unpackDir)
print "Andy"
@@ -53,11 +63,21 @@ def probar_thread(self, no, interval):
def unzip(self, apkpath):
apkpath = unicode(apkpath, "utf8")
- cmd = "tool\\7z.exe x %s -y -o%s *.dex AndroidManifest.xml lib META-INF assets"
- print cmd % (apkpath, self.unpackDir)
+
+ path7zip = ""
+ # This all should likely just become python code, however
+ # in the mean time, attempt to find 7zip via a `which` command
+ # on non-Windows environments
+ if system() == "Windows":
+ path7zip = "tool\\7z.exe"
+ else:
+ path7zip = subprocess.check_output(["which","7za"]).rstrip()
+
+ cmd = "%s x %s -y -o%s *.dex AndroidManifest.xml lib META-INF assets"
+ print cmd % (path7zip, apkpath, self.unpackDir)
self.ui.progressBar.setMaximum(29)
thread.start_new_thread(self.probar_thread, (3, 30))
- os.system(cmd % (apkpath, self.unpackDir))
+ os.system(cmd % (path7zip, apkpath, self.unpackDir))
def Init_Main_text(self):
@@ -166,12 +186,11 @@ def GetFileMd5(self, path):
file.close()
return strMd5
except:
+ # TODO: "Sorry, error calculating MD5!"
return u"Sorry,计算出错!"
-
-
def apkinfo_dialog(self):
self.apkinfo = MyApkInfoForm()
self.Init_Apkinfo_text()
@@ -232,10 +251,9 @@ def apkinfo_dialog(self):
self.apkinfo.ui.edt_version_num.setText(axml_analysis.get_androidversion_code())
self.apkinfo.ui.edt_version_need.setText(axml_analysis.getMinSdkVersion())
-
-
self.apkinfo.show()
+
def extendinfo_dialog(self):
self.dexinfo = DexInfoForm()
self.Init_DexInfo_text()
@@ -269,7 +287,24 @@ def extendinfo_dialog(self):
if __name__ == "__main__":
+ # Attempt to detect user Locale
+ locale = QtCore.QSettings().value("locale/userLocale").toString()
+ if not locale:
+ locale = 'en'
+ else:
+ locale = locale[0:2]
+ localePath = os.path.join(os.path.dirname(__file__), 'i18n/',
+ '{}.qm'.format(locale))
+
app = QtGui.QApplication(sys.argv)
+
+ if os.path.exists(localePath):
+ translator = QtCore.QTranslator()
+ if translator.load(localePath):
+ app.installTranslator(translator)
+ else:
+ print 'Failed to load translator - defaulting to zh!'
+
myapp = ApkDetecterForm()
myapp.show()
- sys.exit(app.exec_())
\ No newline at end of file
+ sys.exit(app.exec_())
diff --git a/CheckProtect.py b/CheckProtect.py
index a745b2c..1ca1556 100644
--- a/CheckProtect.py
+++ b/CheckProtect.py
@@ -4,17 +4,36 @@
import os
from UnzipAPK import UnzipAPK
from AnalysisXML.AXML import AXML
+from PyQt4 import QtGui
+try:
+ _encoding = QtGui.QApplication.UnicodeUTF8
+ def _translate(context, text, disambig):
+ return QtGui.QApplication.translate(context, text, disambig, _encoding)
+except AttributeError:
+ def _translate(context, text, disambig):
+ return QtGui.QApplication.translate(context, text, disambig)
+
+
class CheckProtect():
def __init__(self, apkPath):
#self.apkPath = r"D:\original.apk"
self.apkPath = apkPath
self.protectflag = ""
- self.protectflag_dict = {"libsecexe.so": u"该APK已加固=>梆梆加固", "libAPKProtect.so": u"该APK已加固=>APKProtect加固",
- "libprotectClass.so": u"该APK已加固=>360加固", "libNSaferOnly.so": u"该APK已加固=>通付盾加固",
- "libnqshield.so": u"该APK已加固=>网秦加固", "libshell.so": u"该APK已加固=>腾讯加固",
- "ijiami.dat": u"该APK已加固=>爱加密加固", "libddog.so": u"该APK已加固=>娜迦加固",
- "libmobisec.so": u"该APK已加固=>阿里加固", "libbaiduprotect.so": u"该APK已加固=>百度加固"}
+ self.protectflag_dict = {
+ "libsecexe.so": _translate("ProtectDictionary", "该APK已加固=>梆梆加固", None),
+ "libAPKProtect.so": _translate("ProtectDictionary", "该APK已加固=>梆梆加固(APKProtect)", None),
+ "libprotectClass.so": _translate("ProtectDictionary", "该APK已加固=>360加固", None),
+ "libNSaferOnly.so": _translate("ProtectDictionary", "该APK已加固=>通付盾加固", None),
+ "libnqshield.so": _translate("ProtectDictionary", "该APK已加固=>网秦加固", None),
+ "libshell.so": _translate("ProtectDictionary", "该APK已加固=>腾讯加固", None),
+ "ijiami.dat": _translate("ProtectDictionary", "该APK已加固=>腾讯加固(Ijiami)", None),
+ "libddog.so": _translate("ProtectDictionary", "该APK已加固=>娜迦加固", None),
+ "libmobisec.so": _translate("ProtectDictionary", "该APK已加固=>阿里加固", None),
+ "libbaiduprotect.so": _translate("ProtectDictionary", "该APK已加固=>百度加固", None),
+ "libmd.so": _translate("ProtectDictionary", "该APK已加固=>Medusa", None),
+ "LIAPPClient.sc": _translate("ProtectDictionary", "该APK已加固=>LIAPP", None)
+ }
def getactivity(self, path):
axml_analysis = AXML(path + os.path.sep +"AndroidManifest.xml")
@@ -61,8 +80,8 @@ def check_protectflag(self):
self.protectflag = self.protectflag + self.protectflag_dict[key]
if file_name.has_key("key.dat") and all_dir_name.has_key("apkprotect.com"):
- if self.protectflag == "" or (u"APKProtect加固" not in self.protectflag):
- self.protectflag = self.protectflag + u"APKProtect加固"
+ if self.protectflag == "" or (_translate("ProtectDictionary", "APKProtect加固", None) not in self.protectflag):
+ self.protectflag = self.protectflag + _translate("ProtectDictionary", "APKProtect加固", None)
if self.protectflag != "":
return self.protectflag
@@ -76,10 +95,10 @@ def check_protectflag(self):
self.flag = 1
if self.protectflag == "" and self.flag == 1:
- self.protectflag = u"疑似未知加密"
+ self.protectflag = _translate("ProtectDictionary", "疑似未知加密", None)
if self.protectflag == "":
- self.protectflag = u"该APK未加密"
+ self.protectflag = _translate("ProtectDictionary", "该APK未加密", None)
return self.protectflag
@@ -87,4 +106,4 @@ def check_protectflag(self):
if __name__ == "__main__":
obj = CheckProtect()
- obj.check_protectflag()
\ No newline at end of file
+ obj.check_protectflag()
diff --git a/GUI/dexinfor_ui.py b/GUI/dexinfor_ui.py
index 7f3a20f..511013b 100644
--- a/GUI/dexinfor_ui.py
+++ b/GUI/dexinfor_ui.py
@@ -44,7 +44,7 @@ def setupUi(self, DexInfo):
self.groupBox.setFont(font)
self.groupBox.setObjectName(_fromUtf8("groupBox"))
self.lab_magic = QtGui.QLabel(self.groupBox)
- self.lab_magic.setGeometry(QtCore.QRect(6, 20, 81, 16))
+ self.lab_magic.setGeometry(QtCore.QRect(6, 20, 98, 16))
font = QtGui.QFont()
font.setBold(True)
font.setWeight(75)
@@ -72,7 +72,7 @@ def setupUi(self, DexInfo):
self.lab_header_size.setFont(font)
self.lab_header_size.setObjectName(_fromUtf8("lab_header_size"))
self.lab_endian_tag = QtGui.QLabel(self.groupBox)
- self.lab_endian_tag.setGeometry(QtCore.QRect(6, 144, 71, 16))
+ self.lab_endian_tag.setGeometry(QtCore.QRect(6, 144, 74, 16))
font = QtGui.QFont()
font.setBold(True)
font.setWeight(75)
diff --git a/GUI/dexinfor_ui.ui b/GUI/dexinfor_ui.ui
index b2cea4b..a44fcd7 100644
--- a/GUI/dexinfor_ui.ui
+++ b/GUI/dexinfor_ui.ui
@@ -60,7 +60,7 @@
6
20
- 81
+ 98
16
@@ -136,7 +136,7 @@
6
144
- 71
+ 74
16
diff --git a/README.md b/README.md
index e3a857c..745d540 100644
--- a/README.md
+++ b/README.md
@@ -1,8 +1,29 @@
-# ApkDetecter
+ApkDetecter
+===========
+
android apk查壳工具源代码
-主要功能:
-1、检测DEX文件是否加固及加固厂商
-2、检测APK的基本信息:
- APKMD5值,APK包名,APK版本,签名信息等
-3、DEX文件的字节信息
+主要功能 :
+----------
+1. 检测DEX文件是否加固及加固厂商
+2. 检测APK的基本信息:
+ 1. APKMD5值
+ 2. APK包名
+ 3. APK版本
+ 4. 签名信息等
+3. DEX文件的字节信息
+
+Translation
+-----------
+
+Tool for providing Android APK protector detection with UI
+
+Main Features:
+--------------
+1. Detect DEX file protectors, obfuscators
+2. Detect APK basic information
+ 1. APK MD5
+ 2. APK Package name
+ 3. APK version
+ 4. Signature informaton
+3. Detailed information about the DEX file bytes
\ No newline at end of file
diff --git a/UnzipAPK.py b/UnzipAPK.py
index dfb88b8..0502494 100644
--- a/UnzipAPK.py
+++ b/UnzipAPK.py
@@ -3,6 +3,8 @@
import os
import struct
import tempfile
+import subprocess
+from platform import system
class UnzipAPK():
@@ -83,10 +85,16 @@ def unpackxml(self):
def dexdump(self):
- cmd = 'tool\\dexdump.exe -d %s > %s'
+ pathdexdump = ""
+ if system() == "Windows":
+ pathdexdump = "tool\\dexdump.exe"
+ else:
+ pathdexdump = subprocess.check_output(["which","dexdump"]).rstrip()
+
+ cmd = '%s -d %s > %s'
dexpath = os.path.join(self.unpackDir, "classes.dex")
if os.path.exists(dexpath):
- os.system(cmd % (dexpath, self.unpackDir + os.path.sep +"classes.txt"))
+ os.system(cmd % (pathdexdump, dexpath, self.unpackDir + os.path.sep +"classes.txt"))
def getallname(self):
@@ -104,4 +112,4 @@ def getallname(self):
# if __name__ == "__main__":
# apkPath = r"D:\original.apk"
-# obj = UnzipAPK(apkPath)
\ No newline at end of file
+# obj = UnzipAPK(apkPath)
diff --git a/i18n/en.qm b/i18n/en.qm
new file mode 100644
index 0000000..b7c69fe
Binary files /dev/null and b/i18n/en.qm differ
diff --git a/i18n/en.ts b/i18n/en.ts
new file mode 100644
index 0000000..b146618
--- /dev/null
+++ b/i18n/en.ts
@@ -0,0 +1,351 @@
+
+
+
+
+ APKDetecter
+
+
+ APKDetecter
+ APKDetecter
+
+
+
+ 文 件
+ File
+
+
+
+ 打 开
+ Open
+
+
+
+ DEX信息
+ Dex Information
+
+
+
+ 连接段大小
+ Link Seg. Size
+
+
+
+ DEX 标 识
+ Dex Flags
+
+
+
+ DEX头大小
+ Header Size
+
+
+
+ 连接段偏移
+ Link Seg. Offset
+
+
+
+ 文件大小
+ File Size
+
+
+
+ 字节序列
+ Endian Tag
+
+
+
+ 扩展信息
+ Extra Info
+
+
+
+ About
+ About
+
+
+
+ ApkInfo
+ Apk Info
+
+
+
+ ApkInfo
+
+
+ ApkInformation
+ ApkInformation
+
+
+
+ 文件信息
+ File Information
+
+
+
+ 文件大小
+ File Size
+
+
+
+ 文件包名
+ Package
+
+
+
+ 版 本
+ Version
+
+
+
+ 版本号
+ Version #
+
+
+
+ 系统要求
+ Min SDK
+
+
+
+ 序列号
+ Serial #
+
+
+
+ 发 行 者
+ Publisher
+
+
+
+ 签 发 人
+ Issuer
+
+
+
+ APKMD5
+ APK MD5
+
+
+
+ DEXMD5
+ Dex MD5
+
+
+
+ DexInfo
+
+
+ DexInformation
+ DexInformation
+
+
+
+ DexInfo
+ DexInfo
+
+
+
+ Magic标识
+ Magic Number
+
+
+
+ 校验码
+ Checksum
+
+
+
+ DEX文件大小
+ File Size
+
+
+
+ 文件头长度
+ Header Size
+
+
+
+ 字节序标记
+ Endian Tag
+
+
+
+ 链接段大小
+ Link Size
+
+
+
+ 链接段基地址
+ Link Offset
+
+
+
+ Map数据基地址
+ Map Offset
+
+
+
+ 字符串列表的字符串数
+ String IDs Size
+
+
+
+ 字符串列表表基地址
+ String IDs Offset
+
+
+
+ 字段列表里字段数
+ Field IDs Size
+
+
+
+ 原型列表里原型数
+ Proto IDs Size
+
+
+
+ 方法列表里方法数
+ Method IDs Size
+
+
+
+ 字段列表基地址
+ Data Size
+
+
+
+ 方法列表基地址
+ Proto Ids Offset
+
+
+
+ 数据段的大小
+ Method IDs Offset
+
+
+
+ 原型列表基地址
+ Data Size
+
+
+
+ 类型列表基地址
+ Type IDs Offset
+
+
+
+ 类定义类表中类的数
+ Class Defs Size
+
+
+
+ 类定义列表基地址
+ Class Defs Offset
+
+
+
+ 类型列表中类型数
+ Type IDs Size
+
+
+
+ 数据段基地址
+ Data Offset
+
+
+
+ SHA-1签名
+ File SHA1
+
+
+
+ ProtectDictionary
+
+
+ 该APKå·²å åº=>æ¢æ¢å åº
+ APK is Packed => Bangcle/SecNeo
+
+
+
+ 该APKå·²å åº=>éä»ç¾å åº
+ APK is Packed => Qihoo360 Packer
+
+
+
+ 该APKå·²å åº=>ç½ç§¦å åº
+ APK is Packed => Pass Pay Shield Packer
+
+
+
+ 该APKå·²å åº=>è
¾è®¯å åº
+ APK is Packed => Netqin Packer
+
+
+
+ 该APKå·²å åº=>å¨è¿¦å åº
+ APK is Packed => Tencent Packer
+
+
+
+ 该APKå·²å åº=>é¿éå åº
+ APK is Packed => Naga Packer
+
+
+
+ 该APKå·²å åº=>ç¾åº¦å åº
+ Apk is Packed => Alibaba Packer
+
+
+
+ 该APKå·²å åº=>æ¢æ¢å åº(2)
+ APK is Packed => APKProtector
+
+
+
+ 该APKå·²å åº=>360å åº
+ APK is Packed => Baidu Packer
+
+
+
+ 该APKå·²å åº=>æ¢æ¢å åº(APKProtect)
+ APK is Packed => APKProtector
+
+
+
+ 该APKå·²å åº=>è
¾è®¯å åº(Ijimai)
+ APK is Packed => Ijiami
+
+
+
+ 该APKå·²å åº=>è
¾è®¯å åº(Ijiami)
+ APK is Packed => Ijiami
+
+
+
+ APKProtectå åº
+ APKProtected (potentially only with bad code injected)
+
+
+
+ çä¼¼æªç¥å å¯
+ Potentially Unknown Protector Used
+
+
+
+ 该APKæªå å¯
+ No Protections Detected
+
+
+
+ 该APKå·²å åº=>Medusa
+ APK is Packed => Medusa
+
+
+
+ 该APKå·²å åº=>LIAPP
+ APK is Packed => LIAPP
+
+
+