Skip to content

Commit 626fc56

Browse files
author
Your Name
committed
Merge branch 'v1.0.5' into master
2 parents d3455d9 + e245603 commit 626fc56

File tree

11 files changed

+412
-269
lines changed

11 files changed

+412
-269
lines changed

README.md

Lines changed: 15 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -25,22 +25,25 @@
2525
- Python3的运行环境
2626

2727
### 目录说明
28+
```
2829
AppInfoScanner
2930
|-- libs 程序的核心代码
3031
|-- core
3132
|-- parses.py 用于解析文件中的静态信息
3233
|-- task
33-
|-- android_task.py 用于处理Android相关的文件
34-
|-- ios_task.py 用于处理iOS相关的文件
35-
|-- web_task.py 用于处理Web相关的文件,比如网页右键源代码、H5相关的静态信息
36-
|-- tools 程序需要依赖的工具
37-
|-- apktool.jar 用于反编译apk文件
38-
|-- baksmali.jar 用于反编译dex文件
39-
|-- strings.exe 用于windows 32下获取iPA的字符串信息
40-
|-- strings64.exe 用于windows 64的系统获取iPA的字符串信息
41-
|-- app.py 主运行程序
42-
|-- config.py 用于自定义相关规则
43-
|-- readme.md 程序使用说明
34+
|-- base_task.py 统一任务调度
35+
|-- android_task.py 用于处理Android相关的文件
36+
​ |-- ios_task.py 用于处理iOS相关的文件
37+
​ |-- web_task.py 用于处理Web相关的文件,比如网页右键源代码、H5相关的静态信息
38+
​ |-- tools 程序需要依赖的工具
39+
​ |-- apktool.jar 用于反编译apk文件
40+
​ |-- baksmali.jar 用于反编译dex文件
41+
​ |-- strings.exe 用于windows 32下获取iPA的字符串信息
42+
​ |-- strings64.exe 用于windows 64的系统获取iPA的字符串信息
43+
​ |-- app.py 主运行程序
44+
​ |-- config.py 用于自定义相关规则
45+
​ |-- readme.md 程序使用说明
46+
```
4447

4548

4649

@@ -91,7 +94,7 @@ python3 app.py android -i <Your apk or dex directory> -a
9194

