Skip to content

Commit c2b14cc

Browse files
committed
iOS私有api检查工具,目前已经完成了document api和framework header的相关内容
0 parents  commit c2b14cc

21 files changed

+842
-0
lines changed

Diff for: .gitignore

+65
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
# Created by https://www.gitignore.io/api/python
2+
3+
### Python ###
4+
# Byte-compiled / optimized / DLL files
5+
__pycache__/
6+
*.py[cod]
7+
*$py.class
8+
9+
# C extensions
10+
*.so
11+
12+
# Distribution / packaging
13+
.Python
14+
env/
15+
build/
16+
develop-eggs/
17+
dist/
18+
downloads/
19+
eggs/
20+
.eggs/
21+
lib/
22+
lib64/
23+
parts/
24+
sdist/
25+
var/
26+
*.egg-info/
27+
.installed.cfg
28+
*.egg
29+
30+
# PyInstaller
31+
# Usually these files are written by a python script from a template
32+
# before PyInstaller builds the exe, so as to inject date/other infos into it.
33+
*.manifest
34+
*.spec
35+
36+
# Installer logs
37+
pip-log.txt
38+
pip-delete-this-directory.txt
39+
40+
# Unit test / coverage reports
41+
htmlcov/
42+
.tox/
43+
.coverage
44+
.coverage.*
45+
.cache
46+
nosetests.xml
47+
coverage.xml
48+
*,cover
49+
50+
# Translations
51+
*.mo
52+
*.pot
53+
54+
# Django stuff:
55+
*.log
56+
57+
# Sphinx documentation
58+
docs/_build/
59+
60+
# PyBuilder
61+
target/
62+
63+
64+
# custom
65+
tmp/

Diff for: .project

+17
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<projectDescription>
3+
<name>iOS-private-api-checker</name>
4+
<comment></comment>
5+
<projects>
6+
</projects>
7+
<buildSpec>
8+
<buildCommand>
9+
<name>org.python.pydev.PyDevBuilder</name>
10+
<arguments>
11+
</arguments>
12+
</buildCommand>
13+
</buildSpec>
14+
<natures>
15+
<nature>org.python.pydev.pythonNature</nature>
16+
</natures>
17+
</projectDescription>

Diff for: .pydevproject

+9
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
2+
<?eclipse-pydev version="1.0"?><pydev_project>
3+
<pydev_pathproperty name="org.python.pydev.PROJECT_SOURCE_PATH">
4+
<path>/${PROJECT_DIR_NAME}</path>
5+
<path>/${PROJECT_DIR_NAME}/tmp</path>
6+
</pydev_pathproperty>
7+
<pydev_property name="org.python.pydev.PYTHON_PROJECT_VERSION">python 2.7</pydev_property>
8+
<pydev_property name="org.python.pydev.PYTHON_PROJECT_INTERPRETER">Default</pydev_property>
9+
</pydev_project>

Diff for: .settings/org.eclipse.core.resources.prefs

+11
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
eclipse.preferences.version=1
2+
encoding//api/api_utils.py=utf-8
3+
encoding//db/api_dbs.py=utf-8
4+
encoding//db/dsidx_dbs.py=utf-8
5+
encoding//db/mysql_utils.py=utf-8
6+
encoding//db/other_dbs.py=utf-8
7+
encoding//db/sqlite_utils.py=utf-8
8+
encoding//dump/class_dump_utils.py=utf-8
9+
encoding/batch.py=utf-8
10+
encoding/config.py=utf-8
11+
encoding/iOS_private.py=utf-8

Diff for: README.md

