-
Notifications
You must be signed in to change notification settings - Fork 3
/
andump.py
133 lines (115 loc) · 4.23 KB
/
andump.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
124
125
126
127
128
129
130
131
132
133
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import argparse
import os
import time
import subprocess
REMOTE_FOLDER = "/data/local/tmp"
DUMP_TOOL_PATH_REMOTE = REMOTE_FOLDER + "/dumpMem"
DUMP_FILE_REMOTE = REMOTE_FOLDER + "/dump_memory.raw"
DUMP_TOOL_PATH_LOCAL = os.path.join(os.getcwd(), "bin", "dumpMem")
DUMP_FILE_LOCAL = os.path.join(os.getcwd(), "dump_memory.raw")
class DumpMemory:
def __init__(self,
target_pid,
start_addr,
end_addr,
output_path=DUMP_FILE_LOCAL):
self.target_pid = target_pid
self.output_path = output_path
self.start_addr = start_addr
self.end_addr = end_addr
self.tml_file_dump_list = []
def dump(self):
try:
self.run_adb_cmd(["push", DUMP_TOOL_PATH_LOCAL, REMOTE_FOLDER])
self.run_adb_cmd(["shell", "chmod", "777", DUMP_TOOL_PATH_REMOTE])
self.run_adb_cmd(["shell", "rm", DUMP_FILE_REMOTE])
self.dump_utils()
self.merge_files()
except Exception, ex:
print ex
return False
return True
def dump_utils(self):
dump_size = int(self.end_addr, 16) - int(self.start_addr, 16)
chunk_size = 5 * 1024 * 1024
for i in xrange(0, dump_size / chunk_size):
start_addr = hex_str(int(self.start_addr, 16) + i * chunk_size)
end_addr = hex_str(int(start_addr, 16) + chunk_size)
self.to_dump(start_addr, end_addr, str(time.time()))
if dump_size % chunk_size != 0:
start_addr = hex_str(
int(self.end_addr, 16) - dump_size % chunk_size)
end_addr = self.end_addr
self.to_dump(start_addr, end_addr, str(time.time()))
def to_dump(self, start_addr, end_addr, tmp_file_name):
ret = self.run_adb_cmd([
"shell", DUMP_TOOL_PATH_REMOTE, self.target_pid, start_addr,
end_addr
])
if ret[0]:
raise Exception(ret[0])
self.run_adb_cmd(["pull", DUMP_FILE_REMOTE, tmp_file_name])
self.tml_file_dump_list.append(tmp_file_name)
def merge_files(self):
with open(self.output_path, "wb") as output_file:
for tmp_file_name in self.tml_file_dump_list:
if not os.path.exists(tmp_file_name):
continue
with open(tmp_file_name, "rb") as tmp_file:
output_file.write(tmp_file.read())
os.remove(tmp_file_name)
def run_adb_cmd(self, cmd):
try:
args = ["adb"]
args.extend(cmd)
process = subprocess.Popen(
args,
stdin=subprocess.PIPE,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE)
ret = process.communicate()
return ret
except Exception, ex:
print ret
raise Exception(ex)
def hex_str(int_num):
_hex = hex(int_num)
if _hex.endswith("L") or _hex.endswith("l"):
return _hex[0:-1]
return _hex
def main():
arg_parser = argparse.ArgumentParser(description="Dump Memory")
arg_parser.add_argument(
"-pid", dest="pid", required=True, type=int, help="The process pid")
arg_parser.add_argument(
"-saddr",
dest="start_addr",
required=True,
help="The start address in hexadecimal format")
arg_parser.add_argument(
"-eaddr",
dest="end_addr",
required=True,
help="The end address in hexadecimal format")
args = arg_parser.parse_args()
target_pid = args.pid
start_addr = args.start_addr
end_addr = args.end_addr
try:
if int(start_addr, 16) >= int(end_addr, 16):
print "Parameters error!\n End address must be larger than start address"
return
except Exception, ex:
print "Parameters error!\n Address must be in hexadecimal format.\n Please check again.\n\n"
arg_parser.print_help()
return
dump_memory = DumpMemory(str(target_pid), start_addr, end_addr)
print "Start dump memory..."
if dump_memory.dump():
print "Finished.\nSaved to " + dump_memory.output_path
else:
print "Dump failed!"
if __name__ == '__main__':
main()