├── .github
├── banner.png
└── hero.png
├── .gitignore
├── .gitmodules
├── LICENSE
├── MachOExplorer-Bridging-Header.h
├── MachOExplorer.xcodeproj
└── project.pbxproj
├── MachOExplorer
├── AppDelegate.swift
├── Details
│ ├── MachODetailViewController.swift
│ ├── MachODetailsViewController.swift
│ ├── MachODetailsViewController.xib
│ ├── MachOHexDetailViewController.swift
│ └── MachOHexDetailViewController.xib
├── MachODocument.swift
├── MachODocumentDetailsViewController.swift
├── MachODocumentOutlineViewController.swift
├── MachODocumentOutlineViewController.xib
├── MachODocumentWindowContentViewController.swift
├── MachODocumentWindowController.swift
├── MachoDocumentWindow.xib
├── Model
│ ├── DataModel.swift
│ ├── DetailModel.swift
│ ├── Field
│ │ ├── FieldAdapter.swift
│ │ └── SubFieldAdapter.swift
│ ├── MKAddressedNode+Detail.swift
│ ├── MKBackedNode+Data.swift
│ ├── MKBackedNode+Detail.swift
│ ├── MKNode+Adapter.swift
│ ├── MKNode+Detail.swift
│ ├── MKNode+Outline.swift
│ ├── Model.swift
│ ├── OutlineModel.swift
│ ├── Overrides
│ │ ├── FAT
│ │ │ └── MKFatArch+Model.swift
│ │ ├── MachO
│ │ │ ├── MKExport+Model.swift
│ │ │ ├── MKExportTrieBranch+Model.swift
│ │ │ ├── MKFixup+Model.swift
│ │ │ ├── MKFunctionStarts+Model.swift
│ │ │ ├── MKPointerNode+Model.swift
│ │ │ └── MKSection+Model.swift
│ │ └── ObjC
│ │ │ ├── MKObjCCategory+Model.swift
│ │ │ ├── MKObjCClass+Model.swift
│ │ │ └── MKObjCProtocol+Model.swift
│ ├── Type
│ │ ├── BitFieldTypeAdapter.swift
│ │ ├── CollectionTypeAdapter.swift
│ │ ├── ContainerTypeAdapter.swift
│ │ ├── OptionSetTypeAdapter.swift
│ │ └── TypeAdapter.swift
│ └── Value
│ │ ├── MKOptional+Model.swift
│ │ ├── NSArray+Model.swift
│ │ ├── NSDictionary+Model.swift
│ │ └── NSObject+Model.swift
└── Utility
│ ├── NS+Initialize.h
│ ├── NS+Initialize.m
│ ├── NSValueTransformer+HexRepresentation.swift
│ ├── NSValueTransformer+TakeFirst.swift
│ ├── Utility.h
│ └── Utility.m
├── ReadMe.md
└── Resources
├── Assets.xcassets
└── AppIcon.appiconset
│ ├── AppIcon_512.png
│ ├── AppIcon_512@2x.png
│ └── Contents.json
├── MachOExplorer-Info.plist
└── MainMenu.xib
/.github/banner.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/DeVaukz/MachO-Explorer/e82b6e6136f4312422c276762e837fe853030547/.github/banner.png
--------------------------------------------------------------------------------
/.github/hero.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/DeVaukz/MachO-Explorer/e82b6e6136f4312422c276762e837fe853030547/.github/hero.png
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # OS generated files #
2 | ######################
3 | .DS_Store
4 | .DS_Store?
5 | ._*
6 | .Spotlight-V100
7 | .Trashes
8 | Icon?
9 | ehthumbs.db
10 | Thumbs.db
11 |
12 | # User specific Xcode files #
13 | #############################
14 | *.xcworkspace
15 | *.xcuserdatad
16 |
17 | # Documentation #
18 | #################
19 | html
20 |
21 |
--------------------------------------------------------------------------------
/.gitmodules:
--------------------------------------------------------------------------------
1 | [submodule "Configuration"]
2 | path = Configuration
3 | url = https://github.com/DeVaukz/xcconfigs.git
4 | [submodule "External/MachO-Kit"]
5 | path = External/MachO-Kit
6 | url = https://github.com/DeVaukz/MachO-Kit.git
7 | [submodule "External/WAYWindow"]
8 | path = External/WAYWindow
9 | url = https://github.com/weAreYeah/WAYWindow.git
10 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | The MIT License (MIT)
2 |
3 | Copyright (c) 2018 Devin Vaukz
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
--------------------------------------------------------------------------------
/MachOExplorer-Bridging-Header.h:
--------------------------------------------------------------------------------
1 | //
2 | // Use this file to import your target's public headers that you would like to expose to Swift.
3 | //
4 |
5 | #import "Utility.h"
6 | #import "NS+Initialize.h"
7 |
8 | #import "WAYWindow.h"
9 |
--------------------------------------------------------------------------------
/MachOExplorer/AppDelegate.swift:
--------------------------------------------------------------------------------
1 | //----------------------------------------------------------------------------//
2 | //|
3 | //| MachOExplorer - A Graphical Mach-O Viewer
4 | //! @file AppDelegate.swift
5 | //!
6 | //! @author D.V.
7 | //! @copyright Copyright (c) 2018 D.V. All rights reserved.
8 | //|
9 | //| Permission is hereby granted, free of charge, to any person obtaining a
10 | //| copy of this software and associated documentation files (the "Software"),
11 | //| to deal in the Software without restriction, including without limitation
12 | //| the rights to use, copy, modify, merge, publish, distribute, sublicense,
13 | //| and/or sell copies of the Software, and to permit persons to whom the
14 | //| Software is furnished to do so, subject to the following conditions:
15 | //|
16 | //| The above copyright notice and this permission notice shall be included
17 | //| in all copies or substantial portions of the Software.
18 | //|
19 | //| THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
20 | //| OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
21 | //| MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
22 | //| IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
23 | //| CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
24 | //| TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
25 | //| SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
26 | //----------------------------------------------------------------------------//
27 |
28 | import Cocoa
29 |
30 | @NSApplicationMain
31 | class AppDelegate: NSObject, NSApplicationDelegate
32 | {
33 |
34 | }
35 |
--------------------------------------------------------------------------------
/MachOExplorer/Details/MachODetailViewController.swift:
--------------------------------------------------------------------------------
1 | //----------------------------------------------------------------------------//
2 | //|
3 | //| MachOExplorer - A Graphical Mach-O Viewer
4 | //! @file MachODetailViewController.swift
5 | //!
6 | //! @author D.V.
7 | //! @copyright Copyright (c) 2018 D.V. All rights reserved.
8 | //|
9 | //| Permission is hereby granted, free of charge, to any person obtaining a
10 | //| copy of this software and associated documentation files (the "Software"),
11 | //| to deal in the Software without restriction, including without limitation
12 | //| the rights to use, copy, modify, merge, publish, distribute, sublicense,
13 | //| and/or sell copies of the Software, and to permit persons to whom the
14 | //| Software is furnished to do so, subject to the following conditions:
15 | //|
16 | //| The above copyright notice and this permission notice shall be included
17 | //| in all copies or substantial portions of the Software.
18 | //|
19 | //| THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
20 | //| OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
21 | //| MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
22 | //| IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
23 | //| CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
24 | //| TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
25 | //| SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
26 | //----------------------------------------------------------------------------//
27 |
28 | import Cocoa
29 | import MachOKit
30 |
31 | class MachODetailViewController: NSViewController
32 | {
33 | @objc dynamic var wantsDisplay: Bool = false
34 | lazy var tabViewItem: NSTabViewItem = NSTabViewItem(viewController: self)
35 |
36 | // Model //
37 | @objc var model: Model? = nil
38 | fileprivate var modelBinding: ModelBinding?
39 |
40 | // UI //
41 | @objc var addressMode: MKNodeAddressType = .contextAddress
42 | fileprivate var addressModeBinding: AddressModeBinding?
43 |
44 | override var representedObject: Any? {
45 | willSet {
46 | self.unbind(MachODetailViewController.ModelBinding.Name)
47 | self.unbind(MachODetailViewController.AddressModeBinding.Name)
48 | }
49 | didSet {
50 | guard let representedObject = self.representedObject else { return }
51 | self.bind(MachODetailViewController.ModelBinding.Name, to: representedObject, withKeyPath: "selection", options: nil)
52 | self.bind(MachODetailViewController.AddressModeBinding.Name, to: representedObject, withKeyPath: "addressMode", options: nil)
53 | }
54 | }
55 |
56 | required init?(coder: NSCoder) {
57 | super.init(coder: coder)
58 |
59 | self.commonInit()
60 | }
61 |
62 | override init(nibName nibNameOrNil: NSNib.Name?, bundle nibBundleOrNil: Bundle?) {
63 | super.init(nibName: nibNameOrNil, bundle: nibBundleOrNil)
64 |
65 | self.commonInit()
66 | }
67 |
68 | func commonInit() {
69 | return
70 | }
71 |
72 | deinit {
73 | self.unbind(ModelBinding.Name)
74 | self.unbind(AddressModeBinding.Name)
75 | }
76 | }
77 |
78 |
79 | extension MachODetailViewController
80 | {
81 | @objc var tabViewToolTip: String { return NSStringFromClass(type(of: self)) }
82 |
83 | @objc func willAppear() {
84 | return
85 | }
86 |
87 | @objc func willDisappear() {
88 | return
89 | }
90 | }
91 |
92 |
93 | extension MachODetailViewController /* NSKeyValueBindingCreation */
94 | {
95 | struct ModelBinding {
96 | static let Name = NSBindingName("model")
97 | let observedObject: NSObject
98 | let observedKeyPath: String
99 | }
100 |
101 | struct AddressModeBinding {
102 | static let Name = NSBindingName("addressMode")
103 | let observedObject: NSObject
104 | let observedKeyPath: String
105 | }
106 |
107 | override static func heySwiftSomePeopleStillNeedToOverrideInitialize() /* +initialize */ {
108 | exposeBinding(ModelBinding.Name)
109 | exposeBinding(AddressModeBinding.Name)
110 | }
111 |
112 | override func bind(_ binding: NSBindingName, to observable: Any, withKeyPath keyPath: String, options: [NSBindingOption : Any]? = nil) {
113 | if binding == ModelBinding.Name {
114 | guard let observable = observable as? NSObject else { return }
115 | self.unbind(binding)
116 | self.modelBinding = ModelBinding(observedObject: observable, observedKeyPath: keyPath)
117 | observable.addObserver(self, forKeyPath: keyPath, options: .initial, context: nil)
118 |
119 | } else if binding == AddressModeBinding.Name {
120 | guard let observable = observable as? NSObject else { return }
121 | self.unbind(binding)
122 | self.addressModeBinding = AddressModeBinding(observedObject: observable, observedKeyPath: keyPath)
123 | observable.addObserver(self, forKeyPath: keyPath, options: .initial, context: nil)
124 |
125 | } else {
126 | super.bind(binding, to: observable, withKeyPath: keyPath, options: options)
127 | }
128 | }
129 |
130 | override func unbind(_ binding: NSBindingName) {
131 | if binding == ModelBinding.Name {
132 | guard let binding = self.modelBinding else { return }
133 | binding.observedObject.removeObserver(self, forKeyPath: binding.observedKeyPath, context: nil)
134 | self.modelBinding = nil
135 | self.model = nil
136 |
137 | } else if binding == AddressModeBinding.Name {
138 | guard let binding = self.addressModeBinding else { return }
139 | binding.observedObject.removeObserver(self, forKeyPath: binding.observedKeyPath, context: nil)
140 | self.addressModeBinding = nil
141 | self.addressMode = .contextAddress
142 |
143 | } else {
144 | super.unbind(binding)
145 | }
146 | }
147 |
148 | override func observeValue(forKeyPath keyPath: String?, of object: Any?, change: [NSKeyValueChangeKey : Any]?, context: UnsafeMutableRawPointer?) {
149 | if let object = object as? NSObject {
150 |
151 | if let binding = self.modelBinding, binding.observedObject == object && binding.observedKeyPath == keyPath {
152 | self.model = object.value(forKeyPath: binding.observedKeyPath) as! Model?
153 | return
154 |
155 | } else if let binding = self.addressModeBinding, binding.observedObject == object && binding.observedKeyPath == keyPath {
156 | self.addressMode = MKNodeAddressType(rawValue: (object.value(forKeyPath: binding.observedKeyPath) as! NSNumber).uintValue)!
157 | return
158 | }
159 |
160 | }
161 |
162 | super.observeValue(forKeyPath: keyPath, of: object, change: change, context: context)
163 | }
164 | }
165 |
--------------------------------------------------------------------------------
/MachOExplorer/Details/MachODetailsViewController.swift:
--------------------------------------------------------------------------------
1 | //----------------------------------------------------------------------------//
2 | //|
3 | //| MachOExplorer - A Graphical Mach-O Viewer
4 | //! @file MachODetailsViewController.swift
5 | //!
6 | //! @author D.V.
7 | //! @copyright Copyright (c) 2018 D.V. All rights reserved.
8 | //|
9 | //| Permission is hereby granted, free of charge, to any person obtaining a
10 | //| copy of this software and associated documentation files (the "Software"),
11 | //| to deal in the Software without restriction, including without limitation
12 | //| the rights to use, copy, modify, merge, publish, distribute, sublicense,
13 | //| and/or sell copies of the Software, and to permit persons to whom the
14 | //| Software is furnished to do so, subject to the following conditions:
15 | //|
16 | //| The above copyright notice and this permission notice shall be included
17 | //| in all copies or substantial portions of the Software.
18 | //|
19 | //| THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
20 | //| OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
21 | //| MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
22 | //| IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
23 | //| CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
24 | //| TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
25 | //| SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
26 | //----------------------------------------------------------------------------//
27 |
28 | import Cocoa
29 | import MachOKit
30 |
31 | class MachODetailsViewController: MachODetailViewController
32 | {
33 | @IBOutlet weak var tableView: NSTableView!
34 | @IBOutlet weak var addressColumn: NSTableColumn!
35 | @IBOutlet weak var dataColumn: NSTableColumn!
36 | @IBOutlet weak var descriptionColumn: NSTableColumn!
37 | @IBOutlet weak var valueColumn: NSTableColumn!
38 |
39 | override func commonInit() {
40 | self.title = "Details"
41 | }
42 |
43 | @IBOutlet var controller: NSArrayController!
44 |
45 | @objc dynamic var rowData: [Row] = []
46 |
47 | override var model: Model? {
48 | didSet {
49 | guard self.model?.isEqual(oldValue) == false else { return }
50 |
51 | if let model = self.model as? DetailModel {
52 | self.rowData = MachODetailsViewController.makeRowData(for: model) ?? []
53 | } else {
54 | self.rowData = []
55 | }
56 |
57 | update()
58 | }
59 | }
60 |
61 | override var addressMode: MKNodeAddressType {
62 | didSet {
63 | update()
64 | }
65 | }
66 |
67 | func update() {
68 | self.tableView?.deselectAll(self)
69 |
70 | if self.rowData.count > 0 {
71 | self.wantsDisplay = true
72 | } else {
73 | self.wantsDisplay = false
74 | }
75 |
76 | let formatter = MKHexNumberFormatter(digits: 8)
77 | formatter.uppercase = true
78 | formatter.omitPrefix = true
79 |
80 | for row in rowData {
81 | switch self.addressMode {
82 | case .contextAddress:
83 | row.address = formatter.string(for: row.rawAddress != nil ? row.rawAddress! as NSNumber : nil)
84 | case .vmAddress:
85 | row.address = formatter.string(for: row.rvaAddress != nil ? row.rvaAddress! as NSNumber : nil)
86 | }
87 | }
88 | }
89 | }
90 |
91 |
92 | extension MachODetailsViewController
93 | {
94 | @objc(MachODetailsViewControllerRow)
95 | final class Row: NSObject {
96 | var rawAddress: mk_vm_address_t?
97 | var rvaAddress: mk_vm_address_t?
98 |
99 | @objc dynamic var address: String?
100 | @objc var data: String?
101 | @objc var name: String?
102 | @objc var value: String?
103 |
104 | var underline: Bool = false
105 |
106 | override var description: String {
107 | return self.name ?? ""
108 | }
109 | }
110 |
111 | static func makeRowData(for model: DetailModel) -> [Row]? {
112 | var previous: (UInt, Row)?
113 |
114 | return autoreleasepool {
115 | return model.detail_rows.map({ detailNode -> MachODetailsViewController.Row in
116 | let row = MachODetailsViewController.Row()
117 |
118 | if let contextAddress = detailNode.detail_address(mode: .contextAddress) {
119 | row.rawAddress = contextAddress as! mk_vm_address_t
120 | }
121 | if let vmAddress = detailNode.detail_address(mode: .vmAddress) {
122 | row.rvaAddress = vmAddress as! mk_vm_address_t
123 | }
124 |
125 | if var data = detailNode.detail_data {
126 | let transformer = HexRepresentationValueTransformer()
127 |
128 | // Cap the number of bytes we will format
129 | if data.count > 50 {
130 | data = data.subdata(in: 0..<50)
131 | }
132 |
133 | row.data = transformer.transformedValue(data) as? String;
134 | }
135 |
136 | row.name = detailNode.detail_description
137 | row.value = detailNode.detail_value
138 |
139 | let groupIdentifier: UInt
140 | if let detailNode = detailNode as? DetailRowDisplayModel {
141 | groupIdentifier = detailNode.detail_group_identifier
142 | } else {
143 | groupIdentifier = 0
144 | }
145 |
146 | if let (p, _) = previous, p != groupIdentifier {
147 | row.underline = true
148 | }
149 | previous = (groupIdentifier, row)
150 |
151 | return row
152 | })
153 | }
154 | }
155 | }
156 |
157 |
158 | extension MachODetailsViewController: NSTableViewDelegate
159 | {
160 | class TableRow: NSTableRowView
161 | {
162 | var border: Bool = false
163 |
164 | override func drawBackground(in dirtyRect: NSRect) {
165 | super.drawBackground(in: dirtyRect)
166 |
167 | if self.border {
168 | if let tableView = self.superview as? NSTableView {
169 | tableView.gridColor.set()
170 | } else {
171 | NSColor.separatorColor.set()
172 | }
173 |
174 | // Hack - tableView.gridColor does not look correct in dark mode
175 | if (self.effectiveAppearance.name == NSAppearance.Name.darkAqua) {
176 | NSColor.lightGray.set()
177 | }
178 |
179 | NSBezierPath.strokeLine(
180 | from: NSPoint(x: self.bounds.origin.x, y: self.bounds.origin.y),
181 | to: NSPoint(x: self.bounds.origin.x + self.bounds.size.width, y: self.bounds.origin.y)
182 | )
183 | }
184 | }
185 | }
186 |
187 | func tableView(_ tableView: NSTableView, rowViewForRow row: Int) -> NSTableRowView? {
188 | let rowView = TableRow()
189 |
190 | if self.rowData[row].underline {
191 | rowView.border = true
192 | }
193 |
194 | return rowView
195 | }
196 | }
197 |
--------------------------------------------------------------------------------
/MachOExplorer/Details/MachODetailsViewController.xib:
--------------------------------------------------------------------------------
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 |
134 |
135 |
136 |
137 |
138 |
139 |
140 |
141 |
142 |
143 |
144 |
145 |
146 |
147 |
148 |
149 |
150 |
151 |
152 |
153 |
154 |
155 |
156 |
157 |
158 |
159 |
160 |
161 |
162 |
163 |
164 |
165 |
166 |
167 |
168 |
169 |
170 |
171 |
172 |
173 |
174 |
175 |
176 |
177 |
178 |
179 |
180 |
181 |
182 |
183 |
184 |
185 |
186 |
187 |
188 |
189 |
190 |
191 |
192 |
193 |
194 |
195 |
196 |
197 |
198 |
199 |
200 |
201 |
202 |
203 |
204 |
205 |
206 |
207 |
208 |
209 |
210 |
211 |
212 |
213 |
214 |
215 |
216 |
217 |
218 |
219 |
220 |
221 |
222 |
223 |
224 |
225 |
226 |
227 |
228 |
229 |
230 |
231 |
232 |
233 |
234 |
235 |
--------------------------------------------------------------------------------
/MachOExplorer/Details/MachOHexDetailViewController.swift:
--------------------------------------------------------------------------------
1 | //----------------------------------------------------------------------------//
2 | //|
3 | //| MachOExplorer - A Graphical Mach-O Viewer
4 | //! @file MachOHexDetailViewController.swift
5 | //!
6 | //! @author D.V.
7 | //! @copyright Copyright (c) 2018 D.V. All rights reserved.
8 | //|
9 | //| Permission is hereby granted, free of charge, to any person obtaining a
10 | //| copy of this software and associated documentation files (the "Software"),
11 | //| to deal in the Software without restriction, including without limitation
12 | //| the rights to use, copy, modify, merge, publish, distribute, sublicense,
13 | //| and/or sell copies of the Software, and to permit persons to whom the
14 | //| Software is furnished to do so, subject to the following conditions:
15 | //|
16 | //| The above copyright notice and this permission notice shall be included
17 | //| in all copies or substantial portions of the Software.
18 | //|
19 | //| THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
20 | //| OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
21 | //| MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
22 | //| IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
23 | //| CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
24 | //| TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
25 | //| SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
26 | //----------------------------------------------------------------------------//
27 |
28 | import Cocoa
29 | import MachOKit
30 |
31 | class MachOHexDetailViewController: MachODetailViewController
32 | {
33 | @IBOutlet weak var tableView: NSTableView!
34 | @IBOutlet weak var addressColumn: NSTableColumn!
35 | @IBOutlet weak var dataLoColumn: NSTableColumn!
36 | @IBOutlet weak var dataHiColumn: NSTableColumn!
37 | @IBOutlet weak var valueColumn: NSTableColumn!
38 |
39 | override func commonInit() {
40 | self.title = "Data"
41 | }
42 |
43 | var nodeAddress: mk_vm_address_t?
44 | var nodeData: Data?
45 |
46 | override var addressMode: MKNodeAddressType {
47 | didSet {
48 | if let model = self.model as? DataModel {
49 | self.nodeAddress = model.address(mode: self.addressMode) as! mk_vm_address_t?
50 | }
51 |
52 | update()
53 | }
54 | }
55 |
56 | override var model: Model? {
57 | didSet {
58 | guard self.model?.isEqual(oldValue) == false else { return }
59 |
60 | if let model = self.model as? DataModel {
61 | self.nodeAddress = model.address(mode: self.addressMode) as! mk_vm_address_t?
62 | self.nodeData = model.data
63 | } else {
64 | self.nodeAddress = nil
65 | self.nodeData = nil
66 | }
67 |
68 | update()
69 | }
70 | }
71 |
72 | func update() {
73 | if let tableView = self.tableView {
74 | tableView.reloadData()
75 | }
76 |
77 | if self.nodeData != nil {
78 | self.wantsDisplay = true
79 | } else {
80 | self.wantsDisplay = false
81 | }
82 | }
83 | }
84 |
85 |
86 | extension MachOHexDetailViewController: NSTableViewDataSource
87 | {
88 | func numberOfRows(in tableView: NSTableView) -> Int {
89 | guard let nodeData = self.nodeData else { return 0 }
90 |
91 | var numRows = nodeData.count / 16
92 | if nodeData.count % 16 != 0 {
93 | numRows += 1
94 | }
95 |
96 | return numRows
97 | }
98 |
99 | func tableView(_ tableView: NSTableView, objectValueFor tableColumn: NSTableColumn?, row: Int) -> Any? {
100 | guard let nodeData = self.nodeData else { return nil }
101 |
102 | let offset = row * 16
103 |
104 | if tableColumn == self.addressColumn, let baseAddress = self.nodeAddress {
105 | let address = Int(baseAddress) + offset
106 |
107 | return NSString(format: "%.8lX", address)
108 | }
109 |
110 | let len = min(nodeData.count - offset, 16)
111 | let start = offset
112 | let end = start + len
113 |
114 | var buffer = Array(repeating: 0, count: 16)
115 | nodeData.copyBytes(to: &buffer, from: start.. UInt8 in
125 | if byte < 32 || byte > 126 {
126 | return 46 // '.'
127 | } else {
128 | return byte;
129 | }
130 | })
131 |
132 | return NSString(bytes: &buffer, length: buffer.count, encoding: String.Encoding.ascii.rawValue)
133 | }
134 |
135 | return nil
136 | }
137 | }
138 |
139 |
140 | extension MachOHexDetailViewController: NSTableViewDelegate
141 | {
142 | class TableRow: NSTableRowView
143 | {
144 | override func drawSelection(in dirtyRect: NSRect) {
145 | super.drawSelection(in: dirtyRect)
146 |
147 | if self.interiorBackgroundStyle == .dark && self.isSelected && self.isEmphasized == false {
148 | NSColor(calibratedWhite: 78.0/255.0, alpha: 1.0).set()
149 | NSBezierPath.fill(self.bounds)
150 | }
151 | }
152 | }
153 |
154 | func tableView(_ tableView: NSTableView, rowViewForRow row: Int) -> NSTableRowView? {
155 | return TableRow()
156 | }
157 | }
158 |
--------------------------------------------------------------------------------
/MachOExplorer/Details/MachOHexDetailViewController.xib:
--------------------------------------------------------------------------------
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 |
134 |
135 |
136 |
137 |
138 |
139 |
140 |
141 |
142 |
143 |
144 |
145 |
146 |
147 |
148 |
149 |
150 |
151 |
152 |
153 |
154 |
155 |
156 |
157 |
158 |
159 |
160 |
161 |
162 |
163 |
164 |
165 |
166 |
167 |
168 |
169 |
170 |
171 |
172 |
173 |
174 |
175 |
176 |
177 |
178 |
179 |
180 |
181 |
182 |
183 |
184 |
185 |
186 |
187 |
188 |
189 |
190 |
191 |
192 |
193 |
194 |
195 |
196 |
197 |
198 |
199 |
200 |
201 |
202 |
203 |
--------------------------------------------------------------------------------
/MachOExplorer/MachODocument.swift:
--------------------------------------------------------------------------------
1 | //----------------------------------------------------------------------------//
2 | //|
3 | //| MachOExplorer - A Graphical Mach-O Viewer
4 | //! @file MachODocument.swift
5 | //!
6 | //! @author D.V.
7 | //! @copyright Copyright (c) 2018 D.V. All rights reserved.
8 | //|
9 | //| Permission is hereby granted, free of charge, to any person obtaining a
10 | //| copy of this software and associated documentation files (the "Software"),
11 | //| to deal in the Software without restriction, including without limitation
12 | //| the rights to use, copy, modify, merge, publish, distribute, sublicense,
13 | //| and/or sell copies of the Software, and to permit persons to whom the
14 | //| Software is furnished to do so, subject to the following conditions:
15 | //|
16 | //| The above copyright notice and this permission notice shall be included
17 | //| in all copies or substantial portions of the Software.
18 | //|
19 | //| THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
20 | //| OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
21 | //| MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
22 | //| IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
23 | //| CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
24 | //| TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
25 | //| SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
26 | //----------------------------------------------------------------------------//
27 |
28 | import Cocoa
29 | import MachOKit
30 |
31 | class MachODocument: NSDocument
32 | {
33 | @objc var rootNode: MKNode!
34 |
35 | // UI State //
36 | @objc dynamic var addressMode: MKNodeAddressType = .contextAddress
37 | @objc dynamic var searchString: String? = nil
38 | @objc dynamic var selection: Model? = nil
39 | }
40 |
41 |
42 | extension MachODocument
43 | {
44 | override func read(from url: URL, ofType typeName: String) throws {
45 | let memoryMap = try MKMemoryMap.init(contentsOfFile: url)
46 |
47 | // Try initializing a dyld shared cache
48 | do {
49 | self.rootNode = try MKSharedCache(flags: .fromSourceFile, atAddress: 0, inMapping: memoryMap)
50 | return
51 | } catch let error as NSError {
52 | // If MK_EINVAL is returned, the file is not a shared cache.
53 | if mk_error_t(rawValue: UInt32(error.code)) != MK_EINVAL {
54 | throw error
55 | }
56 | }
57 |
58 | // Try initializing a FAT binary
59 | do {
60 | self.rootNode = try MKFatBinary(memoryMap: memoryMap)
61 | return
62 | } catch let error as NSError {
63 | // If MK_EINVAL is returned, the file is not a FAT binary.
64 | if mk_error_t(rawValue: UInt32(error.code)) != MK_EINVAL {
65 | throw error
66 | }
67 | }
68 |
69 | // Try initializing a Mach-O
70 | self.rootNode = try MKMachOImage(name: nil, flags: MKMachOImageFlags(rawValue: 0), atAddress: 0, inMapping: memoryMap)
71 | }
72 | }
73 |
74 |
75 | extension MachODocument
76 | {
77 | override func makeWindowControllers() {
78 | let windowController = MachODocumentWindowController(windowNibName: NSNib.Name("MachoDocumentWindow"))
79 | self.addWindowController(windowController)
80 | }
81 | }
82 |
--------------------------------------------------------------------------------
/MachOExplorer/MachODocumentDetailsViewController.swift:
--------------------------------------------------------------------------------
1 | //----------------------------------------------------------------------------//
2 | //|
3 | //| MachOExplorer - A Graphical Mach-O Viewer
4 | //! @file MachODocumentDetailsViewController.swift
5 | //!
6 | //! @author D.V.
7 | //! @copyright Copyright (c) 2018 D.V. All rights reserved.
8 | //|
9 | //| Permission is hereby granted, free of charge, to any person obtaining a
10 | //| copy of this software and associated documentation files (the "Software"),
11 | //| to deal in the Software without restriction, including without limitation
12 | //| the rights to use, copy, modify, merge, publish, distribute, sublicense,
13 | //| and/or sell copies of the Software, and to permit persons to whom the
14 | //| Software is furnished to do so, subject to the following conditions:
15 | //|
16 | //| The above copyright notice and this permission notice shall be included
17 | //| in all copies or substantial portions of the Software.
18 | //|
19 | //| THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
20 | //| OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
21 | //| MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
22 | //| IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
23 | //| CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
24 | //| TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
25 | //| SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
26 | //----------------------------------------------------------------------------//
27 |
28 | import Cocoa
29 |
30 | class MachODocumentDetailsViewController: NSTabViewController
31 | {
32 | let detailViewControllers: [MachODetailViewController] = [
33 | MachODetailsViewController(),
34 | MachOHexDetailViewController()
35 | ]
36 |
37 | override var representedObject: Any? {
38 | didSet {
39 | for viewController in self.detailViewControllers {
40 | viewController.representedObject = self.representedObject
41 | }
42 | }
43 | }
44 |
45 | required init?(coder: NSCoder) {
46 | super.init(coder: coder)
47 |
48 | self.commonInit()
49 | }
50 |
51 | override init(nibName nibNameOrNil: NSNib.Name?, bundle nibBundleOrNil: Bundle?) {
52 | super.init(nibName: nibNameOrNil, bundle: nibBundleOrNil)
53 |
54 | self.commonInit()
55 | }
56 |
57 | func commonInit() {
58 | self.transitionOptions = TransitionOptions()
59 | self.tabStyle = .unspecified
60 |
61 | for viewController in self.detailViewControllers {
62 | viewController.addObserver(self, forKeyPath: "wantsDisplay", options: .initial, context: nil)
63 | }
64 | }
65 |
66 | deinit {
67 | for viewController in self.detailViewControllers {
68 | viewController.removeObserver(self, forKeyPath: "wantsDisplay", context: nil)
69 | }
70 | }
71 | }
72 |
73 |
74 | extension MachODocumentDetailsViewController
75 | {
76 | override func tabView(_ tabView: NSTabView, willSelect tabViewItem: NSTabViewItem?) {
77 | super.tabView(tabView, didSelect: tabViewItem)
78 |
79 | if self.tabViewItems.indices.contains(self.selectedTabViewItemIndex),
80 | let outgoingViewController = self.tabViewItems[self.selectedTabViewItemIndex].viewController as? MachODetailViewController
81 | {
82 | outgoingViewController.willDisappear()
83 | }
84 |
85 | if let tabViewItem = tabViewItem,
86 | let incomingViewController = tabViewItem.viewController as? MachODetailViewController
87 | {
88 | incomingViewController.willAppear()
89 | }
90 | }
91 | }
92 |
93 |
94 | extension MachODocumentDetailsViewController
95 | {
96 | @objc func updateVisibleViewControllers() {
97 | let newValue = self.detailViewControllers.filter({ viewController -> Bool in
98 | return viewController.wantsDisplay
99 | }).map({ viewController -> NSTabViewItem in
100 | return viewController.tabViewItem
101 | })
102 |
103 | self.tabViewItems = newValue;
104 | }
105 |
106 | override func observeValue(forKeyPath keyPath: String?, of object: Any?, change: [NSKeyValueChangeKey : Any]?, context: UnsafeMutableRawPointer?) {
107 | if keyPath == "wantsDisplay"
108 | {
109 | type(of: self).cancelPreviousPerformRequests(withTarget: self, selector: #selector(updateVisibleViewControllers), object: nil)
110 | self.perform(#selector(updateVisibleViewControllers), with: nil, afterDelay: 0)
111 | }
112 | else {
113 | super.observeValue(forKeyPath: keyPath, of: object, change: change, context: context)
114 | }
115 | }
116 | }
117 |
--------------------------------------------------------------------------------
/MachOExplorer/MachODocumentOutlineViewController.swift:
--------------------------------------------------------------------------------
1 | //----------------------------------------------------------------------------//
2 | //|
3 | //| MachOExplorer - A Graphical Mach-O Viewer
4 | //! @file MachODocumentOutlineViewController.swift
5 | //!
6 | //! @author D.V.
7 | //! @copyright Copyright (c) 2018 D.V. All rights reserved.
8 | //|
9 | //| Permission is hereby granted, free of charge, to any person obtaining a
10 | //| copy of this software and associated documentation files (the "Software"),
11 | //| to deal in the Software without restriction, including without limitation
12 | //| the rights to use, copy, modify, merge, publish, distribute, sublicense,
13 | //| and/or sell copies of the Software, and to permit persons to whom the
14 | //| Software is furnished to do so, subject to the following conditions:
15 | //|
16 | //| The above copyright notice and this permission notice shall be included
17 | //| in all copies or substantial portions of the Software.
18 | //|
19 | //| THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
20 | //| OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
21 | //| MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
22 | //| IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
23 | //| CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
24 | //| TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
25 | //| SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
26 | //----------------------------------------------------------------------------//
27 |
28 | import Cocoa
29 |
30 | class MachODocumentOutlineViewController: NSViewController, NSOutlineViewDelegate
31 | {
32 | @IBOutlet var outlineController: NSTreeController! {
33 | didSet {
34 | oldValue?.removeObserver(self, forKeyPath: "selectedObjects")
35 | self.outlineController.addObserver(self, forKeyPath: "selectedObjects", options: NSKeyValueObservingOptions(), context: nil)
36 | }
37 | }
38 |
39 | deinit {
40 | self.outlineController.removeObserver(self, forKeyPath: "selectedObjects")
41 | }
42 | }
43 |
44 |
45 | extension MachODocumentOutlineViewController
46 | {
47 | override func observeValue(forKeyPath keyPath: String?, of object: Any?, change: [NSKeyValueChangeKey : Any]?, context: UnsafeMutableRawPointer?) {
48 | if let object = object as? NSTreeController,
49 | object == self.outlineController && keyPath == "selectedObjects"
50 | {
51 | let document = self.representedObject as! MachODocument
52 |
53 | if let newValue = object.selectedObjects as? [Model] {
54 | document.selection = newValue.first
55 | } else {
56 | document.selection = nil
57 | }
58 | }
59 | else {
60 | super.observeValue(forKeyPath: keyPath, of: object, change: change, context: context)
61 | }
62 | }
63 | }
64 |
--------------------------------------------------------------------------------
/MachOExplorer/MachODocumentOutlineViewController.xib:
--------------------------------------------------------------------------------
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 |
--------------------------------------------------------------------------------
/MachOExplorer/MachODocumentWindowContentViewController.swift:
--------------------------------------------------------------------------------
1 | //----------------------------------------------------------------------------//
2 | //|
3 | //| MachOExplorer - A Graphical Mach-O Viewer
4 | //! @file MachODocumentWindowContentViewController.swift
5 | //!
6 | //! @author D.V.
7 | //! @copyright Copyright (c) 2018 D.V. All rights reserved.
8 | //|
9 | //| Permission is hereby granted, free of charge, to any person obtaining a
10 | //| copy of this software and associated documentation files (the "Software"),
11 | //| to deal in the Software without restriction, including without limitation
12 | //| the rights to use, copy, modify, merge, publish, distribute, sublicense,
13 | //| and/or sell copies of the Software, and to permit persons to whom the
14 | //| Software is furnished to do so, subject to the following conditions:
15 | //|
16 | //| The above copyright notice and this permission notice shall be included
17 | //| in all copies or substantial portions of the Software.
18 | //|
19 | //| THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
20 | //| OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
21 | //| MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
22 | //| IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
23 | //| CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
24 | //| TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
25 | //| SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
26 | //----------------------------------------------------------------------------//
27 |
28 | import Cocoa
29 |
30 | class MachODocumentWindowContentViewController: NSSplitViewController
31 | {
32 |
33 | }
34 |
--------------------------------------------------------------------------------
/MachOExplorer/MachODocumentWindowController.swift:
--------------------------------------------------------------------------------
1 | //----------------------------------------------------------------------------//
2 | //|
3 | //| MachOExplorer - A Graphical Mach-O Viewer
4 | //! @file MachODocumentWindowController.swift
5 | //!
6 | //! @author D.V.
7 | //! @copyright Copyright (c) 2018 D.V. All rights reserved.
8 | //|
9 | //| Permission is hereby granted, free of charge, to any person obtaining a
10 | //| copy of this software and associated documentation files (the "Software"),
11 | //| to deal in the Software without restriction, including without limitation
12 | //| the rights to use, copy, modify, merge, publish, distribute, sublicense,
13 | //| and/or sell copies of the Software, and to permit persons to whom the
14 | //| Software is furnished to do so, subject to the following conditions:
15 | //|
16 | //| The above copyright notice and this permission notice shall be included
17 | //| in all copies or substantial portions of the Software.
18 | //|
19 | //| THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
20 | //| OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
21 | //| MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
22 | //| IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
23 | //| CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
24 | //| TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
25 | //| SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
26 | //----------------------------------------------------------------------------//
27 |
28 | import Cocoa
29 |
30 | class MachODocumentWindowController: NSWindowController
31 | {
32 | @IBOutlet var addressModeSelector: NSSegmentedControl!
33 | @IBOutlet var displayModeSelectorItem: NSToolbarItem!
34 | @IBOutlet var displayModeSelector: NSSegmentedControl!
35 | @IBOutlet var searchField: NSSearchField!
36 | @IBOutlet var panelVisibilitySelector: NSSegmentedControl!
37 |
38 | var previousDetailSelection: String? = nil
39 |
40 | override func windowDidLoad() {
41 | super.windowDidLoad()
42 |
43 | let splitViewController = MachODocumentWindowContentViewController()
44 |
45 | // Load the outline view controller (master)
46 | let outlineController = MachODocumentOutlineViewController(nibName: NSNib.Name("MachODocumentOutlineViewController"), bundle: nil)
47 | outlineController.representedObject = self.document
48 | let _ = outlineController.view // Force nib load
49 |
50 | // Load the detail view controller
51 | let detailController = MachODocumentDetailsViewController()
52 | detailController.representedObject = self.document
53 | detailController.addObserver(self, forKeyPath: "tabViewItems", options: [.initial, .new], context: nil)
54 | self.displayModeSelector.bind(NSBindingName("selectedIndex"), to: detailController, withKeyPath: "selectedTabViewItemIndex", options: nil)
55 |
56 | let masterSplitViewItem = NSSplitViewItem(viewController: outlineController)
57 | masterSplitViewItem.minimumThickness = 250
58 | splitViewController.addSplitViewItem(masterSplitViewItem)
59 |
60 | let detailSplitViewItem = NSSplitViewItem(viewController: detailController)
61 | detailSplitViewItem.minimumThickness = 600
62 | splitViewController.addSplitViewItem(detailSplitViewItem)
63 |
64 | self.contentViewController = splitViewController
65 | }
66 | }
67 |
68 |
69 | extension MachODocumentWindowController
70 | {
71 | @IBAction func displayModeChanged(_ sender: NSSegmentedControl?) {
72 | if let sender = sender, sender.selectedSegment >= 0 {
73 | self.previousDetailSelection = sender.label(forSegment: sender.selectedSegment)
74 | } else {
75 | self.previousDetailSelection = nil
76 | }
77 | }
78 |
79 | override func observeValue(forKeyPath keyPath: String?, of object: Any?, change: [NSKeyValueChangeKey : Any]?, context: UnsafeMutableRawPointer?) {
80 | if keyPath == "tabViewItems"
81 | {
82 | let tabViewController = (object as! NSTabViewController)
83 | let newValue: [NSTabViewItem] = tabViewController.tabViewItems
84 |
85 | if newValue.count == 0 {
86 | self.displayModeSelector.isHidden = true
87 | } else {
88 | self.displayModeSelector.isHidden = false
89 | }
90 |
91 | self.displayModeSelector.segmentCount = newValue.count
92 |
93 | var i = 0
94 | for tab in newValue {
95 | self.displayModeSelector.setLabel(tab.label, forSegment: i)
96 | self.displayModeSelector.setWidth(0, forSegment: i)
97 | i = i + 1
98 | }
99 |
100 | if let previousSelection = self.previousDetailSelection {
101 | for i in 0.. 0 {
108 | self.displayModeSelector.selectedSegment = 0
109 | tabViewController.selectedTabViewItemIndex = 0
110 | }
111 |
112 | self.displayModeSelector.layoutSubtreeIfNeeded()
113 | self.displayModeSelector.sizeToFit()
114 | self.displayModeSelectorItem.maxSize = NSSize(width: self.displayModeSelector.frame.size.width, height: self.displayModeSelectorItem.maxSize.height)
115 | self.displayModeSelectorItem.minSize = NSSize(width: 50, height: self.displayModeSelectorItem.minSize.height)
116 | }
117 | else {
118 | super.observeValue(forKeyPath: keyPath, of: object, change: change, context: context)
119 | }
120 | }
121 | }
122 |
--------------------------------------------------------------------------------
/MachOExplorer/MachoDocumentWindow.xib:
--------------------------------------------------------------------------------
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 |
--------------------------------------------------------------------------------
/MachOExplorer/Model/DataModel.swift:
--------------------------------------------------------------------------------
1 | //----------------------------------------------------------------------------//
2 | //|
3 | //| MachOExplorer - A Graphical Mach-O Viewer
4 | //! @file DataModel.swift
5 | //!
6 | //! @author D.V.
7 | //! @copyright Copyright (c) 2018 D.V. All rights reserved.
8 | //|
9 | //| Permission is hereby granted, free of charge, to any person obtaining a
10 | //| copy of this software and associated documentation files (the "Software"),
11 | //| to deal in the Software without restriction, including without limitation
12 | //| the rights to use, copy, modify, merge, publish, distribute, sublicense,
13 | //| and/or sell copies of the Software, and to permit persons to whom the
14 | //| Software is furnished to do so, subject to the following conditions:
15 | //|
16 | //| The above copyright notice and this permission notice shall be included
17 | //| in all copies or substantial portions of the Software.
18 | //|
19 | //| THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
20 | //| OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
21 | //| MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
22 | //| IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
23 | //| CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
24 | //| TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
25 | //| SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
26 | //----------------------------------------------------------------------------//
27 |
28 | import Cocoa
29 | import MachOKit
30 |
31 | @objc protocol DataModel
32 | {
33 | func address(mode addressMode: MKNodeAddressType) -> NSNumber?
34 |
35 | var data: Data? { get }
36 | }
37 |
--------------------------------------------------------------------------------
/MachOExplorer/Model/DetailModel.swift:
--------------------------------------------------------------------------------
1 | //----------------------------------------------------------------------------//
2 | //|
3 | //| MachOExplorer - A Graphical Mach-O Viewer
4 | //! @file DetailModel.swift
5 | //!
6 | //! @author D.V.
7 | //! @copyright Copyright (c) 2018 D.V. All rights reserved.
8 | //|
9 | //| Permission is hereby granted, free of charge, to any person obtaining a
10 | //| copy of this software and associated documentation files (the "Software"),
11 | //| to deal in the Software without restriction, including without limitation
12 | //| the rights to use, copy, modify, merge, publish, distribute, sublicense,
13 | //| and/or sell copies of the Software, and to permit persons to whom the
14 | //| Software is furnished to do so, subject to the following conditions:
15 | //|
16 | //| The above copyright notice and this permission notice shall be included
17 | //| in all copies or substantial portions of the Software.
18 | //|
19 | //| THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
20 | //| OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
21 | //| MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
22 | //| IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
23 | //| CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
24 | //| TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
25 | //| SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
26 | //----------------------------------------------------------------------------//
27 |
28 | import Cocoa
29 | import MachOKit
30 |
31 | @objc protocol DetailModel: Model
32 | {
33 | var detail_rows: [DetailRowModel] { get }
34 | }
35 |
36 | @objc protocol DetailRowModel: Model
37 | {
38 | var detail_value: String? { get }
39 |
40 | var detail_description: String? { get }
41 |
42 | var detail_data: Data? { get }
43 |
44 | func detail_address(mode addressMode: MKNodeAddressType) -> NSNumber?
45 | }
46 |
47 | @objc protocol DetailRowDisplayModel: DetailRowModel
48 | {
49 | var detail_group_identifier: UInt { get }
50 |
51 | var detail_backgroundColor: NSColor? { get }
52 | }
53 |
--------------------------------------------------------------------------------
/MachOExplorer/Model/Field/FieldAdapter.swift:
--------------------------------------------------------------------------------
1 | //----------------------------------------------------------------------------//
2 | //|
3 | //| MachOExplorer - A Graphical Mach-O Viewer
4 | //! @file FieldAdapter.swift
5 | //!
6 | //! @author D.V.
7 | //! @copyright Copyright (c) 2018 D.V. All rights reserved.
8 | //|
9 | //| Permission is hereby granted, free of charge, to any person obtaining a
10 | //| copy of this software and associated documentation files (the "Software"),
11 | //| to deal in the Software without restriction, including without limitation
12 | //| the rights to use, copy, modify, merge, publish, distribute, sublicense,
13 | //| and/or sell copies of the Software, and to permit persons to whom the
14 | //| Software is furnished to do so, subject to the following conditions:
15 | //|
16 | //| The above copyright notice and this permission notice shall be included
17 | //| in all copies or substantial portions of the Software.
18 | //|
19 | //| THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
20 | //| OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
21 | //| MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
22 | //| IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
23 | //| CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
24 | //| TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
25 | //| SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
26 | //----------------------------------------------------------------------------//
27 |
28 | import MachOKit
29 |
30 | class FieldAdapter: NSObject
31 | {
32 | let node: MKNode
33 | let field: MKNodeField
34 |
35 | var type: MKNodeFieldType? {
36 | return self.field.type
37 | }
38 |
39 | var value: NSObject! {
40 | let value = self.field.valueRecipe.value(for: self.field, of: self.node)
41 | return value.value as! NSObject?
42 | }
43 |
44 | var typeAdapter: TypeAdapter? {
45 | if let type = self.type {
46 | return TypeAdapter.For(value: self.value, ofType: type, inNode: self.node)
47 | } else {
48 | return nil
49 | }
50 | }
51 |
52 | var fieldIndex: UInt {
53 | let layout = self.node.layout
54 | var i: UInt = 0
55 | for field in layout.allFields {
56 | if field.name == self.field.name {
57 | break
58 | } else {
59 | i += 1
60 | }
61 | }
62 | return i
63 | }
64 |
65 | var alternateFieldAdapter: FieldAdapter? {
66 | if let alternateFieldName = self.field.alternateFieldName {
67 | if let field = self.node.layout.field(withName: alternateFieldName, searchAllFields: true) {
68 | return self.node.adapter(forField: field)
69 | }
70 | }
71 |
72 | return nil
73 | }
74 |
75 | init(field: MKNodeField, ofNode node: MKNode) {
76 | self.node = node
77 | self.field = field
78 | }
79 | }
80 |
81 | extension FieldAdapter /* OutlineModel */
82 | {
83 | override var outline_nodes: [OutlineNodeModel] {
84 | guard self.field.options.contains(.hidden) == false else { return [] }
85 | guard self.field.options.contains(.displayAsChild) else { return [] }
86 | guard let value = self.value else { return [] }
87 |
88 | if field.options.contains(.mergeContainerContents) {
89 | if let collectionType = self.type as? MKNodeFieldCollectionType,
90 | let elementType = collectionType.elementType {
91 | return value.outline_nodes.reduce([], { $0 + TypeAdapter.For(value: $1 as! NSObject, ofType: elementType, inNode: self.node).outline_nodes })
92 | }
93 | else if self.type is MKNodeFieldContainerType {
94 | return value.outline_nodes
95 | }
96 | else if self.type is MKNodeFieldPointerType,
97 | let pointer = value as? MKPointer {
98 | if let pointee = pointer.pointee.value(forKey: "value") {
99 | return (pointee as! NSObject).outline_nodes
100 | } else {
101 | return []
102 | }
103 | }
104 | }
105 |
106 | // If the type is a pointer and there is no pointee, hide the field
107 | if self.type is MKNodeFieldPointerType,
108 | let pointer = value as? MKPointer,
109 | pointer.pointee.value == nil {
110 | return []
111 | }
112 |
113 | // If the value is an MKNode then always merge the contents unless
114 | // the field options contains ignoreContainerContents.
115 | if value is MKNode && field.options.contains(.ignoreContainerContents) == false {
116 | return value.outline_nodes
117 | }
118 |
119 | return [self]
120 | }
121 | }
122 |
123 | extension FieldAdapter /* DetailModel */
124 | {
125 | override var detail_rows: [DetailRowModel] {
126 | guard self.field.options.contains(.hidden) == false else { return [] }
127 | guard let value = self.value else { return [] }
128 |
129 | if field.options.contains(.displayAsDetail) || field.options.contains(.displayAsChild) == false
130 | {
131 | if field.options.contains(.mergeContainerContents) {
132 | if let collectionType = field.type as? MKNodeFieldCollectionType,
133 | let elementType = collectionType.elementType {
134 | let valueDetailRowModels = value.detail_rows
135 |
136 | var detailRowModels = Array()
137 | detailRowModels.reserveCapacity(valueDetailRowModels.count)
138 | for item in valueDetailRowModels {
139 | if item is FieldAdapter || item is SubFieldAdapter {
140 | detailRowModels.append(item)
141 | } else {
142 | detailRowModels += TypeAdapter.For(value: item as! NSObject, ofType: elementType, inNode: self.node).detail_rows
143 | }
144 | }
145 |
146 | return detailRowModels
147 | }
148 | else if self.field.type is MKNodeFieldContainerType {
149 | return value.detail_rows
150 | }
151 | }
152 | else if field.options.contains(.ignoreContainerContents) == false,
153 | let typeAdapter = self.typeAdapter,
154 | typeAdapter.providesSubFields {
155 | return [self] + typeAdapter.detail_rows.map({ detailRowModel -> SubFieldAdapter in
156 | return SubFieldAdapter(valueProvider: detailRowModel as! NSObject, inField: self)
157 | })
158 | }
159 |
160 | return [self]
161 | }
162 | else if field.options.contains(.displayContainerContentsAsDetail)
163 | {
164 | if let collectionType = field.type as? MKNodeFieldCollectionType,
165 | let elementType = collectionType.elementType,
166 | elementType is MKNodeFieldTypeNode == false {
167 | return value.detail_rows.reduce([], { $0 + TypeAdapter.For(value: $1 as! NSObject, ofType: elementType, inNode: self.node).detail_rows })
168 | }
169 | else if self.field.type is MKNodeFieldContainerType {
170 | return value.detail_rows
171 | }
172 | }
173 |
174 | // If the type is a pointer, then we always proxy the contents
175 | if self.type is MKNodeFieldPointerType,
176 | let pointer = value as? MKPointer {
177 | if let pointee = pointer.pointee.value(forKey: "value") {
178 | return (pointee as! NSObject).detail_rows
179 | } else {
180 | //return []
181 | }
182 | }
183 |
184 | return []
185 | }
186 | }
187 |
188 | extension FieldAdapter /* OutlineNodeModel */
189 | {
190 | override var outline_isLeaf: Bool {
191 | return self.outline_childCount == 0
192 | }
193 |
194 | override var outline_childCount: Int {
195 | return self.outline_children.count
196 | }
197 |
198 | override var outline_children: [OutlineNodeModel] {
199 | if self.field.options.contains(.displayContainerContentsAsChild)
200 | {
201 | if let collectionType = field.type as? MKNodeFieldCollectionType {
202 | if let elementType = collectionType.elementType {
203 | return value.outline_nodes.reduce([], { $0 + TypeAdapter.For(value: $1 as! NSObject, ofType: elementType, inNode: self.node).outline_nodes })
204 | } else {
205 | return value.outline_nodes
206 | }
207 | }
208 | }
209 |
210 | // If the type is a pointer, then we always proxy the contents
211 | if self.type is MKNodeFieldPointerType,
212 | let pointer = value as? MKPointer {
213 | if let pointee = pointer.pointee.value(forKey: "value") {
214 | return (pointee as! NSObject).outline_children
215 | } else {
216 | return []
217 | }
218 | }
219 |
220 | return self.value.outline_children
221 | }
222 |
223 | override var outline_title: String {
224 | if let description = self.field.description {
225 | return description
226 | } else {
227 | return self.field.name
228 | }
229 | }
230 | }
231 |
232 | extension FieldAdapter /* DetailRowModel */
233 | {
234 | override var detail_value: String? {
235 | let fieldValue: String?
236 | let alternateValue: String? = self.alternateFieldAdapter?.detail_value
237 |
238 | if let alternateValue = alternateValue,
239 | self.field.options.contains(.substituteAlternateFieldValue) {
240 | return alternateValue
241 | }
242 |
243 | if self.field.options.contains(.ignoreContainerContents) == false,
244 | let typeAdapter = self.typeAdapter,
245 | typeAdapter.providesSubFields {
246 | return alternateValue
247 | }
248 |
249 | if let formatter = self.field.valueFormatter,
250 | let formattedDescription = formatter.string(for: self.value) {
251 | fieldValue = formattedDescription
252 | } else {
253 | fieldValue = self.value?.detail_value
254 | }
255 |
256 | if let alternateValue = alternateValue,
257 | let fieldValue = fieldValue,
258 | self.field.options.contains(.hideAlternateFieldValue) == false {
259 | return fieldValue + " (" + alternateValue + ")"
260 | } else {
261 | return fieldValue
262 | }
263 | }
264 |
265 | override var detail_description: String? {
266 | let fieldDescription: String?
267 | let alternateDescription: String? = self.alternateFieldAdapter?.detail_description
268 |
269 | if let alternateDescription = alternateDescription,
270 | self.field.options.contains(.substituteAlternateFieldDescription) {
271 | return alternateDescription
272 | }
273 |
274 |
275 | if let fd = self.field.description {
276 | fieldDescription = fd
277 | } else {
278 | fieldDescription = self.field.name
279 | }
280 |
281 | if let alternateDescription = alternateDescription,
282 | let fieldDescription = fieldDescription,
283 | self.field.options.contains(.showAlternateFieldDescription) {
284 | return fieldDescription + " (" + alternateDescription + ")"
285 | } else {
286 | return fieldDescription
287 | }
288 | }
289 |
290 | override var detail_data: Data? {
291 | guard self.field.options.contains(.hideData) == false else { return nil }
292 |
293 | if let dataRecipe = self.field.dataRecipe,
294 | let node = self.node as? MKBackedNode {
295 | return dataRecipe.data(for: self.field, of: node)
296 | } else {
297 | return self.value.detail_data
298 | }
299 | }
300 |
301 | override func detail_address(mode addressMode: MKNodeAddressType) -> NSNumber? {
302 | guard self.field.options.contains(.hideAddress) == false else { return nil }
303 |
304 | if let dataRecipe = self.field.dataRecipe,
305 | let node = self.node as? MKBackedNode {
306 | var addr: NSNumber?
307 |
308 | ExceptionSafePerform {
309 | addr = dataRecipe.address(addressMode.rawValue, of: self.field, of: node)
310 | }
311 |
312 | return addr
313 | }
314 | else if let node = self.node as? MKAddressedNode, self.fieldIndex == 0 {
315 | return node.nodeAddress(addressMode) as NSNumber
316 | }
317 | else {
318 | return self.value.detail_address(mode: addressMode)
319 | }
320 | }
321 | }
322 |
323 | extension FieldAdapter: DetailRowDisplayModel
324 | {
325 | var detail_group_identifier: UInt {
326 | return self.node.detail_group_identifier
327 | }
328 |
329 | var detail_backgroundColor: NSColor? {
330 | return nil
331 | }
332 | }
333 |
334 | extension FieldAdapter: DataModel
335 | {
336 | func address(mode addressMode: MKNodeAddressType) -> NSNumber? {
337 | if let dataRecipe = self.field.dataRecipe,
338 | let node = self.node as? MKBackedNode {
339 | return dataRecipe.address(addressMode.rawValue, of: self.field, of: node)
340 | } else {
341 | return nil
342 | }
343 | }
344 |
345 | var data: Data? {
346 | if let dataRecipe = self.field.dataRecipe,
347 | let node = self.node as? MKBackedNode {
348 | return dataRecipe.data(for: self.field, of: node)
349 | } else {
350 | return nil
351 | }
352 | }
353 | }
354 |
--------------------------------------------------------------------------------
/MachOExplorer/Model/Field/SubFieldAdapter.swift:
--------------------------------------------------------------------------------
1 | //----------------------------------------------------------------------------//
2 | //|
3 | //| MachOExplorer - A Graphical Mach-O Viewer
4 | //! @file SubFieldAdapter.swift
5 | //!
6 | //! @author D.V.
7 | //! @copyright Copyright (c) 2018 D.V. All rights reserved.
8 | //|
9 | //| Permission is hereby granted, free of charge, to any person obtaining a
10 | //| copy of this software and associated documentation files (the "Software"),
11 | //| to deal in the Software without restriction, including without limitation
12 | //| the rights to use, copy, modify, merge, publish, distribute, sublicense,
13 | //| and/or sell copies of the Software, and to permit persons to whom the
14 | //| Software is furnished to do so, subject to the following conditions:
15 | //|
16 | //| The above copyright notice and this permission notice shall be included
17 | //| in all copies or substantial portions of the Software.
18 | //|
19 | //| THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
20 | //| OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
21 | //| MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
22 | //| IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
23 | //| CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
24 | //| TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
25 | //| SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
26 | //----------------------------------------------------------------------------//
27 |
28 | import MachOKit
29 |
30 | class SubFieldAdapter: NSObject
31 | {
32 | unowned let field: FieldAdapter
33 | let valueProvider: NSObject
34 |
35 | init(valueProvider: NSObject, inField field: FieldAdapter) {
36 | self.field = field
37 | self.valueProvider = valueProvider
38 | }
39 | }
40 |
41 | extension SubFieldAdapter /* OutlineNodeModel */
42 | {
43 | override var outline_title: String {
44 | return self.valueProvider.outline_title
45 | }
46 | }
47 |
48 | extension SubFieldAdapter /* DetailRowModel */
49 | {
50 | override var detail_value: String? {
51 | return self.valueProvider.detail_value
52 | }
53 |
54 | override var detail_description: String? {
55 | return self.valueProvider.detail_description
56 | }
57 | }
58 |
59 | extension SubFieldAdapter: DetailRowDisplayModel
60 | {
61 | var detail_group_identifier: UInt {
62 | return self.field.detail_group_identifier
63 | }
64 |
65 | var detail_backgroundColor: NSColor? {
66 | return self.field.detail_backgroundColor
67 | }
68 | }
69 |
--------------------------------------------------------------------------------
/MachOExplorer/Model/MKAddressedNode+Detail.swift:
--------------------------------------------------------------------------------
1 | //----------------------------------------------------------------------------//
2 | //|
3 | //| MachOExplorer - A Graphical Mach-O Viewer
4 | //! @file MKAddressedNode+Detail.swift
5 | //!
6 | //! @author D.V.
7 | //! @copyright Copyright (c) 2018 D.V. All rights reserved.
8 | //|
9 | //| Permission is hereby granted, free of charge, to any person obtaining a
10 | //| copy of this software and associated documentation files (the "Software"),
11 | //| to deal in the Software without restriction, including without limitation
12 | //| the rights to use, copy, modify, merge, publish, distribute, sublicense,
13 | //| and/or sell copies of the Software, and to permit persons to whom the
14 | //| Software is furnished to do so, subject to the following conditions:
15 | //|
16 | //| The above copyright notice and this permission notice shall be included
17 | //| in all copies or substantial portions of the Software.
18 | //|
19 | //| THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
20 | //| OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
21 | //| MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
22 | //| IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
23 | //| CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
24 | //| TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
25 | //| SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
26 | //----------------------------------------------------------------------------//
27 |
28 | import MachOKit
29 |
30 | extension MKAddressedNode
31 | {
32 | override func detail_address(mode addressMode: MKNodeAddressType) -> NSNumber? {
33 | var addr: mk_vm_address_t?
34 |
35 | ExceptionSafePerform {
36 | addr = self.nodeAddress(addressMode)
37 | }
38 |
39 | return addr as NSNumber?
40 | }
41 | }
42 |
--------------------------------------------------------------------------------
/MachOExplorer/Model/MKBackedNode+Data.swift:
--------------------------------------------------------------------------------
1 | //----------------------------------------------------------------------------//
2 | //|
3 | //| MachOExplorer - A Graphical Mach-O Viewer
4 | //! @file MKBackedNode+Data.swift
5 | //!
6 | //! @author D.V.
7 | //! @copyright Copyright (c) 2018 D.V. All rights reserved.
8 | //|
9 | //| Permission is hereby granted, free of charge, to any person obtaining a
10 | //| copy of this software and associated documentation files (the "Software"),
11 | //| to deal in the Software without restriction, including without limitation
12 | //| the rights to use, copy, modify, merge, publish, distribute, sublicense,
13 | //| and/or sell copies of the Software, and to permit persons to whom the
14 | //| Software is furnished to do so, subject to the following conditions:
15 | //|
16 | //| The above copyright notice and this permission notice shall be included
17 | //| in all copies or substantial portions of the Software.
18 | //|
19 | //| THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
20 | //| OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
21 | //| MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
22 | //| IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
23 | //| CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
24 | //| TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
25 | //| SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
26 | //----------------------------------------------------------------------------//
27 |
28 | import MachOKit
29 |
30 | extension MKBackedNode: DataModel
31 | {
32 | func address(mode addressMode: MKNodeAddressType) -> NSNumber? {
33 | return self.nodeAddress(addressMode) as NSNumber
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/MachOExplorer/Model/MKBackedNode+Detail.swift:
--------------------------------------------------------------------------------
1 | //----------------------------------------------------------------------------//
2 | //|
3 | //| MachOExplorer - A Graphical Mach-O Viewer
4 | //! @file MKBackedNode+Detail.swift
5 | //!
6 | //! @author D.V.
7 | //! @copyright Copyright (c) 2018 D.V. All rights reserved.
8 | //|
9 | //| Permission is hereby granted, free of charge, to any person obtaining a
10 | //| copy of this software and associated documentation files (the "Software"),
11 | //| to deal in the Software without restriction, including without limitation
12 | //| the rights to use, copy, modify, merge, publish, distribute, sublicense,
13 | //| and/or sell copies of the Software, and to permit persons to whom the
14 | //| Software is furnished to do so, subject to the following conditions:
15 | //|
16 | //| The above copyright notice and this permission notice shall be included
17 | //| in all copies or substantial portions of the Software.
18 | //|
19 | //| THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
20 | //| OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
21 | //| MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
22 | //| IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
23 | //| CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
24 | //| TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
25 | //| SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
26 | //----------------------------------------------------------------------------//
27 |
28 | import MachOKit
29 |
30 | extension MKBackedNode
31 | {
32 | override var detail_data: Data? {
33 | return self.data
34 | }
35 | }
36 |
37 |
--------------------------------------------------------------------------------
/MachOExplorer/Model/MKNode+Adapter.swift:
--------------------------------------------------------------------------------
1 | //----------------------------------------------------------------------------//
2 | //|
3 | //| MachOExplorer - A Graphical Mach-O Viewer
4 | //! @file MKNode+Adapter.swift
5 | //!
6 | //! @author D.V.
7 | //! @copyright Copyright (c) 2018 D.V. All rights reserved.
8 | //|
9 | //| Permission is hereby granted, free of charge, to any person obtaining a
10 | //| copy of this software and associated documentation files (the "Software"),
11 | //| to deal in the Software without restriction, including without limitation
12 | //| the rights to use, copy, modify, merge, publish, distribute, sublicense,
13 | //| and/or sell copies of the Software, and to permit persons to whom the
14 | //| Software is furnished to do so, subject to the following conditions:
15 | //|
16 | //| The above copyright notice and this permission notice shall be included
17 | //| in all copies or substantial portions of the Software.
18 | //|
19 | //| THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
20 | //| OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
21 | //| MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
22 | //| IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
23 | //| CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
24 | //| TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
25 | //| SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
26 | //----------------------------------------------------------------------------//
27 |
28 | import MachOKit
29 |
30 | extension MKNode
31 | {
32 | @objc func adapter(forField field: MKNodeField) -> FieldAdapter? {
33 | return FieldAdapter(field: field, ofNode: self)
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/MachOExplorer/Model/MKNode+Detail.swift:
--------------------------------------------------------------------------------
1 | //----------------------------------------------------------------------------//
2 | //|
3 | //| MachOExplorer - A Graphical Mach-O Viewer
4 | //! @file MKNode+Detail.swift
5 | //!
6 | //! @author D.V.
7 | //! @copyright Copyright (c) 2018 D.V. All rights reserved.
8 | //|
9 | //| Permission is hereby granted, free of charge, to any person obtaining a
10 | //| copy of this software and associated documentation files (the "Software"),
11 | //| to deal in the Software without restriction, including without limitation
12 | //| the rights to use, copy, modify, merge, publish, distribute, sublicense,
13 | //| and/or sell copies of the Software, and to permit persons to whom the
14 | //| Software is furnished to do so, subject to the following conditions:
15 | //|
16 | //| The above copyright notice and this permission notice shall be included
17 | //| in all copies or substantial portions of the Software.
18 | //|
19 | //| THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
20 | //| OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
21 | //| MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
22 | //| IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
23 | //| CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
24 | //| TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
25 | //| SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
26 | //----------------------------------------------------------------------------//
27 |
28 | import MachOKit
29 |
30 | extension MKNode /* DetailModel */
31 | {
32 | override var detail_rows: [DetailRowModel] {
33 | var rows = Array()
34 |
35 | let nodeLayout = self.layout
36 | let nodeFields = nodeLayout.allFields
37 |
38 | for field in nodeFields {
39 | guard field.options.contains(.displayAsDetail) || field.options.contains(.displayAsChild) == false else { continue }
40 |
41 | if let fieldAdapter = self.adapter(forField: field) {
42 | rows += fieldAdapter.detail_rows
43 | }
44 | }
45 |
46 | return rows
47 | }
48 | }
49 |
50 | extension MKNode /* DetailRowModel */
51 | {
52 | override var detail_value: String? {
53 | #if TRACE_DESCRIPTIONS_AND_VALUES
54 | return "[N]" + self.description
55 | #else
56 | return self.description
57 | #endif
58 | }
59 |
60 | override var detail_description: String? {
61 | #if TRACE_DESCRIPTIONS_AND_VALUES
62 | return "[N]" + type(of: self).description()
63 | #else
64 | return type(of: self).description()
65 | #endif
66 | }
67 |
68 | override var detail_data: Data? {
69 | return nil
70 | }
71 |
72 | override func detail_address(mode addressMode: MKNodeAddressType) -> NSNumber? {
73 | return nil
74 | }
75 | }
76 |
77 | extension MKNode: DetailRowDisplayModel
78 | {
79 | var detail_group_identifier: UInt {
80 | return unsafeBitCast(self, to: UInt.self)
81 | }
82 |
83 | var detail_backgroundColor: NSColor? {
84 | return nil
85 | }
86 | }
87 |
--------------------------------------------------------------------------------
/MachOExplorer/Model/MKNode+Outline.swift:
--------------------------------------------------------------------------------
1 | //----------------------------------------------------------------------------//
2 | //|
3 | //| MachOExplorer - A Graphical Mach-O Viewer
4 | //! @file MKNode+Outline.swift
5 | //!
6 | //! @author D.V.
7 | //! @copyright Copyright (c) 2018 D.V. All rights reserved.
8 | //|
9 | //| Permission is hereby granted, free of charge, to any person obtaining a
10 | //| copy of this software and associated documentation files (the "Software"),
11 | //| to deal in the Software without restriction, including without limitation
12 | //| the rights to use, copy, modify, merge, publish, distribute, sublicense,
13 | //| and/or sell copies of the Software, and to permit persons to whom the
14 | //| Software is furnished to do so, subject to the following conditions:
15 | //|
16 | //| The above copyright notice and this permission notice shall be included
17 | //| in all copies or substantial portions of the Software.
18 | //|
19 | //| THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
20 | //| OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
21 | //| MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
22 | //| IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
23 | //| CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
24 | //| TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
25 | //| SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
26 | //----------------------------------------------------------------------------//
27 |
28 | import MachOKit
29 |
30 | extension MKNode /* OutlineModel */
31 | {
32 | }
33 |
34 | extension MKNode /* OutlineNodeModel */
35 | {
36 | override var outline_isLeaf: Bool {
37 | return self.outline_children.count == 0
38 | }
39 |
40 | override var outline_childCount: Int {
41 | return self.outline_children.count
42 | }
43 |
44 | override var outline_children: [OutlineNodeModel] {
45 | if let cachedChildren = objc_getAssociatedObject(self, "outlineChildren") as? [OutlineNodeModel] {
46 | return cachedChildren
47 | }
48 |
49 | var children = Array()
50 |
51 | let nodeLayout = self.layout
52 | let nodeFields = nodeLayout.allFields
53 |
54 | for field in nodeFields {
55 | if let fieldAdapter = self.adapter(forField: field) {
56 | children += fieldAdapter.outline_nodes
57 | }
58 | }
59 |
60 | objc_setAssociatedObject(self, "outlineChildren", children, .OBJC_ASSOCIATION_RETAIN_NONATOMIC)
61 | return children
62 | }
63 |
64 | override var outline_title: String {
65 | #if TRACE_DESCRIPTIONS_AND_VALUES
66 | return "[N]" + self.description
67 | #else
68 | return self.description
69 | #endif
70 | }
71 | }
72 |
--------------------------------------------------------------------------------
/MachOExplorer/Model/Model.swift:
--------------------------------------------------------------------------------
1 | //----------------------------------------------------------------------------//
2 | //|
3 | //| MachOExplorer - A Graphical Mach-O Viewer
4 | //! @file Model.swift
5 | //!
6 | //! @author D.V.
7 | //! @copyright Copyright (c) 2018 D.V. All rights reserved.
8 | //|
9 | //| Permission is hereby granted, free of charge, to any person obtaining a
10 | //| copy of this software and associated documentation files (the "Software"),
11 | //| to deal in the Software without restriction, including without limitation
12 | //| the rights to use, copy, modify, merge, publish, distribute, sublicense,
13 | //| and/or sell copies of the Software, and to permit persons to whom the
14 | //| Software is furnished to do so, subject to the following conditions:
15 | //|
16 | //| The above copyright notice and this permission notice shall be included
17 | //| in all copies or substantial portions of the Software.
18 | //|
19 | //| THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
20 | //| OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
21 | //| MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
22 | //| IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
23 | //| CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
24 | //| TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
25 | //| SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
26 | //----------------------------------------------------------------------------//
27 |
28 | import Cocoa
29 | import MachOKit
30 |
31 | @objc protocol Model: NSObjectProtocol { }
32 |
--------------------------------------------------------------------------------
/MachOExplorer/Model/OutlineModel.swift:
--------------------------------------------------------------------------------
1 | //----------------------------------------------------------------------------//
2 | //|
3 | //| MachOExplorer - A Graphical Mach-O Viewer
4 | //! @file OutlineModel.swift
5 | //!
6 | //! @author D.V.
7 | //! @copyright Copyright (c) 2018 D.V. All rights reserved.
8 | //|
9 | //| Permission is hereby granted, free of charge, to any person obtaining a
10 | //| copy of this software and associated documentation files (the "Software"),
11 | //| to deal in the Software without restriction, including without limitation
12 | //| the rights to use, copy, modify, merge, publish, distribute, sublicense,
13 | //| and/or sell copies of the Software, and to permit persons to whom the
14 | //| Software is furnished to do so, subject to the following conditions:
15 | //|
16 | //| The above copyright notice and this permission notice shall be included
17 | //| in all copies or substantial portions of the Software.
18 | //|
19 | //| THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
20 | //| OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
21 | //| MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
22 | //| IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
23 | //| CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
24 | //| TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
25 | //| SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
26 | //----------------------------------------------------------------------------//
27 |
28 | import Cocoa
29 | import MachOKit
30 |
31 | @objc protocol OutlineModel: Model
32 | {
33 | var outline_nodes: [OutlineNodeModel] { get }
34 | }
35 |
36 | @objc protocol OutlineNodeModel: Model
37 | {
38 | var outline_isLeaf: Bool { get }
39 |
40 | var outline_childCount: Int { get }
41 |
42 | var outline_children: [OutlineNodeModel] { get }
43 |
44 | var outline_title: String { get }
45 | }
46 |
--------------------------------------------------------------------------------
/MachOExplorer/Model/Overrides/FAT/MKFatArch+Model.swift:
--------------------------------------------------------------------------------
1 | //----------------------------------------------------------------------------//
2 | //|
3 | //| MachOExplorer - A Graphical Mach-O Viewer
4 | //! @file MKFatArch+Model.swift
5 | //!
6 | //! @author D.V.
7 | //! @copyright Copyright (c) 2018 D.V. All rights reserved.
8 | //|
9 | //| Permission is hereby granted, free of charge, to any person obtaining a
10 | //| copy of this software and associated documentation files (the "Software"),
11 | //| to deal in the Software without restriction, including without limitation
12 | //| the rights to use, copy, modify, merge, publish, distribute, sublicense,
13 | //| and/or sell copies of the Software, and to permit persons to whom the
14 | //| Software is furnished to do so, subject to the following conditions:
15 | //|
16 | //| The above copyright notice and this permission notice shall be included
17 | //| in all copies or substantial portions of the Software.
18 | //|
19 | //| THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
20 | //| OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
21 | //| MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
22 | //| IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
23 | //| CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
24 | //| TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
25 | //| SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
26 | //----------------------------------------------------------------------------//
27 |
28 | import MachOKit
29 |
30 | extension MKFatArch /* OutlineModel */
31 | {
32 | override var outline_children: [OutlineNodeModel] {
33 | var children = super.outline_children
34 |
35 | if let machoImage = try? MKMachOImage(name: nil, flags: .init(rawValue: 0), atAddress: mk_vm_address_t(self.offset), inMapping: self.memoryMap) {
36 | children += machoImage.outline_nodes
37 | }
38 |
39 | return children
40 | }
41 | }
42 |
--------------------------------------------------------------------------------
/MachOExplorer/Model/Overrides/MachO/MKExport+Model.swift:
--------------------------------------------------------------------------------
1 | //----------------------------------------------------------------------------//
2 | //|
3 | //| MachOExplorer - A Graphical Mach-O Viewer
4 | //! @file MKExport+Model.swift
5 | //!
6 | //! @author D.V.
7 | //! @copyright Copyright (c) 2018 D.V. All rights reserved.
8 | //|
9 | //| Permission is hereby granted, free of charge, to any person obtaining a
10 | //| copy of this software and associated documentation files (the "Software"),
11 | //| to deal in the Software without restriction, including without limitation
12 | //| the rights to use, copy, modify, merge, publish, distribute, sublicense,
13 | //| and/or sell copies of the Software, and to permit persons to whom the
14 | //| Software is furnished to do so, subject to the following conditions:
15 | //|
16 | //| The above copyright notice and this permission notice shall be included
17 | //| in all copies or substantial portions of the Software.
18 | //|
19 | //| THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
20 | //| OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
21 | //| MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
22 | //| IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
23 | //| CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
24 | //| TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
25 | //| SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
26 | //----------------------------------------------------------------------------//
27 |
28 | import MachOKit
29 |
30 | extension MKExport /* DetailModel */
31 | {
32 | override var detail_rows: [DetailRowModel] {
33 | return [self]
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/MachOExplorer/Model/Overrides/MachO/MKExportTrieBranch+Model.swift:
--------------------------------------------------------------------------------
1 | //----------------------------------------------------------------------------//
2 | //|
3 | //| MachOExplorer - A Graphical Mach-O Viewer
4 | //! @file MKExportTrieBranch+Model.swift
5 | //!
6 | //! @author D.V.
7 | //! @copyright Copyright (c) 2018 D.V. All rights reserved.
8 | //|
9 | //| Permission is hereby granted, free of charge, to any person obtaining a
10 | //| copy of this software and associated documentation files (the "Software"),
11 | //| to deal in the Software without restriction, including without limitation
12 | //| the rights to use, copy, modify, merge, publish, distribute, sublicense,
13 | //| and/or sell copies of the Software, and to permit persons to whom the
14 | //| Software is furnished to do so, subject to the following conditions:
15 | //|
16 | //| The above copyright notice and this permission notice shall be included
17 | //| in all copies or substantial portions of the Software.
18 | //|
19 | //| THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
20 | //| OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
21 | //| MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
22 | //| IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
23 | //| CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
24 | //| TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
25 | //| SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
26 | //----------------------------------------------------------------------------//
27 |
28 | import MachOKit
29 |
30 | extension MKExportTrieBranch
31 | {
32 | @objc var address: mk_vm_address_t {
33 | return (self.nearestAncestor(ofType: MKExportsInfo.self) as! MKExportsInfo).nodeVMAddress + self.offset
34 | }
35 |
36 | override func adapter(forField field: MKNodeField) -> FieldAdapter? {
37 | if field.name == "offset" {
38 | let modifiedValueRecipe = MKNodeFieldOperationReadKeyPath(keyPath: "address")
39 | let modifiedField = MKNodeField(name: field.name, description: "Next Node", type: field.type, value: modifiedValueRecipe, data: field.dataRecipe, formatter: Formatter.mk_hexCompact(), options: field.options)
40 |
41 | return FieldAdapter(field: modifiedField, ofNode: self)
42 | } else {
43 | return super.adapter(forField: field)
44 | }
45 | }
46 | }
47 |
48 | extension MKExportTrieBranch /* DetailRowDisplayModel */
49 | {
50 | override var detail_group_identifier: UInt {
51 | return unsafeBitCast(self.parent, to: UInt.self)
52 | }
53 | }
54 |
--------------------------------------------------------------------------------
/MachOExplorer/Model/Overrides/MachO/MKFixup+Model.swift:
--------------------------------------------------------------------------------
1 | //----------------------------------------------------------------------------//
2 | //|
3 | //| MachOExplorer - A Graphical Mach-O Viewer
4 | //! @file MKFixup+Model.swift
5 | //!
6 | //! @author D.V.
7 | //! @copyright Copyright (c) 2018 D.V. All rights reserved.
8 | //|
9 | //| Permission is hereby granted, free of charge, to any person obtaining a
10 | //| copy of this software and associated documentation files (the "Software"),
11 | //| to deal in the Software without restriction, including without limitation
12 | //| the rights to use, copy, modify, merge, publish, distribute, sublicense,
13 | //| and/or sell copies of the Software, and to permit persons to whom the
14 | //| Software is furnished to do so, subject to the following conditions:
15 | //|
16 | //| The above copyright notice and this permission notice shall be included
17 | //| in all copies or substantial portions of the Software.
18 | //|
19 | //| THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
20 | //| OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
21 | //| MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
22 | //| IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
23 | //| CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
24 | //| TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
25 | //| SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
26 | //----------------------------------------------------------------------------//
27 |
28 | import MachOKit
29 |
30 | extension MKFixup /* DetailModel */
31 | {
32 | override var detail_rows: [DetailRowModel] {
33 | return [self]
34 | }
35 | }
36 |
37 | extension MKFixup /* DetailRowModel */
38 | {
39 | override var detail_value: String? {
40 | let addressField = self.layout.field(withName: "address", searchAllFields: false)!
41 | let address = addressField.valueFormatter?.string(for: addressField.valueRecipe.value(for: addressField, of: self).value)
42 |
43 | let sectionField = self.layout.field(withName: "section", searchAllFields: false)!
44 | let section = sectionField.valueRecipe.value(for: sectionField, of: self).value?.description
45 |
46 | if let section = section {
47 | return "\(address!) (\(section))"
48 | } else {
49 | return "\(address!)"
50 | }
51 | }
52 |
53 | override var detail_description: String? {
54 | let typeField = self.layout.field(withName: "type", searchAllFields: false)!
55 | let type = typeField.valueFormatter?.string(for: typeField.valueRecipe.value(for: typeField, of: self).value)
56 |
57 | return type
58 | }
59 | }
60 |
--------------------------------------------------------------------------------
/MachOExplorer/Model/Overrides/MachO/MKFunctionStarts+Model.swift:
--------------------------------------------------------------------------------
1 | //----------------------------------------------------------------------------//
2 | //|
3 | //| MachOExplorer - A Graphical Mach-O Viewer
4 | //! @file MKFunctionStarts+Model.swift
5 | //!
6 | //! @author D.V.
7 | //! @copyright Copyright (c) 2018 D.V. All rights reserved.
8 | //|
9 | //| Permission is hereby granted, free of charge, to any person obtaining a
10 | //| copy of this software and associated documentation files (the "Software"),
11 | //| to deal in the Software without restriction, including without limitation
12 | //| the rights to use, copy, modify, merge, publish, distribute, sublicense,
13 | //| and/or sell copies of the Software, and to permit persons to whom the
14 | //| Software is furnished to do so, subject to the following conditions:
15 | //|
16 | //| The above copyright notice and this permission notice shall be included
17 | //| in all copies or substantial portions of the Software.
18 | //|
19 | //| THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
20 | //| OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
21 | //| MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
22 | //| IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
23 | //| CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
24 | //| TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
25 | //| SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
26 | //----------------------------------------------------------------------------//
27 |
28 | import MachOKit
29 |
30 | extension MKFunctionStarts /* OutlineNodeModel */
31 | {
32 | override var outline_children: [OutlineNodeModel] {
33 | return []
34 | }
35 | }
36 |
37 | extension MKFunctionStarts /* DetailModel */
38 | {
39 | class Adapter: NSObject {
40 | var offset: MKFunctionOffset?
41 | var function: MKFunction?
42 |
43 | init(offset: MKFunctionOffset?, function: MKFunction?) {
44 | super.init()
45 | self.offset = offset
46 | self.function = function
47 | }
48 |
49 | override var detail_value: String? {
50 | return self.function?.detail_value
51 | }
52 |
53 | override var detail_description: String? {
54 | return self.offset?.detail_value
55 | }
56 |
57 | override var detail_data: Data? {
58 | return self.offset?.detail_data
59 | }
60 |
61 | override func detail_address(mode addressMode: MKNodeAddressType) -> NSNumber? {
62 | return self.offset?.detail_address(mode: addressMode)
63 | }
64 | }
65 |
66 | override var detail_rows: [DetailRowModel] {
67 | var rows = Array()
68 |
69 | let offsets = self.offsets
70 | let functions = self.functions
71 |
72 | var i = 0;
73 | let count = max(offsets.count, functions.count)
74 | while i < count {
75 | let offset = i < offsets.count ? offsets[i] : nil
76 | let function = i < functions.count ? functions[i] : nil
77 |
78 | rows.append(Adapter(offset: offset, function: function))
79 | i = i + 1
80 | }
81 |
82 | return rows
83 | }
84 | }
85 |
--------------------------------------------------------------------------------
/MachOExplorer/Model/Overrides/MachO/MKPointerNode+Model.swift:
--------------------------------------------------------------------------------
1 | //----------------------------------------------------------------------------//
2 | //|
3 | //| MachOExplorer - A Graphical Mach-O Viewer
4 | //! @file MKPointerNode+Model.swift
5 | //!
6 | //! @author D.V.
7 | //! @copyright Copyright (c) 2018 D.V. All rights reserved.
8 | //|
9 | //| Permission is hereby granted, free of charge, to any person obtaining a
10 | //| copy of this software and associated documentation files (the "Software"),
11 | //| to deal in the Software without restriction, including without limitation
12 | //| the rights to use, copy, modify, merge, publish, distribute, sublicense,
13 | //| and/or sell copies of the Software, and to permit persons to whom the
14 | //| Software is furnished to do so, subject to the following conditions:
15 | //|
16 | //| The above copyright notice and this permission notice shall be included
17 | //| in all copies or substantial portions of the Software.
18 | //|
19 | //| THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
20 | //| OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
21 | //| MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
22 | //| IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
23 | //| CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
24 | //| TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
25 | //| SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
26 | //----------------------------------------------------------------------------//
27 |
28 | import MachOKit
29 |
30 | extension MKPointerNode /* OutlineModel */
31 | {
32 | override var outline_nodes: [OutlineNodeModel] {
33 | // Use KVC to get the 'value' to work around a swift compiler crash
34 | if let pointee = self.pointee.value(forKey: "value") {
35 | return [(pointee as! NSObject)]
36 | } else {
37 | return super.outline_nodes
38 | }
39 | }
40 | }
41 |
--------------------------------------------------------------------------------
/MachOExplorer/Model/Overrides/MachO/MKSection+Model.swift:
--------------------------------------------------------------------------------
1 | //----------------------------------------------------------------------------//
2 | //|
3 | //| MachOExplorer - A Graphical Mach-O Viewer
4 | //! @file MKSection+Model.swift
5 | //!
6 | //! @author D.V.
7 | //! @copyright Copyright (c) 2018 D.V. All rights reserved.
8 | //|
9 | //| Permission is hereby granted, free of charge, to any person obtaining a
10 | //| copy of this software and associated documentation files (the "Software"),
11 | //| to deal in the Software without restriction, including without limitation
12 | //| the rights to use, copy, modify, merge, publish, distribute, sublicense,
13 | //| and/or sell copies of the Software, and to permit persons to whom the
14 | //| Software is furnished to do so, subject to the following conditions:
15 | //|
16 | //| The above copyright notice and this permission notice shall be included
17 | //| in all copies or substantial portions of the Software.
18 | //|
19 | //| THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
20 | //| OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
21 | //| MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
22 | //| IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
23 | //| CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
24 | //| TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
25 | //| SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
26 | //----------------------------------------------------------------------------//
27 |
28 | import MachOKit
29 |
30 | extension MKSection
31 | {
32 | override func adapter(forField field: MKNodeField) -> FieldAdapter? {
33 | if field.name == "name" ||
34 | field.name == "alignment" ||
35 | field.name == "fileOffset" ||
36 | field.name == "vmAddress" ||
37 | field.name == "size" ||
38 | field.name == "type" ||
39 | field.name == "userAttributes" ||
40 | field.name == "systemAttributes" {
41 | return nil
42 | }
43 |
44 | return super.adapter(forField: field)
45 | }
46 | }
47 |
48 | extension MKSection /* OutlineNodeModel */
49 | {
50 | override var outline_title: String {
51 | return "Section (" + self.description + ")"
52 | }
53 | }
54 |
--------------------------------------------------------------------------------
/MachOExplorer/Model/Overrides/ObjC/MKObjCCategory+Model.swift:
--------------------------------------------------------------------------------
1 | //----------------------------------------------------------------------------//
2 | //|
3 | //| MachOExplorer - A Graphical Mach-O Viewer
4 | //! @file MKObjCCategory+Model.swift
5 | //!
6 | //! @author D.V.
7 | //! @copyright Copyright (c) 2018 D.V. All rights reserved.
8 | //|
9 | //| Permission is hereby granted, free of charge, to any person obtaining a
10 | //| copy of this software and associated documentation files (the "Software"),
11 | //| to deal in the Software without restriction, including without limitation
12 | //| the rights to use, copy, modify, merge, publish, distribute, sublicense,
13 | //| and/or sell copies of the Software, and to permit persons to whom the
14 | //| Software is furnished to do so, subject to the following conditions:
15 | //|
16 | //| The above copyright notice and this permission notice shall be included
17 | //| in all copies or substantial portions of the Software.
18 | //|
19 | //| THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
20 | //| OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
21 | //| MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
22 | //| IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
23 | //| CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
24 | //| TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
25 | //| SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
26 | //----------------------------------------------------------------------------//
27 |
28 | import MachOKit
29 |
30 | extension MKObjCCategory
31 | {
32 | override open var description: String {
33 | if let name = self.name.pointee.value?.string {
34 | return name
35 | } else {
36 | return super.description
37 | }
38 | }
39 | }
40 |
--------------------------------------------------------------------------------
/MachOExplorer/Model/Overrides/ObjC/MKObjCClass+Model.swift:
--------------------------------------------------------------------------------
1 | //----------------------------------------------------------------------------//
2 | //|
3 | //| MachOExplorer - A Graphical Mach-O Viewer
4 | //! @file MKObjCClass+Model.swift
5 | //!
6 | //! @author D.V.
7 | //! @copyright Copyright (c) 2018 D.V. All rights reserved.
8 | //|
9 | //| Permission is hereby granted, free of charge, to any person obtaining a
10 | //| copy of this software and associated documentation files (the "Software"),
11 | //| to deal in the Software without restriction, including without limitation
12 | //| the rights to use, copy, modify, merge, publish, distribute, sublicense,
13 | //| and/or sell copies of the Software, and to permit persons to whom the
14 | //| Software is furnished to do so, subject to the following conditions:
15 | //|
16 | //| The above copyright notice and this permission notice shall be included
17 | //| in all copies or substantial portions of the Software.
18 | //|
19 | //| THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
20 | //| OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
21 | //| MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
22 | //| IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
23 | //| CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
24 | //| TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
25 | //| SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
26 | //----------------------------------------------------------------------------//
27 |
28 | import MachOKit
29 |
30 | extension MKObjCClass
31 | {
32 | override open var description: String {
33 | if let className = self.classData.pointee.value?.name.pointee.value?.string {
34 | return className
35 | } else {
36 | return super.description
37 | }
38 | }
39 | }
40 |
--------------------------------------------------------------------------------
/MachOExplorer/Model/Overrides/ObjC/MKObjCProtocol+Model.swift:
--------------------------------------------------------------------------------
1 | //----------------------------------------------------------------------------//
2 | //|
3 | //| MachOExplorer - A Graphical Mach-O Viewer
4 | //! @file MKObjCProtocol+Model.swift
5 | //!
6 | //! @author D.V.
7 | //! @copyright Copyright (c) 2018 D.V. All rights reserved.
8 | //|
9 | //| Permission is hereby granted, free of charge, to any person obtaining a
10 | //| copy of this software and associated documentation files (the "Software"),
11 | //| to deal in the Software without restriction, including without limitation
12 | //| the rights to use, copy, modify, merge, publish, distribute, sublicense,
13 | //| and/or sell copies of the Software, and to permit persons to whom the
14 | //| Software is furnished to do so, subject to the following conditions:
15 | //|
16 | //| The above copyright notice and this permission notice shall be included
17 | //| in all copies or substantial portions of the Software.
18 | //|
19 | //| THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
20 | //| OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
21 | //| MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
22 | //| IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
23 | //| CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
24 | //| TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
25 | //| SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
26 | //----------------------------------------------------------------------------//
27 |
28 | import MachOKit
29 |
30 | extension MKObjCProtocol
31 | {
32 | override open var description: String {
33 | if let name = self.mangledName.pointee.value?.string {
34 | return name
35 | } else {
36 | return super.description
37 | }
38 | }
39 | }
40 |
--------------------------------------------------------------------------------
/MachOExplorer/Model/Type/BitFieldTypeAdapter.swift:
--------------------------------------------------------------------------------
1 | //----------------------------------------------------------------------------//
2 | //|
3 | //| MachOExplorer - A Graphical Mach-O Viewer
4 | //! @file BitFieldTypeAdapter.swift
5 | //!
6 | //! @author D.V.
7 | //! @copyright Copyright (c) 2018 D.V. All rights reserved.
8 | //|
9 | //| Permission is hereby granted, free of charge, to any person obtaining a
10 | //| copy of this software and associated documentation files (the "Software"),
11 | //| to deal in the Software without restriction, including without limitation
12 | //| the rights to use, copy, modify, merge, publish, distribute, sublicense,
13 | //| and/or sell copies of the Software, and to permit persons to whom the
14 | //| Software is furnished to do so, subject to the following conditions:
15 | //|
16 | //| The above copyright notice and this permission notice shall be included
17 | //| in all copies or substantial portions of the Software.
18 | //|
19 | //| THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
20 | //| OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
21 | //| MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
22 | //| IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
23 | //| CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
24 | //| TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
25 | //| SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
26 | //----------------------------------------------------------------------------//
27 |
28 | import MachOKit
29 |
30 | class BitfieldTypeAdapter: TypeAdapter
31 | {
32 | required init(value: NSObject, ofType type: MKNodeFieldType, inNode node: MKNode) {
33 | assert(type is MKNodeFieldBitfieldType)
34 | super.init(value: value, ofType: type, inNode: node)
35 | }
36 |
37 | override var providesSubFields: Bool {
38 | let type = self.type as! MKNodeFieldBitfieldType
39 |
40 | if type.bits.count > 1 {
41 | return true
42 | } else {
43 | return false
44 | }
45 | }
46 | }
47 |
48 | extension BitfieldTypeAdapter /* DetailModel */
49 | {
50 | override var detail_rows: [DetailRowModel] {
51 | guard let value = self.value as? NSNumber else { return super.detail_rows }
52 |
53 | let type = self.type as! MKNodeFieldBitfieldType
54 | var rows = Array()
55 |
56 | for mask in type.bits {
57 | let maskedValue = value.mk_mask(using: mask)
58 | let shiftedValue = maskedValue.mk_shift(type.shift(forMask: mask))
59 |
60 | if let type = type.type(forMask: mask) {
61 | if type is MKNodeFieldEnumerationType {
62 | rows += BitfieldEnumerationTypeAdapter(value: shiftedValue, unshiftedValue: maskedValue, ofType: type, inContainerType: self.type, inNode: self.node).detail_rows
63 | } else {
64 | rows += TypeAdapter.For(value: shiftedValue, ofType: type, inNode: self.node).detail_rows
65 | }
66 | } else {
67 | // TODO -
68 | continue;
69 | }
70 | }
71 |
72 | return rows
73 | }
74 | }
75 |
76 |
77 |
78 | class BitfieldEnumerationTypeAdapter: TypeAdapter
79 | {
80 | let unshiftedValue: NSObject
81 | let containerType: MKNodeFieldType
82 |
83 | required init(value: NSObject, unshiftedValue: NSObject, ofType type: MKNodeFieldType, inContainerType containerType: MKNodeFieldType, inNode node: MKNode) {
84 | assert(type is MKNodeFieldEnumerationType)
85 | self.unshiftedValue = unshiftedValue
86 | self.containerType = containerType
87 | super.init(value: value, ofType: type, inNode: node)
88 | }
89 |
90 | required init(value: NSObject, ofType type: MKNodeFieldType, inNode node: MKNode) {
91 | assert(type is MKNodeFieldContainerType)
92 | self.unshiftedValue = value
93 | self.containerType = type
94 | super.init(value: value, ofType: type, inNode: node)
95 | }
96 |
97 | override var detail_description: String? {
98 | switch (self.containerType as! MKNodeFieldNumericType).size(for: self.node) {
99 | case 1:
100 | return Formatter.mk_hex8().string(for: self.unshiftedValue)
101 | case 2:
102 | return Formatter.mk_hex16().string(for: self.unshiftedValue)
103 | case 4:
104 | return Formatter.mk_hex32().string(for: self.unshiftedValue)
105 | case 8:
106 | return Formatter.mk_hex64().string(for: self.unshiftedValue)
107 | default:
108 | return Formatter.mk_hex().string(for: self.unshiftedValue)
109 | }
110 | }
111 | }
112 |
--------------------------------------------------------------------------------
/MachOExplorer/Model/Type/CollectionTypeAdapter.swift:
--------------------------------------------------------------------------------
1 | //----------------------------------------------------------------------------//
2 | //|
3 | //| MachOExplorer - A Graphical Mach-O Viewer
4 | //! @file CollectionTypeAdapter.swift
5 | //!
6 | //! @author D.V.
7 | //! @copyright Copyright (c) 2018 D.V. All rights reserved.
8 | //|
9 | //| Permission is hereby granted, free of charge, to any person obtaining a
10 | //| copy of this software and associated documentation files (the "Software"),
11 | //| to deal in the Software without restriction, including without limitation
12 | //| the rights to use, copy, modify, merge, publish, distribute, sublicense,
13 | //| and/or sell copies of the Software, and to permit persons to whom the
14 | //| Software is furnished to do so, subject to the following conditions:
15 | //|
16 | //| The above copyright notice and this permission notice shall be included
17 | //| in all copies or substantial portions of the Software.
18 | //|
19 | //| THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
20 | //| OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
21 | //| MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
22 | //| IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
23 | //| CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
24 | //| TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
25 | //| SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
26 | //----------------------------------------------------------------------------//
27 |
28 | import MachOKit
29 |
30 | class CollectionTypeAdapter: TypeAdapter
31 | {
32 | required init(value: NSObject, ofType type: MKNodeFieldType, inNode node: MKNode) {
33 | assert(type is MKNodeFieldCollectionType)
34 | super.init(value: value, ofType: type, inNode: node)
35 | }
36 | }
37 |
38 | extension CollectionTypeAdapter /* OutlineModel */
39 | {
40 | override var outline_nodes: [OutlineNodeModel] {
41 | let collectionType = self.type as! MKNodeFieldCollectionType
42 |
43 | if let elementType = collectionType.elementType {
44 | return self.value.outline_nodes.reduce([], { $0 + TypeAdapter.For(value: $1 as! NSObject, ofType: elementType, inNode: self.node).outline_nodes })
45 | } else {
46 | return self.value.outline_nodes
47 | }
48 | }
49 | }
50 |
51 | extension CollectionTypeAdapter /* DetailModel */
52 | {
53 | override var detail_rows: [DetailRowModel] {
54 | let collectionType = self.type as! MKNodeFieldCollectionType
55 |
56 | if let elementType = collectionType.elementType {
57 | return self.value.detail_rows.reduce([], { $0 + TypeAdapter.For(value: $1 as! NSObject, ofType: elementType, inNode: self.node).detail_rows })
58 | } else {
59 | return self.value.detail_rows
60 | }
61 | }
62 | }
63 |
--------------------------------------------------------------------------------
/MachOExplorer/Model/Type/ContainerTypeAdapter.swift:
--------------------------------------------------------------------------------
1 | //----------------------------------------------------------------------------//
2 | //|
3 | //| MachOExplorer - A Graphical Mach-O Viewer
4 | //! @file ContainerTypeAdapter.swift
5 | //!
6 | //! @author D.V.
7 | //! @copyright Copyright (c) 2018 D.V. All rights reserved.
8 | //|
9 | //| Permission is hereby granted, free of charge, to any person obtaining a
10 | //| copy of this software and associated documentation files (the "Software"),
11 | //| to deal in the Software without restriction, including without limitation
12 | //| the rights to use, copy, modify, merge, publish, distribute, sublicense,
13 | //| and/or sell copies of the Software, and to permit persons to whom the
14 | //| Software is furnished to do so, subject to the following conditions:
15 | //|
16 | //| The above copyright notice and this permission notice shall be included
17 | //| in all copies or substantial portions of the Software.
18 | //|
19 | //| THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
20 | //| OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
21 | //| MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
22 | //| IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
23 | //| CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
24 | //| TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
25 | //| SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
26 | //----------------------------------------------------------------------------//
27 |
28 | import MachOKit
29 |
30 | class ContainerTypeAdapter: TypeAdapter
31 | {
32 | required init(value: NSObject, ofType type: MKNodeFieldType, inNode node: MKNode) {
33 | assert(type is MKNodeFieldContainerType)
34 | super.init(value: value, ofType: type, inNode: node)
35 | }
36 | }
37 |
38 | extension ContainerTypeAdapter /* OutlineModel */
39 | {
40 | override var outline_nodes: [OutlineNodeModel] {
41 | return self.value.outline_nodes
42 | }
43 | }
44 |
45 | extension ContainerTypeAdapter /* DetailModel */
46 | {
47 | override var detail_rows: [DetailRowModel] {
48 | return self.value.detail_rows
49 | }
50 | }
51 |
--------------------------------------------------------------------------------
/MachOExplorer/Model/Type/OptionSetTypeAdapter.swift:
--------------------------------------------------------------------------------
1 | //----------------------------------------------------------------------------//
2 | //|
3 | //| MachOExplorer - A Graphical Mach-O Viewer
4 | //! @file OptionSetTypeAdapter.swift
5 | //!
6 | //! @author D.V.
7 | //! @copyright Copyright (c) 2018 D.V. All rights reserved.
8 | //|
9 | //| Permission is hereby granted, free of charge, to any person obtaining a
10 | //| copy of this software and associated documentation files (the "Software"),
11 | //| to deal in the Software without restriction, including without limitation
12 | //| the rights to use, copy, modify, merge, publish, distribute, sublicense,
13 | //| and/or sell copies of the Software, and to permit persons to whom the
14 | //| Software is furnished to do so, subject to the following conditions:
15 | //|
16 | //| The above copyright notice and this permission notice shall be included
17 | //| in all copies or substantial portions of the Software.
18 | //|
19 | //| THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
20 | //| OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
21 | //| MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
22 | //| IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
23 | //| CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
24 | //| TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
25 | //| SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
26 | //----------------------------------------------------------------------------//
27 |
28 | import MachOKit
29 |
30 | class OptionSetTypeAdapter: TypeAdapter
31 | {
32 | required init(value: NSObject, ofType type: MKNodeFieldType, inNode node: MKNode) {
33 | assert(type is MKNodeFieldOptionSetType)
34 | super.init(value: value, ofType: type, inNode: node)
35 | }
36 |
37 | override var providesSubFields: Bool { return true }
38 | }
39 |
40 | extension OptionSetTypeAdapter /* DetailModel, DetailRowModel */
41 | {
42 | class OptionDetailRowAdapter: NSObject
43 | {
44 | let value: NSNumber
45 | let name: String
46 |
47 | init(_ value: NSNumber, _ name: String) {
48 | self.value = value
49 | self.name = name
50 | }
51 |
52 | override var detail_value: String? {
53 | return self.name
54 | }
55 |
56 | override var detail_description: String? {
57 | return Formatter.mk_hex().string(for: self.value)
58 | }
59 | }
60 |
61 | override var detail_rows: [DetailRowModel] {
62 | guard let value = self.value as? NSNumber else { return [] }
63 |
64 | let v: UInt64 = value.mk_UnsignedValue(nil)
65 | guard v != 0 || (self.type as! MKNodeFieldOptionSetType).options[0] != nil else {
66 | return []
67 | }
68 |
69 | var rows = Array()
70 |
71 | for (mask, name) in (self.type as! MKNodeFieldOptionSetType).options {
72 | let m: UInt64 = mask.mk_UnsignedValue(nil)
73 |
74 | if m == 0 && v != 0 {
75 | continue
76 | }
77 |
78 | if (v & m) == m {
79 | rows.append(OptionDetailRowAdapter(mask, name))
80 | } else if (self.type as! MKNodeFieldOptionSetType).optionSetTraits.contains(.partialMatchingAllowed) {
81 | if (v & m) != 0 {
82 | rows.append(OptionDetailRowAdapter(mask, name))
83 | }
84 | }
85 | }
86 |
87 | return rows
88 | }
89 | }
90 |
--------------------------------------------------------------------------------
/MachOExplorer/Model/Type/TypeAdapter.swift:
--------------------------------------------------------------------------------
1 | //----------------------------------------------------------------------------//
2 | //|
3 | //| MachOExplorer - A Graphical Mach-O Viewer
4 | //! @file TypeAdapter.swift
5 | //!
6 | //! @author D.V.
7 | //! @copyright Copyright (c) 2018 D.V. All rights reserved.
8 | //|
9 | //| Permission is hereby granted, free of charge, to any person obtaining a
10 | //| copy of this software and associated documentation files (the "Software"),
11 | //| to deal in the Software without restriction, including without limitation
12 | //| the rights to use, copy, modify, merge, publish, distribute, sublicense,
13 | //| and/or sell copies of the Software, and to permit persons to whom the
14 | //| Software is furnished to do so, subject to the following conditions:
15 | //|
16 | //| The above copyright notice and this permission notice shall be included
17 | //| in all copies or substantial portions of the Software.
18 | //|
19 | //| THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
20 | //| OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
21 | //| MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
22 | //| IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
23 | //| CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
24 | //| TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
25 | //| SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
26 | //----------------------------------------------------------------------------//
27 |
28 | import MachOKit
29 |
30 | class TypeAdapter: NSObject
31 | {
32 | let value: NSObject
33 | let type: MKNodeFieldType
34 | let node: MKNode
35 |
36 | required init(value: NSObject, ofType type: MKNodeFieldType, inNode node: MKNode) {
37 | self.value = value
38 | self.type = type
39 | self.node = node;
40 | }
41 |
42 | static func For(value: NSObject, ofType type: MKNodeFieldType, inNode node: MKNode) -> TypeAdapter {
43 | if type is MKNodeFieldOptionSetType {
44 | return OptionSetTypeAdapter(value: value, ofType: type, inNode: node)
45 | }
46 | else if type is MKNodeFieldBitfieldType {
47 | return BitfieldTypeAdapter(value: value, ofType: type, inNode: node)
48 | }
49 | else if type is MKNodeFieldCollectionType {
50 | return CollectionTypeAdapter(value: value, ofType: type, inNode: node)
51 | }
52 | else if type is MKNodeFieldContainerType {
53 | return ContainerTypeAdapter(value: value, ofType: type, inNode: node)
54 | }
55 | else {
56 | return TypeAdapter(value: value, ofType: type, inNode: node)
57 | }
58 | }
59 |
60 | var providesSubFields: Bool { return false }
61 | }
62 |
63 | extension TypeAdapter /* OutlineModel */
64 | {
65 | override var outline_nodes: [OutlineNodeModel] {
66 | return [self]
67 | }
68 | }
69 |
70 | extension TypeAdapter /* OutlineNodeModel */
71 | {
72 | override var outline_isLeaf: Bool {
73 | return self.value.outline_isLeaf
74 | }
75 |
76 | override var outline_childCount: Int {
77 | return self.value.outline_childCount
78 | }
79 |
80 | override var outline_children: [OutlineNodeModel] {
81 | return self.value.outline_children
82 | }
83 |
84 | override var outline_title: String {
85 | if let formatter = self.type.formatter,
86 | let formattedDescription = formatter.string(for: self.value) {
87 | return formattedDescription
88 | } else {
89 | return self.value.outline_title
90 | }
91 | }
92 | }
93 |
94 | extension TypeAdapter /* DetailModel */
95 | {
96 | override var detail_rows: [DetailRowModel] {
97 | return [self]
98 | }
99 | }
100 |
101 | extension TypeAdapter /* DetailRowModel */
102 | {
103 | override var detail_value: String? {
104 | if let formatter = self.type.formatter,
105 | let formattedDescription = formatter.string(for: self.value) {
106 | return formattedDescription
107 | } else if let valueDescription = self.value.detail_value {
108 | return valueDescription
109 | } else {
110 | return nil
111 | }
112 | }
113 |
114 | override var detail_description: String? {
115 | return self.type.name
116 | }
117 |
118 | override var detail_data: Data? {
119 | return self.value.detail_data
120 | }
121 |
122 | override func detail_address(mode addressMode: MKNodeAddressType) -> NSNumber? {
123 | return self.value.detail_address(mode: addressMode)
124 | }
125 | }
126 |
--------------------------------------------------------------------------------
/MachOExplorer/Model/Value/MKOptional+Model.swift:
--------------------------------------------------------------------------------
1 | //----------------------------------------------------------------------------//
2 | //|
3 | //| MachOExplorer - A Graphical Mach-O Viewer
4 | //! @file MKOptional+Model.swift
5 | //!
6 | //! @author D.V.
7 | //! @copyright Copyright (c) 2018 D.V. All rights reserved.
8 | //|
9 | //| Permission is hereby granted, free of charge, to any person obtaining a
10 | //| copy of this software and associated documentation files (the "Software"),
11 | //| to deal in the Software without restriction, including without limitation
12 | //| the rights to use, copy, modify, merge, publish, distribute, sublicense,
13 | //| and/or sell copies of the Software, and to permit persons to whom the
14 | //| Software is furnished to do so, subject to the following conditions:
15 | //|
16 | //| The above copyright notice and this permission notice shall be included
17 | //| in all copies or substantial portions of the Software.
18 | //|
19 | //| THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
20 | //| OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
21 | //| MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
22 | //| IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
23 | //| CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
24 | //| TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
25 | //| SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
26 | //----------------------------------------------------------------------------//
27 |
28 | import MachOKit
29 |
30 | extension MKOptional /* OutlineModel */
31 | {
32 | override var outline_nodes: [OutlineNodeModel] {
33 | // Use KVC to get the 'value' to work around a swift compiler crash
34 | if let value = self.value(forKey: "value") as? OutlineModel {
35 | return value.outline_nodes
36 | } else {
37 | return []
38 | }
39 | }
40 | }
41 |
42 | extension MKOptional /* DetailModel */
43 | {
44 | override var detail_rows: [DetailRowModel] {
45 | // Use KVC to get the 'value' to work around a swift compiler crash
46 | if let value = self.value(forKey: "value") as? DetailModel {
47 | return value.detail_rows
48 | } else {
49 | return []
50 | }
51 | }
52 | }
53 |
--------------------------------------------------------------------------------
/MachOExplorer/Model/Value/NSArray+Model.swift:
--------------------------------------------------------------------------------
1 | //----------------------------------------------------------------------------//
2 | //|
3 | //| MachOExplorer - A Graphical Mach-O Viewer
4 | //! @file NSArray+Model.swift
5 | //!
6 | //! @author D.V.
7 | //! @copyright Copyright (c) 2018 D.V. All rights reserved.
8 | //|
9 | //| Permission is hereby granted, free of charge, to any person obtaining a
10 | //| copy of this software and associated documentation files (the "Software"),
11 | //| to deal in the Software without restriction, including without limitation
12 | //| the rights to use, copy, modify, merge, publish, distribute, sublicense,
13 | //| and/or sell copies of the Software, and to permit persons to whom the
14 | //| Software is furnished to do so, subject to the following conditions:
15 | //|
16 | //| The above copyright notice and this permission notice shall be included
17 | //| in all copies or substantial portions of the Software.
18 | //|
19 | //| THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
20 | //| OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
21 | //| MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
22 | //| IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
23 | //| CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
24 | //| TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
25 | //| SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
26 | //----------------------------------------------------------------------------//
27 |
28 | import MachOKit
29 |
30 | extension NSArray /* OutlineModel */
31 | {
32 | override var outline_nodes: [OutlineNodeModel] {
33 | return (self as! [NSObject]).reduce([], { $0 + $1.outline_nodes })
34 | }
35 | }
36 |
37 | extension NSArray /* DetailModel */
38 | {
39 | override var detail_rows: [DetailRowModel] {
40 | if self.count < 1 {
41 | return [];
42 | }
43 |
44 | var detailRowModels = Array()
45 |
46 | // Optimization - Ask the first item for its detail_rows, assume that
47 | // the detail_rows of every item will contain the same number of
48 | // DetailRowModel objects.
49 | let reserveCapacity = self.count * (self[0] as! NSObject).detail_rows.count;
50 | detailRowModels.reserveCapacity(reserveCapacity);
51 |
52 | for item in self {
53 | detailRowModels += (item as! NSObject).detail_rows;
54 | }
55 |
56 | return detailRowModels;
57 | }
58 | }
59 |
--------------------------------------------------------------------------------
/MachOExplorer/Model/Value/NSDictionary+Model.swift:
--------------------------------------------------------------------------------
1 | //----------------------------------------------------------------------------//
2 | //|
3 | //| MachOExplorer - A Graphical Mach-O Viewer
4 | //! @file NSDictionary+Model.swift
5 | //!
6 | //! @author D.V.
7 | //! @copyright Copyright (c) 2018 D.V. All rights reserved.
8 | //|
9 | //| Permission is hereby granted, free of charge, to any person obtaining a
10 | //| copy of this software and associated documentation files (the "Software"),
11 | //| to deal in the Software without restriction, including without limitation
12 | //| the rights to use, copy, modify, merge, publish, distribute, sublicense,
13 | //| and/or sell copies of the Software, and to permit persons to whom the
14 | //| Software is furnished to do so, subject to the following conditions:
15 | //|
16 | //| The above copyright notice and this permission notice shall be included
17 | //| in all copies or substantial portions of the Software.
18 | //|
19 | //| THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
20 | //| OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
21 | //| MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
22 | //| IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
23 | //| CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
24 | //| TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
25 | //| SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
26 | //----------------------------------------------------------------------------//
27 |
28 | import MachOKit
29 |
30 | extension NSDictionary /* OutlineModel */
31 | {
32 | override var outline_nodes: [OutlineNodeModel] {
33 | return (self.allValues as! [NSObject]).reduce([], { $0 + $1.outline_nodes })
34 | }
35 | }
36 |
37 | extension NSDictionary /* DetailModel */
38 | {
39 | override var detail_rows: [DetailRowModel] {
40 | return (self.allValues as! [NSObject]).reduce([], { $0 + $1.detail_rows })
41 | }
42 | }
43 |
--------------------------------------------------------------------------------
/MachOExplorer/Model/Value/NSObject+Model.swift:
--------------------------------------------------------------------------------
1 | //----------------------------------------------------------------------------//
2 | //|
3 | //| MachOExplorer - A Graphical Mach-O Viewer
4 | //! @file NSObject+Model.swift
5 | //!
6 | //! @author D.V.
7 | //! @copyright Copyright (c) 2018 D.V. All rights reserved.
8 | //|
9 | //| Permission is hereby granted, free of charge, to any person obtaining a
10 | //| copy of this software and associated documentation files (the "Software"),
11 | //| to deal in the Software without restriction, including without limitation
12 | //| the rights to use, copy, modify, merge, publish, distribute, sublicense,
13 | //| and/or sell copies of the Software, and to permit persons to whom the
14 | //| Software is furnished to do so, subject to the following conditions:
15 | //|
16 | //| The above copyright notice and this permission notice shall be included
17 | //| in all copies or substantial portions of the Software.
18 | //|
19 | //| THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
20 | //| OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
21 | //| MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
22 | //| IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
23 | //| CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
24 | //| TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
25 | //| SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
26 | //----------------------------------------------------------------------------//
27 |
28 | import MachOKit
29 |
30 | extension NSObject: Model { }
31 |
32 | extension NSObject: OutlineModel
33 | {
34 | var outline_nodes: [OutlineNodeModel] {
35 | return [self]
36 | }
37 | }
38 |
39 | extension NSObject: OutlineNodeModel
40 | {
41 | var outline_isLeaf: Bool {
42 | return true
43 | }
44 |
45 | var outline_childCount: Int {
46 | return 0
47 | }
48 |
49 | var outline_children: [OutlineNodeModel] {
50 | return []
51 | }
52 |
53 | var outline_title: String {
54 | return self.description
55 | }
56 | }
57 |
58 | extension NSObject: DetailModel
59 | {
60 | var detail_rows: [DetailRowModel] {
61 | return [self]
62 | }
63 | }
64 |
65 | extension NSObject: DetailRowModel
66 | {
67 | var detail_value: String? {
68 | return self.description
69 | }
70 |
71 | var detail_description: String? {
72 | return type(of: self).description()
73 | }
74 |
75 | var detail_data: Data? {
76 | return nil
77 | }
78 |
79 | func detail_address(mode addressMode: MKNodeAddressType) -> NSNumber? {
80 | return nil
81 | }
82 | }
83 |
--------------------------------------------------------------------------------
/MachOExplorer/Utility/NS+Initialize.h:
--------------------------------------------------------------------------------
1 | //----------------------------------------------------------------------------//
2 | //|
3 | //| MachOExplorer - A Graphical Mach-O Viewer
4 | //! @file NS+Initialize.h
5 | //!
6 | //! @author D.V.
7 | //! @copyright Copyright (c) 2018 D.V. All rights reserved.
8 | //|
9 | //| Permission is hereby granted, free of charge, to any person obtaining a
10 | //| copy of this software and associated documentation files (the "Software"),
11 | //| to deal in the Software without restriction, including without limitation
12 | //| the rights to use, copy, modify, merge, publish, distribute, sublicense,
13 | //| and/or sell copies of the Software, and to permit persons to whom the
14 | //| Software is furnished to do so, subject to the following conditions:
15 | //|
16 | //| The above copyright notice and this permission notice shall be included
17 | //| in all copies or substantial portions of the Software.
18 | //|
19 | //| THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
20 | //| OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
21 | //| MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
22 | //| IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
23 | //| CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
24 | //| TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
25 | //| SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
26 | //----------------------------------------------------------------------------//
27 |
28 | @import Cocoa;
29 |
30 | @interface NSViewController (Initialize)
31 | + (void)heySwiftSomePeopleStillNeedToOverrideInitialize;
32 | @end
33 |
--------------------------------------------------------------------------------
/MachOExplorer/Utility/NS+Initialize.m:
--------------------------------------------------------------------------------
1 | //----------------------------------------------------------------------------//
2 | //|
3 | //| MachOExplorer - A Graphical Mach-O Viewer
4 | //| NS+Initialize.m
5 | //|
6 | //| D.V.
7 | //| Copyright (c) 2018 D.V. All rights reserved.
8 | //|
9 | //| Permission is hereby granted, free of charge, to any person obtaining a
10 | //| copy of this software and associated documentation files (the "Software"),
11 | //| to deal in the Software without restriction, including without limitation
12 | //| the rights to use, copy, modify, merge, publish, distribute, sublicense,
13 | //| and/or sell copies of the Software, and to permit persons to whom the
14 | //| Software is furnished to do so, subject to the following conditions:
15 | //|
16 | //| The above copyright notice and this permission notice shall be included
17 | //| in all copies or substantial portions of the Software.
18 | //|
19 | //| THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
20 | //| OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
21 | //| MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
22 | //| IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
23 | //| CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
24 | //| TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
25 | //| SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
26 | //----------------------------------------------------------------------------//
27 |
28 | #import "NS+Initialize.h"
29 | #import
30 |
31 | @implementation NSViewController (Initialize)
32 |
33 | static void (*NSViewController_OriginalInitialize)(id, SEL) = NULL;
34 |
35 | static void NSViewController_Initialize(Class self, SEL _cmd)
36 | {
37 | if (NSViewController_OriginalInitialize)
38 | NSViewController_OriginalInitialize(self, _cmd);
39 |
40 | [self heySwiftSomePeopleStillNeedToOverrideInitialize];
41 | }
42 |
43 | + (void)load
44 | {
45 | NSViewController_OriginalInitialize = (typeof(NSViewController_OriginalInitialize))class_replaceMethod(object_getClass(NSViewController.class), @selector(initialize), (IMP)&NSViewController_Initialize, "v16@0:8");
46 | }
47 |
48 | + (void)heySwiftSomePeopleStillNeedToOverrideInitialize
49 | {
50 | /* For subclasses */
51 | }
52 |
53 | @end
54 |
--------------------------------------------------------------------------------
/MachOExplorer/Utility/NSValueTransformer+HexRepresentation.swift:
--------------------------------------------------------------------------------
1 | //----------------------------------------------------------------------------//
2 | //|
3 | //| MachOExplorer - A Graphical Mach-O Viewer
4 | //! @file NSValueTransformer+HexRepresentation.swift
5 | //!
6 | //! @author D.V.
7 | //! @copyright Copyright (c) 2018 D.V. All rights reserved.
8 | //|
9 | //| Permission is hereby granted, free of charge, to any person obtaining a
10 | //| copy of this software and associated documentation files (the "Software"),
11 | //| to deal in the Software without restriction, including without limitation
12 | //| the rights to use, copy, modify, merge, publish, distribute, sublicense,
13 | //| and/or sell copies of the Software, and to permit persons to whom the
14 | //| Software is furnished to do so, subject to the following conditions:
15 | //|
16 | //| The above copyright notice and this permission notice shall be included
17 | //| in all copies or substantial portions of the Software.
18 | //|
19 | //| THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
20 | //| OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
21 | //| MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
22 | //| IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
23 | //| CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
24 | //| TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
25 | //| SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
26 | //----------------------------------------------------------------------------//
27 |
28 | import Foundation
29 |
30 | class HexRepresentationValueTransformer: ValueTransformer
31 | {
32 | override static func allowsReverseTransformation() -> Bool {
33 | return false
34 | }
35 |
36 | override static func transformedValueClass() -> AnyClass {
37 | return NSString.self
38 | }
39 |
40 | override func transformedValue(_ value: Any?) -> Any? {
41 | guard let data = value as? Data else { return nil }
42 |
43 | let hexCodes: [UInt8] = [48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 65, 66, 67, 68, 69, 70]
44 | var characters = Array(repeating: 0, count: data.count * 2)
45 |
46 | data.enumerateBytes({ bytesPtr, index, stop in
47 | var i = 0
48 |
49 | for byte in bytesPtr {
50 | let hiByte = (byte & 0xF0) >> 4
51 | let loByte = (byte & 0x0F) >> 0
52 |
53 | characters[i] = hexCodes[Int(hiByte)]
54 | characters[i+1] = hexCodes[Int(loByte)]
55 |
56 | i = i + 2
57 | }
58 | })
59 |
60 | return NSString(bytes: &characters, length: characters.count, encoding: String.Encoding.ascii.rawValue)
61 | }
62 | }
63 |
--------------------------------------------------------------------------------
/MachOExplorer/Utility/NSValueTransformer+TakeFirst.swift:
--------------------------------------------------------------------------------
1 | //----------------------------------------------------------------------------//
2 | //|
3 | //| MachOExplorer - A Graphical Mach-O Viewer
4 | //! @file NSValueTransformer+TakeFirst.swift
5 | //!
6 | //! @author D.V.
7 | //! @copyright Copyright (c) 2018 D.V. All rights reserved.
8 | //|
9 | //| Permission is hereby granted, free of charge, to any person obtaining a
10 | //| copy of this software and associated documentation files (the "Software"),
11 | //| to deal in the Software without restriction, including without limitation
12 | //| the rights to use, copy, modify, merge, publish, distribute, sublicense,
13 | //| and/or sell copies of the Software, and to permit persons to whom the
14 | //| Software is furnished to do so, subject to the following conditions:
15 | //|
16 | //| The above copyright notice and this permission notice shall be included
17 | //| in all copies or substantial portions of the Software.
18 | //|
19 | //| THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
20 | //| OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
21 | //| MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
22 | //| IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
23 | //| CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
24 | //| TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
25 | //| SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
26 | //----------------------------------------------------------------------------//
27 |
28 | import Foundation
29 |
30 | class TakeFirstValueTransformer: ValueTransformer
31 | {
32 | override static func allowsReverseTransformation() -> Bool {
33 | return true
34 | }
35 |
36 | override func transformedValue(_ value: Any?) -> Any? {
37 | guard let value = value else { return nil }
38 |
39 | return (value as! NSArray).firstObject
40 | }
41 |
42 | override func reverseTransformedValue(_ value: Any?) -> Any? {
43 | guard let value = value else { return nil }
44 |
45 | return [value];
46 | }
47 | }
48 |
--------------------------------------------------------------------------------
/MachOExplorer/Utility/Utility.h:
--------------------------------------------------------------------------------
1 | //----------------------------------------------------------------------------//
2 | //|
3 | //| MachOExplorer - A Graphical Mach-O Viewer
4 | //! @file Utility.h
5 | //!
6 | //! @author D.V.
7 | //! @copyright Copyright (c) 2018 D.V. All rights reserved.
8 | //|
9 | //| Permission is hereby granted, free of charge, to any person obtaining a
10 | //| copy of this software and associated documentation files (the "Software"),
11 | //| to deal in the Software without restriction, including without limitation
12 | //| the rights to use, copy, modify, merge, publish, distribute, sublicense,
13 | //| and/or sell copies of the Software, and to permit persons to whom the
14 | //| Software is furnished to do so, subject to the following conditions:
15 | //|
16 | //| The above copyright notice and this permission notice shall be included
17 | //| in all copies or substantial portions of the Software.
18 | //|
19 | //| THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
20 | //| OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
21 | //| MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
22 | //| IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
23 | //| CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
24 | //| TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
25 | //| SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
26 | //----------------------------------------------------------------------------//
27 |
28 | @import Foundation;
29 |
30 | NS_ASSUME_NONNULL_BEGIN
31 |
32 | NSException * _Nullable ExceptionSafePerform(NS_NOESCAPE dispatch_block_t block);
33 |
34 | NS_ASSUME_NONNULL_END
35 |
--------------------------------------------------------------------------------
/MachOExplorer/Utility/Utility.m:
--------------------------------------------------------------------------------
1 | //----------------------------------------------------------------------------//
2 | //|
3 | //| MachOExplorer - A Graphical Mach-O Viewer
4 | //| Utility.m
5 | //|
6 | //| D.V.
7 | //| Copyright (c) 2018 D.V. All rights reserved.
8 | //|
9 | //| Permission is hereby granted, free of charge, to any person obtaining a
10 | //| copy of this software and associated documentation files (the "Software"),
11 | //| to deal in the Software without restriction, including without limitation
12 | //| the rights to use, copy, modify, merge, publish, distribute, sublicense,
13 | //| and/or sell copies of the Software, and to permit persons to whom the
14 | //| Software is furnished to do so, subject to the following conditions:
15 | //|
16 | //| The above copyright notice and this permission notice shall be included
17 | //| in all copies or substantial portions of the Software.
18 | //|
19 | //| THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
20 | //| OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
21 | //| MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
22 | //| IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
23 | //| CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
24 | //| TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
25 | //| SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
26 | //----------------------------------------------------------------------------//
27 |
28 | #import "Utility.h"
29 |
30 | NSException* ExceptionSafePerform(dispatch_block_t block)
31 | {
32 | @try {
33 | block();
34 | return nil;
35 | } @catch (NSException *exception) {
36 | return exception;
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/ReadMe.md:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Mach-O Explorer is a graphical Mach-O viewer for macOS. It aims to provide an interface and feature set that are similar to the venerable [MachOView](http://sourceforge.net/projects/machoview/) application. Parsing is handled by Mach-O Kit. Mach-O Explorer leverages Mach-O Kit's rich description system to present the parsed data using very little code.
6 |
7 | 
8 |
9 | Mach-O Explorer should deploy back to OS X 10.11 (and possibly further) but is *currently* only being actively tested on macOS 10.14.
10 |
11 | ### Limitations
12 |
13 | * Mach-O Explorer does not include a disassembler. This may be added in the future.
14 | * Mach-O Explorer can not attach to a running process to analyze its headers. This may be added in the future once support in Mach-O Kit improves.
15 | * Mach-O Explorer does not support editing Mach-O files and there are no plans to add this feature.
16 |
17 | ## Getting Started
18 |
19 | ### Requirements
20 |
21 | * Xcode 11.0 or later to build
22 |
23 | ### Compiling
24 |
25 | ***Use a recursive git clone***.
26 |
27 | ```
28 | git clone --recursive https://github.com/DeVaukz/MachO-Explorer
29 | ```
30 |
31 | Open the `MachOExplorer.xcodeproj` file, select the `MachOExplorer` target and click Run.
32 |
33 | ## License
34 |
35 | Mach-O Explorer is released under the MIT license. See
36 | [LICENSE.md](https://github.com/DeVaukz/MachO-Explorer/blob/master/LICENSE).
37 |
--------------------------------------------------------------------------------
/Resources/Assets.xcassets/AppIcon.appiconset/AppIcon_512.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/DeVaukz/MachO-Explorer/e82b6e6136f4312422c276762e837fe853030547/Resources/Assets.xcassets/AppIcon.appiconset/AppIcon_512.png
--------------------------------------------------------------------------------
/Resources/Assets.xcassets/AppIcon.appiconset/AppIcon_512@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/DeVaukz/MachO-Explorer/e82b6e6136f4312422c276762e837fe853030547/Resources/Assets.xcassets/AppIcon.appiconset/AppIcon_512@2x.png
--------------------------------------------------------------------------------
/Resources/Assets.xcassets/AppIcon.appiconset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "mac",
5 | "size" : "16x16",
6 | "scale" : "1x"
7 | },
8 | {
9 | "idiom" : "mac",
10 | "size" : "16x16",
11 | "scale" : "2x"
12 | },
13 | {
14 | "idiom" : "mac",
15 | "size" : "32x32",
16 | "scale" : "1x"
17 | },
18 | {
19 | "idiom" : "mac",
20 | "size" : "32x32",
21 | "scale" : "2x"
22 | },
23 | {
24 | "idiom" : "mac",
25 | "size" : "128x128",
26 | "scale" : "1x"
27 | },
28 | {
29 | "idiom" : "mac",
30 | "size" : "128x128",
31 | "scale" : "2x"
32 | },
33 | {
34 | "idiom" : "mac",
35 | "size" : "256x256",
36 | "scale" : "1x"
37 | },
38 | {
39 | "idiom" : "mac",
40 | "size" : "256x256",
41 | "scale" : "2x"
42 | },
43 | {
44 | "size" : "512x512",
45 | "idiom" : "mac",
46 | "filename" : "AppIcon_512.png",
47 | "scale" : "1x"
48 | },
49 | {
50 | "size" : "512x512",
51 | "idiom" : "mac",
52 | "filename" : "AppIcon_512@2x.png",
53 | "scale" : "2x"
54 | }
55 | ],
56 | "info" : {
57 | "version" : 1,
58 | "author" : "xcode"
59 | }
60 | }
--------------------------------------------------------------------------------
/Resources/MachOExplorer-Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | en
7 | CFBundleDocumentTypes
8 |
9 |
10 | LSItemContentTypes
11 |
12 | com.apple.mach-o-dylib
13 |
14 | CFBundleTypeRole
15 | Viewer
16 | LSHandlerRank
17 | Alternate
18 | NSDocumentClass
19 | $(PRODUCT_MODULE_NAME).MachODocument
20 |
21 |
22 | LSItemContentTypes
23 |
24 | public.unix-executable
25 |
26 | CFBundleTypeRole
27 | Viewer
28 | LSHandlerRank
29 | Alternate
30 | NSDocumentClass
31 | $(PRODUCT_MODULE_NAME).MachODocument
32 |
33 |
34 | LSItemContentTypes
35 |
36 | public.data
37 |
38 | CFBundleTypeRole
39 | Viewer
40 | LSHandlerRank
41 | Alternate
42 | NSDocumentClass
43 | $(PRODUCT_MODULE_NAME).MachODocument
44 |
45 |
46 | CFBundleExecutable
47 | $(EXECUTABLE_NAME)
48 | CFBundleIconFile
49 |
50 | CFBundleIdentifier
51 | $(PRODUCT_BUNDLE_IDENTIFIER)
52 | CFBundleInfoDictionaryVersion
53 | 6.0
54 | CFBundleName
55 | $(PRODUCT_NAME)
56 | CFBundleDisplayName
57 | Mach-O Explorer
58 | CFBundlePackageType
59 | APPL
60 | CFBundleShortVersionString
61 | 1.0
62 | CFBundleSignature
63 | ????
64 | CFBundleVersion
65 | 1
66 | LSApplicationCategoryType
67 | public.app-category.utilities
68 | LSMinimumSystemVersion
69 | $(MACOSX_DEPLOYMENT_TARGET)
70 | NSHumanReadableCopyright
71 | Copyright © 2018-2020 DeVaukz. All rights reserved.
72 | NSMainNibFile
73 | MainMenu
74 | NSPrincipalClass
75 | NSApplication
76 |
77 |
78 |
--------------------------------------------------------------------------------