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,26 @@
1
+ require_relative '../lib/url_scheme_fuzzer'
2
+ require_relative 'url_scheme_fuzz_widget'
3
+ require_relative 'url_scheme_widget'
4
+
5
+ module Idb
6
+ class URLHandlerWidget < Qt::TabWidget
7
+
8
+ def initialize *args
9
+ super *args
10
+
11
+ @tabs = Hash.new
12
+
13
+ @url_scheme = URLSchemeWidget.new self
14
+ @tabs[:scheme] = addTab(@url_scheme, "URL Schemes")
15
+
16
+ @url_fuzz = URLSchemeFuzzWidget.new self
17
+ @tabs[:fuzzer] = addTab(@url_fuzz, "Fuzzer")
18
+ end
19
+
20
+ def disable_for_simulator
21
+ @tabs[:fuzzer]
22
+
23
+ end
24
+
25
+ end
26
+ end
@@ -0,0 +1,103 @@
1
+ module Idb
2
+ class URLSchemeFuzzWidget < Qt::Widget
3
+
4
+ def initialize *args
5
+ super *args
6
+
7
+ @fuzz_config_layout = Qt::GridLayout.new
8
+ setLayout @fuzz_config_layout
9
+
10
+ @fuzz_config_fuzz_strings = Qt::ListWidget.new self
11
+ @fuzz_config_fuzz_strings_label = Qt::Label.new "<b>Fuzz Strings:<b>"
12
+ @fuzzer = URLSchemeFuzzer.new
13
+ @fuzzer.default_fuzz_strings.each { |x|
14
+ @fuzz_config_fuzz_strings.addItem x
15
+ }
16
+
17
+ @fuzz_config_new_fuzz = Qt::LineEdit.new
18
+ @fuzz_config_add_fuzz = Qt::PushButton.new "Add"
19
+ @fuzz_config_add_fuzz.connect(SIGNAL :released) {
20
+ @fuzz_config_fuzz_strings.addItem @fuzz_config_new_fuzz.text
21
+ @fuzz_config_new_fuzz.text = ""
22
+ @fuzz_config_remove_fuzz.setEnabled(true)
23
+ }
24
+ @fuzz_config_remove_fuzz = Qt::PushButton.new "Remove"
25
+ @fuzz_config_remove_fuzz.connect(SIGNAL :released) {
26
+ row = @fuzz_config_fuzz_strings.current_row
27
+ @fuzz_config_fuzz_strings.takeItem row unless row.nil?
28
+ if @fuzz_config_fuzz_strings.count == 0
29
+ @fuzz_config_remove_fuzz.setEnabled(false)
30
+ end
31
+ }
32
+
33
+
34
+ @fuzz_strings = Qt::GroupBox.new self
35
+ @fuzz_strings.setTitle "Fuzz Strings"
36
+ @fuzz_strings_layout = Qt::GridLayout.new
37
+ @fuzz_strings.setLayout @fuzz_strings_layout
38
+
39
+ @fuzz_strings_layout.addWidget @fuzz_config_fuzz_strings, 1,0, 1, 2
40
+ @fuzz_strings_layout.addWidget @fuzz_config_new_fuzz, 2,0, 1 ,2
41
+ @fuzz_strings_layout.addWidget @fuzz_config_add_fuzz, 3,0
42
+ @fuzz_strings_layout.addWidget @fuzz_config_remove_fuzz, 3,1
43
+
44
+
45
+
46
+ @fuzz_template = Qt::GroupBox.new self
47
+ @fuzz_template.setTitle "Fuzz Template"
48
+ @fuzz_template_layout = Qt::GridLayout.new
49
+ @fuzz_template.setLayout @fuzz_template_layout
50
+ @fuzz_config_template_label = Qt::Label.new "Use $@$ to mark injection fuzz points"
51
+ @fuzz_config_template = Qt::LineEdit.new
52
+
53
+
54
+ @fuzz_config_button = Qt::PushButton.new "Fuzz"
55
+ @fuzz_config_button.connect(SIGNAL :released) {
56
+ @fuzzer.delete_old_reports
57
+
58
+
59
+ fuzz_strings = Array.new
60
+ 0.upto(@fuzz_config_fuzz_strings.count-1) { |i|
61
+ fuzz_strings << @fuzz_config_fuzz_strings.item(i).text
62
+ }
63
+ input = @fuzzer.generate_inputs @fuzz_config_template.text, fuzz_strings
64
+ input.each { |url|
65
+ #TODO: progress bar
66
+ #TODO: kill app after each run
67
+ #TODO: check for crash report
68
+ crashed = @fuzzer.execute url
69
+ @log_window.append_message "#{url}\t#{crashed}"
70
+ break if crashed
71
+ Qt::CoreApplication.processEvents
72
+ sleep 2
73
+ Qt::CoreApplication.processEvents
74
+ }
75
+ }
76
+
77
+ @fuzz_template_layout.addWidget @fuzz_config_template_label, 0,0
78
+ @fuzz_template_layout.addWidget @fuzz_config_template, 1,0
79
+ @fuzz_template_layout.addWidget @fuzz_config_button, 2,0, 1, 2
80
+
81
+
82
+ @fuzz_result = Qt::GroupBox.new self
83
+ @fuzz_result.setTitle "Results"
84
+ @fuzz_result_layout = Qt::GridLayout.new
85
+ @fuzz_result.setLayout @fuzz_result_layout
86
+ @log_window = LogPlainTextEdit.new
87
+ @log_window.setReadOnly(true)
88
+ @fuzz_result_layout.addWidget @log_window, 0,0
89
+
90
+
91
+ @fuzz_config_layout.addWidget @fuzz_strings, 0,0
92
+ @fuzz_config_layout.addWidget @fuzz_template, 1, 0
93
+ @fuzz_config_layout.addWidget @fuzz_result, 0, 1, 2, 1
94
+
95
+
96
+
97
+
98
+
99
+ end
100
+
101
+
102
+ end
103
+ end
@@ -0,0 +1,60 @@
1
+ module Idb
2
+ class URLSchemeWidget < Qt::Widget
3
+ def initialize *args
4
+ super *args
5
+
6
+ @url_handler_list = Qt::GroupBox.new self
7
+ @url_handler_list.setTitle "List of registered URL Handlers"
8
+ @url_handler_list_layout = Qt::GridLayout.new
9
+ @url_handler_list.setLayout @url_handler_list_layout
10
+
11
+ @refresh = Qt::PushButton.new "Refresh"
12
+ @refresh.connect(SIGNAL :released) {
13
+ refresh
14
+ }
15
+
16
+ @list = Qt::ListWidget.new self
17
+ @list.connect(SIGNAL('itemClicked(QListWidgetItem*)')) { |item|
18
+ @url_open_string.text = item.text + "://"
19
+ }
20
+
21
+ @url_handler_list_layout.add_widget @list, 0, 0
22
+ @url_handler_list_layout.add_widget @refresh, 1, 0
23
+
24
+
25
+
26
+ @url_open = Qt::GroupBox.new self
27
+ @url_open.setTitle "Open URL"
28
+ @url_open_layout = Qt::GridLayout.new
29
+ @url_open.setLayout @url_open_layout
30
+
31
+ @url_open_string = Qt::LineEdit.new
32
+ @url_open_button = Qt::PushButton.new "Open"
33
+ @url_open_button.connect(SIGNAL :released) {
34
+ $device.open_url @url_open_string.text
35
+ }
36
+ @url_open_layout.addWidget @url_open_string, 0,0
37
+ @url_open_layout.addWidget @url_open_button, 1,0
38
+
39
+ layout = Qt::GridLayout.new do |v|
40
+ v.add_widget @url_handler_list, 0, 0
41
+ v.add_widget @url_open, 0, 1
42
+ v.add_widget @fuzz_config, 1, 0, 2, 2
43
+
44
+ end
45
+ setLayout(layout)
46
+ end
47
+
48
+ def refresh
49
+ @list.clear
50
+ url_handlers = $selected_app.get_url_handlers
51
+ url_handlers.each { |x|
52
+ @list.addItem x
53
+ }
54
+ end
55
+
56
+ def clear
57
+ @list.clear
58
+ end
59
+ end
60
+ end
@@ -0,0 +1,89 @@
1
+ require_relative '../lib/weak_class_dump_wrapper'
2
+
3
+ module Idb
4
+ class WeakClassDumpWidget < Qt::Widget
5
+ def initialize *args
6
+ super *args
7
+
8
+
9
+
10
+ @layout = Qt::GridLayout.new
11
+ setLayout @layout
12
+
13
+ @run = Qt::PushButton.new "Dump Classes"
14
+ @layout.addWidget @run, 0,0
15
+ @run.connect(SIGNAL :released) {
16
+ run_cycript
17
+ }
18
+
19
+
20
+ @results = Qt::PushButton.new "List Results"
21
+ @layout.addWidget @results, 0,1
22
+
23
+ @results.connect(SIGNAL :released) {
24
+ @weak_class_dump_wrapper.pull_header_files
25
+ refresh_header_list
26
+ }
27
+
28
+ @open_folder = Qt::PushButton.new "Open Folder"
29
+ @layout.addWidget @open_folder, 0,2
30
+
31
+ @open_folder.connect(SIGNAL :released) {
32
+ Launchy.open @local_path
33
+ }
34
+
35
+
36
+ @header_list = Qt::ListWidget.new self
37
+ @header_list_label = Qt::Label.new "<b>Header Files:<b>"
38
+ @header_list.connect(SIGNAL('itemClicked(QListWidgetItem*)')) { |item|
39
+ @content.clear
40
+ @content.appendHtml(CodeRay.scan_file(@local_path + "/" + item.text).page(
41
+ :line_numbers => nil,
42
+ :css => :style
43
+ ))
44
+ }
45
+
46
+ @header_list.connect(SIGNAL('itemDoubleClicked(QListWidgetItem*)')) { |item|
47
+ $device.ops.open @local_path + "/" + item.text
48
+ }
49
+
50
+ @content = Qt::PlainTextEdit.new
51
+ @content.setReadOnly(true)
52
+
53
+ @splitter = Qt::Splitter.new
54
+ @splitter.addWidget @header_list
55
+ @splitter.addWidget @content
56
+ @splitter.setStretchFactor 1, 1.5
57
+ @splitter.setSizePolicy(Qt::SizePolicy::Expanding, Qt::SizePolicy::Expanding)
58
+ @layout.addWidget @splitter, 1, 0, 1, 3
59
+
60
+ end
61
+
62
+ def run_cycript
63
+ @local_path = "#{$selected_app.cache_dir}/weak_class_dump_headers"
64
+ @weak_class_dump_wrapper = WeakClassDumpWrapper.new @local_path
65
+ @weak_class_dump_wrapper.execute_cycript
66
+
67
+ error = Qt::MessageBox.new
68
+ error.setInformativeText("Cycript dumping the class information... This may take some time. On success the device will play the lock sound. You can then list the header files and view them.")
69
+ error.setIcon(Qt::MessageBox::Information)
70
+ error.exec
71
+
72
+ end
73
+
74
+ def refresh_header_list
75
+ @header_list.clear
76
+ @weak_class_dump_wrapper.get_header_files.each { |x|
77
+ @header_list.addItem x
78
+ }
79
+ end
80
+
81
+
82
+ def refresh
83
+ unless $selected_app.cache_dir.nil?
84
+ @local_path = "#{$selected_app.cache_dir}/weak_class_dump_headers"
85
+ @weak_class_dump_wrapper = WeakClassDumpWrapper.new @local_path
86
+ end
87
+ end
88
+ end
89
+ end
@@ -0,0 +1,72 @@
1
+ #!/usr/bin/env ruby
2
+ require_relative '../lib/ssh_port_forwarder'
3
+ require_relative '../lib/settings'
4
+ require_relative '../lib/usb_muxd_wrapper'
5
+ require 'log4r'
6
+
7
+ module Idb
8
+ class SSHPortForwarderHelper
9
+ def self.run
10
+
11
+ # initialize log
12
+ $log = Log4r::Logger.new 'port_forward'
13
+ outputter = Log4r::Outputter.stdout
14
+ outputter.formatter = Log4r::PatternFormatter.new(:pattern => "[%l] %d :: %c :: %m")
15
+ $log.outputters = [ outputter ]
16
+
17
+ # load settings
18
+ settings_path = File.dirname(ENV['HOME'] + "/.idb/config/")
19
+ settings_filename = "settings.yml"
20
+ settings = Settings.new "#{settings_path}/#{settings_filename}"
21
+
22
+ if settings['device_connection_mode'] == "ssh"
23
+ $log.debug "Connecting via SSH"
24
+
25
+ # setup forwards
26
+ $ssh_forwards = SSHPortForwarder.new settings['ssh_username'], settings['ssh_password'], settings['ssh_host'], settings['ssh_port']
27
+ else
28
+ $log.debug "Connecting via USB"
29
+
30
+ $usbmuxd = USBMuxdWrapper.new
31
+ proxy_port = $usbmuxd.find_available_port
32
+ $log.debug "Using port #{proxy_port} for SSH forwarding"
33
+
34
+ $usbmuxd.proxy proxy_port, settings['ssh_port']
35
+ # setup forwards
36
+ $ssh_forwards = SSHPortForwarder.new settings['ssh_username'], settings['ssh_password'], 'localhost', proxy_port
37
+ end
38
+
39
+
40
+ $log.info 'Setting up port forwarding...'
41
+
42
+ # Special idb internal port
43
+ $ssh_forwards.add_remote_forward Integer(settings['idb_utility_port']), 'localhost', Integer(settings['idb_utility_port'])
44
+
45
+ unless settings['remote_forwards'].nil?
46
+ settings['remote_forwards'].each { |x|
47
+ $ssh_forwards.add_remote_forward Integer(x['remote_port']), x['local_host'], Integer(x['local_port'])
48
+ }
49
+ end
50
+
51
+ unless settings['local_forwards'].nil?
52
+ settings['local_forwards'].each { |x|
53
+ $ssh_forwards.add_local_forward Integer(x['local_port']), x['remote_host'], Integer(x['remote_port'])
54
+ }
55
+ end
56
+
57
+ # start event loop
58
+ $ssh_forwards.start
59
+ end
60
+ end
61
+
62
+ begin
63
+ SSHPortForwarderHelper.run
64
+ rescue SystemExit, Interrupt
65
+ $log.info "Cleaning up before exiting"
66
+ $log.info "Closing SSH connection"
67
+ $ssh_forwards.stop
68
+ $log.info "Stopping any SSH via USB forwarding"
69
+ $usbmuxd.stop_all
70
+ end
71
+
72
+ end
@@ -0,0 +1,295 @@
1
+ require 'Qt'
2
+ require 'awesome_print'
3
+ require_relative 'lib/settings'
4
+ require_relative 'lib/simulator'
5
+ require_relative 'lib/device'
6
+ require_relative 'lib/qt_thread_fix'
7
+ require_relative 'gui/app_list_widget_item'
8
+ require_relative 'gui/screenshot_wizard'
9
+ require_relative 'gui/app_details_group_box'
10
+ require_relative 'gui/app_list_dialog'
11
+ require_relative 'gui/main_tab_widget'
12
+ require_relative 'gui/settings_dialog'
13
+ require_relative 'gui/device_info_group_box'
14
+ require_relative 'gui/ca_manager_dialog'
15
+
16
+ module Idb
17
+ TARGET = "Hello"
18
+
19
+ # logging
20
+ require 'log4r'
21
+
22
+ $width = 1024
23
+ $height = 768
24
+
25
+ class Idb < Qt::MainWindow
26
+
27
+ def initialize
28
+ super
29
+
30
+
31
+ # initialize log
32
+ $log = Log4r::Logger.new 'idb'
33
+ outputter = Log4r::Outputter.stdout
34
+ outputter.formatter = Log4r::PatternFormatter.new(:pattern => "[%l] %d :: %c :: %m")
35
+
36
+ $log.outputters = [ outputter ]
37
+
38
+ if RUBY_VERSION.start_with? "2.0"
39
+ error = Qt::MessageBox.new
40
+ error.setInformativeText("You are using ruby 2.0 which does not work well with QT bindings: custom signals don't work. It is very likely that idb will not function as intended. Consider using ruby 1.9 or 2.1 instead.")
41
+ error.setIcon(Qt::MessageBox::Critical)
42
+ error.exec
43
+ end
44
+
45
+
46
+
47
+ # enable threading. See https://github.com/ryanmelt/qtbindings/issues/63
48
+ @thread_fix = QtThreadFix.new
49
+ settings_path = File.dirname(ENV['HOME'] + "/.idb/config/")
50
+ $tmp_path = ENV['HOME'] + "/.idb/tmp/"
51
+ puts $tmp_path
52
+ unless File.directory?(settings_path)
53
+ $log.info "Creating settings directory: #{settings_path}"
54
+ FileUtils.mkdir_p(settings_path)
55
+ end
56
+
57
+ settings_filename = "settings.yml"
58
+ $settings = Settings.new "#{settings_path}/#{settings_filename}"
59
+
60
+ setWindowTitle "idb"
61
+ Qt::CoreApplication::setApplicationName("idb")
62
+ setWindowIconText('idb')
63
+ init_ui
64
+
65
+ # size = Qt::Size.new($width, $height)
66
+ # size = size.expandedTo(self.minimumSizeHint())
67
+ # resize(size)
68
+ # resize $width, $height
69
+
70
+ # center
71
+
72
+ # showMaximized();
73
+ # show
74
+ # self.raise
75
+ end
76
+
77
+ def self.execute_in_main_thread(blocking = false, sleep_period = 0.001)
78
+ if Thread.current != Thread.main
79
+ complete = false
80
+ QtThreadFix.ruby_thread_queue << lambda {|| yield; complete = true}
81
+ if blocking
82
+ until complete
83
+ sleep(sleep_period)
84
+ end
85
+ end
86
+ else
87
+ yield
88
+ end
89
+ end
90
+
91
+ def init_ui
92
+ # setup central widget and grid layout
93
+ @central_widget = Qt::Widget.new self
94
+ self.setCentralWidget @central_widget
95
+ @grid = Qt::GridLayout.new @central_widget
96
+
97
+ @grid.setColumnMinimumWidth(0,450)
98
+
99
+
100
+ # Box for App details
101
+ @app_details = AppDetailsGroupBox.new @central_widget
102
+ @app_details.connect(SIGNAL(:app_changed)) {
103
+ @main_tabs.app_changed
104
+ @app_binary.app_changed
105
+ @menu_item_screenshot.setEnabled(true)
106
+ }
107
+ @app_details.connect(SIGNAL(:show_device_status)) {
108
+ @device_status = DeviceStatusDialog.new
109
+ @device_status.exec
110
+ }
111
+
112
+
113
+ @grid.addWidget @app_details, 0,0
114
+
115
+ # App Binary Details
116
+ @app_binary = AppBinaryGroupBox.new @central_widget
117
+ @grid.addWidget @app_binary, 1,0
118
+ @app_binary.connect(SIGNAL('binary_analyzed()')) {
119
+ @main_tabs.refresh_app_binary
120
+ }
121
+
122
+ @spacer = Qt::SpacerItem.new 0,1, Qt::SizePolicy::Fixed, Qt::SizePolicy::Expanding
123
+ @grid.addItem @spacer, 2,0
124
+
125
+ # Main Tab Widget
126
+ @main_tabs = MainTabWidget.new @central_widget
127
+ @grid.addWidget @main_tabs, 0,1,3,1
128
+
129
+ # device Details
130
+ @device_details = DeviceInfoGroupBox.new @central_widget
131
+ @device_details.connect(SIGNAL :disconnect) {
132
+ @main_tabs.disable_all
133
+ @app_binary.clear
134
+ @app_binary.disable_analyze_binary
135
+ @app_details.clear
136
+ @app_details.disable_select_app
137
+ @usb_device.setChecked(false)
138
+ }
139
+ @grid.addWidget @device_details, 3,0,2,2
140
+
141
+ menu
142
+
143
+ end
144
+
145
+
146
+ def menu
147
+
148
+ ##########################################
149
+ # MENU
150
+ ##########################################
151
+ # File
152
+ menu_item_settings = Qt::Action.new "&Settings", self
153
+ menu_item_settings.connect(SIGNAL :triggered) {
154
+ setting = SettingsDialog.new self
155
+ setting.connect(SIGNAL :accepted) {
156
+ if $settings['device_connection_mode'] == "ssh"
157
+ @usb_device.setText("SSH Device")
158
+ else
159
+ @usb_device.setText("USB Device")
160
+ end
161
+ }
162
+ setting.exec
163
+ }
164
+ @menu_file = menuBar().addMenu "&File"
165
+ @menu_file.addAction menu_item_settings
166
+
167
+ @menu_item_screenshot = Qt::Action.new "&Screenshot", self
168
+ @menu_item_screenshot.setEnabled(false)
169
+ @menu_item_screenshot.connect(SIGNAL :triggered) {
170
+ tool = ScreenShotWizard::ScreenShotWizard.new_with_app $selected_app
171
+ }
172
+ @menu_item_cert = Qt::Action.new "&Certificate Manager", self
173
+ @menu_item_cert.setEnabled(false)
174
+ @menu_item_cert.connect(SIGNAL :triggered) {
175
+ ca = CAManagerDialog.new self
176
+ ca.exec
177
+ }
178
+ @menu_tools = menuBar().addMenu "&Tools"
179
+ @menu_tools.addAction @menu_item_screenshot
180
+ @menu_tools.addAction @menu_item_cert
181
+
182
+
183
+ #Devices
184
+ @sim_group = Qt::ActionGroup.new @menu_devices
185
+
186
+ @menu_devices = menuBar().addMenu "&Devices"
187
+ @usb_device = Qt::Action.new "USB Device", self
188
+ if $settings['device_connection_mode'] == "ssh"
189
+ @usb_device.setText("SSH Device")
190
+ else
191
+ @usb_device.setText("USB Device")
192
+ end
193
+
194
+ @usb_device.setCheckable(true)
195
+ @usb_device.connect(SIGNAL(:triggered)) { |x|
196
+ $device.disconnect unless $device.nil?
197
+
198
+ progress = Qt::ProgressDialog.new "Connecting to device. Please wait...", nil, 0, 2, @central_widget
199
+ progress.setWindowModality(Qt::WindowModal);
200
+ progress.setValue 1
201
+ progress.show
202
+ progress.raise
203
+
204
+ begin
205
+ $device = Device.new $settings.ssh_username,
206
+ $settings.ssh_password,
207
+ $settings.ssh_host,
208
+ $settings.ssh_port
209
+ rescue
210
+
211
+ end
212
+ unless $device.nil?
213
+ unless $device.configured?
214
+ puts "Y"
215
+ $log.info "Device not seen before. Opening status page."
216
+ error = Qt::MessageBox.new self
217
+ error.setInformativeText("This device has not been configured yet. Opening Status page to verify all required tools are installed on the device.")
218
+ error.setIcon(Qt::MessageBox::Warning)
219
+ error.exec
220
+ @device_status = DeviceStatusDialog.new
221
+ @device_status.exec
222
+ end
223
+
224
+
225
+
226
+
227
+ @app_details.enable_select_app
228
+ @device_details.update_device
229
+ @menu_item_cert.setEnabled(true)
230
+ @main_tabs.enableDeviceFunctions
231
+
232
+ end
233
+
234
+ progress.reset
235
+ }
236
+ menu_item = @menu_devices.addAction @usb_device
237
+ @sim_group.addAction @usb_device
238
+
239
+
240
+ x = @menu_devices.addSeparator
241
+ x.setText("Simulators")
242
+
243
+ Simulator.get_simulators.each { |s|
244
+ action = @menu_devices.addAction s
245
+ @sim_group.addAction action
246
+ action.setCheckable(true)
247
+ action.connect(SIGNAL(:triggered)) { |x|
248
+ $device = Simulator.new s
249
+ @app_details.enable_select_app
250
+ @device_details.update_device
251
+ @menu_item_cert.setEnabled(true)
252
+ }
253
+
254
+ @menu_devices.addAction action
255
+ }
256
+
257
+
258
+
259
+
260
+ end
261
+
262
+
263
+ def center
264
+ qdw = Qt::DesktopWidget.new
265
+
266
+ screenWidth = qdw.width
267
+ screenHeight = qdw.height
268
+
269
+ x = (screenWidth - $width) / 2
270
+ y = (screenHeight - $height) / 2
271
+
272
+ move x, y
273
+ end
274
+
275
+ def self.run
276
+ app = Qt::Application.new ARGV
277
+ app.setWindowIcon(Qt::Icon.new File.join(File.dirname(File.expand_path(__FILE__)), '/gui/images/iphone.ico'))
278
+
279
+ app.setApplicationName("idb")
280
+
281
+ idb = Idb.new
282
+ idb.setWindowState Qt::WindowActive
283
+ idb.showMaximized
284
+ idb.raise
285
+ app.exec
286
+
287
+ $log.info "Performing cleanup before exiting."
288
+ $device.close unless $device.nil?
289
+ $log.info "Thanks for using idb."
290
+
291
+ end
292
+ end
293
+
294
+
295
+ end