idb 2.9.0 → 2.9.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.rubocop.yml +30 -0
- data/Gemfile.lock +5 -0
- data/idb.gemspec +1 -0
- data/lib/gui/app_binary_tab_widget.rb +7 -14
- data/lib/gui/app_details_group_box.rb +63 -88
- data/lib/gui/app_list_dialog.rb +29 -35
- data/lib/gui/app_list_widget_item.rb +1 -5
- data/lib/gui/app_tab_widget.rb +17 -22
- data/lib/gui/binary_strings_widget.rb +7 -15
- data/lib/gui/ca_manager_dialog.rb +32 -54
- data/lib/gui/cache_db_widget.rb +21 -26
- data/lib/gui/certificate_item.rb +2 -2
- data/lib/gui/default_protection_class_group_widget.rb +7 -12
- data/lib/gui/device_info_group_box.rb +26 -23
- data/lib/gui/main_tab_widget.rb +2 -21
- data/lib/gui/shared_libraries_widget.rb +1 -1
- data/lib/gui/sqlite_widget.rb +1 -3
- data/lib/gui/weak_class_dump_widget.rb +1 -1
- data/lib/idb.rb +3 -3
- data/lib/idb/version.rb +1 -1
- data/lib/lib/abstract_device.rb +7 -11
- data/lib/lib/app.rb +49 -59
- data/lib/lib/app_binary.rb +18 -29
- data/lib/lib/ca_interface.rb +46 -59
- data/lib/lib/device.rb +68 -155
- data/lib/lib/device_ca_interface.rb +7 -13
- data/lib/lib/host_file_wrapper.rb +6 -8
- data/lib/lib/ios8_last_launch_services_map_wrapper.rb +11 -18
- data/lib/lib/local_operations.rb +24 -32
- data/lib/lib/otool_wrapper.rb +30 -33
- data/lib/lib/rsync_git_manager.rb +26 -22
- data/lib/lib/screen_shot_util.rb +20 -28
- data/lib/lib/settings.rb +14 -17
- data/lib/lib/simulator.rb +11 -16
- data/lib/lib/simulator_ca_interface.rb +1 -3
- data/lib/lib/ssh_operations.rb +49 -65
- data/lib/lib/ssh_port_forwarder.rb +9 -13
- data/lib/lib/tools.rb +3 -3
- data/lib/lib/url_scheme_fuzzer.rb +41 -49
- data/lib/lib/usb_muxd_wrapper.rb +6 -8
- data/lib/lib/weak_class_dump_wrapper.rb +15 -16
- metadata +19 -9
- data/lib/gui/console_widget.rb +0 -163
- data/lib/gui/cycript_console_widget.rb +0 -68
- data/lib/gui/cycript_thread.rb +0 -81
- data/lib/lib/console_launcher.rb +0 -24
- data/lib/lib/i_device_diagnostics_wrapper.rb +0 -90
- data/lib/lib/snoop_it_wrapper.rb +0 -80
data/lib/lib/screen_shot_util.rb
CHANGED
@@ -2,8 +2,7 @@ require_relative 'ssh_operations'
|
|
2
2
|
|
3
3
|
module Idb
|
4
4
|
class ScreenShotUtil
|
5
|
-
|
6
|
-
def initialize data_path, ops, sim = true
|
5
|
+
def initialize(data_path, ops, sim = true)
|
7
6
|
@data_path = data_path
|
8
7
|
ap @data_path
|
9
8
|
@snapshot_path = "#{@data_path}/Library/Caches/Snapshots"
|
@@ -13,41 +12,35 @@ module Idb
|
|
13
12
|
|
14
13
|
def mark
|
15
14
|
if @sim
|
16
|
-
#create snapshot dir!
|
17
|
-
|
18
|
-
Dir.mkdir_p @snapshot_path
|
19
|
-
end
|
15
|
+
# create snapshot dir!
|
16
|
+
Dir.mkdir_p @snapshot_path unless Dir.exist? @snapshot_path
|
20
17
|
end
|
21
18
|
mark_time
|
22
19
|
end
|
23
20
|
|
24
|
-
|
25
21
|
def check
|
26
22
|
# there should really be only one directory in here which is named
|
27
23
|
# based on the bundle id of the app. lets go through all, just in case.
|
28
24
|
|
29
|
-
snap_dirs = @ops.list_dir("#{@snapshot_path}/").reject {|e| e =~ /^\.\.?$/}
|
30
|
-
|
25
|
+
snap_dirs = @ops.list_dir("#{@snapshot_path}/").reject { |e| e =~ /^\.\.?$/ }
|
31
26
|
|
32
|
-
snap_dirs.each
|
27
|
+
snap_dirs.each do |dir|
|
33
28
|
full_snap_dir = "#{@snapshot_path}/#{dir}"
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
}
|
29
|
+
next unless @ops.directory? full_snap_dir
|
30
|
+
|
31
|
+
# walk through all files in snaphot dir
|
32
|
+
content = @ops.dir_glob(full_snap_dir, "**/*")
|
33
|
+
|
34
|
+
# see if any is younger than mark.
|
35
|
+
content.each do |f|
|
36
|
+
# full_path = "#{full_snap_dir}/#{f}"
|
37
|
+
full_path = f
|
38
|
+
if @ops.file?(full_path) && @ops.mtime(full_path) > @time
|
39
|
+
return full_path
|
40
|
+
end
|
47
41
|
end
|
48
|
-
|
49
|
-
|
50
|
-
|
42
|
+
end
|
43
|
+
nil
|
51
44
|
end
|
52
45
|
|
53
46
|
private
|
@@ -55,6 +48,5 @@ module Idb
|
|
55
48
|
def mark_time
|
56
49
|
@time = Time.now
|
57
50
|
end
|
58
|
-
|
59
51
|
end
|
60
|
-
end
|
52
|
+
end
|
data/lib/lib/settings.rb
CHANGED
@@ -1,23 +1,19 @@
|
|
1
1
|
# encoding: utf-8
|
2
2
|
require 'yaml'
|
3
3
|
|
4
|
-
#YAML::ENGINE.yamler='psych'
|
4
|
+
# YAML::ENGINE.yamler='psych'
|
5
5
|
|
6
6
|
module Idb
|
7
7
|
class Settings
|
8
|
-
|
9
|
-
def initialize file_name
|
8
|
+
def initialize(file_name)
|
10
9
|
@file_name = file_name
|
11
10
|
if file_name.nil?
|
12
|
-
@data =
|
11
|
+
@data = {}
|
13
12
|
else
|
14
|
-
|
15
|
-
@data = Hash.new
|
16
|
-
end
|
13
|
+
@data = {} unless load
|
17
14
|
end
|
18
15
|
end
|
19
16
|
|
20
|
-
|
21
17
|
def load
|
22
18
|
if File.exist? @file_name
|
23
19
|
$log.info "Loading configuration from #{@file_name}"
|
@@ -26,7 +22,7 @@ module Idb
|
|
26
22
|
true
|
27
23
|
else
|
28
24
|
$log.warn "No configuration found, generating default."
|
29
|
-
@data =
|
25
|
+
@data = {}
|
30
26
|
@data["ssh_host"] = "localhost"
|
31
27
|
@data["ssh_port"] = 22
|
32
28
|
@data["ssh_username"] = "root"
|
@@ -42,26 +38,27 @@ module Idb
|
|
42
38
|
|
43
39
|
def store
|
44
40
|
$log.info "Storing new configuration at #{@file_name}."
|
45
|
-
conf_file = File.open(@file_name,"w")
|
41
|
+
conf_file = File.open(@file_name, "w")
|
46
42
|
conf_file.puts(@data.to_yaml)
|
47
43
|
conf_file.close
|
48
44
|
end
|
49
45
|
|
50
46
|
private
|
47
|
+
|
51
48
|
def method_missing(method, *args, &block)
|
52
49
|
m = method.to_s
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
return @data[m.to_sym]
|
57
|
-
end
|
50
|
+
|
51
|
+
return @data[m] if @data.key?(m)
|
52
|
+
return @data[m.to_sym] if @data.key?(m.to_sym)
|
58
53
|
begin
|
59
54
|
@data.send(method, *args, &block)
|
60
55
|
rescue
|
61
|
-
|
56
|
+
super
|
62
57
|
end
|
63
58
|
end
|
64
59
|
|
65
|
-
|
60
|
+
def respond_to_missing?(method_name, include_private = false)
|
61
|
+
@data.key?(method_name) || @data.key?(method_name.to_sym) || super
|
62
|
+
end
|
66
63
|
end
|
67
64
|
end
|
data/lib/lib/simulator.rb
CHANGED
@@ -6,40 +6,38 @@ module Idb
|
|
6
6
|
class Simulator < AbstractDevice
|
7
7
|
attr_accessor :sim_dir
|
8
8
|
|
9
|
-
def initialize
|
9
|
+
def initialize(sim_dir)
|
10
10
|
puts "Initializing simulator with #{sim_dir}"
|
11
11
|
@sim_dir = sim_dir
|
12
12
|
@apps_dir = @sim_dir + "/Applications"
|
13
13
|
@ops = LocalOperations.new
|
14
|
-
|
15
14
|
end
|
16
15
|
|
17
16
|
def open_installed?
|
18
17
|
true
|
19
18
|
end
|
20
19
|
|
21
|
-
def app_launch
|
22
|
-
cmd = '/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneSimulator.platform/
|
20
|
+
def app_launch(app)
|
21
|
+
cmd = '/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneSimulator.platform/' \
|
22
|
+
'Developer/Applications/iPhone\ Simulator.app/Contents/MacOS/' \
|
23
|
+
'iPhone\ Simulator -SimulateApplication '
|
23
24
|
$log.info "Launching app..."
|
24
25
|
@ops.launch_app cmd, app.binary_path
|
25
26
|
end
|
26
27
|
|
27
|
-
|
28
|
-
def self.get_simulators
|
28
|
+
def self.simulators
|
29
29
|
basedir = ENV['HOME'] + '/Library/Application Support/iPhone Simulator'
|
30
30
|
|
31
|
-
return
|
31
|
+
return [] unless Dir.exist? basedir
|
32
32
|
|
33
33
|
dirs = Dir.glob("#{basedir}/**")
|
34
|
-
if dirs.length
|
35
|
-
raise "No simulators found in #{basedir}."
|
36
|
-
end
|
34
|
+
raise "No simulators found in #{basedir}." if dirs.length.zero?
|
37
35
|
|
38
|
-
|
36
|
+
dirs
|
39
37
|
end
|
40
38
|
|
41
39
|
def ca_interface
|
42
|
-
|
40
|
+
SimulatorCAInterface.new @sim_dir
|
43
41
|
end
|
44
42
|
|
45
43
|
def disconnect
|
@@ -53,8 +51,5 @@ module Idb
|
|
53
51
|
def simulator?
|
54
52
|
true
|
55
53
|
end
|
56
|
-
|
57
|
-
|
58
|
-
|
59
54
|
end
|
60
|
-
end
|
55
|
+
end
|
@@ -5,12 +5,10 @@ require_relative 'ca_interface'
|
|
5
5
|
|
6
6
|
module Idb
|
7
7
|
class SimulatorCAInterface < CAInterface
|
8
|
-
|
9
|
-
def initialize sim_path
|
8
|
+
def initialize(sim_path)
|
10
9
|
@sim_path = sim_path
|
11
10
|
@store_path = "/Library/Keychains/TrustStore.sqlite3"
|
12
11
|
@db_path = @sim_path + @store_path
|
13
12
|
end
|
14
|
-
|
15
13
|
end
|
16
14
|
end
|
data/lib/lib/ssh_operations.rb
CHANGED
@@ -6,28 +6,27 @@ module Idb
|
|
6
6
|
class SSHOperations
|
7
7
|
attr_accessor :ssh
|
8
8
|
|
9
|
-
def initialize
|
9
|
+
def initialize(username, password, hostname, port)
|
10
10
|
@hostname = hostname
|
11
11
|
@username = username
|
12
12
|
@password = password
|
13
13
|
@port = port
|
14
|
-
|
15
14
|
$log.info "Establishing SSH Session for #{username}@#{hostname}:#{port}"
|
15
|
+
connect
|
16
|
+
end
|
16
17
|
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
error.exec
|
30
|
-
end
|
18
|
+
def connect
|
19
|
+
@ssh = Net::SSH.start @hostname, @username, password: @password, port: @port
|
20
|
+
|
21
|
+
# initialize sftp connection and wait until it is open
|
22
|
+
$log.info 'Establishing SFTP Session...'
|
23
|
+
@sftp = Net::SFTP::Session.new @ssh
|
24
|
+
@sftp.loop { @sftp.opening? }
|
25
|
+
rescue StandardError => ex
|
26
|
+
error = Qt::MessageBox.new
|
27
|
+
error.setInformativeText("SSH connection could not be established: #{ex.message}")
|
28
|
+
error.setIcon(Qt::MessageBox::Critical)
|
29
|
+
error.exec
|
31
30
|
end
|
32
31
|
|
33
32
|
def disconnect
|
@@ -35,11 +34,8 @@ module Idb
|
|
35
34
|
@ssh.close
|
36
35
|
end
|
37
36
|
|
38
|
-
|
39
|
-
|
40
|
-
if opts[:as_user]
|
41
|
-
command = "su - #{ opts[:as_user] } -c \"#{command}\""
|
42
|
-
end
|
37
|
+
def execute(command, opts = {})
|
38
|
+
command = "su - #{opts[:as_user]} -c \"#{command}\"" if opts[:as_user]
|
43
39
|
|
44
40
|
if opts[:non_blocking]
|
45
41
|
$log.debug "Executing non-blocking SSH command: #{command}"
|
@@ -50,17 +46,15 @@ module Idb
|
|
50
46
|
end
|
51
47
|
end
|
52
48
|
|
53
|
-
def chmod
|
54
|
-
@sftp.setstat(file, :
|
49
|
+
def chmod(file, permissions)
|
50
|
+
@sftp.setstat(file, permissions: permissions)
|
55
51
|
end
|
56
52
|
|
57
53
|
def download_recursive(remote_path, local_path)
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
return false
|
63
|
-
end
|
54
|
+
@sftp.download! remote_path, local_path, recursive: true
|
55
|
+
rescue
|
56
|
+
$log.error "Failed to download #{remote_path}."
|
57
|
+
return false
|
64
58
|
end
|
65
59
|
|
66
60
|
def download(remote_path, local_path = nil)
|
@@ -71,76 +65,66 @@ module Idb
|
|
71
65
|
@sftp.download! remote_path, local_path
|
72
66
|
end
|
73
67
|
rescue
|
74
|
-
|
68
|
+
$log.error "Error downloading file."
|
75
69
|
return false
|
76
70
|
end
|
77
|
-
|
78
|
-
|
71
|
+
true
|
79
72
|
end
|
80
73
|
|
81
74
|
def upload(local_path, remote_path)
|
82
75
|
@sftp.upload! local_path, remote_path
|
83
76
|
end
|
84
77
|
|
85
|
-
def list_dir
|
86
|
-
@sftp.dir.entries(dir).map
|
78
|
+
def list_dir(dir)
|
79
|
+
@sftp.dir.entries(dir).map(&:name)
|
87
80
|
end
|
88
81
|
|
89
|
-
def list_dir_full
|
82
|
+
def list_dir_full(dir)
|
90
83
|
@sftp.dir.entries(dir)
|
91
84
|
end
|
92
85
|
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
rescue
|
99
|
-
return false
|
100
|
-
end
|
101
|
-
|
86
|
+
def file_exists?(path)
|
87
|
+
@sftp.stat!(path)
|
88
|
+
return true
|
89
|
+
rescue
|
90
|
+
return false
|
102
91
|
end
|
103
92
|
|
104
|
-
def launch
|
93
|
+
def launch(path)
|
105
94
|
@ssh.exec path
|
106
95
|
end
|
107
96
|
|
108
|
-
def dir_glob
|
109
|
-
@sftp.dir.glob(path,pattern).map {|x| "#{path}/#{x.name}"}
|
97
|
+
def dir_glob(path, pattern)
|
98
|
+
@sftp.dir.glob(path, pattern).map { |x| "#{path}/#{x.name}" }
|
110
99
|
end
|
111
100
|
|
112
|
-
def mkdir
|
101
|
+
def mkdir(path)
|
113
102
|
@sftp.mkdir path
|
114
103
|
end
|
115
104
|
|
116
|
-
def directory?
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
nil
|
121
|
-
end
|
105
|
+
def directory?(path)
|
106
|
+
@sftp.stat!(path).directory?
|
107
|
+
rescue
|
108
|
+
nil
|
122
109
|
end
|
123
110
|
|
124
|
-
def file?
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
false
|
129
|
-
end
|
111
|
+
def file?(path)
|
112
|
+
@sftp.stat!(path).file?
|
113
|
+
rescue
|
114
|
+
false
|
130
115
|
end
|
131
116
|
|
132
|
-
def mtime
|
117
|
+
def mtime(path)
|
133
118
|
Time.new @sftp.stat!(path).mtime
|
134
119
|
end
|
135
120
|
|
136
|
-
def open
|
121
|
+
def open(path)
|
137
122
|
Launchy.open path
|
138
123
|
end
|
139
124
|
|
140
|
-
def launch_app
|
125
|
+
def launch_app(command, app)
|
141
126
|
puts "#{command} \"#{app}\""
|
142
|
-
|
127
|
+
execute("#{command} \"#{app}\"")
|
143
128
|
end
|
144
|
-
|
145
129
|
end
|
146
130
|
end
|
@@ -1,43 +1,39 @@
|
|
1
1
|
require 'net/ssh'
|
2
2
|
require 'log4r'
|
3
3
|
|
4
|
-
|
5
4
|
module Idb
|
6
5
|
class SSHPortForwarder
|
7
|
-
|
8
|
-
def initialize username, password, hostname, port
|
6
|
+
def initialize(username, password, hostname, port)
|
9
7
|
# initialize log
|
10
8
|
@log = Log4r::Logger.new 'port_forward'
|
11
9
|
outputter = Log4r::Outputter.stdout
|
12
|
-
outputter.formatter =
|
10
|
+
outputter.formatter = Log4r::PatternFormatter.new(pattern: "[%l] %d :: %c :: %m")
|
13
11
|
|
14
|
-
@log.outputters = [
|
12
|
+
@log.outputters = [outputter]
|
15
13
|
|
16
14
|
@log.info 'Establishing SSH port forwarding...'
|
17
|
-
@ssh = Net::SSH.start hostname, username, :
|
15
|
+
@ssh = Net::SSH.start hostname, username, password: password, port: port
|
18
16
|
end
|
19
17
|
|
20
|
-
def add_local_forward
|
18
|
+
def add_local_forward(local_port, remote_host, remote_port)
|
21
19
|
@log.info " - Forwarding local:#{local_port} -> #{remote_host}:#{remote_port}"
|
22
20
|
@ssh.forward.local local_port, remote_host, remote_port
|
23
21
|
end
|
24
22
|
|
25
|
-
def add_remote_forward
|
23
|
+
def add_remote_forward(remote_port, local_host, local_port)
|
26
24
|
@log.info " - Forwarding remote:#{remote_port} -> #{local_host}:#{local_port}"
|
27
25
|
@ssh.forward.remote_to local_port, local_host, remote_port
|
28
26
|
end
|
29
27
|
|
30
28
|
def start
|
31
|
-
@ssh.loop
|
32
|
-
|
33
|
-
|
29
|
+
@ssh.loop do
|
30
|
+
true
|
31
|
+
end
|
34
32
|
end
|
35
33
|
|
36
34
|
def stop
|
37
35
|
$log.info "Closing SSH connection."
|
38
36
|
@ssh.close
|
39
37
|
end
|
40
|
-
|
41
|
-
|
42
38
|
end
|
43
39
|
end
|