+10
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
## iOS私有API检查工具 ##
2+
3+
参考
4+
5+
- [RuntimeBrowser](https://github.com/nst/RuntimeBrowser/tree/master/tools/ios_headers_history)
6+
7+
- [iOS-private-api-scanner](https://github.com/mrmign/iOS-private-api-scanner)
8+
9+
1. `私有的api = (class-dump Framework下的库生成的头文件中的api - (Framework下的头文件里的api = 有文档的api + 没有文档的api)) + PrivateFramework下的api`
10+
2. 私有的api在公开的Framework及私有的PrivateFramework都有。

Diff for: api/__init__.py

Whitespace-only changes.

Diff for: api/api_utils.py

+92
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
1+
#coding=utf-8
2+
'''
3+
Created on 2015年10月27日
4+
Framework下的头文件里的api = 有文档的api + 没有文档的api
5+
@author: hzwangzhiwei
6+
'''
7+
from db import dsidx_dbs
8+
import os
9+
10+
def framework_dump_header_apis(sdk, framework_folder):
11+
'''
12+
class-dump Framework下的库生成的头文件中的api
13+
sdk: sdk version
14+
info: 用class-dump对所有的公开库(/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator7.0.sdk/System/Library/Frameworks)进行逆向工程得到所有的头文件内容。提取每个.h文件中的api得到api集合set_A。
15+
'''
16+
pass
17+
18+
def framework_header_apis(sdk, framework_folder):
19+
'''
20+
get all public frameworks' header files(documented)
21+
'''
22+
def iterate_dir(framework, prefix, path):
23+
files = []
24+
for f in os.listdir(path):
25+
if os.path.isfile(os.path.join(path, f)):
26+
files.append((framework, prefix + f, os.path.join(path, f)))
27+
elif os.path.isdir(os.path.join(path, f)):
28+
files += iterate_dir(framework, prefix + f + "/", os.path.join(path, f))
29+
return files
30+
all_headers = []
31+
32+
for framework in os.listdir(framework_folder):
33+
if framework.endswith(".framework"):
34+
header_path = framework_folder + framework +"/Headers/"
35+
if os.path.exists(header_path):
36+
#for header in os.listdir(header_path):
37+
# file_path = header_path + header
38+
# allpaths.append((framework, header, file_path))
39+
all_headers += iterate_dir(framework, "", os.path.join(framework_folder, header_path))
40+
41+
return all_headers
42+
43+
#没有文档的api
44+
def undocument_apis(sdk):
45+
'''
46+
info:不在文档中的api方法
47+
'''
48+
framework_header_apis(sdk) - document_apis(sdk)
49+
50+
#有文档的api
51+
def document_apis(sdk, db_path):
52+
'''
53+
has document apis
54+
info:获得带文档的api。(/Users/sngTest/Library/Developer/Shared/Documentation/DocSets/com.apple.adc.documentation.AppleiOS7.0.iOSLibrary.docset/Contents/Resources),在里面有个docSet.dsidx的文件,这就是Xcode针对api做的数据库,从这里可以获得带文档的api的各种信息了,从而有了带文档的api集合set_B。
55+
56+
'''
57+
doc_apis = []
58+
#从dsidx 数据库中获得初始数据
59+
apiset = dsidx_dbs.get_dsidx_apis(db_path)
60+
#过滤初始数据获得有文档的api集合
61+
for api in apiset:
62+
Z_PK = api['Z_PK']
63+
ZDECLAREDIN = api['ZDECLAREDIN']
64+
# get containername from ZCONTAINER table
65+
container_name = ''
66+
if Z_PK:
67+
container_name = dsidx_dbs.get_container_name(Z_PK, db_path) or ''
68+
# get frameworkname and headerpath from ZHEADER table
69+
70+
framework_name = ''
71+
header_path = ''
72+
if ZDECLAREDIN:
73+
frame_header = dsidx_dbs.get_framework_and_header(ZDECLAREDIN, db_path)
74+
if frame_header:
75+
framework_name = frame_header.get('ZFRAMEWORKNAME', '')
76+
header_path = frame_header.get('ZHEADERPATH', '')
77+
78+
doc_apis.append({'api_name': api['ZTOKENNAME'], 'class_name': container_name, 'type': api['ZTOKENTYPE'], 'header_file': header_path, 'framework': framework_name, 'sdk': sdk})
79+
return doc_apis
80+
81+
def private_framework_apis(sdk):
82+
'''
83+
PrivateFramework下的api
84+
'''
85+
pass
86+
87+
def all_private_apis(sdk):
88+
pub_private_apis = framework_dump_header_apis(sdk) - document_apis(sdk) - undocument_apis(sdk)
89+
90+
pri_private_apis = private_framework_apis(sdk)
91+
92+
return pub_private_apis + pri_private_apis

Diff for: batch.py

+26
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
#coding=utf-8
2+
'''
3+
Created on 2015年10月27日
4+
一些预处理脚本
5+
@author: hzwangzhiwei
6+
'''
7+
from db import api_dbs
8+
from api import api_utils
9+
10+
#重建document api数据库
11+
def rebuild_document_api(sdk, docset):
12+
#先删除对应的sdk document api数据
13+
api_dbs.delete_document_by_sdk(sdk)
14+
15+
document_apis = api_utils.document_apis(sdk, docset)
16+
for api in document_apis:
17+
print api
18+
19+
return api_dbs.insert_document_dbs(document_apis)
20+
21+
22+
if __name__ == '__main__':
23+
#重建sdk=7.0的有文档api
24+
print rebuild_document_api('7.0', 'docSet.dsidx')
25+
26+

Diff for: config.py

+19
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
#coding=utf-8
2+
'''
3+
Created on 2015年10月27日
4+
5+
@author: hzwangzhiwei
6+
'''
7+
8+
mysql_info = {
9+
'HOST': '127.0.0.1',
10+
'PORT': 3306,
11+
'USERNAME': 'root',
12+
'PASSWORD': 'root',
13+
'CHARTSET': 'UTF8',
14+
'DB': 'ios_private',
15+
}
16+
17+
sqlite_info = {
18+
'DB': 'ios_private.db',
19+
}

Diff for: db/__init__.py

Whitespace-only changes.

Diff for: db/api_dbs.py

+19
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
#coding=utf-8
2+
'''
3+
Created on 2015年10月27日
4+
5+
@author: hzwangzhiwei
6+
'''
7+
from db.sqlite_utils import SqliteHandler
8+
9+
#批量插入有文档的api
10+
def insert_document_dbs(datas):
11+
sql = "insert into document_apis(api_name, class_name, type, header_file, sdk, framework) values(:api_name, :class_name, :type, :header_file, :sdk, :framework)"
12+
return SqliteHandler().exec_insert_many(sql, datas)
13+
14+
15+
def delete_document_by_sdk(sdk):
16+
sql = "delete from document_apis where sdk = ?;"
17+
return SqliteHandler().exec_update(sql, (sdk, ))
18+
19+

Diff for: db/dsidx_dbs.py

+30
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
#coding=utf-8
2+
'''
3+
Created on 2015年10月27日
4+
.dsidx 文件解读
5+
@author: hzwangzhiwei
6+
'''
7+
from db.sqlite_utils import SqliteHandler
8+
def get_dsidx_apis(db_path):
9+
'''
10+
has document apis
11+
info:获得带文档的api。(/Users/sngTest/Library/Developer/Shared/Documentation/DocSets/com.apple.adc.documentation.AppleiOS7.0.iOSLibrary.docset/Contents/Resources),在里面有个docSet.dsidx的文件,这就是Xcode针对api做的数据库,从这里可以获得带文档的api的各种信息了,从而有了带文档的api集合set_B。
12+
13+
'''
14+
sql = "SELECT T.Z_PK, T.ZTOKENNAME, T.ZTOKENTYPE, T.ZCONTAINER, M.ZDECLAREDIN FROM ZTOKEN AS T, ZTOKENMETAINFORMATION AS M WHERE ZTOKENTYPE IN (3,9,12,13,16) AND T.Z_PK = M.ZTOKEN"
15+
apiset = SqliteHandler(db = db_path).exec_select(sql)
16+
return apiset
17+
18+
19+
def get_container_name(Z_PK, db_path):
20+
sql = "SELECT ZCONTAINERNAME FROM ZCONTAINER WHERE Z_PK = ?;"
21+
container = SqliteHandler(db = db_path).exec_select_one(sql, (Z_PK, ))
22+
if container:
23+
return container['ZCONTAINERNAME']
24+
return None
25+
26+
27+
def get_framework_and_header(Z_PK, db_path):
28+
sql = "SELECT ZFRAMEWORKNAME, ZHEADERPATH FROM ZHEADER WHERE Z_PK = ?;"
29+
rst = SqliteHandler(db = db_path).exec_select_one(sql, (Z_PK, ))
30+
return rst

Diff for: db/mysql_utils.py

+6
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
#coding=utf-8
2+
'''
3+
Created on 2015年10月27日
4+
5+
@author: hzwangzhiwei
6+
'''

Diff for: db/other_dbs.py

+58
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
#coding=utf-8
2+
'''
3+
Created on 2015年10月27日
4+
5+
@author: hzwangzhiwei
6+
'''
7+
from db.sqlite_utils import SqliteHandler
8+
def create_some_table():
9+
#创建framework_header_apis
10+
sql1 = ("create table framework_dump_header_apis("
11+
"api_name varchar,"
12+
"class_name varchar,"
13+
"type varchar,"
14+
"header_file varchar,"
15+
"sdk varchar,"
16+
"framework varchar)")
17+
18+
19+
sql2 = ("create table framework_header_apis("
20+
"api_name varchar,"
21+
"class_name varchar,"
22+
"type varchar,"
23+
"header_file varchar,"
24+
"sdk varchar,"
25+
"framework varchar)")
26+
27+
28+
sql3 = ("create table document_apis("
29+
"api_name varchar,"
30+
"class_name varchar,"
31+
"type varchar,"
32+
"header_file varchar,"
33+
"sdk varchar,"
34+
"framework varchar)")
35+
36+
37+
sql4 = ("create table undocument_apis("
38+
"api_name varchar,"
39+
"class_name varchar,"
40+
"type varchar,"
41+
"header_file varchar,"
42+
"sdk varchar,"
43+
"framework varchar)")
44+
45+
46+
sql5 = ("create table private_apis("
47+
"api_name varchar,"
48+
"class_name varchar,"
49+
"type varchar,"
50+
"header_file varchar,"
51+
"sdk varchar,"
52+
"framework varchar)")
53+
54+
SqliteHandler().exec_sql(sql1, ())
55+
SqliteHandler().exec_sql(sql2, ())
56+
SqliteHandler().exec_sql(sql3, ())
57+
SqliteHandler().exec_sql(sql4, ())
58+
SqliteHandler().exec_sql(sql5, ())

0 commit comments

Comments
 (0)