idb 1.3.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (103) hide show
  1. checksums.yaml +7 -0
  2. data/.DS_Store +0 -0
  3. data/.gitignore +19 -0
  4. data/Gemfile +4 -0
  5. data/Gemfile.lock +65 -0
  6. data/LICENSE.txt +22 -0
  7. data/README.md +29 -0
  8. data/Rakefile +2 -0
  9. data/bin/idb +5 -0
  10. data/idb.gemspec +41 -0
  11. data/lib/LICENSE +20 -0
  12. data/lib/README.md +54 -0
  13. data/lib/config/.dummy +0 -0
  14. data/lib/config/settings.yml +8 -0
  15. data/lib/gui/app_binary_tab_widget.rb +45 -0
  16. data/lib/gui/app_details_group_box.rb +213 -0
  17. data/lib/gui/app_list_dialog.rb +67 -0
  18. data/lib/gui/app_list_widget_item.rb +9 -0
  19. data/lib/gui/binary_strings_widget.rb +33 -0
  20. data/lib/gui/browse_filesystem_widget.rb +4 -0
  21. data/lib/gui/ca_manager_dialog.rb +137 -0
  22. data/lib/gui/cache_db_widget.rb +61 -0
  23. data/lib/gui/certificate_item.rb +5 -0
  24. data/lib/gui/console_widget.rb +163 -0
  25. data/lib/gui/cycript_console_widget.rb +68 -0
  26. data/lib/gui/cycript_thread.rb +81 -0
  27. data/lib/gui/device_info_group_box.rb +55 -0
  28. data/lib/gui/device_status_dialog.rb +351 -0
  29. data/lib/gui/file_system_events_widget.rb +4 -0
  30. data/lib/gui/fs_viewer_tab_widget.rb +245 -0
  31. data/lib/gui/i_device_syslog_thread.rb +47 -0
  32. data/lib/gui/images/check.png +0 -0
  33. data/lib/gui/images/folder.ico +0 -0
  34. data/lib/gui/images/iphone.ico +0 -0
  35. data/lib/gui/images/screenshot.png +0 -0
  36. data/lib/gui/key_chain_widget.rb +86 -0
  37. data/lib/gui/local_storage_tab_widget.rb +37 -0
  38. data/lib/gui/log_plain_text_edit.rb +18 -0
  39. data/lib/gui/log_widget.rb +71 -0
  40. data/lib/gui/main_tab_widget.rb +179 -0
  41. data/lib/gui/pasteboard_monitor_widget.rb +116 -0
  42. data/lib/gui/path_list_widget_item.rb +5 -0
  43. data/lib/gui/pb_watcher_thread.rb +63 -0
  44. data/lib/gui/plist_file_widget.rb +66 -0
  45. data/lib/gui/qt_ruby_variant.rb +16 -0
  46. data/lib/gui/screenshot_wizard.rb +169 -0
  47. data/lib/gui/settings_dialog.rb +69 -0
  48. data/lib/gui/settings_tab_widget.rb +149 -0
  49. data/lib/gui/shared_libraries_widget.rb +47 -0
  50. data/lib/gui/snoop_it_fs_events_widget.rb +150 -0
  51. data/lib/gui/snoop_it_keychain_widget.rb +172 -0
  52. data/lib/gui/snoop_it_sensitive_api_widget.rb +128 -0
  53. data/lib/gui/snoop_it_tab_widget.rb +27 -0
  54. data/lib/gui/snoop_it_update_thread.rb +48 -0
  55. data/lib/gui/sqlite_widget.rb +73 -0
  56. data/lib/gui/ssh_port_forward_tab_widget.rb +209 -0
  57. data/lib/gui/tool_widget.rb +94 -0
  58. data/lib/gui/url_handler_widget.rb +26 -0
  59. data/lib/gui/url_scheme_fuzz_widget.rb +103 -0
  60. data/lib/gui/url_scheme_widget.rb +60 -0
  61. data/lib/gui/weak_class_dump_widget.rb +89 -0
  62. data/lib/helper/ssh_port_forwarder.rb +72 -0
  63. data/lib/idb.rb +295 -0
  64. data/lib/idb/version.rb +3 -0
  65. data/lib/lib/CgBI.rb +153 -0
  66. data/lib/lib/abstract_device.rb +31 -0
  67. data/lib/lib/app.rb +286 -0
  68. data/lib/lib/app_binary.rb +57 -0
  69. data/lib/lib/ca_interface.rb +151 -0
  70. data/lib/lib/configuration.rb +0 -0
  71. data/lib/lib/console_launcher.rb +24 -0
  72. data/lib/lib/device.rb +438 -0
  73. data/lib/lib/device_ca_interface.rb +36 -0
  74. data/lib/lib/host_file_wrapper.rb +27 -0
  75. data/lib/lib/i_device_diagnostics_wrapper.rb +90 -0
  76. data/lib/lib/keychain_plist_parser.rb +15 -0
  77. data/lib/lib/local_operations.rb +67 -0
  78. data/lib/lib/otool_wrapper.rb +116 -0
  79. data/lib/lib/plist_util.rb +72 -0
  80. data/lib/lib/qt_thread_fix.rb +29 -0
  81. data/lib/lib/rsync_git_manager.rb +81 -0
  82. data/lib/lib/screen_shot_util.rb +59 -0
  83. data/lib/lib/settings.rb +67 -0
  84. data/lib/lib/simulator.rb +60 -0
  85. data/lib/lib/simulator_ca_interface.rb +16 -0
  86. data/lib/lib/snoop_it_wrapper.rb +80 -0
  87. data/lib/lib/ssh_operations.rb +136 -0
  88. data/lib/lib/ssh_port_forwarder.rb +43 -0
  89. data/lib/lib/tools.rb +11 -0
  90. data/lib/lib/url_scheme_fuzzer.rb +98 -0
  91. data/lib/lib/usb_muxd_wrapper.rb +32 -0
  92. data/lib/lib/weak_class_dump_wrapper.rb +62 -0
  93. data/lib/utils/dumpdecrypted/README +4 -0
  94. data/lib/utils/dumpdecrypted/dumpdecrypted_armv6.dylib +0 -0
  95. data/lib/utils/dumpdecrypted/dumpdecrypted_armv7.dylib +0 -0
  96. data/lib/utils/ios-ssl-kill-switch/com.isecpartners.nabla.sslkillswitch_v0.5-iOS_6.1.deb +0 -0
  97. data/lib/utils/keychain_dump/README +2 -0
  98. data/lib/utils/keychain_dump/keychain_dump +0 -0
  99. data/lib/utils/pbwatcher/pbwatcher +0 -0
  100. data/lib/utils/pcviewer/protectionclassviewer +0 -0
  101. data/lib/utils/weak_class_dump/README +5 -0
  102. data/lib/utils/weak_class_dump/weak_classdump.cy +726 -0
  103. metadata +412 -0