9295
```
9396
python3 app.py android -i <Your apk or dex directory> -t 10
94-
```
97+
```
9598

9699
### iOS 相关操作说明
97100

app.py

Lines changed: 16 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -7,70 +7,67 @@
77
import click
88

99
from libs.core import Bootstrapper
10-
from libs.task.android_task import AndroidTask
11-
from libs.task.ios_task import iOSTask
12-
from libs.task.web_task import WebTask
10+
from libs.task.base_task import BaseTask
1311

1412
@click.group(help="Python script for automatically retrieving key information in app.")
1513
def cli():
1614
pass
1715

1816
# 创建Android任务
1917
@cli.command(help="Get the key information of Android system.")
20-
@click.option("-i", "--input", required=True, type=str, help="Input APK file or DEX directory.")
18+
@click.option("-i", "--inputs", required=True, type=str, help="Input APK file or DEX directory.")
2119
@click.option("-r", "--rules", required=False, type=str, default="", help="Add regular search rule.")
2220
@click.option("-s", "--net-sniffer", is_flag=True, default=False, help="Whether to enable network sniffing.")
2321
@click.option("-n", '--no-resource', is_flag=True, default=False,help="Ignore resource files.")
2422
@click.option("-p", '--package',required=False,type=str,default="",help="Specifies the retrieval package name.")
25-
@click.option("-a", '--all',is_flag=True, default=False,help="Output all strings.")
23+
@click.option("-a", '--all-str',is_flag=True, default=False,help="Output all strings.")
2624
@click.option("-t", '--threads',required=False, type=int,default=10,help="Set the number of threads to 10 by default")
27-
def android(input: str, rules: str, net_sniffer: bool,no_resource:bool,package:str,all:bool,threads:int) -> None:
25+
def android(inputs: str, rules: str, net_sniffer: bool,no_resource:bool,package:str,all_str:bool,threads:int) -> None:
2826
try:
2927
# 初始化全局对象
3028
bootstrapper = Bootstrapper(__file__)
3129
bootstrapper.init()
3230

33-
task = AndroidTask(input, rules, net_sniffer,no_resource,package,all,threads)
34-
# 让内层代码直接抛出异常,不做rollback。
35-
task.start()
31+
BaseTask("Android", inputs, rules, net_sniffer, no_resource, package, all_str, threads).start()
3632
except Exception as e:
3733
raise e
3834

3935

4036
@cli.command(help="Get the key information of iOS system.")
41-
@click.option("-i", "--input", required=True, type=str, help="Input IPA file or ELF file.")
37+
@click.option("-i", "--inputs", required=True, type=str, help="Input IPA file or ELF file.")
4238
@click.option("-r", "--rules", required=False, type=str, default="", help="Add regular search rule.")
4339
@click.option("-s", "--net-sniffer", is_flag=True, default=False, help="Whether to enable network sniffing.")
4440
@click.option("-n", '--no-resource', is_flag=True, default=False,help="Ignore resource files.")
45-
@click.option("-a", '--all',is_flag=True, default=False,help="Output all strings.")
41+
@click.option("-a", '--all-str',is_flag=True, default=False,help="Output all strings.")
4642
@click.option("-t", '--threads',required=False, type=int,default=10,help="Set the number of threads to 10 by default")
47-
def ios(input: str, rules: str, net_sniffer: bool,no_resource:bool,all:bool,threads:int) -> None:
43+
def ios(inputs: str, rules: str, net_sniffer: bool,no_resource:bool,all_str:bool,threads:int) -> None:
4844
try:
4945
# 初始化全局对象
5046
bootstrapper = Bootstrapper(__file__)
5147
bootstrapper.init()
5248

53-
task = iOSTask(input, rules, net_sniffer,no_resource,all,threads)
54-
# 让内层代码直接抛出异常,不做rollback。
55-
task.start()
49+
BaseTask("iOS", inputs, rules, net_sniffer, no_resource, all_str, threads).start()
50+
5651
except Exception as e:
5752
raise e
5853

5954

6055
@cli.command(help="Get the key information of Web system.")
61-
@click.option("-i", "--input", required=True, type=str, help="Input WebSite dir.")
56+
@click.option("-i", "--inputs", required=True, type=str, help="Input WebSite dir.")
6257
@click.option("-r", "--rules", required=False, type=str, default="", help="Add regular search rule.")
63-
@click.option("-a", '--all',is_flag=True, default=False,help="Output all strings.")
58+
@click.option("-a", '--all-str',is_flag=True, default=False,help="Output all strings.")
6459
@click.option("-t", '--threads',required=False, type=int,default=10,help="Set the number of threads to 10 by default")
65-
def web(input: str, rules: str, all:bool,threads:int) -> None:
60+
def web(inputs: str, rules: str, all_str:bool,threads:int) -> None:
6661
try:
6762
# 初始化全局对象
6863
bootstrapper = Bootstrapper(__file__)
6964
bootstrapper.init()
7065

66+
# BaseTask("Web", inputs, rules,all_str, threads).start()
67+
7168
task = WebTask(input, rules,all,threads)
72-
# 让内层代码直接抛出异常,不做rollback。
7369
task.start()
70+
7471
except Exception as e:
7572
raise e
7673

config.py

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,19 +3,33 @@
33
# Github: https://github.com/kelvinBen/AppInfoScanner
44

55

6-
# 此处用于搜索组件信息,如fastjson、gson等
6+
# 此处用于搜索组件信息
7+
# com.alibaba.fastjson -> fastjson
8+
# com.google.gson -> gson
9+
# com.fasterxml.jackson -> jackson
10+
# net.sf.json ->
11+
# javax.xml.parsers.DocumentBuilder -> dom方式
12+
# javax.xml.parsers.SAXParser -> sax方式
13+
# org.jdom.input.SAXBuilder -> jdom
14+
# org.dom4j.io.SAXReader -> dom4j
715
filter_components = [
816
'com.alibaba.fastjson',
917
'com.google.gson',
1018
'com.fasterxml.jackson',
11-
'net.sf.json'
19+
'net.sf.json',
20+
'javax.xml.parsers.DocumentBuilder',
21+
'javax.xml.parsers.SAXParser',
22+
'org.jdom.input.SAXBuilder',
23+
'org.dom4j.io.SAXReader'
1224
]
1325

1426
# 此处目前支持过滤
1527
# 1. https://以及http://开头的
1628
# 2. IPv4的ip地址
1729
# 3. URI地址
1830
filter_strs =[
31+
r'^http://.*',
32+
r'^https://.*',
1933
r'.*(http://.*)',
2034
r'.*(https://.*)',
2135
r'.*((?:[0-9]{1,3}\.){3}[0-9]{1,3}).*',

libs/core/__init__.py

Lines changed: 17 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,11 @@
11
# -*- coding: utf-8 -*-
22
# Author: kelvinBen
33
# Github: https://github.com/kelvinBen/AppInfoScanner
4-
5-
import platform
64
import os
5+
import time
76
import shutil
7+
import platform
8+
89

910
# smali 所在路径
1011
smali_path = ""
@@ -30,49 +31,42 @@ def __init__(self, path):
3031
global os_type
3132
global output_path
3233
global script_root_dir
33-
global result_path
34+
global txt_result_path
35+
global xls_result_path
3436
global strings_path
3537

38+
create_time = time.strftime("%Y%m%d%H%M%S", time.localtime())
39+
3640
script_root_dir = os.path.dirname(os.path.abspath(path))
3741
tools_dir = os.path.join(script_root_dir,"tools")
38-
42+
3943
if platform.system() == "Windows":
4044
machine2bits = {'AMD64':64, 'x86_64': 64, 'i386': 32, 'x86': 32}
4145
machine2bits.get(platform.machine())
4246

4347
if platform.machine() == 'i386' or platform.machine() == 'x86':
44-
strings_path = os.path.join(script_root_dir,"strings.exe")
48+
strings_path = os.path.join(tools_dir,"strings.exe")
4549
else:
46-
strings_path = os.path.join(script_root_dir,"strings64.exe")
50+
strings_path = os.path.join(tools_dir,"strings64.exe")
4751
else:
4852
strings_path ="strings"
49-
# os_type = "win"
50-
# smali_str = "smali.bat"
51-
# back_smali_str = "backsmali.bat"
52-
# apktool_path_str = "apktool.bat"
53-
# elif platform.system() == "Linux":
54-
# os_type = "lin"
55-
# smali_str = "smali"
56-
# back_smali_str = "backsmali"
57-
# apktool_path_str = "apktool"
58-
# else:
59-
# os_type = "mac"
60-
# smali_str = "smali"
61-
6253

63-
# smali_path = os.path.join(tools_dir,str(os_type) + os.sep + smali_str)
6454
backsmali_path = os.path.join(tools_dir,"baksmali.jar")
6555
apktool_path = os.path.join(tools_dir, "apktool.jar")
6656
output_path = os.path.join(script_root_dir,"out")
67-
result_path = os.path.join(script_root_dir,"result.txt")
57+
txt_result_path = os.path.join(script_root_dir,"result_"+str(create_time)+".txt")
58+
xls_result_path = os.path.join(script_root_dir,"result_"+str(create_time)+".xls")
6859

6960
def init(self):
7061
if os.path.exists(output_path):
7162
shutil.rmtree(output_path)
7263
os.makedirs(output_path)
7364

74-
if os.path.exists(result_path):
75-
os.remove(result_path)
65+
if os.path.exists(txt_result_path):
66+
os.remove(txt_result_path)
67+
68+
if os.path.exists(xls_result_path):
69+
os.remove(xls_result_path)
7670

7771

7872

libs/core/parses.py

Lines changed: 42 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -2,72 +2,70 @@
22
# Author: kelvinBen
33
# Github: https://github.com/kelvinBen/AppInfoScanner
44

5-
6-
import threading
7-
import config
85
import re
96
import os
7+
import config
8+
import threading
109
import libs.core as cores
1110

1211
class ParsesThreads(threading.Thread):
1312

14-
def __init__(self,threadID,name,file_queue,all,result_dict):
13+
def __init__(self,threadID,name,file_queue,all,result_dict,types):
1514
threading.Thread.__init__(self)
1615
self.file_queue = file_queue
1716
self.name = name
1817
self.threadID = threadID
1918
self.result_list = []
2019
self.all = all
2120
self.result_dict=result_dict
21+
self.types = types
2222

23-
def __regular_parse__(self,threadLock):
23+
def __regular_parse__(self):
2424
while True:
25-
try:
26-
file_path = self.file_queue.get(timeout = 5)
27-
scan_str = ("Scan file : %s" % file_path)
28-
print(scan_str)
29-
30-
try:
31-
os.path.basename(file_path).split(".")[1]
32-
except Exception as e:
33-
self.__get_string__(file_path,threadLock)
34-
continue
35-
self.__file_parse__(file_path,threadLock)
36-
37-
result_set = set(self.result_list)
38-
if len(result_set) !=0:
39-
self.result_dict[file_path] = result_set
40-
41-
if self.file_queue.empty():
42-
break
43-
except Exception as e:
25+
if self.file_queue.empty():
4426
break
27+
28+
file_path = self.file_queue.get(timeout = 5)
29+
scan_str = ("Scan file : %s" % file_path)
30+
print(scan_str)
31+
32+
if self.types == "iOS":
33+
self.__get_string_by_iOS__(file_path)
34+
else:
35+
self.__get_string_by_file__(file_path)
36+
37+
result_set = set(self.result_list)
38+
if len(result_set) !=0:
39+
self.result_dict[file_path] = result_set
40+
41+
def __get_string_by_iOS__(self,file_path):
42+
output_path = cores.output_path
43+
strings_path = cores.strings_path
44+
temp = os.path.join(output_path,"temp.txt")
45+
cmd_str = ("%s %s > %s") % (strings_path,file_path,temp)
46+
if os.system(cmd_str) == 0:
47+
with open(temp,"r",encoding='utf-8',errors='ignore') as f:
48+
lines = f.readlines()
49+
for line in lines:
50+
self.__parse_string__(line)
4551

46-
def __file_parse__(self,file_path,threadLock):
47-
with open(file_path,"r",encoding="utf8") as file :
48-
file_content = file.read()
52+
def __get_string_by_file__(self,file_path):
53+
with open(file_path,"r",encoding="utf8",errors='ignore') as f :
54+
file_content = f.read()
4955
# 获取到所有的字符串
5056
pattern = re.compile(r'\"(.*?)\"')
5157
results = pattern.findall(file_content)
5258

5359
# 遍历所有的字符串
5460
for result in set(results):
55-
self.__parse_string__(result,threadLock)
56-
57-
def __get_string__(self,dir_file_path,threadLock):
58-
temp = os.path.join(cores.output_path,"temp.txt")
59-
cmd_str = ("%s %s > %s") % (cores.strings_path,dir_file_path,temp)
60-
if os.system(cmd_str) == 0:
61-
with open(temp,"r") as f:
62-
lines = f.readlines()
63-
for line in lines:
64-
self.__parse_string__(line,threadLock)
65-
66-
def __parse_string__(self,result,threadLock):
61+
self.__parse_string__(result)
62+
63+
def __parse_string__(self,result):
6764
# 通过正则筛选需要过滤的字符串
6865
for filter_str in config.filter_strs:
6966
filter_str_pat = re.compile(filter_str)
7067
filter_resl = filter_str_pat.findall(result)
68+
# print(result,filter_resl)
7169
# 过滤掉未搜索到的内容
7270
if len(filter_resl)!=0:
7371
# 提取第一个结果
@@ -76,9 +74,9 @@ def __parse_string__(self,result,threadLock):
7674
if self.__filter__(resl_str) == 0:
7775
continue
7876

79-
threadLock.acquire()
80-
self.result_list.append(filter_resl[0])
81-
threadLock.release()
77+
self.threadLock.acquire()
78+
self.result_list.append(resl_str)
79+
self.threadLock.release()
8280
continue
8381

8482
def __filter__(self,resl_str):
@@ -105,5 +103,5 @@ def __filter__(self,resl_str):
105103
return return_flag
106104

107105
def run(self):
108-
threadLock = threading.Lock()
109-
self.__regular_parse__(threadLock)
106+
self.threadLock = threading.Lock()
107+
self.__regular_parse__()

0 commit comments

Comments
 (0)