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,68 @@
1
+ require_relative 'console_widget'
2
+ require_relative 'cycript_thread'
3
+ require 'open3'
4
+
5
+ module Idb
6
+ class CycriptConsoleWidget < Qt::Widget
7
+
8
+ def initialize *args
9
+ super *args
10
+ @to_send = nil
11
+ @console = ConsoleWidget.new
12
+ @console.connect(SIGNAL('command(QString)')) {|cmd|
13
+ puts cmd.inspect
14
+ @cycript_thread.send_data cmd + "\n"
15
+ # @cycript_thread.send_data "testtest\n"
16
+ }
17
+
18
+ @start = Qt::PushButton.new "Start"
19
+ @start.connect(SIGNAL :released) {
20
+ # @start.setEnabled(false)
21
+ # @stop.setEnabled(true)
22
+ start
23
+
24
+ #@console.result data
25
+
26
+ }
27
+
28
+ @stop = Qt::PushButton.new "Stop"
29
+ @stop.connect(SIGNAL :released) {
30
+ Thread.list.each {|t| p t}
31
+ @cycript_thread.send_data "testtest\n"
32
+ Thread.pass
33
+
34
+ }
35
+
36
+ layout = Qt::VBoxLayout.new do |v|
37
+ v.add_widget(@console)
38
+ v.add_widget(@start)
39
+ v.add_widget(@stop)
40
+ end
41
+ setLayout(layout)
42
+
43
+
44
+ end
45
+ def pure_string s
46
+ x = loop{ s[/\033\[\d+m/] = "" }
47
+ rescue IndexError
48
+ return s
49
+ x
50
+ end
51
+
52
+ def start
53
+ @cycript_thread = CycriptThread.new
54
+ @cycript_thread.connect(SIGNAL('new_entry(QString)')) {|line|
55
+ @console.result line
56
+ }
57
+ @cycript_thread.launch_process
58
+ end
59
+
60
+ def stop
61
+ @cycript_thread.stop
62
+ end
63
+
64
+
65
+
66
+
67
+ end
68
+ end
@@ -0,0 +1,81 @@
1
+ require 'net/ssh'
2
+
3
+ module Idb
4
+ class CycriptThread < Qt::Object
5
+ signals "new_entry(QString)"
6
+
7
+ attr_accessor :channel
8
+
9
+ def initialize *args
10
+ super *args
11
+ $terminate_cycript_thread = false
12
+ @queue = Queue.new
13
+
14
+
15
+
16
+ end
17
+
18
+ def send_data data
19
+ puts "sending data"
20
+ # @queue << data
21
+ @channel.send_data data
22
+ # @channel.send_data "testtest\n"
23
+ end
24
+
25
+
26
+ def stop
27
+ $terminate_cycript_thread = true
28
+ end
29
+
30
+ def launch_process
31
+
32
+ @channel = $device.ssh.open_channel do |ch|
33
+ channel.request_pty do |ch, success|
34
+ raise "Error requesting pty" unless success
35
+ ch.exec("export TERM=vt220; stty -echo -icanon; cycript -p SpringBoard") do |ch, success|
36
+ raise "Error opening shell" unless success
37
+
38
+ ch.on_extended_data do |ch, type, data|
39
+ STDOUT.print "Error: #{data}\n"
40
+ end
41
+
42
+ ch.on_data do |ch, data|
43
+ puts "emitting"
44
+ emit new_entry(data)
45
+ puts "done"
46
+ end
47
+
48
+ ch.on_close { |ch|
49
+ $log.info "cycript terminated"
50
+ }
51
+
52
+
53
+ end
54
+ end
55
+ end
56
+
57
+
58
+ puts "thred"
59
+ @abc = Thread.new do
60
+ loop do
61
+ #TODO mutex to protect device?
62
+ #even better: make one central thread that calls process.
63
+ # and all functions using it call it to ensure its running. or auto start it.
64
+ sleep 0.5
65
+ puts "loop"
66
+ $device.ssh.loop 0.1
67
+ puts "done"
68
+ if $terminate_cycript_thread
69
+ $log.info "Terminating cycript"
70
+ channel.close
71
+ break
72
+ end
73
+ end
74
+ $log.info "Terminating thread"
75
+ end
76
+
77
+
78
+ end
79
+
80
+ end
81
+ end
@@ -0,0 +1,55 @@
1
+ require_relative 'device_status_dialog'
2
+
3
+ module Idb
4
+ class DeviceInfoGroupBox < Qt::GroupBox
5
+ signals "disconnect()"
6
+
7
+ def initialize *args
8
+ super *args
9
+
10
+ # details on selected app
11
+ @layout = Qt::GridLayout.new
12
+ setLayout(@layout)
13
+ setTitle "Selected Device"
14
+
15
+ @device = Qt::Label.new "<b><font color='red'>Please select a device from the 'Devices' menu.</font></b>", self, 0
16
+ @layout.addWidget @device, 0, 0, 2, 1
17
+ end
18
+
19
+ def update_device
20
+ if $device.device?
21
+ uname = $device.ops.execute("/bin/uname -a")
22
+ ssh_connection_info = ""
23
+ if $device.mode == "usb"
24
+ ssh_connection_info = " "
25
+ @device.setText "<b>USB device:</b> <b><font color='red'>Manually connect via SSH as #{$settings.ssh_username}@localhost:#{$device.usb_ssh_port}</font></b><br>#{uname}"
26
+ else
27
+ @device.setText "<b>USB device:</b> ssh://#{$settings.ssh_username}:[redacted]@#{$settings.ssh_host}:#{$settings.ssh_port}<br>#{uname}"
28
+ end
29
+
30
+ @status = Qt::PushButton.new "Status"
31
+ @status.connect(SIGNAL(:released)) {
32
+ @device_status = DeviceStatusDialog.new
33
+ @device_status.exec
34
+ }
35
+ @layout.addWidget @status, 0, 1
36
+
37
+ @disconnect = Qt::PushButton.new "Disconnect"
38
+ @disconnect.connect(SIGNAL(:released)) {
39
+ $device.close unless $device.nil?
40
+ $device = nil
41
+ emit disconnect()
42
+ @disconnect.setEnabled(false)
43
+ @status.setEnabled(false)
44
+ @device.setText("<b><font color='red'>Please select a device from the 'Devices' menu.</font></b>")
45
+ }
46
+ @layout.addWidget @disconnect, 1, 1
47
+
48
+ else
49
+ @device.setText "<b>Simulator:</b> #{$device.sim_dir}"
50
+ end
51
+ end
52
+
53
+
54
+ end
55
+ end
@@ -0,0 +1,351 @@
1
+ module Idb
2
+ class DeviceStatusDialog < Qt::Dialog
3
+
4
+
5
+ def installed_check_mark
6
+ installed_check_mark = Qt::Label.new
7
+ pixmap = Qt::Pixmap.new File.join(File.dirname(File.expand_path(__FILE__)), '/images/check.png')
8
+ installed_check_mark.setPixmap pixmap
9
+ installed_check_mark
10
+ end
11
+
12
+ def mark_rsync_installed
13
+ @rsync_label.text = @rsync_label.text + "<br>found: #{$device.rsync_path}"
14
+ @layout.addWidget installed_check_mark, 7, 1
15
+ setFixedHeight(sizeHint().height());
16
+ end
17
+
18
+ def mark_clutch_installed
19
+ @clutch_label.text = @clutch_label.text + "<br>found: #{$device.clutch_path}"
20
+ @layout.addWidget installed_check_mark, 8, 1
21
+ setFixedHeight(sizeHint().height());
22
+ end
23
+
24
+ def mark_keychain_dump_installed
25
+ @keychain_dump_label.text = @keychain_dump_label.text + "<br>found: #{$device.keychain_dump_path}"
26
+ @layout.addWidget installed_check_mark, 6, 1
27
+ setFixedHeight(sizeHint().height());
28
+ end
29
+
30
+ def mark_pcviewer_installed
31
+ @pcviewer_label.text = @pcviewer_label.text + "<br>found: #{$device.pcviewer_path}"
32
+ @layout.addWidget installed_check_mark, 5, 1
33
+ setFixedHeight(sizeHint().height());
34
+ end
35
+
36
+ def mark_pbwatcher_installed
37
+ @pbwatcher_label.text = @pbwatcher_label.text + "<br>found: #{$device.pbwatcher_path}"
38
+ @layout.addWidget installed_check_mark, 4, 1
39
+ setFixedHeight(sizeHint().height());
40
+ end
41
+
42
+ def mark_dumpdecrypted_installed
43
+ @dumpdecrypted_label.text = @dumpdecrypted_label.text + "<br>Found: #{$device.dumpdecrypted_path}"
44
+ @layout.addWidget installed_check_mark, 3, 1
45
+ setFixedHeight(sizeHint().height());
46
+ end
47
+
48
+
49
+ def mark_apt_get_installed
50
+ @aptget_label.text = @aptget_label.text + "<br>Found: #{$device.apt_get_path}"
51
+ @layout.addWidget installed_check_mark, 0, 1
52
+ setFixedHeight(sizeHint().height());
53
+ end
54
+
55
+ def mark_open_installed
56
+ @open_label.text = @open_label.text + "<br>Found: #{$device.open_path}"
57
+ @layout.addWidget installed_check_mark, 1, 1
58
+ setFixedHeight(sizeHint().height());
59
+ end
60
+
61
+ def mark_openurl_installed
62
+ @openurl_label.text = @openurl_label.text + "<br>Found: #{$device.openurl_path}"
63
+ @layout.addWidget installed_check_mark, 2, 1
64
+ setFixedHeight(sizeHint().height());
65
+ end
66
+
67
+ def mark_cycript_installed
68
+ @cycript_label.text = @cycript_label.text + "<br>Found: #{$device.cycript_path}"
69
+ @layout.addWidget installed_check_mark, 8, 1
70
+ setFixedHeight(sizeHint().height());
71
+ end
72
+
73
+
74
+ def initialize *args
75
+ super *args
76
+ @layout = Qt::GridLayout.new
77
+ setLayout(@layout)
78
+ setWindowTitle "Device Status"
79
+
80
+ @close_button = Qt::PushButton.new "Close"
81
+ @close_button.connect(SIGNAL(:released)) {|x|
82
+ reject()
83
+ }
84
+ #TODO: prevent closing
85
+ @layout.addWidget @close_button, 9, 2
86
+
87
+
88
+ #######################
89
+ ### APT-GET
90
+ #######################
91
+
92
+
93
+ @aptget_label = Qt::Label.new "<b>apt-get / aptitude</b><br>(Install additional software packages)"
94
+ @layout.addWidget @aptget_label, 0, 0
95
+
96
+
97
+ if $device.apt_get_installed?
98
+ mark_apt_get_installed
99
+ else
100
+ @install_aptget = Qt::PushButton.new "Install"
101
+ @install_aptget.connect(SIGNAL(:released)) {
102
+ $device.install_apt_get
103
+ if $device.apt_get_installed?
104
+ @install_aptget.hide
105
+ mark_apt_get_installed
106
+ end
107
+ }
108
+ @layout.addWidget @install_aptget, 0, 1
109
+ end
110
+ #######################
111
+ ### OPEN
112
+ #######################
113
+
114
+ @open_label = Qt::Label.new "<b>open</b><br>(Open apps on the device)"
115
+ @layout.addWidget @open_label, 1, 0
116
+
117
+ if $device.open_installed?
118
+ mark_open_installed
119
+ else
120
+ @install_open = Qt::PushButton.new "Install"
121
+ @install_open.connect(SIGNAL(:released)) {
122
+ $device.install_open
123
+ if $device.open_installed?
124
+ @install_open.hide
125
+ mark_open_installed
126
+ else
127
+ error = Qt::MessageBox.new
128
+ error.setInformativeText("open could not be installed. Please make sure Cydia has finished all tasks and is closed on the device.")
129
+ error.setIcon(Qt::MessageBox::Critical)
130
+ error.exec
131
+ end
132
+ }
133
+ @layout.addWidget @install_open, 1, 1
134
+ end
135
+
136
+ #######################
137
+ ### OPEN URL
138
+ #######################
139
+
140
+
141
+ @openurl_label = Qt::Label.new "<b>openURL</b><br>(Open URL on the device)"
142
+ @layout.addWidget @openurl_label, 2, 0
143
+
144
+
145
+ if $device.openurl_installed?
146
+ mark_openurl_installed
147
+ else
148
+ # @install_openurl = Qt::PushButton.new "Install"
149
+ # @install_openurl.connect(SIGNAL(:released)) {
150
+ # $device.install_openurl
151
+ # if $device.open_installed?
152
+ # @install_open.hide
153
+ # mark_open_installed
154
+ # end
155
+ # }
156
+ # @layout.addWidget @install_openurl, 2, 1
157
+ end
158
+
159
+
160
+ #######################
161
+ ### DUMPDECRYPTED
162
+ #######################
163
+
164
+ @dumpdecrypted_label = Qt::Label.new "<b>dumpdecrypted</b><br>(Decrypt app binaries on the device).<br>Developed and maintained by Stefan Esser https://github.com/stefanesser/dumpdecrypted"
165
+ @layout.addWidget @dumpdecrypted_label, 3, 0
166
+
167
+ if $device.dumpdecrypted_installed?
168
+ mark_dumpdecrypted_installed
169
+ else
170
+ @install_dumpdecrypted = Qt::PushButton.new "Install"
171
+ @install_dumpdecrypted.connect(SIGNAL(:released)) {
172
+ $device.install_dumpdecrypted
173
+ if $device.dumpdecrypted_installed?
174
+ @install_dumpdecrypted.hide
175
+ mark_dumpdecrypted_installed
176
+ else
177
+ error = Qt::MessageBox.new
178
+ error.setInformativeText("No compiled version of dumpdecrypted was found in utils/dumpdecrypted. It cannot be shipped with idb due to licensing issues. Compilation failed likely due to XCode 5 not shipping the right version of gcc anymore. Try manually copying dumpdecrypted.dylib into /var/root on the device.")
179
+ error.setIcon(Qt::MessageBox::Critical)
180
+ error.exec
181
+ end
182
+
183
+ }
184
+ @layout.addWidget @install_dumpdecrypted, 3, 1
185
+ end
186
+
187
+
188
+ #######################
189
+ ### PBWATCHER
190
+ #######################
191
+
192
+
193
+ @pbwatcher_label = Qt::Label.new "<b>pbwatcher</b><br>(idb pasteboard monitor helper)"
194
+ @layout.addWidget @pbwatcher_label, 4, 0
195
+
196
+ if $device.pbwatcher_installed?
197
+ mark_pbwatcher_installed
198
+ else
199
+ @install_pbwatcher = Qt::PushButton.new "Install"
200
+ @install_pbwatcher.connect(SIGNAL(:released)) {
201
+ $device.install_pbwatcher
202
+ if $device.pbwatcher_installed?
203
+ @install_pbwatcher.hide
204
+ mark_pbwatcher_installed
205
+ end
206
+ }
207
+
208
+
209
+ @layout.addWidget @install_pbwatcher, 4, 1
210
+ end
211
+
212
+
213
+ #######################
214
+ ### PCVIEWER
215
+ #######################
216
+
217
+
218
+ @pcviewer_label = Qt::Label.new "<b>pcviewer</b><br>(idb file protection class helper)"
219
+ @layout.addWidget @pcviewer_label, 5, 0
220
+
221
+ if $device.pcviewer_installed?
222
+ mark_pcviewer_installed
223
+ else
224
+ @install_pcviewer = Qt::PushButton.new "Install"
225
+ @install_pcviewer.connect(SIGNAL(:released)) {
226
+ $device.install_pcviewer
227
+ if $device.pcviewer_installed?
228
+ @install_pcviewer.hide
229
+ mark_pcviewer_installed
230
+ end
231
+ }
232
+
233
+
234
+ @layout.addWidget @install_pcviewer, 5, 1
235
+ end
236
+
237
+ #######################
238
+ ### KEYCHAIN_DUMPER
239
+ #######################
240
+
241
+
242
+ @keychain_dump_label = Qt::Label.new "<b>keychain_dump</b><br>(dumps the keychain into a plist file.<br>https://code.google.com/p/iphone-dataprotection/)"
243
+ @layout.addWidget @keychain_dump_label, 6, 0
244
+
245
+ if $device.keychain_dump_installed?
246
+ mark_keychain_dump_installed
247
+ else
248
+ @install_keychain_dump = Qt::PushButton.new "Install"
249
+ @install_keychain_dump.connect(SIGNAL(:released)) {
250
+ $device.install_keychain_dump
251
+ if $device.keychain_dump_installed?
252
+ @install_keychain_dump.hide
253
+ mark_keychain_dump_installed
254
+ end
255
+ }
256
+
257
+
258
+ @layout.addWidget @install_keychain_dump, 6, 1
259
+
260
+ end
261
+
262
+
263
+ #######################
264
+ ### rsync
265
+ #######################
266
+
267
+
268
+ @rsync_label = Qt::Label.new "<b>rsync</b><br>(folder synchronization)"
269
+ @layout.addWidget @rsync_label, 7, 0
270
+
271
+ if $device.rsync_installed?
272
+ mark_rsync_installed
273
+ else
274
+ @install_rsync = Qt::PushButton.new "Install"
275
+ @install_rsync.connect(SIGNAL(:released)) {
276
+ $device.install_rsync
277
+ if $device.rsync_installed?
278
+ @install_rsync.hide
279
+ mark_rsync_installed
280
+ else
281
+ error = Qt::MessageBox.new
282
+ error.setInformativeText("rsync could not be installed. Please make sure Cydia has finished all tasks and is closed on the device.")
283
+ error.setIcon(Qt::MessageBox::Critical)
284
+ error.exec
285
+ end
286
+ }
287
+
288
+
289
+ @layout.addWidget @install_rsync, 7, 1
290
+
291
+ end
292
+
293
+
294
+ #######################
295
+ ### CYCRIPT
296
+ #######################
297
+
298
+ @cycript_label = Qt::Label.new "<b>cycript</b><br>(explore and modify running applications using a hybrid of Objective-C++ and JavaScript. http://www.cycript.org/ )"
299
+ @layout.addWidget @cycript_label, 8, 0
300
+
301
+ if $device.cycript_installed?
302
+ mark_cycript_installed
303
+ else
304
+ @install_cycript = Qt::PushButton.new "Install"
305
+ @install_cycript.connect(SIGNAL(:released)) {
306
+ $device.install_cycript
307
+ if $device.cycript_installed?
308
+ @install_cycript.hide
309
+ mark_cycript_installed
310
+ else
311
+ error = Qt::MessageBox.new
312
+ error.setInformativeText("cycript could not be installed. Please make sure Cydia has finished all tasks and is closed on the device.")
313
+ error.setIcon(Qt::MessageBox::Critical)
314
+ error.exec
315
+ end
316
+ }
317
+ @layout.addWidget @install_cycript, 8, 1
318
+ end
319
+
320
+ #######################
321
+ ### clutch
322
+ #######################
323
+
324
+
325
+ # @clutch_label = Qt::Label.new "<b>Clutch (not used by idb)</b><br>(App cracking tool that also performs decryption. Installation from cydia.iphonecake.com.)"
326
+ # @layout.addWidget @clutch_label, 8, 0
327
+ #
328
+ # if $device.clutch_installed?
329
+ # mark_clutch_installed
330
+ # else
331
+ # @install_clutch = Qt::PushButton.new "Install"
332
+ # @install_clutch.connect(SIGNAL(:released)) {
333
+ # $device.setup_clutch_source
334
+ # $device.install_clutch
335
+ # if $device.clutch_installed?
336
+ # @install_clutch.hide
337
+ # mark_clutch_installed
338
+ # end
339
+ # }
340
+ #
341
+ #
342
+ # @layout.addWidget @install_clutch, 8, 1
343
+ #
344
+ # end
345
+
346
+ setFixedHeight(sizeHint().height());
347
+ end
348
+
349
+
350
+ end
351
+ end