-
Notifications
You must be signed in to change notification settings - Fork 14
Expand file tree
/
Copy pathhopper_static_audit.py
More file actions
127 lines (107 loc) · 2.75 KB
/
Copy pathhopper_static_audit.py
File metadata and controls
127 lines (107 loc) · 2.75 KB
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
#
# Hopper Python script for static triage of macOS apps.
# Run inside Hopper with the target Mach-O loaded.
#
TARGETS = [
"system",
"popen",
"execve",
"execl",
"execvp",
"NSTask",
"AuthorizationExecuteWithPrivileges",
"NSXPCConnection",
"xpc_connection_set_event_handler",
"xpc_connection_create_mach_service",
"listener:shouldAcceptNewConnection:",
"setExportedObject:",
"setExportedInterface:",
"strcpy",
"strcat",
"sprintf",
"vsprintf",
"memcpy",
"mktemp",
"tmpnam",
"sqlite3_exec",
"dlopen",
"dlsym",
"chmod",
"chown",
"open",
"unlink",
]
def iter_procedures(doc):
for seg in doc.getSegmentsList():
for proc in seg.getProceduresList():
yield proc
def emit(msg):
print(msg)
def safe_name(obj):
try:
return obj.getName()
except Exception:
return "<unnamed>"
def find_matching_procedures(doc, targets):
hits = []
lowered = [t.lower() for t in targets]
for proc in iter_procedures(doc):
name = safe_name(proc)
lname = name.lower()
if any(t in lname for t in lowered):
hits.append(proc)
return hits
def find_matching_strings(doc, targets):
hits = []
lowered = [t.lower() for t in targets]
for s in doc.getStrings():
try:
text = s.getString()
except Exception:
continue
ltext = text.lower()
if any(t in ltext for t in lowered):
hits.append(s)
return hits
def dump_xrefs(doc, addr):
try:
xrefs = doc.getXRefsToAddress(addr)
except Exception as exc:
emit(" [xref lookup failed: %s]" % exc)
return
seen = set()
for xref in xrefs:
try:
from_addr = xref.fromAddress()
except Exception:
continue
if from_addr in seen:
continue
seen.add(from_addr)
emit(" XREF from 0x%x" % from_addr)
def main():
doc = Document.getCurrentDocument()
if doc is None:
emit("No Hopper document is open.")
return
emit("== Matching Procedures ==")
procs = find_matching_procedures(doc, TARGETS)
if not procs:
emit(" No matching procedures found.")
for proc in procs:
addr = proc.getEntryPoint()
name = safe_name(proc)
emit("[PROC] 0x%x %s" % (addr, name))
dump_xrefs(doc, addr)
emit("")
emit("== Matching Strings ==")
strings = find_matching_strings(doc, TARGETS)
if not strings:
emit(" No matching strings found.")
for s in strings:
try:
emit("[STR] 0x%x %s" % (s.getAddress(), s.getString()))
except Exception:
pass
if __name__ == "__main__":
main()