forked from lapwat/nfcscreenoffpatcher
-
Notifications
You must be signed in to change notification settings - Fork 0
/
server.py
123 lines (111 loc) · 5.04 KB
/
server.py
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
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
import os
import shutil
import zipfile
import http.server as server
from datetime import datetime
from patcher import Patcher
from dotenv import dotenv_values
class HTTPRequestHandler(server.SimpleHTTPRequestHandler):
def do_GET(self):
if self.path == '/':
# for custom response during server check, comment each line below until "# above here"
self.path = '/data/index.html'
if not os.path.exists('data/index.html'):
os.makedirs(os.path.dirname('data/index.html'), exist_ok=True)
with open('data/index.html', 'a') as fd:
fd.write('<html><h1><center>NFC Screen Off Patcher</center></h1></html>')
elif self.path in ['/stats.csv', '/data.csv']:
self.path = '/data/stats.csv'
if self.path in ['/data/index.html', '/data/stats.csv']:
return server.SimpleHTTPRequestHandler.do_GET(self)
else:
self.send_response(404)
self.send_header('Content-type', 'text/html')
self.end_headers()
self.wfile.write(bytes('File Not Found', 'utf-8'))
# above here, and uncomment the 4 "self" lines below
# custom response example, use 800-899 for built-in client abort after message, or 700-799 to show message and continue patching
#self.send_response(826)
#self.send_header('Content-type', 'text/html')
#self.end_headers()
#self.wfile.write(bytes('Example custom message', 'utf-8'))
return
def do_PUT(self):
patcher = None
try:
# save archive
filename = os.path.basename(self.path)
file_length = int(self.headers['Content-Length'])
with open(filename, 'wb') as output_file:
output_file.write(self.rfile.read(file_length))
if filename == '.env':
# give .env to patcher.py
timestamp = int(datetime.now().timestamp())
extract_dir = f'data/{timestamp}'
os.makedirs(extract_dir, exist_ok=True)
shutil.move(filename, os.path.join(extract_dir, filename))
patcher = Patcher.factory(extract_dir)
patcher.log_stats('env-upload')
self.send_response(200)
self.send_header('Content-type', 'text/html')
self.end_headers()
self.wfile.write(bytes('.env received', 'utf-8'))
return
# unzip
timestamp = int(datetime.now().timestamp())
extract_dir = f'data/{timestamp}'
with zipfile.ZipFile(filename) as archive:
archive.extractall(extract_dir)
# disassemble
patcher = Patcher.factory(extract_dir)
patcher.disassemble()
# temporarily disable patching for known fail states
#if patcher.sdk >= '34':
# patcher.clean()
# patcher.log_stats('fail-SDK-34')
# self.send_response(535)
# self.send_header('Content-type', 'text/html')
# self.end_headers()
# self.wfile.write(bytes('Test', 'utf-8'))
# return
# check that apk has been successfully disassembled
if not patcher.is_successfully_disassembled():
patcher.clean()
patcher.log_stats('fail-disassemble')
self.send_error(545)
# Rename the failed patch zip file with the DATE_ID (both lines)
#failed_patch_filename = f'{patcher.date_id}.zip'
#os.rename(filename, failed_patch_filename)
return
# patch
patcher.patch_ScreenStateHelper()
patcher.patch_NfcService()
patcher.assemble()
# write aligned apk in response
with open(f'{extract_dir}/{patcher.apk_name}_align.apk', 'rb') as apk:
self.send_response(200)
self.send_header("Content-Type", 'application/vnd.android.package-archive')
fs = os.fstat(apk.fileno())
self.send_header("Content-Length", str(fs.st_size))
self.end_headers()
self.wfile.write(apk.read())
patcher.clean()
patcher.log_stats()
except Exception as error:
print(timestamp, error)
if patcher:
patcher.clean()
patcher.log_stats('exception')
self.send_response(555)
self.send_header('Content-type', 'text/html')
self.end_headers()
self.wfile.write(bytes('Exception', 'utf-8'))
# Rename the failed patch zip file with the DATE_ID (both lines)
#failed_patch_filename = f'{patcher.date_id}.zip'
#os.rename(filename, failed_patch_filename)
#finally:
# delete uploaded zip
# if filename and os.path.exists(filename):
# os.remove(filename)
if __name__ == '__main__':
server.test(HandlerClass=HTTPRequestHandler)