forked from mandiant/macOS-tools
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathnib_parse.py
99 lines (83 loc) · 2.82 KB
/
nib_parse.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
##########################################
##Author: James T. Bennett
##NIB file parser
##########################################
########################################################################
# Copyright 2017 FireEye
#
# FireEye licenses this file to you under the Apache License, Version
# 2.0 (the "License"); you may not use this file except in compliance with the
# License. You may obtain a copy of the License at:
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
# implied. See the License for the specific language governing
# permissions and limitations under the License.
########################################################################
import ccl_bplist
import argparse
def getClassName(o):
if 'NSClassName' in o:
cn = o['NSClassName']
if '$class' in cn:
return cn['NS.string']
else:
cn = o['$class']['$classes'][0]
if '$class' in cn:
return cn['NS.string']
return cn
def getContents(o):
if 'NSCell' in o and 'NSContents' in o['NSCell']:
if 'NS.string' in o['NSCell']['NSContents']:
return o['NSCell']['NSContents']['NS.string']
elif 'NSClassName' in o['NSCell']['NSContents']:
return o['NSCell']['NSContents']['NSClassName']
else:
return o['NSCell']['NSContents']
if 'NSTitle' in o:
if 'NS.string' in o['NSTitle']:
return o['NSTitle']['NS.string']
else:
return o['NSTitle']
else:
return None
def main():
parser=argparse.ArgumentParser(description="NeXTSTEP Interface Builder (NIB) file parser prints a list of all connections defined in a NIB file")
parser.add_argument('nibfile', help='path to a NIB file')
args = parser.parse_args()
with open(args.nibfile, "rb") as rp:
plist = ccl_bplist.load(rp)
nib = ccl_bplist.deserialise_NsKeyedArchiver(plist)
ibcons = nib['IB.objectdata']['NSConnections']['NS.objects']
for i in range(len(ibcons)):
if 'NSLabel' not in ibcons[i]:
continue
lbl = ibcons[i]['NSLabel']
id = dict(nib['IB.objectdata']['NSConnections'])['NS.objects'][i].value
sname = "NA"
srcid = "NA"
dname = "NA"
dstid = "NA"
if 'NSSource' in ibcons[i]:
srcid = dict(ibcons[i])['NSSource'].value
src = ibcons[i]['NSSource']
sname = getClassName(src)
scontents = getContents(src)
if 'NSDestination' in ibcons[i]:
dstid = dict(ibcons[i])['NSDestination'].value
dst = ibcons[i]['NSDestination']
dname = getClassName(dst)
dcontents = getContents(dst)
out = "%d: %s (%s) - %s " % (i, lbl, id, sname)
if scontents:
out += "[%s] " % scontents
out += "(%s) ---> %s " % (srcid, dname)
if dcontents:
out += "[%s] " % dcontents
out += "(%s)" % dstid
print(out.encode("utf-8"))
if __name__ == '__main__':
main()