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.
- 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,36 @@
|
|
|
1
|
+
require_relative 'ca_interface'
|
|
2
|
+
|
|
3
|
+
module Idb
|
|
4
|
+
class DeviceCAInterface < CAInterface
|
|
5
|
+
|
|
6
|
+
def initialize device
|
|
7
|
+
@device = device
|
|
8
|
+
@device_store_path = "/private/var/Keychains/TrustStore.sqlite3"
|
|
9
|
+
base_path = "#{$tmp_path}/device"
|
|
10
|
+
FileUtils.mkdir_p base_path
|
|
11
|
+
@db_path = "#{base_path}/TrustStore.sqlite3"
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
def get_certs
|
|
18
|
+
@device.ops.download @device_store_path, @db_path
|
|
19
|
+
super
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
def remove_cert cert
|
|
23
|
+
FileUtils.copy_file @db_path, "#{@db_path}-#{Time.now.to_s}"
|
|
24
|
+
super cert
|
|
25
|
+
@device.ops.upload @db_path, @device_store_path
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
def add_cert cert_file
|
|
29
|
+
FileUtils.copy_file @db_path, "#{@db_path}-#{Time.now.to_s}"
|
|
30
|
+
super cert_file
|
|
31
|
+
@device.ops.upload @db_path, @device_store_path
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
end
|
|
36
|
+
end
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
module Idb
|
|
2
|
+
class HostFileWrapper
|
|
3
|
+
|
|
4
|
+
def initialize
|
|
5
|
+
@cache_path = "#{$tmp_path}/device/hosts"
|
|
6
|
+
end
|
|
7
|
+
|
|
8
|
+
def content
|
|
9
|
+
FileUtils.mkpath "#{$tmp_path}/device" unless File.directory? "#{$tmp_path}/device"
|
|
10
|
+
$device.ops.download "/etc/hosts", @cache_path
|
|
11
|
+
begin
|
|
12
|
+
File.open(@cache_path,"r").read
|
|
13
|
+
rescue
|
|
14
|
+
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
def save text
|
|
19
|
+
# upload
|
|
20
|
+
File.open(@cache_path,"w") { |f|
|
|
21
|
+
f.puts text
|
|
22
|
+
}
|
|
23
|
+
$device.ops.upload(@cache_path, "/etc/hosts")
|
|
24
|
+
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
end
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
require 'ffi'
|
|
2
|
+
|
|
3
|
+
module IMobileDevice
|
|
4
|
+
extend FFI::Library
|
|
5
|
+
|
|
6
|
+
ffi_lib 'libimobiledevice'
|
|
7
|
+
IDeviceEventType = enum(
|
|
8
|
+
:idevice_device_added, 1,
|
|
9
|
+
:idevice_device_remove
|
|
10
|
+
)
|
|
11
|
+
|
|
12
|
+
class IDeviceEventT < FFI::Struct
|
|
13
|
+
layout :event, IDeviceEventType,
|
|
14
|
+
:udid, :string,
|
|
15
|
+
:conn_type, :int
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
ConnectionType = enum(
|
|
19
|
+
:connection_usbmuxd, 1
|
|
20
|
+
)
|
|
21
|
+
|
|
22
|
+
class IDevicePrivate < FFI::Struct
|
|
23
|
+
layout :udid, :string,
|
|
24
|
+
:conn_type, ConnectionType,
|
|
25
|
+
:conn_data, :pointer
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
attach_function :idevice_get_device_list, [:pointer, :pointer], :int
|
|
31
|
+
attach_function :idevice_event_subscribe, [:pointer, :pointer], :int
|
|
32
|
+
attach_function :idevice_new, [:pointer, :string], :int
|
|
33
|
+
# attach_function :syslog_relay_client_start_service, [IDevicePrivate, :pointer, :string], :int
|
|
34
|
+
# attach_function :syslog_relay_start_capture, [:pointer, :pointer, :pointer], :int
|
|
35
|
+
# attach_function :syslog_relay_client_free, [:pointer], :int
|
|
36
|
+
|
|
37
|
+
def self.startLogging
|
|
38
|
+
ret = idevice_new(IDevicePrivate, @udid)
|
|
39
|
+
if ret != 0
|
|
40
|
+
puts "ERROR"
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
end
|
|
47
|
+
def self.stopLogging
|
|
48
|
+
puts "stopstopstop"
|
|
49
|
+
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
# DeviceEvn :device, [:pointer, :long, :uint8], :void
|
|
53
|
+
|
|
54
|
+
DeviceEventCB = FFI::Function.new(:void, [:pointer, :pointer]) do |event, userdata|
|
|
55
|
+
# cast event to struct
|
|
56
|
+
event_t = IDeviceEventT.new event
|
|
57
|
+
if event_t[:event] == :idevice_device_added
|
|
58
|
+
if @syslog.nil? or @syslog == false
|
|
59
|
+
if @udid.nil? or @udid == false
|
|
60
|
+
@udid = event_t[:udid]
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
if @udid == event_t[:udid]
|
|
64
|
+
#TODO error checking
|
|
65
|
+
puts "[*] Start Logging"
|
|
66
|
+
IMobileDevice.startLogging
|
|
67
|
+
end
|
|
68
|
+
end
|
|
69
|
+
elsif avent_t[:event] == :idevice_device_remove
|
|
70
|
+
if not @syslog.nil? and @udid == event_t[:udid]
|
|
71
|
+
puts "[*] Disconnected"
|
|
72
|
+
end
|
|
73
|
+
end
|
|
74
|
+
end
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
devices = FFI::MemoryPointer.new :pointer
|
|
78
|
+
num = FFI::MemoryPointer.new :int
|
|
79
|
+
x = IMobileDevice.idevice_get_device_list(devices, num)
|
|
80
|
+
device = devices.read_pointer.get_array_of_string(0,num.read_int).first
|
|
81
|
+
puts "Device #{device}"
|
|
82
|
+
IMobileDevice.idevice_event_subscribe(IMobileDevice::DeviceEventCB, nil)
|
|
83
|
+
|
|
84
|
+
|
|
85
|
+
|
|
86
|
+
while true
|
|
87
|
+
|
|
88
|
+
end
|
|
89
|
+
|
|
90
|
+
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
# encoding: utf-8
|
|
2
|
+
require 'nokogiri'
|
|
3
|
+
require 'plist4r'
|
|
4
|
+
require 'awesome_print'
|
|
5
|
+
|
|
6
|
+
module Idb
|
|
7
|
+
class KeychainPlistParser
|
|
8
|
+
attr_accessor :entries
|
|
9
|
+
|
|
10
|
+
def initialize plist_path
|
|
11
|
+
$log.info 'Parsing keychain plist file..'
|
|
12
|
+
@entries = Plist4r.open(plist_path)["Array"]
|
|
13
|
+
end
|
|
14
|
+
end
|
|
15
|
+
end
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
module Idb
|
|
2
|
+
class LocalOperations
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
def file? path
|
|
6
|
+
File.file? path
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
def download a, b
|
|
11
|
+
FileUtils.copy_file(a,b)
|
|
12
|
+
return true
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
def directory? path
|
|
17
|
+
File.directory? path
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
def mtime path
|
|
21
|
+
File.mtime path
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def open path
|
|
25
|
+
begin
|
|
26
|
+
Launchy.open path
|
|
27
|
+
return true
|
|
28
|
+
rescue Exception => e
|
|
29
|
+
$log.error "Could not open file #{path}: #{e.message}"
|
|
30
|
+
$log.error e.backtrace
|
|
31
|
+
return false
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
def list_dir path
|
|
36
|
+
Dir.entries path
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
def list_dir_full path
|
|
40
|
+
Dir.entries path
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
def dir_glob path, pattern
|
|
44
|
+
full_path = "#{path}/#{pattern}"
|
|
45
|
+
Dir.glob(full_path)
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
def file_exists? file
|
|
49
|
+
File.exists? file
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
def execute cmd
|
|
53
|
+
`#{cmd}`
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
def execute_fork cmd
|
|
57
|
+
(pid = fork) ? Process.detach(pid) : exec(cmd)
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
def launch_app command, app
|
|
61
|
+
$log.info "Executing #{command} #{app}"
|
|
62
|
+
self.execute_fork("#{command} \"#{app}\"")
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
|
|
66
|
+
end
|
|
67
|
+
end
|
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
require 'awesome_print'
|
|
2
|
+
|
|
3
|
+
module Idb
|
|
4
|
+
class OtoolWrapper
|
|
5
|
+
attr_accessor :load_commands, :shared_libraries, :pie, :arc, :canaries
|
|
6
|
+
|
|
7
|
+
def initialize binary
|
|
8
|
+
@otool_path = "/usr/bin/otool"
|
|
9
|
+
unless File.exist? @otool_path.to_s
|
|
10
|
+
$log.error "otool not available. Some functions will not work properly."
|
|
11
|
+
error = Qt::MessageBox.new
|
|
12
|
+
error.setInformativeText("This feature requires otool to be installed on the host running idb. This is the default on OS X but it may not be available for other platforms.")
|
|
13
|
+
error.setIcon(Qt::MessageBox::Critical)
|
|
14
|
+
error.exec
|
|
15
|
+
@otool_path = nil
|
|
16
|
+
|
|
17
|
+
return
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
@binary = binary
|
|
21
|
+
parse_load_commands
|
|
22
|
+
parse_shared_libraries
|
|
23
|
+
parse_header
|
|
24
|
+
process_symbol_table
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
private
|
|
29
|
+
def parse_shared_libraries
|
|
30
|
+
if @otool_path.nil?
|
|
31
|
+
@shared_libraries = Array.new
|
|
32
|
+
@shared_libraries << "Error; otool not available"
|
|
33
|
+
return
|
|
34
|
+
end
|
|
35
|
+
@raw_shared_libraries_output = `#{@otool_path} -L '#{@binary}'`
|
|
36
|
+
lines = @raw_shared_libraries_output.split("\n")
|
|
37
|
+
@shared_libraries = lines[1,lines.size].map{ |x| x.strip} unless lines.nil?
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
def process_symbol_table
|
|
41
|
+
if @otool_path.nil?
|
|
42
|
+
@canaries = "Error"
|
|
43
|
+
@arc = "Error"
|
|
44
|
+
return
|
|
45
|
+
end
|
|
46
|
+
symbols = `#{@otool_path} -I -v '#{@binary}'`
|
|
47
|
+
if symbols.include? "stack_chk_fail" or symbols.include? "stack_chk_guard"
|
|
48
|
+
@canaries = true
|
|
49
|
+
else
|
|
50
|
+
@canaries = false
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
if symbols.include? "_objc_release"
|
|
54
|
+
@arc = true
|
|
55
|
+
else
|
|
56
|
+
@arc = false
|
|
57
|
+
end
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
|
|
61
|
+
|
|
62
|
+
|
|
63
|
+
def parse_header
|
|
64
|
+
if @otool_path.nil?
|
|
65
|
+
@pie = "Error"
|
|
66
|
+
return
|
|
67
|
+
end
|
|
68
|
+
pie_flag = 0x00200000
|
|
69
|
+
@raw_load_output = `#{@otool_path} -h '#{@binary}'`
|
|
70
|
+
|
|
71
|
+
# fourth row contains values. then split them up.
|
|
72
|
+
vals = @raw_load_output.split("\n")[3].split(" ")
|
|
73
|
+
|
|
74
|
+
#7th field contains the flags
|
|
75
|
+
flags = vals[7].to_i(16)
|
|
76
|
+
|
|
77
|
+
if flags & pie_flag == pie_flag
|
|
78
|
+
@pie = true
|
|
79
|
+
else
|
|
80
|
+
@pie = false
|
|
81
|
+
end
|
|
82
|
+
|
|
83
|
+
|
|
84
|
+
end
|
|
85
|
+
|
|
86
|
+
def parse_load_commands
|
|
87
|
+
if @otool_path.nil?
|
|
88
|
+
@load_commands = nil
|
|
89
|
+
return
|
|
90
|
+
end
|
|
91
|
+
@raw_load_output = `#{@otool_path} -l '#{@binary}'`
|
|
92
|
+
delim = "Load command"
|
|
93
|
+
regex_cmd = /Load command (\d+)/
|
|
94
|
+
regex_parse_key_vals = /\s*(cmd|cryptid)\s(.+)/
|
|
95
|
+
|
|
96
|
+
@load_commands = Hash.new
|
|
97
|
+
|
|
98
|
+
@raw_load_output.split("\n").each {|line|
|
|
99
|
+
|
|
100
|
+
if match = regex_cmd.match(line)
|
|
101
|
+
@load_commands[@cmd] = @command unless @cmd.nil?
|
|
102
|
+
@cmd = match[1]
|
|
103
|
+
@command = Hash.new
|
|
104
|
+
end
|
|
105
|
+
|
|
106
|
+
if match = regex_parse_key_vals.match(line)
|
|
107
|
+
@command[match[1]] = match[2]
|
|
108
|
+
end
|
|
109
|
+
}
|
|
110
|
+
end
|
|
111
|
+
|
|
112
|
+
|
|
113
|
+
|
|
114
|
+
|
|
115
|
+
end
|
|
116
|
+
end
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
require 'plist4r'
|
|
2
|
+
require 'rbconfig'
|
|
3
|
+
require 'nokogiri'
|
|
4
|
+
require 'coderay'
|
|
5
|
+
|
|
6
|
+
module Idb
|
|
7
|
+
class PlistUtil
|
|
8
|
+
|
|
9
|
+
attr_accessor :schemas, :binary_name, :bundle_identifier, :plist_data, :plist_file
|
|
10
|
+
|
|
11
|
+
def initialize(plist_file)
|
|
12
|
+
@plist_file = plist_file
|
|
13
|
+
|
|
14
|
+
@plutil = Pathname.new("/usr/bin/plutil")
|
|
15
|
+
if(!@plutil.exist?)
|
|
16
|
+
raise "plutil not found at #{@plutil}. aborting."
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
parse_plist_file
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
def parse_info_plist
|
|
23
|
+
extract_binary_name
|
|
24
|
+
extract_url_handlers
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
def dump
|
|
28
|
+
doc = Nokogiri::XML(File.open(@plist_file)) do |config|
|
|
29
|
+
config.nonet.noblanks
|
|
30
|
+
end
|
|
31
|
+
puts CodeRay.scan(doc.to_xml(:indent => 2), :xml).terminal
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
private
|
|
35
|
+
def parse_plist_file
|
|
36
|
+
$log.info 'Parsing plist file..'
|
|
37
|
+
|
|
38
|
+
# Make sure plist file is in xml and not binary
|
|
39
|
+
if RbConfig::CONFIG['host_os'] =~ /linux/
|
|
40
|
+
`#{@plutil.realpath} -i "#{@plist_file}" -o "#{@plist_file}"`
|
|
41
|
+
else
|
|
42
|
+
`#{@plutil.realpath} -convert xml1 "#{@plist_file}"`
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
# @plist_data = Plist::parse_xml(@plist_file)
|
|
46
|
+
@plist_data = Plist4r.open @plist_file
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
def extract_url_handlers
|
|
50
|
+
@schemas = Array.new
|
|
51
|
+
|
|
52
|
+
if @plist_data['CFBundleURLTypes'] != nil
|
|
53
|
+
for type in @plist_data['CFBundleURLTypes']
|
|
54
|
+
if !type.nil? and !type['CFBundleURLSchemes'].nil?
|
|
55
|
+
@schemas += type['CFBundleURLSchemes']
|
|
56
|
+
else
|
|
57
|
+
@schemas += ['None']
|
|
58
|
+
end
|
|
59
|
+
end
|
|
60
|
+
end
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
def extract_binary_name
|
|
64
|
+
@binary_name = @plist_data['CFBundleExecutable']
|
|
65
|
+
@bundle_identifier = @plist_data['CFBundleIdentifier']
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
|
|
69
|
+
|
|
70
|
+
|
|
71
|
+
end
|
|
72
|
+
end
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
require 'thread'
|
|
2
|
+
|
|
3
|
+
module Idb
|
|
4
|
+
class QtThreadFix < Qt::Object
|
|
5
|
+
slots 'ruby_thread_timeout()'
|
|
6
|
+
@@ruby_thread_queue = Queue.new
|
|
7
|
+
|
|
8
|
+
def initialize
|
|
9
|
+
super()
|
|
10
|
+
# Enable threading
|
|
11
|
+
@ruby_thread_sleep_period = 0.01
|
|
12
|
+
@ruby_thread_timer = Qt::Timer.new(self)
|
|
13
|
+
connect(@ruby_thread_timer, SIGNAL('timeout()'), SLOT('ruby_thread_timeout()'))
|
|
14
|
+
@ruby_thread_timer.method_missing(:start, 0)
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def ruby_thread_timeout
|
|
18
|
+
unless @@ruby_thread_queue.empty?
|
|
19
|
+
proc_to_call = @@ruby_thread_queue.pop
|
|
20
|
+
proc_to_call.call
|
|
21
|
+
end
|
|
22
|
+
sleep(@ruby_thread_sleep_period)
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
def self.ruby_thread_queue
|
|
26
|
+
@@ruby_thread_queue
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
end
|