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,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