idb 1.3.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.DS_Store +0 -0
- data/.gitignore +19 -0
- data/Gemfile +4 -0
- data/Gemfile.lock +65 -0
- data/LICENSE.txt +22 -0
- data/README.md +29 -0
- data/Rakefile +2 -0
- data/bin/idb +5 -0
- data/idb.gemspec +41 -0
- data/lib/LICENSE +20 -0
- data/lib/README.md +54 -0
- data/lib/config/.dummy +0 -0
- data/lib/config/settings.yml +8 -0
- data/lib/gui/app_binary_tab_widget.rb +45 -0
- data/lib/gui/app_details_group_box.rb +213 -0
- data/lib/gui/app_list_dialog.rb +67 -0
- data/lib/gui/app_list_widget_item.rb +9 -0
- data/lib/gui/binary_strings_widget.rb +33 -0
- data/lib/gui/browse_filesystem_widget.rb +4 -0
- data/lib/gui/ca_manager_dialog.rb +137 -0
- data/lib/gui/cache_db_widget.rb +61 -0
- data/lib/gui/certificate_item.rb +5 -0
- data/lib/gui/console_widget.rb +163 -0
- data/lib/gui/cycript_console_widget.rb +68 -0
- data/lib/gui/cycript_thread.rb +81 -0
- data/lib/gui/device_info_group_box.rb +55 -0
- data/lib/gui/device_status_dialog.rb +351 -0
- data/lib/gui/file_system_events_widget.rb +4 -0
- data/lib/gui/fs_viewer_tab_widget.rb +245 -0
- data/lib/gui/i_device_syslog_thread.rb +47 -0
- data/lib/gui/images/check.png +0 -0
- data/lib/gui/images/folder.ico +0 -0
- data/lib/gui/images/iphone.ico +0 -0
- data/lib/gui/images/screenshot.png +0 -0
- data/lib/gui/key_chain_widget.rb +86 -0
- data/lib/gui/local_storage_tab_widget.rb +37 -0
- data/lib/gui/log_plain_text_edit.rb +18 -0
- data/lib/gui/log_widget.rb +71 -0
- data/lib/gui/main_tab_widget.rb +179 -0
- data/lib/gui/pasteboard_monitor_widget.rb +116 -0
- data/lib/gui/path_list_widget_item.rb +5 -0
- data/lib/gui/pb_watcher_thread.rb +63 -0
- data/lib/gui/plist_file_widget.rb +66 -0
- data/lib/gui/qt_ruby_variant.rb +16 -0
- data/lib/gui/screenshot_wizard.rb +169 -0
- data/lib/gui/settings_dialog.rb +69 -0
- data/lib/gui/settings_tab_widget.rb +149 -0
- data/lib/gui/shared_libraries_widget.rb +47 -0
- data/lib/gui/snoop_it_fs_events_widget.rb +150 -0
- data/lib/gui/snoop_it_keychain_widget.rb +172 -0
- data/lib/gui/snoop_it_sensitive_api_widget.rb +128 -0
- data/lib/gui/snoop_it_tab_widget.rb +27 -0
- data/lib/gui/snoop_it_update_thread.rb +48 -0
- data/lib/gui/sqlite_widget.rb +73 -0
- data/lib/gui/ssh_port_forward_tab_widget.rb +209 -0
- data/lib/gui/tool_widget.rb +94 -0
- data/lib/gui/url_handler_widget.rb +26 -0
- data/lib/gui/url_scheme_fuzz_widget.rb +103 -0
- data/lib/gui/url_scheme_widget.rb +60 -0
- data/lib/gui/weak_class_dump_widget.rb +89 -0
- data/lib/helper/ssh_port_forwarder.rb +72 -0
- data/lib/idb.rb +295 -0
- data/lib/idb/version.rb +3 -0
- data/lib/lib/CgBI.rb +153 -0
- data/lib/lib/abstract_device.rb +31 -0
- data/lib/lib/app.rb +286 -0
- data/lib/lib/app_binary.rb +57 -0
- data/lib/lib/ca_interface.rb +151 -0
- data/lib/lib/configuration.rb +0 -0
- data/lib/lib/console_launcher.rb +24 -0
- data/lib/lib/device.rb +438 -0
- data/lib/lib/device_ca_interface.rb +36 -0
- data/lib/lib/host_file_wrapper.rb +27 -0
- data/lib/lib/i_device_diagnostics_wrapper.rb +90 -0
- data/lib/lib/keychain_plist_parser.rb +15 -0
- data/lib/lib/local_operations.rb +67 -0
- data/lib/lib/otool_wrapper.rb +116 -0
- data/lib/lib/plist_util.rb +72 -0
- data/lib/lib/qt_thread_fix.rb +29 -0
- data/lib/lib/rsync_git_manager.rb +81 -0
- data/lib/lib/screen_shot_util.rb +59 -0
- data/lib/lib/settings.rb +67 -0
- data/lib/lib/simulator.rb +60 -0
- data/lib/lib/simulator_ca_interface.rb +16 -0
- data/lib/lib/snoop_it_wrapper.rb +80 -0
- data/lib/lib/ssh_operations.rb +136 -0
- data/lib/lib/ssh_port_forwarder.rb +43 -0
- data/lib/lib/tools.rb +11 -0
- data/lib/lib/url_scheme_fuzzer.rb +98 -0
- data/lib/lib/usb_muxd_wrapper.rb +32 -0
- data/lib/lib/weak_class_dump_wrapper.rb +62 -0
- data/lib/utils/dumpdecrypted/README +4 -0
- data/lib/utils/dumpdecrypted/dumpdecrypted_armv6.dylib +0 -0
- data/lib/utils/dumpdecrypted/dumpdecrypted_armv7.dylib +0 -0
- data/lib/utils/ios-ssl-kill-switch/com.isecpartners.nabla.sslkillswitch_v0.5-iOS_6.1.deb +0 -0
- data/lib/utils/keychain_dump/README +2 -0
- data/lib/utils/keychain_dump/keychain_dump +0 -0
- data/lib/utils/pbwatcher/pbwatcher +0 -0
- data/lib/utils/pcviewer/protectionclassviewer +0 -0
- data/lib/utils/weak_class_dump/README +5 -0
- data/lib/utils/weak_class_dump/weak_classdump.cy +726 -0
- 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,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
|