idb 1.3.1

Sign up to get free protection for your applications and to get access to all the features.
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,71 @@
1
+ require_relative 'log_plain_text_edit'
2
+ require_relative 'i_device_syslog_thread'
3
+ require 'htmlentities'
4
+
5
+ module Idb
6
+ class LogWidget < Qt::Widget
7
+
8
+ def initialize *args
9
+ super *args
10
+
11
+ @start = Qt::PushButton.new "Start"
12
+ @start.connect(SIGNAL :released) {
13
+ @start.setEnabled(false)
14
+ @stop.setEnabled(true)
15
+ start_log
16
+ }
17
+
18
+ @stop = Qt::PushButton.new "Stop"
19
+ @stop.setEnabled(false)
20
+ @stop.connect(SIGNAL :released) {
21
+ @start.setEnabled(true)
22
+ @stop.setEnabled(false)
23
+ stop_log
24
+ }
25
+
26
+ @log_window = LogPlainTextEdit.new
27
+ @log_window.setReadOnly(true)
28
+
29
+ layout = Qt::VBoxLayout.new do |v|
30
+ v.add_widget(@log_window)
31
+ v.add_widget(@start)
32
+ v.add_widget(@stop)
33
+ end
34
+ setLayout(layout)
35
+ @colored = true
36
+
37
+ end
38
+
39
+
40
+ def start_log
41
+ h = HTMLEntities.new
42
+ @log_window.append_message "Please wait.. Streaming device syslog..."
43
+ @log_thread = IDeviceSyslogThread.new
44
+ @log_thread.connect(SIGNAL('new_entry(QString)')) {|line|
45
+ color = 'black'
46
+ if @colored
47
+ if line.include? "<Notice>"
48
+ color = 'grey'
49
+ elsif line.include? "<Error>"
50
+ color = 'red'
51
+ elsif line.include? "<Warning>"
52
+ color = 'Orange'
53
+ elsif line.include? "<Debug>"
54
+ color = 'Green'
55
+ end
56
+ end
57
+
58
+
59
+
60
+ line = line.encode('utf-8', :invalid => :replace, :undef => :replace, :replace => '_')
61
+
62
+ @log_window.append_message "<font color='#{color}'>#{h.encode(line.chomp)}</font>"
63
+ }
64
+ end
65
+
66
+ def stop_log
67
+ @log_thread.stop
68
+ end
69
+
70
+ end
71
+ end
@@ -0,0 +1,179 @@
1
+ require_relative 'local_storage_tab_widget'
2
+ require_relative 'url_handler_widget'
3
+ require_relative 'app_binary_tab_widget'
4
+ require_relative 'log_widget'
5
+ require_relative 'snoop_it_tab_widget'
6
+ require_relative 'cycript_console_widget'
7
+ require_relative 'pasteboard_monitor_widget'
8
+ require_relative 'fs_viewer_tab_widget'
9
+ require_relative 'key_chain_widget'
10
+ require_relative 'tool_widget'
11
+ require 'Qt'
12
+
13
+ module Idb
14
+ class MainTabWidget < Qt::TabWidget
15
+
16
+
17
+ def initialize *args
18
+ super *args
19
+ @tabs = Hash.new
20
+
21
+ @local_storage = LocalStorageTabWidget.new self
22
+ @local_storage.setEnabled(false)
23
+ @tabs[:local_storage] = addTab(@local_storage, "Storage")
24
+ @local_storage.connect(SIGNAL('currentChanged(int)')) { |x|
25
+ #@local_storage.currentWidget.refresh
26
+ }
27
+
28
+ @url_handler = URLHandlerWidget.new self
29
+ @url_handler.setEnabled(false)
30
+ @tabs[:url_handlers] = addTab(@url_handler, "URL Handlers")
31
+ connect(SIGNAL('currentChanged(int)')) { |x|
32
+ # if isTabEnabled(@tabs[:url_handlers]) and
33
+ # @tabs[:url_handlers] == currentIndex
34
+ #
35
+ # @url_handler.refresh
36
+ # end
37
+ }
38
+
39
+ @app_binary = AppBinaryTabWidget.new self
40
+ @app_binary.setEnabled(false)
41
+ @tabs[:app_binary] = addTab(@app_binary, "Binary")
42
+ @app_binary.connect(SIGNAL('currentChanged(int)')) { |x|
43
+ @app_binary.currentWidget.refresh
44
+ }
45
+
46
+ @fs_viewer = FsViewerTabWidget.new self
47
+ @fs_viewer.setEnabled(false)
48
+ @tabs[:fs_viewer] = addTab(@fs_viewer, "Filesystem")
49
+
50
+ @tools = ToolWidget.new self
51
+ @tools.setEnabled(false)
52
+ @tabs[:tools] = addTab(@tools, "Tools")
53
+
54
+ # @isnoop = SnoopItTabWidget.new self
55
+ # @isnoop.setEnabled(false)
56
+ # @tabs[:isnoop] = addTab(@isnoop, "Snoop-It")
57
+ # setTabToolTip(@tabs[:isnoop],"The performance of the snoop-it integration is not good enough to enable the tab yet. If people would find it useful, let me know and I'll put time into it.")
58
+
59
+ @log = LogWidget.new self
60
+ @log.setEnabled(false)
61
+ @tabs[:log] = addTab(@log, "Log")
62
+
63
+ @keychain = KeyChainWidget.new self
64
+ @keychain.setEnabled(false)
65
+ @tabs[:keychain] = addTab(@keychain, "Keychain")
66
+
67
+ # @cycript = CycriptConsoleWidget.new self
68
+ # @cycript.setEnabled(false)
69
+ # @tabs[:cycript] = addTab(@cycript, "Cycript")
70
+ # setTabToolTip(@tabs[:cycript],"Cycript needs proper terminal emulation. At the moment this tab is not very useful and disabled.")
71
+
72
+ @pasteboard = PasteboardMonitorWidget.new self
73
+ @pasteboard.setEnabled(false)
74
+ @tabs[:pasteboard] = addTab(@pasteboard, "Pasteboard")
75
+
76
+ disable_all
77
+ end
78
+
79
+ def enableLog
80
+ @log.setEnabled(true)
81
+ setTabEnabled(@tabs[:log], true)
82
+ end
83
+
84
+ def enableAppBinary
85
+ @app_binary.setEnabled(true)
86
+ setTabEnabled(@tabs[:app_binary], true)
87
+ @app_binary.enableTabs
88
+ end
89
+
90
+ def enableCycript
91
+ # @cycript.setEnabled(true)
92
+ # setTabEnabled(@tabs[:cycript], true)
93
+ end
94
+
95
+ def enableLocalStorage
96
+ @local_storage.setEnabled(true)
97
+ setTabEnabled(@tabs[:local_storage], true)
98
+ end
99
+
100
+ def enableURLHandlers
101
+ @url_handler.setEnabled(true)
102
+ setTabEnabled(@tabs[:url_handlers], true)
103
+ end
104
+
105
+ def enablePasteboard
106
+ @pasteboard.setEnabled(true)
107
+ setTabEnabled(@tabs[:pasteboard], true)
108
+ end
109
+
110
+ def enableFSViewer
111
+ @fs_viewer.setEnabled(true)
112
+ setTabEnabled(@tabs[:fs_viewer], true)
113
+ end
114
+
115
+ def enableTools
116
+ @tools.setEnabled(true)
117
+ setTabEnabled(@tabs[:tools], true)
118
+ end
119
+
120
+
121
+ def enableKeychain
122
+ @keychain.setEnabled(true)
123
+ setTabEnabled(@tabs[:keychain], true)
124
+ end
125
+
126
+
127
+ def enableDeviceFunctions
128
+ enableCycript
129
+ enableLog
130
+ enablePasteboard
131
+ enableKeychain
132
+ end
133
+
134
+ def disable_all
135
+ setTabEnabled(@tabs[:local_storage], false)
136
+ setTabEnabled(@tabs[:log], false)
137
+ setTabEnabled(@tabs[:app_binary],false)
138
+ setTabEnabled(@tabs[:url_handlers],false)
139
+ setTabEnabled(@tabs[:pasteboard],false)
140
+ # setTabEnabled(@tabs[:cycript],false)
141
+ # setTabEnabled(@tabs[:isnoop],false)
142
+ setTabEnabled(@tabs[:fs_viewer],false)
143
+ setTabEnabled(@tabs[:keychain],false)
144
+ setTabEnabled(@tabs[:tools],false)
145
+ end
146
+
147
+ def clear
148
+ @tabs.each { |tab|
149
+ tab.clear
150
+ }
151
+
152
+ end
153
+
154
+ def refresh_current_tab
155
+ currentWidget.refresh_current_tab
156
+ end
157
+
158
+ def refresh_app_binary
159
+ enableAppBinary
160
+ end
161
+
162
+ def app_changed
163
+ clear
164
+ enableLocalStorage
165
+ enableURLHandlers
166
+ # refresh_current_tab
167
+ @app_binary.refresh
168
+ enableFSViewer
169
+ @fs_viewer.set_start $selected_app.app_dir
170
+ enableTools
171
+ @tools.enable_screenshot
172
+
173
+
174
+ end
175
+
176
+
177
+
178
+ end
179
+ end
@@ -0,0 +1,116 @@
1
+ require_relative 'pb_watcher_thread'
2
+ require_relative 'log_plain_text_edit'
3
+
4
+ module Idb
5
+ class PasteboardMonitorWidget < Qt::Widget
6
+
7
+ def initialize *args
8
+ super *args
9
+
10
+ @pbs_to_watch = Hash.new
11
+ @pbs_to_watch["general"] = ""
12
+
13
+
14
+ @stop = Qt::PushButton.new "Stop"
15
+ @stop.setEnabled(false)
16
+ @stop.connect(SIGNAL :released) {
17
+ @start.setEnabled(true)
18
+ @stop.setEnabled(false)
19
+ stop_log
20
+ @pb_config.setEnabled(true)
21
+ }
22
+
23
+ @log_window = LogPlainTextEdit.new
24
+ @log_window.setReadOnly(true)
25
+
26
+ @start = Qt::PushButton.new "Start"
27
+ @start.connect(SIGNAL :released) {
28
+ unless $device.pbwatcher_installed?
29
+ error = Qt::MessageBox.new
30
+ error.setInformativeText("pbwatcher not found on the device. Please visit the status dialog and install it.")
31
+ error.setIcon(Qt::MessageBox::Critical)
32
+ error.exec
33
+ else
34
+ @pb_config.setEnabled(false)
35
+ @start.setEnabled(false)
36
+ @stop.setEnabled(true)
37
+ launch_process
38
+ end
39
+ }
40
+
41
+
42
+ @pb_config = Qt::GroupBox.new self
43
+ @pb_config.setTitle "Pasteboard Names"
44
+ @pb_config_layout = Qt::GridLayout.new
45
+ @pb_config.setLayout @pb_config_layout
46
+
47
+ @pb_names = Qt::ListWidget.new @self
48
+
49
+ @pb_add = Qt::PushButton.new "Add"
50
+ @pb_add.connect(SIGNAL :released) {
51
+ @pbs_to_watch[@pb_text.text] = ""
52
+ @pb_names.addItem @pb_text.text
53
+ @pb_text.text = ""
54
+ @pb_remove.setEnabled(true)
55
+ }
56
+
57
+
58
+ @pb_remove = Qt::PushButton.new "Remove"
59
+ @pb_remove.setEnabled(false)
60
+ @pb_remove.connect(SIGNAL :released) {
61
+ removed_pb = @pb_names.item(@pb_names.current_row)
62
+ @pbs_to_watch.delete removed_pb.text unless removed_pb.nil?
63
+
64
+ row = @pb_names.current_row
65
+ @pb_names.takeItem row unless row.nil?
66
+ if @pb_names.count == 0
67
+ @pb_remove.setEnabled(false)
68
+ end
69
+ }
70
+
71
+ @pb_text = Qt::LineEdit.new
72
+
73
+ @pb_config_layout.addWidget @pb_names, 0, 0, 1, 2
74
+ @pb_config_layout.addWidget @pb_text, 1, 0, 1, 2
75
+ @pb_config_layout.addWidget @pb_add, 2, 0, 1, 1
76
+ @pb_config_layout.addWidget @pb_remove, 2, 1, 1, 1
77
+
78
+
79
+ layout = Qt::GridLayout.new do |h|
80
+ h.add_widget @log_window, 0,0
81
+ h.add_widget @pb_config, 0,1
82
+
83
+ h.add_widget @start, 1, 0, 1, 2
84
+ h.add_widget @stop, 2, 0, 1, 2
85
+ end
86
+ setLayout(layout)
87
+
88
+ end
89
+
90
+
91
+ def launch_process
92
+ h = HTMLEntities.new
93
+ @log_window.append_message "Please wait.."
94
+ @pbwatcher_thread = PBWatcherThread.new
95
+ @pbwatcher_thread.connect(SIGNAL('new_entry(QString)')) {|line|
96
+ color = 'black'
97
+ date, time, app, payload = line.split " ", 4
98
+ pb, data = payload.split ":", 2
99
+ if @pbs_to_watch[pb] != data
100
+ @pbs_to_watch[pb] = data
101
+ new_entry = "#{time} #{pb} => #{data}"
102
+ new_entry = new_entry.encode('utf-8', :invalid => :replace, :undef => :replace, :replace => '_')
103
+ @log_window.append_message "<font color='#{color}'>#{h.encode(new_entry.chomp)}</font>"
104
+ end
105
+
106
+
107
+ }
108
+ @pbwatcher_thread.start_pbwatcher_thread @pbs_to_watch.select{|x,y| x != 'general' }.map{|x,y| "\"#{x}\""}.join ' '
109
+
110
+ end
111
+
112
+ def stop_log
113
+ @pbwatcher_thread.stop
114
+ end
115
+ end
116
+ end
@@ -0,0 +1,5 @@
1
+ module Idb
2
+ class PathListWidgetItem < Qt::ListWidgetItem
3
+ attr_accessor :full_path
4
+ end
5
+ end
@@ -0,0 +1,63 @@
1
+ module Idb
2
+ class PBWatcherThread < Qt::Object
3
+ signals "new_entry(QString)"
4
+
5
+ def initialize *args
6
+ super *args
7
+ $terminate_pbwatcher_thread = false
8
+ end
9
+
10
+
11
+ def stop
12
+ $terminate_pbwatcher_thread = true
13
+ end
14
+
15
+
16
+ def start_pbwatcher_thread pbs
17
+ @pbwatcher_thread = Thread.new do
18
+ channel = $device.ssh.open_channel do |ch|
19
+ ch.request_pty do |ch, success|
20
+ cmd = "/var/root/pbwatcher 1 #{pbs}"
21
+ $log.info "Executing pbwatcher: #{cmd}"
22
+ ch.exec cmd do |ch, success|
23
+ $log.error "could not execute command" unless success
24
+
25
+ # "on_data" is called when the process writes something to stdout
26
+ ch.on_data do |c, data|
27
+ emit new_entry(data)
28
+ end
29
+
30
+ # "on_extended_data" is called when the process writes something to stderr
31
+ ch.on_extended_data do |c, type, data|
32
+ emit new_entry(data)
33
+ end
34
+
35
+ ch.on_close { |ch|
36
+ $log.info "pbwatcher terminated"
37
+ }
38
+ end
39
+ end
40
+ end
41
+
42
+ loop do
43
+ #TODO mutex to protect device?
44
+ #even better: make one central thread that calls process.
45
+ # and all functions using it call it to ensure its running. or auto start it.
46
+ sleep 0.5
47
+ $device.ssh.process
48
+ #$device.ssh.process 0
49
+ if $terminate_pbwatcher_thread
50
+ $log.info "Terminating pbwatcher"
51
+ channel.close
52
+ break
53
+ end
54
+ end
55
+ $log.info "Terminating thread"
56
+ end
57
+
58
+
59
+ end
60
+
61
+
62
+ end
63
+ end
@@ -0,0 +1,66 @@
1
+ require_relative 'path_list_widget_item'
2
+
3
+ module Idb
4
+ class PlistFileWidget < Qt::Widget
5
+
6
+ def initialize *args
7
+ super *args
8
+
9
+ @refresh = Qt::PushButton.new "Refresh"
10
+ @refresh.connect(SIGNAL :released) {
11
+ refresh
12
+ }
13
+
14
+
15
+ @list = Qt::ListWidget.new self
16
+ @list.connect(SIGNAL('itemDoubleClicked(QListWidgetItem*)')) { |item|
17
+ cache_name = $selected_app.cache_file item.full_path
18
+ if cache_name.nil?
19
+ $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."
20
+ else
21
+ $device.ops.open cache_name
22
+ end
23
+ }
24
+ # @list.setContextMenuPolicy(Qt::CustomContextMenu);
25
+ # @list.connect(SIGNAL('customContextMenuRequested(QPoint)')) { |item|
26
+ # menu = Qt::Menu.new("Context menu", self)
27
+ # menu.addAction(Qt::Action.new("Hello", self));
28
+ # menu.exec(mapToGlobal(pos));
29
+ #
30
+ # }
31
+
32
+
33
+ # "Launch app"
34
+
35
+ layout = Qt::VBoxLayout.new do |v|
36
+ v.add_widget(@list)
37
+ v.add_widget(@refresh)
38
+ end
39
+ setLayout(layout)
40
+ end
41
+
42
+ def clear
43
+ @list.clear
44
+ end
45
+
46
+ def refresh
47
+ @list.clear
48
+ plist_files = $selected_app.find_plist_files
49
+ plist_files.each { |full_path|
50
+ item = PathListWidgetItem.new
51
+ if $device.simulator?
52
+ item.setText full_path.sub($selected_app.app_dir,'')
53
+ else
54
+ pc = $device.protection_class full_path
55
+ item.setText full_path.sub($selected_app.app_dir,'') + " => " + pc.strip
56
+ end
57
+ item.full_path = full_path
58
+ @list.addItem item
59
+ }
60
+ end
61
+
62
+
63
+
64
+
65
+ end
66
+ end