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,67 @@
1
+
2
+ module Idb
3
+ class AppListDialog < Qt::Dialog
4
+ attr_accessor :app_list
5
+
6
+ def initialize *args
7
+ super *args
8
+
9
+ setWindowTitle("App Selection")
10
+ @layout = Qt::GridLayout.new
11
+ setLayout(@layout)
12
+
13
+ @app_list = Qt::ListWidget.new self
14
+ @app_list.setSortingEnabled(true);
15
+ @app_list.connect(SIGNAL('itemDoubleClicked(QListWidgetItem*)')) { |item|
16
+ emit accept
17
+ }
18
+ @layout.addWidget @app_list, 0, 0, 1, 2
19
+
20
+ refresh_app_list
21
+
22
+
23
+ @save_button = Qt::PushButton.new "Select"
24
+ @save_button.setDefault true
25
+
26
+ @save_button.connect(SIGNAL(:released)) {|x|
27
+ accept()
28
+ }
29
+ @cancel_button = Qt::PushButton.new "Cancel"
30
+ @cancel_button.connect(SIGNAL(:released)) {|x|
31
+ reject()
32
+ }
33
+
34
+ @layout.addWidget @save_button, 1, 1
35
+ @layout.addWidget @cancel_button, 1, 0
36
+
37
+ setFixedHeight(500);
38
+ setFixedWidth(400);
39
+
40
+
41
+ end
42
+
43
+ def refresh_app_list
44
+ app_uuids = $device.get_app_uuids
45
+ progress = Qt::ProgressDialog.new "Reading App list...", nil, 1, app_uuids.size, self
46
+ progress.setAutoClose true
47
+ progress.setWindowModality(Qt::WindowModal);
48
+ progress.show
49
+ progress.raise
50
+
51
+
52
+ app_uuids.each { |uuid|
53
+ a = App.new uuid
54
+
55
+ i = AppListWidgetItem.new @app_list, 0
56
+ i.setText (a.bundle_id.to_s + " => " + a.bundle_name.to_s)
57
+ i.app = a
58
+ @app_list.add_item i
59
+ progress.setValue(progress.value+1);
60
+
61
+
62
+ }
63
+ end
64
+
65
+
66
+ end
67
+ end
@@ -0,0 +1,9 @@
1
+ module Idb
2
+
3
+ class AppListWidgetItem < Qt::ListWidgetItem
4
+ attr_accessor :app
5
+
6
+
7
+ end
8
+
9
+ end
@@ -0,0 +1,33 @@
1
+ module Idb
2
+ class BinaryStringsWidget < Qt::Widget
3
+
4
+ def initialize *args
5
+ super *args
6
+ @layout = Qt::GridLayout.new
7
+ setLayout(@layout)
8
+
9
+ @details = Qt::PlainTextEdit.new
10
+ @details.setReadOnly(true)
11
+
12
+
13
+ @extract = Qt::PushButton.new "Extract Strings"
14
+ @extract.connect(SIGNAL :released) {
15
+ @details.clear
16
+ strings = $selected_app.strings
17
+ @details.appendPlainText(strings)
18
+ }
19
+
20
+ @layout.addWidget @details, 0,0
21
+ @layout.addWidget @extract, 1,0
22
+
23
+
24
+
25
+
26
+ end
27
+
28
+ def refresh
29
+
30
+ end
31
+
32
+ end
33
+ end
@@ -0,0 +1,4 @@
1
+ module Idb
2
+ class BrowseFilesystemWidget
3
+ end
4
+ end
@@ -0,0 +1,137 @@
1
+ require_relative 'certificate_item'
2
+
3
+ module Idb
4
+
5
+ class CAManagerDialog < Qt::Dialog
6
+
7
+ def initialize *args
8
+ super *args
9
+ @layout = Qt::GridLayout.new
10
+ setLayout(@layout)
11
+ setWindowTitle("CA Certificate Management")
12
+
13
+
14
+
15
+ @model = Qt::StandardItemModel.new
16
+
17
+ @selection_model = Qt::ItemSelectionModel.new @model
18
+ @selection_model.model
19
+
20
+ @cert_tab = Qt::TableView.new
21
+ @cert_tab.setModel @selection_model.model
22
+ @cert_tab.setSelectionModel(@selection_model)
23
+
24
+ @cert_tab.setSelectionBehavior(Qt::AbstractItemView::SelectRows)
25
+ @cert_tab.setEditTriggers(Qt::AbstractItemView::NoEditTriggers )
26
+
27
+
28
+ @selection_model.connect(SIGNAL('selectionChanged(QItemSelection,QItemSelection)')) {|x,y|
29
+ if x.indexes.length == 0
30
+ @delete_button.setEnabled(false)
31
+ else
32
+ @delete_button.setEnabled(true)
33
+ @selected_row = x.indexes[0].row
34
+ end
35
+
36
+ }
37
+
38
+
39
+ @refresh_button = Qt::PushButton.new "Refresh"
40
+ @refresh_button.connect(SIGNAL(:released)) {|x|
41
+ refresh_table
42
+ }
43
+
44
+ @delete_button = Qt::PushButton.new "Delete"
45
+ @delete_button.setEnabled(false)
46
+ @delete_button.connect(SIGNAL(:released)) {|x|
47
+ item_containing_cert = @model.takeRow(@selected_row)[0]
48
+ if not item_containing_cert.nil?
49
+ @if.remove_cert item_containing_cert.certificate
50
+ end
51
+ refresh_table
52
+ }
53
+
54
+
55
+ @import_button = Qt::PushButton.new "Import..."
56
+ @import_button.setToolTip("Import an existing certificate")
57
+ @import_button.connect(SIGNAL(:released)) { |x|
58
+ @file_dialog = Qt::FileDialog.new
59
+ @file_dialog.setAcceptMode(Qt::FileDialog::AcceptOpen)
60
+ filters = Array.new
61
+ filters << "PEM Files (*.pem)"
62
+ filters << "Any files (*)"
63
+ @file_dialog.setNameFilters(filters);
64
+
65
+ @file_dialog.connect(SIGNAL('fileSelected(QString)')) { |x|
66
+ begin
67
+ @if.server_cert(x)
68
+ rescue Exception => e
69
+ error = Qt::MessageBox.new self
70
+ error.setInformativeText("Couldn't import certificate")
71
+ error.setDetailedText(e.message)
72
+ error.setIcon(Qt::MessageBox::Critical)
73
+ error.exec
74
+ end
75
+ refresh_table
76
+ }
77
+
78
+
79
+
80
+ @file_dialog.exec
81
+ }
82
+
83
+ @close_button = Qt::PushButton.new "Close"
84
+ @close_button.connect(SIGNAL(:released)) {|x|
85
+ @if.stop_cert_server
86
+ reject()
87
+ }
88
+
89
+ @layout.addWidget @cert_tab, 0, 0, 4, 4
90
+ @layout.addWidget @refresh_button, 0, 4
91
+ @layout.addWidget @delete_button, 1,4
92
+ @layout.addWidget @import_button, 2,4
93
+ @layout.addItem Qt::SpacerItem.new(0,1, Qt::SizePolicy::Fixed, Qt::SizePolicy::Expanding), 3, 4
94
+ @layout.addWidget @close_button, 4, 4
95
+
96
+ @if = $device.ca_interface
97
+ refresh_table
98
+
99
+
100
+
101
+ #setFixedHeight(sizeHint().height());
102
+ setMinimumSize(800,500)
103
+ end
104
+
105
+ def refresh_table
106
+ @model.clear
107
+ @model.setHorizontalHeaderItem(0, Qt::StandardItem.new("Subject"))
108
+ @model.setHorizontalHeaderItem(1, Qt::StandardItem.new("Expiry"))
109
+ @model.setHorizontalHeaderItem(2, Qt::StandardItem.new("Issuer"))
110
+
111
+ @if.get_certs.each { |cert|
112
+ row = Array.new
113
+ item = CertificateItem.new(cert.subject.to_a.map { |x| "#{x[0]}: #{x[1]}"}.join("\n"))
114
+ item.certificate = cert
115
+ row << item
116
+ row << Qt::StandardItem.new(cert.not_after.to_s)
117
+ row << Qt::StandardItem.new(cert.issuer.to_a.map { |x| "#{x[0]}: #{x[1]}"}.join("\n"))
118
+ @model.appendRow(row)
119
+ }
120
+ @cert_tab.resizeColumnsToContents
121
+ @cert_tab.resizeRowsToContents
122
+
123
+
124
+ # puts "#{i.to_s.ljust(2)} - Subject: #{cert.subject}"
125
+ # puts " Details: #{cert.inspect}"
126
+
127
+
128
+
129
+ end
130
+
131
+
132
+
133
+
134
+
135
+ end
136
+
137
+ end
@@ -0,0 +1,61 @@
1
+ module Idb
2
+ class CacheDbWidget < Qt::Widget
3
+
4
+ def initialize *args
5
+ super *args
6
+
7
+ @refresh = Qt::PushButton.new "Refresh"
8
+ @refresh.connect(SIGNAL :released) {
9
+ refresh
10
+ }
11
+
12
+ @list = Qt::ListWidget.new self
13
+ @list.connect(SIGNAL('itemDoubleClicked(QListWidgetItem*)')) { |item|
14
+ # x = ConsoleLauncher.new
15
+ #TODO: find sqlite binary
16
+ #x.run "/usr/bin/sqlite3 #{Dir.getwd}/#{$selected_app.cache_file item.full_path}"
17
+
18
+ cache_name = $selected_app.cache_file item.full_path
19
+ if cache_name.nil?
20
+ $log.error "File #{item.full_path} could not be downloaded. Either the file does not exist (e.g., dead symlink) or there is a permission problem."
21
+ else
22
+ if RbConfig::CONFIG['host_os'] =~ /linux/
23
+ Process.spawn "'#{$settings['sqlite_editor']}' '#{Dir.getwd}/#{cache_name}'"
24
+ else
25
+ Process.spawn "open -a '#{$settings['sqlite_editor']}' '#{Dir.getwd}/#{cache_name}'"
26
+ end
27
+ end
28
+
29
+ }
30
+ # "Launch app"
31
+
32
+ layout = Qt::VBoxLayout.new do |v|
33
+ v.add_widget(@list)
34
+ v.add_widget(@refresh)
35
+ end
36
+ setLayout(layout)
37
+ end
38
+
39
+ def clear
40
+ @list.clear
41
+ end
42
+
43
+
44
+ def refresh
45
+ @list.clear
46
+ cache_dbs = $selected_app.find_cache_dbs
47
+ cache_dbs.each { |full_path|
48
+ item = PathListWidgetItem.new
49
+ if $device.simulator?
50
+ item.setText full_path.sub($selected_app.app_dir,'')
51
+ else
52
+ pc = $device.protection_class full_path
53
+ item.setText full_path.sub($selected_app.app_dir,'') + " => " + pc.strip
54
+ end
55
+ item.full_path = full_path
56
+ @list.addItem item
57
+ }
58
+ end
59
+
60
+ end
61
+ end
@@ -0,0 +1,5 @@
1
+ module Idb
2
+ class CertificateItem < Qt::StandardItem
3
+ attr_accessor :certificate
4
+ end
5
+ end
@@ -0,0 +1,163 @@
1
+ module Idb
2
+ class ConsoleWidget < Qt::PlainTextEdit
3
+
4
+ signals "command(QString)"
5
+
6
+ def initialize *args
7
+ super *args
8
+ setPrompt("> ")
9
+ @locked = false
10
+ @history_down = Array.new
11
+ @history_up = Array.new
12
+ end
13
+
14
+ def keyPressEvent e, callSuper=false
15
+ if callSuper
16
+ super e
17
+ end
18
+ if @locked
19
+ return
20
+ end
21
+
22
+ case e.key
23
+ when Qt::Key_Return
24
+ handleEnter
25
+
26
+ when Qt::Key_Backspace
27
+ handleLeft e
28
+
29
+ when Qt::Key_Up
30
+ handleHistoryUp
31
+
32
+ when Qt::Key_Down
33
+ handleHistoryDown
34
+
35
+ when Qt::Key_Left
36
+ handleLeft e
37
+
38
+ when Qt::Key_Home
39
+ handleHome
40
+ else
41
+ super e
42
+ end
43
+ end
44
+
45
+ def handleEnter
46
+ cmd = getCommand
47
+
48
+ if 0 < cmd.length
49
+ while @history_down.count > 0
50
+ @history_up.push(@history_down.pop)
51
+ end
52
+ @history_up.push cmd
53
+ end
54
+
55
+ moveToEndOfLine
56
+
57
+ if cmd.length > 0
58
+ @locked = true
59
+ setFocus
60
+ insertPlainText("\n")
61
+ emit command(cmd)
62
+ else
63
+ insertPlainText("\n")
64
+ insertPlainText(@userPrompt)
65
+ ensureCursorVisible
66
+ end
67
+ end
68
+
69
+ def result result
70
+ insertPlainText(result)
71
+ insertPlainText("\n")
72
+ insertPlainText(@userPrompt)
73
+ ensureCursorVisible
74
+ @locked = false
75
+ end
76
+
77
+ def append text
78
+ insertPlainText(text)
79
+ insertPlainText("\n")
80
+ ensureCursorVisible
81
+ end
82
+
83
+ def handleHistoryUp
84
+ if 0 < @history_up.count
85
+ cmd = @history_up.pop
86
+ @history_down.push(cmd)
87
+
88
+ clearLine
89
+ insertPlainText(cmd)
90
+ end
91
+
92
+ historySkip = true
93
+ end
94
+
95
+ def handleHistoryDown
96
+ if 0 < @history_down.count && historySkip
97
+ @history_up.push(@history_down.pop)
98
+ historySkip = false
99
+ end
100
+
101
+ if 0 < @history_down.count
102
+ cmd = @history_down.pop()
103
+ @history_up.push(cmd)
104
+
105
+ clearLine()
106
+ insertPlainText(cmd)
107
+ else
108
+ clearLine()
109
+ end
110
+ end
111
+
112
+
113
+ def clearLine
114
+ c = textCursor()
115
+ c.select(Qt::TextCursor::LineUnderCursor)
116
+ c.removeSelectedText()
117
+ insertPlainText(@userPrompt)
118
+ end
119
+
120
+ def getCommand
121
+ c = textCursor()
122
+ c.select(Qt::TextCursor::LineUnderCursor)
123
+
124
+ text = c.selectedText()
125
+ text = text[@userPrompt.length,text.length]
126
+ puts text
127
+ text
128
+
129
+ end
130
+
131
+ def moveToEndOfLine
132
+ moveCursor(Qt::TextCursor::EndOfLine);
133
+ end
134
+
135
+ def handleLeft event
136
+ if getIndex(textCursor) > @userPrompt.length
137
+ keyPressEvent(event, true)
138
+ end
139
+ end
140
+
141
+ def handleHome
142
+ c = textCursor
143
+ c.movePosition(Qt::TextCursor::StartOfLine)
144
+ c.movePosition(Qt::TextCursor::Right, Qt::TextCursor::MoveAnchor, @userPrompt.length)
145
+ setTextCursor(c)
146
+ end
147
+
148
+
149
+ def getIndex crQTextCursor
150
+ column = 1
151
+ b = crQTextCursor.block()
152
+ column = crQTextCursor.position - b.position
153
+ column
154
+ end
155
+
156
+ def setPrompt prompt
157
+ @userPrompt = prompt
158
+ clearLine()
159
+ end
160
+
161
+
162
+ end
163
+ end