@@ -0,0 +1,4 @@
1
+ module Idb
2
+ class FileSystemEventsWidget < Qt::Widget
3
+ end
4
+ end
@@ -0,0 +1,245 @@
1
+ require_relative '../lib/rsync_git_manager'
2
+ module Idb
3
+ class FsViewerTabWidget < Qt::TabWidget
4
+
5
+ attr_accessor :start
6
+
7
+ def initialize *args
8
+ super *args
9
+
10
+ @icons = Qt::FileIconProvider.new
11
+
12
+ @layout = Qt::GridLayout.new
13
+ setLayout @layout
14
+
15
+ @rsync = Qt::PushButton.new "Rsync + Git"
16
+ @layout.addWidget @rsync, 0,0
17
+ @rsync.connect(SIGNAL :released) {
18
+ @manager.sync_new_revision
19
+
20
+ }
21
+
22
+ @open_folder = Qt::PushButton.new "Open Folder"
23
+ @layout.addWidget @open_folder, 0,1
24
+
25
+ @open_folder.connect(SIGNAL :released) {
26
+ Launchy.open @local_path
27
+
28
+ }
29
+
30
+ @open_gitk = Qt::PushButton.new "Open gitk"
31
+ @layout.addWidget @open_gitk, 0,2
32
+
33
+ @open_gitk.connect(SIGNAL :released) {
34
+ Process.spawn "(cd #{@local_path} && gitk)"
35
+ }
36
+
37
+
38
+
39
+ @treeview = Qt::TreeWidget.new
40
+ @treeview.connect(SIGNAL('itemExpanded(QTreeWidgetItem*)')) { |dir|
41
+ add_dirs dir, dir.text(1)
42
+ }
43
+
44
+
45
+ # @treeview.connect(SIGNAL('itemPressed(QTreeWidgetItem*, int)')) { |dir|
46
+ # @selected_dir = dir.text(1)
47
+ # populate_files dir.text(1)
48
+ # }
49
+
50
+ selection = @treeview.selectionModel()
51
+ selection.connect(SIGNAL('selectionChanged(QItemSelection,QItemSelection)')) {|x,y|
52
+ unless @treeview.selectedItems.length == 0
53
+ item = @treeview.selectedItems[0]
54
+ @selected_dir = item.text(1)
55
+ populate_files item.text(1)
56
+ end
57
+ }
58
+
59
+
60
+ @file_details = Qt::GroupBox.new self
61
+ @file_details.setTitle "Details"
62
+ @file_details_layout = Qt::GridLayout.new
63
+ @file_details.setLayout @file_details_layout
64
+
65
+ @file_details_file = Qt::Label.new ""
66
+ #
67
+ @file_details_user_label = Qt::Label.new "<b>User</b>"
68
+ @file_details_user = Qt::Label.new ""
69
+ @file_details_group_label = Qt::Label.new "<b>Group</b>"
70
+ @file_details_group = Qt::Label.new ""
71
+ @file_details_permissions_label = Qt::Label.new "<b>Permission</b>"
72
+ @file_details_permissions = Qt::Label.new ""
73
+ @file_details_protection_label = Qt::Label.new "<b>Protection Class</b>"
74
+ @file_details_protection = Qt::Label.new ""
75
+ @file_details_layout.addWidget @file_details_file
76
+
77
+ @file_details_layout.addWidget @file_details_file, 0, 0, 1, 2
78
+ @file_details_layout.addWidget @file_details_user_label, 1, 0
79
+ @file_details_layout.addWidget @file_details_user, 1, 1
80
+ @file_details_layout.addWidget @file_details_group_label, 2, 0
81
+ @file_details_layout.addWidget @file_details_group, 2, 1
82
+ @file_details_layout.addWidget @file_details_permissions_label, 3, 0
83
+ @file_details_layout.addWidget @file_details_permissions, 3, 1
84
+ @file_details_layout.addWidget @file_details_protection_label, 4, 0
85
+ @file_details_layout.addWidget @file_details_protection, 4, 1
86
+ @file_details_layout.addItem Qt::SpacerItem.new(0,1, Qt::SizePolicy::Expanding, Qt::SizePolicy::Fixed ), 0, 2
87
+ @layout.addWidget @file_details, 2, 0, 1, 3
88
+ @file_details.setSizePolicy(Qt::SizePolicy::Minimum, Qt::SizePolicy::Minimum)
89
+
90
+
91
+
92
+ @model = Qt::StandardItemModel.new
93
+
94
+ @selection_model = Qt::ItemSelectionModel.new @model
95
+
96
+
97
+ @file_list = Qt::TableView.new
98
+ @file_list.setModel @selection_model.model
99
+ @file_list.setSelectionModel(@selection_model)
100
+ @file_list.setSelectionBehavior(Qt::AbstractItemView::SelectRows)
101
+ @file_list.setEditTriggers(Qt::AbstractItemView::NoEditTriggers )
102
+ @file_list.setSizePolicy(Qt::SizePolicy::Expanding,Qt::SizePolicy::Expanding);
103
+
104
+ @splitter = Qt::Splitter.new
105
+ @splitter.addWidget @treeview
106
+ @splitter.addWidget @file_list
107
+ @splitter.setStretchFactor 1, 1.5
108
+ @splitter.setSizePolicy(Qt::SizePolicy::Expanding, Qt::SizePolicy::Expanding)
109
+ @layout.addWidget @splitter, 1, 0, 1, 3
110
+
111
+
112
+
113
+ @file_list.connect(SIGNAL('doubleClicked(QModelIndex)')) {|x|
114
+ cache_name = $selected_app.cache_file "#{@selected_dir}/#{@model.item(x.row,0).text}"
115
+ if cache_name.nil?
116
+ $log.error "File #{@selected_dir}/#{@model.item(x.row,0).text} could not be downloaded. Either the file does not exist (e.g., dead symlink) or there is a permission problem."
117
+ else
118
+ unless $device.ops.open cache_name
119
+ error = Qt::MessageBox.new
120
+ error.setInformativeText("Could not open file #{cache_name}. Likely there is no app registered for this file type. See log for more details.")
121
+ error.setIcon(Qt::MessageBox::Critical)
122
+ error.exec
123
+
124
+ end
125
+ end
126
+ }
127
+
128
+ @selection_model.connect(SIGNAL('selectionChanged(QItemSelection,QItemSelection)')) {|x,y|
129
+ unless x.indexes.length == 0
130
+ # for icon if desired
131
+ # tmp_file = Qt::TemporaryFile.new "XXXXXX#{d.name}"
132
+ # tmp_file.open
133
+ # puts tmp_file.fileName
134
+ row = x.indexes[0].row
135
+ filename = @model.item(row,0).text
136
+ @file_details_file.text = "#{@selected_dir}/#{filename}"
137
+ @file_details_user.text = @model.item(row,3).text
138
+ @file_details_group.text = @model.item(row,4).text
139
+ @file_details_permissions.text = @model.item(row,2).text
140
+ @file_details_protection.text = $device.protection_class "#{@selected_dir}/#{filename}"
141
+ end
142
+ }
143
+ end
144
+
145
+ def populate_files path
146
+ @model.clear
147
+ @model.setHorizontalHeaderItem(0, Qt::StandardItem.new("filename"))
148
+ @model.setHorizontalHeaderItem(1, Qt::StandardItem.new("size"))
149
+ @model.setHorizontalHeaderItem(2, Qt::StandardItem.new("permissions"))
150
+ @model.setHorizontalHeaderItem(3, Qt::StandardItem.new("uid"))
151
+ @model.setHorizontalHeaderItem(4, Qt::StandardItem.new("gid"))
152
+
153
+ dirs = $device.ops.list_dir_full path
154
+ dirs.each { |d|
155
+ unless d.directory?
156
+ row = Array.new
157
+ row << Qt::StandardItem.new(d.name)
158
+ size = d.attributes.size rescue ""
159
+ row << Qt::StandardItem.new(size.to_s)
160
+ perms = d.attributes.permissions rescue ""
161
+ row << Qt::StandardItem.new(perms.to_s)
162
+ owner = d.attributes.uid # rescue d.attributes.uid
163
+ row << Qt::StandardItem.new(owner.to_s)
164
+ group = d.attributes.gid # rescue d.attributes.gid
165
+ row << Qt::StandardItem.new(group.to_s)
166
+ @model.appendRow(row)
167
+ end
168
+ }
169
+ @file_list.resizeColumnsToContents
170
+ @file_list.resizeRowsToContents
171
+
172
+ end
173
+
174
+
175
+
176
+ def add_dirs parent, cur_dir
177
+ if parent.text(2) == "true"
178
+ # we added chilcren for this already
179
+ return
180
+ end
181
+ parent.setText(2, "true")
182
+ dirs = $device.ops.list_dir_full cur_dir
183
+ dirs.each { |d|
184
+ if d.name != "." and d.name != ".."
185
+ full_path = "#{cur_dir}/#{d.name}"
186
+ if d.directory?
187
+ dirs = $device.ops.list_dir_full full_path
188
+ expandable = has_subdirs? full_path
189
+ node = addChild parent, d.name, full_path, expandable
190
+ end
191
+ end
192
+ }
193
+ end
194
+
195
+ def has_subdirs? dir
196
+ files = $device.ops.list_dir_full dir
197
+ if files.length == 2
198
+ # only "." and ".."
199
+ return false
200
+ else
201
+ files.each { |f|
202
+ if f.name != "." and f.name != ".." and f.directory?
203
+ return true
204
+ end
205
+ }
206
+ end
207
+ return false
208
+ end
209
+
210
+ def refresh
211
+ add_dirs @root_node, @start
212
+
213
+
214
+ end
215
+
216
+
217
+
218
+ def addChild(parent, child_text, path, expandable)
219
+ tree_item = Qt::TreeWidgetItem.new
220
+ tree_item.setText(0, child_text)
221
+ tree_item.setText(1, path)
222
+ parent.addChild tree_item
223
+ if expandable
224
+ tree_item.setChildIndicatorPolicy(Qt::TreeWidgetItem::ShowIndicator)
225
+ else
226
+ tree_item.setChildIndicatorPolicy(Qt::TreeWidgetItem::DontShowIndicator)
227
+ end
228
+ tree_item
229
+ end
230
+
231
+ def set_start start
232
+ @treeview.clear
233
+ @root_node = Qt::TreeWidgetItem.new
234
+ @root_node.setText(0, "app root")
235
+ @root_node.setChildIndicatorPolicy(Qt::TreeWidgetItem::ShowIndicator)
236
+ @treeview.addTopLevelItem @root_node
237
+ @start = start
238
+ @selected_dir = start
239
+ @root_node.setText(1, @start)
240
+ @local_path = "#{$selected_app.cache_dir}/idb_mirror.git"
241
+ @manager = RsyncGitManager.new start, @local_path
242
+ end
243
+
244
+ end
245
+ end
@@ -0,0 +1,47 @@
1
+ require_relative '../lib/tools'
2
+
3
+ module Idb
4
+ class IDeviceSyslogThread < Qt::Object
5
+ signals "new_entry(QString)"
6
+
7
+ def initialize *args
8
+ super *args
9
+ $terminate_syslog_thread = false
10
+ if which('idevicesyslog').nil?
11
+ error = Qt::MessageBox.new
12
+ error.setInformativeText("This feature requires idevicesyslog to be installed on the host running idb. Try:<br>OS X: brew install libimobiledevice<br>Ubuntu: apt-get install libimobiledevice-utils")
13
+ error.setIcon(Qt::MessageBox::Critical)
14
+ error.exec
15
+ return false
16
+ end
17
+ start_log_thread
18
+ puts @log_thread
19
+ end
20
+
21
+
22
+ def stop
23
+ $terminate_syslog_thread = true
24
+ end
25
+
26
+
27
+ private
28
+ def start_log_thread
29
+ @log_thread = Thread.new do
30
+ @log = IO.popen("idevicesyslog")
31
+ @log.each do |line|
32
+ if $terminate_syslog_thread
33
+ break
34
+ end
35
+ emit new_entry(line)
36
+ end
37
+ puts "[*] Terminating thread"
38
+ Process.kill("INT", @log.pid)
39
+ @log.close
40
+ end
41
+
42
+
43
+ end
44
+
45
+
46
+ end
47
+ end
Binary file
Binary file
Binary file
@@ -0,0 +1,86 @@
1
+ require_relative '../lib/keychain_plist_parser'
2
+
3
+ module Idb
4
+ class KeyChainWidget < Qt::TableWidget
5
+
6
+ def initialize *args
7
+ super *args
8
+ @layout = Qt::GridLayout.new
9
+ setLayout(@layout)
10
+
11
+
12
+ @model = Qt::StandardItemModel.new
13
+
14
+ @selection_model = Qt::ItemSelectionModel.new @model
15
+ @selection_model.connect(SIGNAL('selectionChanged(QItemSelection,QItemSelection)')) {|x,y|
16
+ unless x.indexes.length == 0
17
+ row = x.indexes[0].row
18
+ text = ""
19
+ text << "DATA\n"
20
+ text << "=======================\n"
21
+ text << @keychain.entries[row]["data"].to_s
22
+
23
+ text << "\n\nV_DATA\n"
24
+ text << "=======================\n"
25
+ text << @keychain.entries[row]["v_Data"].to_s
26
+ @details.clear
27
+ @details.appendPlainText text
28
+
29
+ end
30
+
31
+ }
32
+
33
+ @keychain_tab = Qt::TableView.new
34
+ @keychain_tab.setModel @selection_model.model
35
+ @keychain_tab.setSelectionModel(@selection_model)
36
+
37
+ @keychain_tab.setSelectionBehavior(Qt::AbstractItemView::SelectRows)
38
+ @keychain_tab.setEditTriggers(Qt::AbstractItemView::NoEditTriggers )
39
+
40
+ @layout.addWidget @keychain_tab, 0,0
41
+
42
+ @details = Qt::PlainTextEdit.new
43
+ @details.setReadOnly(true)
44
+ @layout.addWidget @details, 1, 0
45
+
46
+ @dump = Qt::PushButton.new "Dump Keychain"
47
+ @dump.connect(SIGNAL :released) {
48
+ $device.dump_keychain
49
+ @keychain = KeychainPlistParser.new "#{$tmp_path}/device/genp.plist"
50
+ populate_table
51
+ }
52
+ @layout.addWidget @dump, 2, 0
53
+ end
54
+
55
+ def populate_table
56
+ @details.clear
57
+ @model.clear
58
+ @model.setHorizontalHeaderItem(0, Qt::StandardItem.new("Access Group"))
59
+ @model.setHorizontalHeaderItem(1, Qt::StandardItem.new("Account"))
60
+ @model.setHorizontalHeaderItem(2, Qt::StandardItem.new("Service"))
61
+ @model.setHorizontalHeaderItem(3, Qt::StandardItem.new("Protection"))
62
+ @model.setHorizontalHeaderItem(4, Qt::StandardItem.new("Creation"))
63
+ @model.setHorizontalHeaderItem(5, Qt::StandardItem.new("Modification"))
64
+
65
+
66
+ @keychain.entries.each { |item|
67
+ row = Array.new
68
+ row << Qt::StandardItem.new(item['agrp'].to_s)
69
+ row << Qt::StandardItem.new(item['acct'].to_s)
70
+ row << Qt::StandardItem.new(item['svce'].to_s)
71
+ row << Qt::StandardItem.new(item['protection_class'].to_s)
72
+ row << Qt::StandardItem.new(item['cdat'].to_s)
73
+ row << Qt::StandardItem.new(item['mdat'].to_s)
74
+ @model.appendRow(row)
75
+ }
76
+ @keychain_tab.resizeColumnsToContents
77
+ @keychain_tab.resizeRowsToContents
78
+
79
+
80
+ end
81
+
82
+
83
+
84
+
85
+ end
86
+ end
@@ -0,0 +1,37 @@
1
+ require_relative 'plist_file_widget'
2
+ require_relative 'sqlite_widget'
3
+ require_relative 'cache_db_widget'
4
+
5
+ module Idb
6
+ class LocalStorageTabWidget < Qt::TabWidget
7
+
8
+ def initialize *args
9
+ super *args
10
+
11
+ @tabs = Hash.new
12
+
13
+ @plist = PlistFileWidget.new self
14
+ @tabs[:plist] = addTab(@plist, "plists")
15
+
16
+ @sqlite = SqliteWidget.new self
17
+ @tabs[:sqlite] = addTab(@sqlite, "sqlite dbs")
18
+
19
+ @cachedb = CacheDbWidget.new self
20
+ @tabs[:cachedb] = addTab(@cachedb, "Cache.dbs")
21
+
22
+ end
23
+
24
+ def clear
25
+ @tabs.each { |tab|
26
+ tab.clear
27
+ }
28
+ end
29
+
30
+ def refresh_current_tab
31
+ puts "refresh local storage tab"
32
+ currentWidget.refresh
33
+ end
34
+
35
+
36
+ end
37
+ end
@@ -0,0 +1,18 @@
1
+ module Idb
2
+ class LogPlainTextEdit < Qt::PlainTextEdit
3
+
4
+ def initialize *args
5
+ super *args
6
+
7
+
8
+ end
9
+
10
+ def append_message text
11
+
12
+ appendHtml(text);
13
+ verticalScrollBar.setValue(verticalScrollBar.maximum)
14
+ end
15
+
16
+
17
+ end
18
+ end