idb 2.1.0 → 2.5.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 94b05b90dac0f6ec5d2d307d23014a2a7a4a10da
4
- data.tar.gz: 5d2f0e5a97d747755a4030fb6e23824abfa50c5f
3
+ metadata.gz: 64226ae62cd205643d25b1ba1864b5a54d163b4d
4
+ data.tar.gz: 40eeb316e70e2165a12c96ba7da69fc1932ac111
5
5
  SHA512:
6
- metadata.gz: 1332f364438b0ea9e23ba283b17067f956c901ebc28484cb1f976b07df3930b59b586abb0a5dd8c41e36dd1eaf6a38c5ceb8c15736d2fbef3af9ece0d51dd114
7
- data.tar.gz: ad4bbfcbba28ea9cd69ab868678ffe99d67315c2aeb025ecee3af95879f030906b5d6fc038ab05278f4fe92567c70567a5311a91865703a632ef2979725286d6
6
+ metadata.gz: 388da49012ccce3480ccc91fba98e7c8fddb384559a589b246d69000da16f0770f5792df830e628542645458002ab5ec6663828b931405740d01bf086aef3732
7
+ data.tar.gz: 9da5c592809bb8e364818d82d0e522d56155fb1d0610c0dcc583cc2169c184aecc7fe5fb106a209c363bca77123d30d13746c87e94b3305422e56d95869c0e5e
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- idb (2.1.0)
4
+ idb (2.5.0)
5
5
  awesome_print
6
6
  coderay
7
7
  ffi
@@ -29,7 +29,7 @@ GEM
29
29
  tilt
30
30
  hexdump (0.2.3)
31
31
  htmlentities (4.3.2)
32
- launchy (2.4.2)
32
+ launchy (2.4.3)
33
33
  addressable (~> 2.3)
34
34
  libxml-ruby (2.7.0)
35
35
  libxml4r (0.2.6)
data/README.md CHANGED
@@ -1,3 +1,8 @@
1
+ [![Gem Version](https://badge.fury.io/rb/idb.svg)](http://badge.fury.io/rb/idb)
2
+ [![Dependency Status](https://gemnasium.com/dmayer/idb.png)](https://gemnasium.com/dmayer/idb)
3
+ [![Code Climate](https://codeclimate.com/github/dmayer/idb.png)](https://codeclimate.com/github/dmayer/idb)
4
+ <img src="https://stats.cysec.org/piwik.php?idsite=2&rec=1" style="border:0" alt="" />
5
+
1
6
  # Idb
2
7
 
3
8
  idb is a tool to simplify some common tasks for iOS pentesting and research. Originally there was a command line version of the tool, but it is no longer under development so you should get the GUI version.
@@ -10,10 +15,10 @@ idb has some prerequisites. As it turns out, things like ruby and Qt are difficu
10
15
 
11
16
  ### 1. Prerequisites
12
17
  #### 1.1 Ruby Environment
13
- idb requires a valid ruby 1.9.3 or 2.1 installation. **Ruby 2.0 does not work properly** due to issues with qtbindings.
18
+ idb requires a valid ruby 1.9.3 or 2.1 installation and it is recommended to install the used ruby using [RVM](https://rvm.io/). **Ruby 2.0 does not work properly** due to issues with qtbindings.
14
19
 
15
20
  **Important Note:** Shared library support is required! This is the default for many system rubies, but if you install a ruby via `rvm` or similar, you need to do one of the following:
16
- * Under `rvm` use `--enable-shared` when installing ruby.
21
+ * **Under `rvm` use `rvm install 2.1 --enable-shared` when installing ruby.**
17
22
  * Under `ruby-install`/`chruby` use `-- --enable-shared` when installing ruby.
18
23
  * Under `ruby-build`/`rbenv` with `ruby-build` use `CONFIGURE_OPTS=--enable-shared [command]` when installing Ruby.
19
24
 
@@ -3,7 +3,7 @@ require_relative '../lib/app'
3
3
  module Idb
4
4
 
5
5
  class AppDetailsGroupBox < Qt::GroupBox
6
- attr_accessor :uuid, :bundle_id
6
+ attr_accessor :uuid, :bundle_id, :vals, :icon
7
7
  signals "app_changed()"
8
8
  signals "show_device_status()"
9
9
 
@@ -16,56 +16,6 @@ module Idb
16
16
  setTitle "App Details"
17
17
 
18
18
 
19
- @icon_button_layout = Qt::GridLayout.new
20
-
21
-
22
- # select app
23
- @select_app_button = Qt::PushButton.new "Select App..."
24
- @select_app_button.setEnabled(false)
25
- @select_app_button.connect(SIGNAL(:released)) { |x|
26
- @app_list = AppListDialog.new
27
- @app_list.connect(SIGNAL('accepted()')) {
28
- $selected_app = @app_list.app_list.currentItem().app
29
- @vals['uuid'].setText($selected_app.uuid)
30
- @vals['bundle_id'].setText($selected_app.bundle_id)
31
- @vals['bundle_name'].setText($selected_app.bundle_name)
32
- @vals['url_handlers'].setText($selected_app.get_url_handlers.join("\n"))
33
- @vals['platform_version'].setText($selected_app.platform_version)
34
- @vals['sdk_version'].setText($selected_app.sdk_version)
35
- @vals['minimum_os_version'].setText($selected_app.minimum_os_version)
36
- @launch_app.setEnabled(true)
37
- @open_folder.setEnabled(true)
38
-
39
- begin
40
- icon_file = $selected_app.get_icon_file
41
- pixmap = Qt::Pixmap.new(icon_file)
42
- @icon.setPixmap pixmap.scaledToWidth(50) unless icon_file.nil?
43
-
44
- rescue => e
45
- $log.error "Icon CONVERSION failed. #{e.message}"
46
- @icon.setPixmap Qt::Pixmap.new
47
- # lets ignore conversion errors for now..
48
- end
49
-
50
- emit app_changed()
51
- }
52
-
53
- @app_list.exec
54
- }
55
-
56
-
57
- @icon_button_widget = Qt::Widget.new self
58
- @icon_button_widget.setLayout @icon_button_layout
59
-
60
- @icon = Qt::Label.new
61
-
62
- @icon_button_layout.addWidget @icon, 0, 0, 1, 1
63
- @icon_button_layout.addWidget @select_app_button, 0, 1, 1, 3
64
- @layout.addWidget @icon_button_widget, 0, 0, 1, 2
65
-
66
-
67
-
68
-
69
19
  @labels = Hash.new
70
20
  @vals = Hash.new
71
21
  @cur_row = 1
@@ -77,6 +27,8 @@ module Idb
77
27
  addDetail 'platform_version', 'Platform Version'
78
28
  addDetail 'sdk_version', 'SDK Version'
79
29
  addDetail 'minimum_os_version', 'Minimum OS'
30
+ addDetail 'keychain_access_groups', 'Keychain Access Groups'
31
+ addDetail 'data_dir', 'Data Directory'
80
32
 
81
33
  @launch_app = Qt::PushButton.new "Launch App"
82
34
  @launch_app.setEnabled(false)
@@ -106,17 +58,38 @@ module Idb
106
58
 
107
59
  }
108
60
 
61
+ clear
62
+
63
+ end
64
+
65
+ def app_changed
66
+ @vals['uuid'].setText($selected_app.uuid)
67
+ @vals['bundle_id'].setText($selected_app.bundle_id)
68
+ @vals['bundle_name'].setText($selected_app.bundle_name)
69
+ @vals['url_handlers'].setText($selected_app.get_url_handlers.join("\n"))
70
+ @vals['platform_version'].setText($selected_app.platform_version)
71
+ @vals['sdk_version'].setText($selected_app.sdk_version)
72
+ @vals['minimum_os_version'].setText($selected_app.minimum_os_version)
73
+ @vals['keychain_access_groups'].setText($selected_app.keychain_access_groups)
74
+ @vals['data_dir'].setText($selected_app.data_directory.sub("/private/var/mobile/Containers/Data/Application",""))
75
+ @launch_app.setEnabled(true)
76
+ @open_folder.setEnabled(true)
77
+
78
+
79
+
109
80
  end
110
81
 
111
82
  def clear
112
83
  $selected_app = nil
113
- @vals['uuid'].setText("")
114
- @vals['bundle_id'].setText("")
115
- @vals['bundle_name'].setText("")
116
- @vals['url_handlers'].setText("")
117
- @vals['platform_version'].setText("")
118
- @vals['sdk_version'].setText("")
119
- @vals['minimum_os_version'].setText("")
84
+ @vals['uuid'].setText("[No Application Selected]")
85
+ @vals['bundle_id'].setText("[No Application Selected]")
86
+ @vals['bundle_name'].setText("[No Application Selected]")
87
+ @vals['url_handlers'].setText("[No Application Selected]")
88
+ @vals['platform_version'].setText("[No Application Selected]")
89
+ @vals['sdk_version'].setText("[No Application Selected]")
90
+ @vals['minimum_os_version'].setText("[No Application Selected]")
91
+ @vals['data_dir'].setText("[No Application Selected]")
92
+ @vals['keychain_access_groups'].setText("[No Application Selected]")
120
93
  @launch_app.setEnabled(false)
121
94
  @open_folder.setEnabled(false)
122
95
 
@@ -124,6 +97,8 @@ module Idb
124
97
 
125
98
 
126
99
 
100
+
101
+
127
102
  def addDetail id, label
128
103
  @labels[id] = Qt::Label.new "<b>#{label}</b>", self, 0
129
104
  @vals[id] = Qt::Label.new "", self, 0
@@ -132,15 +107,6 @@ module Idb
132
107
  @cur_row += 1
133
108
  end
134
109
 
135
-
136
- def enable_select_app
137
- @select_app_button.setEnabled(true)
138
- end
139
-
140
- def disable_select_app
141
- @select_app_button.setEnabled(false)
142
- end
143
-
144
110
  end
145
111
 
146
112
  class AppBinaryGroupBox < Qt::GroupBox
@@ -180,6 +146,8 @@ module Idb
180
146
  addDetail 'canaries', 'Stack Canaries'
181
147
  addDetail 'arc', 'ARC'
182
148
 
149
+ clear
150
+
183
151
  end
184
152
 
185
153
 
@@ -197,11 +165,11 @@ module Idb
197
165
  end
198
166
 
199
167
  def clear
200
- @vals['encryption_enabled'].setText("")
201
- @vals['cryptid'].setText("")
202
- @vals['pie'].setText("")
203
- @vals['canaries'].setText("")
204
- @vals['arc'].setText("")
168
+ @vals['encryption_enabled'].setText("[Binary not yet analyzed]")
169
+ @vals['cryptid'].setText("[Binary not yet analyzed]")
170
+ @vals['pie'].setText("[Binary not yet analyzed]")
171
+ @vals['canaries'].setText("[Binary not yet analyzed]")
172
+ @vals['arc'].setText("[Binary not yet analyzed]")
205
173
  end
206
174
 
207
175
  def disable_analyze_binary
@@ -41,6 +41,16 @@ module Idb
41
41
  end
42
42
 
43
43
  def refresh_app_list
44
+ if $device.ios_version == 8
45
+ box = Qt::MessageBox.new 1, "Refreshing...", "Refreshing uicache to ensure app information is up-to-date. This may take a few seconds."
46
+ box.setStandardButtons(0)
47
+ box.show
48
+ box.raise
49
+ # need to refresh iOS uicache in case app was installed after last reboot.
50
+ # Otherwise the /var/mobile/Library/MobileInstallation/LastLaunchServicesMap.plist will be out of date
51
+ $device.ops.execute "/usr/bin/uicache"
52
+ box.hide
53
+ end
44
54
  app_uuids = $device.get_app_uuids
45
55
  progress = Qt::ProgressDialog.new "Reading App list...", nil, 1, app_uuids.size, self
46
56
  progress.setAutoClose true
@@ -0,0 +1,52 @@
1
+ module Idb
2
+ class AppTabWidget < Qt::TabWidget
3
+ attr_accessor :app_details, :app_binary
4
+ signals "app_changed()"
5
+ signals "binary_analyzed()"
6
+
7
+ def initialize *args
8
+ super *args
9
+
10
+ @layout = Qt::GridLayout.new self
11
+ setLayout(@layout)
12
+
13
+
14
+
15
+ @layout.addWidget @select_app_button, 0,0
16
+
17
+ # Box for App details
18
+ @app_details = AppDetailsGroupBox.new @central_widget
19
+ @app_details.connect(SIGNAL(:show_device_status)) {
20
+ @device_status = DeviceStatusDialog.new
21
+ @device_status.exec
22
+ }
23
+
24
+
25
+ @layout.addWidget @app_details, 1,0, 2, 1
26
+
27
+ # App Binary Details
28
+ @app_binary = AppBinaryGroupBox.new @central_widget
29
+ @layout.addWidget @app_binary, 1,1
30
+ @app_binary.connect(SIGNAL('binary_analyzed()')) {
31
+ emit binary_analyzed()
32
+ }
33
+
34
+ @spacer_horizontal = Qt::SpacerItem.new 0,1, Qt::SizePolicy::Expanding, Qt::SizePolicy::Fixed
35
+ @layout.addItem @spacer_horizontal, 1, 2
36
+
37
+ @spacer = Qt::SpacerItem.new 0,1, Qt::SizePolicy::Fixed, Qt::SizePolicy::Expanding
38
+
39
+ @layout.addItem @spacer, 2, 1, 2,1
40
+ @layout.addItem @spacer, 3, 0
41
+
42
+
43
+ end
44
+
45
+ def app_changed
46
+ @app_binary.app_changed
47
+ @app_details.app_changed
48
+
49
+ end
50
+
51
+ end
52
+ end
@@ -20,9 +20,9 @@ module Idb
20
20
  $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."
21
21
  else
22
22
  if RbConfig::CONFIG['host_os'] =~ /linux/
23
- Process.spawn "'#{$settings['sqlite_editor']}' '#{Dir.getwd}/#{cache_name}'"
23
+ Process.spawn "'#{$settings['sqlite_editor']}' '#{cache_name}'"
24
24
  else
25
- Process.spawn "open -a '#{$settings['sqlite_editor']}' '#{Dir.getwd}/#{cache_name}'"
25
+ Process.spawn "open -a '#{$settings['sqlite_editor']}' '#{cache_name}'"
26
26
  end
27
27
  end
28
28
 
@@ -50,7 +50,11 @@ module Idb
50
50
  item.setText full_path.sub($selected_app.app_dir,'')
51
51
  else
52
52
  pc = $device.protection_class full_path
53
- item.setText full_path.sub($selected_app.app_dir,'') + " => " + pc.strip
53
+ if full_path.start_with? $selected_app.app_dir
54
+ item.setText "[App Bundle]" + full_path.sub($selected_app.app_dir,'') + " => " + pc.strip
55
+ elsif full_path.start_with? $selected_app.data_dir
56
+ item.setText "[Data Dir]" + full_path.sub($selected_app.data_dir,'') + " => " + pc.strip
57
+ end
54
58
  end
55
59
  item.full_path = full_path
56
60
  @list.addItem item
@@ -3,6 +3,7 @@ require_relative 'device_status_dialog'
3
3
  module Idb
4
4
  class DeviceInfoGroupBox < Qt::GroupBox
5
5
  signals "disconnect()"
6
+ signals "connect_clicked()"
6
7
 
7
8
  def initialize *args
8
9
  super *args
@@ -12,19 +13,25 @@ module Idb
12
13
  setLayout(@layout)
13
14
  setTitle "Selected Device"
14
15
 
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
16
+ @device = Qt::Label.new "<b><font color='red'>Please select a device from the 'Devices' menu or click 'Connect'.</font></b>", self, 0
17
+ @layout.addWidget @device, 0, 0, 2 ,1
18
+ @connect = Qt::PushButton.new "Connect to USB/SSH device"
19
+ @connect.connect(SIGNAL(:released)) {
20
+ emit connect_clicked()
21
+ }
22
+ @layout.addWidget @connect, 0,1,2,1
17
23
  end
18
24
 
19
25
  def update_device
20
26
  if $device.device?
27
+ @connect.hide
21
28
  uname = $device.ops.execute("/bin/uname -a")
22
29
  ssh_connection_info = ""
23
30
  if $device.mode == "usb"
24
31
  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}"
32
+ @device.setText "<b>USB device:</b> Manually connect via SSH as #{$settings.ssh_username}@localhost:#{$device.usb_ssh_port}"
26
33
  else
27
- @device.setText "<b>USB device:</b> ssh://#{$settings.ssh_username}:[redacted]@#{$settings.ssh_host}:#{$settings.ssh_port}<br>#{uname}"
34
+ @device.setText "<b>SSH device:</b> ssh://#{$settings.ssh_username}:[redacted]@#{$settings.ssh_host}:#{$settings.ssh_port}"
28
35
  end
29
36
 
30
37
  @status = Qt::PushButton.new "Status"
@@ -39,12 +46,14 @@ module Idb
39
46
  $device.close unless $device.nil?
40
47
  $device = nil
41
48
  emit disconnect()
42
- @disconnect.setEnabled(false)
43
- @status.setEnabled(false)
49
+ @disconnect.hide
50
+ @connect.show
51
+ @status.hide
44
52
  @device.setText("<b><font color='red'>Please select a device from the 'Devices' menu.</font></b>")
45
53
  }
46
54
  @layout.addWidget @disconnect, 1, 1
47
55
 
56
+
48
57
  else
49
58
  @device.setText "<b>Simulator:</b> #{$device.sim_dir}"
50
59
  end
@@ -99,7 +99,10 @@ module Idb
99
99
  else
100
100
  @install_aptget = Qt::PushButton.new "Install"
101
101
  @install_aptget.connect(SIGNAL(:released)) {
102
- $device.install_apt_get
102
+ error = Qt::MessageBox.new
103
+ error.setText("Aptitude or apt-get must be installed on the device using Cydia.")
104
+ error.setIcon(Qt::MessageBox::Critical)
105
+ error.exec
103
106
  if $device.apt_get_installed?
104
107
  @install_aptget.hide
105
108
  mark_apt_get_installed
@@ -15,7 +15,14 @@ module Idb
15
15
  @rsync = Qt::PushButton.new "Rsync + Git"
16
16
  @layout.addWidget @rsync, 0,0
17
17
  @rsync.connect(SIGNAL :released) {
18
- @manager.sync_new_revision
18
+ @manager.start_new_revision
19
+ if $device.ios_version == 8
20
+ @manager.sync_dir $selected_app.app_dir, "app_bundle"
21
+ @manager.sync_dir $selected_app.data_dir, "data_bundle"
22
+ else
23
+ @manager.sync_dir $selected_app.app_dir, "app_bundle"
24
+ end
25
+ @manager.commit_new_revision
19
26
 
20
27
  }
21
28
 
@@ -228,17 +235,40 @@ module Idb
228
235
  tree_item
229
236
  end
230
237
 
231
- def set_start start
238
+ def update_start
232
239
  @treeview.clear
240
+ @selected_dir = $selected_app.app_dir
241
+ @local_path = "#{$selected_app.cache_dir}/idb_mirror.git"
242
+ @manager = RsyncGitManager.new @local_path
243
+
244
+ if $device.ios_version == 8
245
+ start_ios_8
246
+ else
247
+ start_ios_pre8
248
+ end
249
+ end
250
+
251
+ def start_ios_pre8
233
252
  @root_node = Qt::TreeWidgetItem.new
234
- @root_node.setText(0, "app root")
253
+ @root_node.setText(0, "[App Bundle]")
235
254
  @root_node.setChildIndicatorPolicy(Qt::TreeWidgetItem::ShowIndicator)
236
255
  @treeview.addTopLevelItem @root_node
237
- @start = start
238
- @selected_dir = start
239
- @root_node.setText(1, @start)
240
- @local_path = "#{$selected_app.cache_dir}/idb_mirror.git"
241
- @manager = RsyncGitManager.new start, @local_path
256
+ @root_node.setText(1, $selected_app.app_dir)
257
+ end
258
+
259
+ def start_ios_8
260
+ @bundle_root_node = Qt::TreeWidgetItem.new
261
+ @bundle_root_node.setText(0, "[App Bundle]")
262
+ @bundle_root_node.setChildIndicatorPolicy(Qt::TreeWidgetItem::ShowIndicator)
263
+ @bundle_root_node.setText(1, $selected_app.app_dir)
264
+
265
+ @data_root_node = Qt::TreeWidgetItem.new
266
+ @data_root_node.setText(0, "[Data Dir]")
267
+ @data_root_node.setChildIndicatorPolicy(Qt::TreeWidgetItem::ShowIndicator)
268
+ @data_root_node.setText(1, $selected_app.data_dir)
269
+
270
+ @treeview.addTopLevelItem @bundle_root_node
271
+ @treeview.addTopLevelItem @data_root_node
242
272
  end
243
273
 
244
274
  end
@@ -0,0 +1,87 @@
1
+
2
+ module Idb
3
+ class GlobalAppDetailsGroupBox < Qt::GroupBox
4
+ signals "app_changed()"
5
+
6
+ def initialize *args
7
+ super *args
8
+
9
+ # details on selected app
10
+ @layout = Qt::GridLayout.new
11
+ setLayout(@layout)
12
+ setTitle "Selected Application"
13
+
14
+ @app = Qt::Label.new "<b>Connect to a device first.</b>", self, 0
15
+ @layout.addWidget @app, 0, 0
16
+
17
+ @app_details = Qt::Widget.new
18
+ @app_details_layout = Qt::GridLayout.new
19
+ @app_details_layout.setContentsMargins(0,0,0,0)
20
+
21
+ @app_details.setLayout(@app_details_layout)
22
+
23
+ @icon = Qt::Label.new
24
+ @app_details_layout.addWidget @icon, 0, 0, 2,1
25
+
26
+ @selected_app_label = Qt::Label.new "<b>Selected App:</b>"
27
+ @selected_app = Qt::Label.new ""
28
+ @app_details_layout.addWidget @selected_app_label, 0, 1
29
+ @app_details_layout.addWidget @selected_app, 0,2
30
+
31
+ @uuid_label = Qt::Label.new "<b>UUID:</b>"
32
+ @uuid = Qt::Label.new ""
33
+ @app_details_layout.addWidget @uuid_label, 1, 1
34
+ @app_details_layout.addWidget @uuid, 1,2
35
+
36
+ @layout.addWidget @app_details, 0,0
37
+ @app_details.hide
38
+
39
+
40
+ @select_app_button = Qt::PushButton.new "Select App..."
41
+ @select_app_button.setEnabled(false)
42
+ @select_app_button.connect(SIGNAL(:released)) { |x|
43
+ @app_list = AppListDialog.new
44
+ @app_list.connect(SIGNAL('accepted()')) {
45
+ $selected_app = @app_list.app_list.currentItem().app
46
+ @selected_app.setText($selected_app.bundle_name + " (" + $selected_app.bundle_id + ")")
47
+ @uuid.setText($selected_app.uuid)
48
+ begin
49
+ icon_file = $selected_app.get_icon_file
50
+ pixmap = Qt::Pixmap.new(icon_file)
51
+ @icon.setPixmap pixmap.scaledToWidth(50) unless icon_file.nil?
52
+
53
+ rescue => e
54
+ $log.error "Icon CONVERSION failed. #{e.message}"
55
+ @icon.setPixmap Qt::Pixmap.new
56
+ # lets ignore conversion errors for now..
57
+ end
58
+
59
+ @app_details.show
60
+ @app.hide
61
+ emit app_changed()
62
+ }
63
+ @app_list.exec
64
+ }
65
+
66
+ @layout.addWidget @select_app_button, 0,1
67
+ end
68
+
69
+
70
+ def disconnect
71
+ @app.setText("<b>Connect to a device first.</b>")
72
+ @app.show
73
+ @app_details.hide
74
+ @select_app_button.setEnabled(false)
75
+ end
76
+
77
+ def enable
78
+ @app.setText("<b><font color='red'>Please click the 'Select Application' button.</font></b>")
79
+ @app.show
80
+ @app_details.hide
81
+ @select_app_button.setEnabled(true)
82
+ end
83
+
84
+
85
+
86
+ end
87
+ end
@@ -8,16 +8,25 @@ require_relative 'pasteboard_monitor_widget'
8
8
  require_relative 'fs_viewer_tab_widget'
9
9
  require_relative 'keychain_widget'
10
10
  require_relative 'tool_widget'
11
+ require_relative 'app_tab_widget'
11
12
  require 'Qt'
12
13
 
13
14
  module Idb
14
15
  class MainTabWidget < Qt::TabWidget
15
-
16
+ attr_accessor :app_info
16
17
 
17
18
  def initialize *args
18
19
  super *args
19
20
  @tabs = Hash.new
20
21
 
22
+
23
+ @app_info = AppTabWidget.new self
24
+ @tabs[:app_info] = addTab(@app_info, "App Info")
25
+ @app_info.connect(SIGNAL('binary_analyzed()')) {
26
+ enableAppBinary
27
+ }
28
+
29
+
21
30
  @local_storage = LocalStorageTabWidget.new self
22
31
  @local_storage.setEnabled(false)
23
32
  @tabs[:local_storage] = addTab(@local_storage, "Storage")
@@ -76,6 +85,10 @@ module Idb
76
85
  disable_all
77
86
  end
78
87
 
88
+ def enable_select_app
89
+ @app_info.enable_select_app
90
+ end
91
+
79
92
  def enableLog
80
93
  @log.setEnabled(true)
81
94
  setTabEnabled(@tabs[:log], true)
@@ -165,8 +178,9 @@ module Idb
165
178
  enableURLHandlers
166
179
  # refresh_current_tab
167
180
  @app_binary.refresh
181
+ @app_info.app_changed
168
182
  enableFSViewer
169
- @fs_viewer.set_start $selected_app.app_dir
183
+ @fs_viewer.update_start
170
184
  enableTools
171
185
  @tools.enable_screenshot
172
186
 
@@ -52,7 +52,11 @@ module Idb
52
52
  item.setText full_path.sub($selected_app.app_dir,'')
53
53
  else
54
54
  pc = $device.protection_class full_path
55
- item.setText full_path.sub($selected_app.app_dir,'') + " => " + pc.strip
55
+ if full_path.start_with? $selected_app.app_dir
56
+ item.setText "[App Bundle]" + full_path.sub($selected_app.app_dir,'') + " => " + pc.strip
57
+ elsif full_path.start_with? $selected_app.data_dir
58
+ item.setText "[Data Dir]" + full_path.sub($selected_app.data_dir,'') + " => " + pc.strip
59
+ end
56
60
  end
57
61
  item.full_path = full_path
58
62
  @list.addItem item
@@ -14,7 +14,7 @@ module ScreenShotWizard
14
14
  def self.new_with_app app
15
15
  wiz = self.new
16
16
  wiz.app = app
17
- wiz.screenshot = ScreenShotUtil.new app.app_dir, $device.ops, false
17
+ wiz.screenshot = ScreenShotUtil.new app.data_dir, $device.ops, false
18
18
  wiz
19
19
  end
20
20
 
@@ -20,13 +20,14 @@ module Idb
20
20
  error.exec
21
21
  else
22
22
  cache_name = $selected_app.cache_file item.full_path
23
+ puts cache_name
23
24
  if cache_name.nil?
24
25
  $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."
25
26
  else
26
27
  if RbConfig::CONFIG['host_os'] =~ /linux/
27
- Process.spawn "'#{$settings['sqlite_editor']}' '#{Dir.getwd}/#{cache_name}'"
28
+ Process.spawn "'#{$settings['sqlite_editor']}' '#{cache_name}'"
28
29
  else
29
- Process.spawn "open -a '#{$settings['sqlite_editor']}' '#{Dir.getwd}/#{cache_name}'"
30
+ Process.spawn "open -a '#{$settings['sqlite_editor']}' '#{cache_name}'"
30
31
  end
31
32
  end
32
33
 
@@ -62,7 +63,11 @@ module Idb
62
63
  item.setText full_path.sub($selected_app.app_dir,'')
63
64
  else
64
65
  pc = $device.protection_class full_path
65
- item.setText full_path.sub($selected_app.app_dir,'') + " => " + pc.strip
66
+ if full_path.start_with? $selected_app.app_dir
67
+ item.setText "[App Bundle]" + full_path.sub($selected_app.app_dir,'') + " => " + pc.strip
68
+ elsif full_path.start_with? $selected_app.data_dir
69
+ item.setText "[Data Dir]" + full_path.sub($selected_app.data_dir,'') + " => " + pc.strip
70
+ end
66
71
  end
67
72
 
68
73
  item.full_path = full_path
data/lib/idb.rb CHANGED
@@ -12,6 +12,7 @@ require_relative 'gui/main_tab_widget'
12
12
  require_relative 'gui/settings_dialog'
13
13
  require_relative 'gui/device_info_group_box'
14
14
  require_relative 'gui/ca_manager_dialog'
15
+ require_relative 'gui/global_app_details_group_box'
15
16
 
16
17
  module Idb
17
18
  TARGET = "Hello"
@@ -69,9 +70,10 @@ module Idb
69
70
 
70
71
  # center
71
72
 
72
- # showMaximized();
73
- # show
74
- # self.raise
73
+ self.showMaximized()
74
+ self.raise
75
+ self.activateWindow
76
+
75
77
  end
76
78
 
77
79
  def self.execute_in_main_thread(blocking = false, sleep_period = 0.001)
@@ -96,47 +98,47 @@ module Idb
96
98
 
97
99
  @grid.setColumnMinimumWidth(0,450)
98
100
 
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
101
  # Main Tab Widget
126
102
  @main_tabs = MainTabWidget.new @central_widget
127
- @grid.addWidget @main_tabs, 0,1,3,1
103
+ @grid.addWidget @main_tabs, 4,0,1,2
104
+
128
105
 
129
106
  # device Details
130
107
  @device_details = DeviceInfoGroupBox.new @central_widget
108
+ @device_details.setSizePolicy Qt::SizePolicy::Expanding, Qt::SizePolicy::Fixed
109
+ @device_details.connect(SIGNAL(:connect_clicked)) {
110
+ @usb_device.trigger
111
+ }
131
112
  @device_details.connect(SIGNAL :disconnect) {
132
113
  @main_tabs.disable_all
133
- @app_binary.clear
134
- @app_binary.disable_analyze_binary
135
- @app_details.clear
136
- @app_details.disable_select_app
114
+ @main_tabs.app_info.app_binary.clear
115
+ @main_tabs.app_info.app_binary.disable_analyze_binary
116
+ @main_tabs.app_info.app_details.clear
137
117
  @usb_device.setChecked(false)
118
+ @global_app_details.disconnect
119
+ }
120
+ @grid.addWidget @device_details, 0,0
121
+
122
+
123
+ # global app details
124
+ @global_app_details = GlobalAppDetailsGroupBox.new
125
+ @global_app_details.setSizePolicy Qt::SizePolicy::Expanding, Qt::SizePolicy::Fixed
126
+ @global_app_details.connect(SIGNAL :app_changed) {
127
+ @menu_item_screenshot.setEnabled(true)
128
+ @main_tabs.app_changed
138
129
  }
139
- @grid.addWidget @device_details, 3,0,2,2
130
+ @grid.addWidget @global_app_details, 0, 1
131
+
132
+
133
+ @spacer = Qt::SpacerItem.new 0,5, Qt::SizePolicy::Fixed, Qt::SizePolicy::Fixed
134
+ @grid.addItem @spacer, 1,0,1,2
135
+ @grid.addItem @spacer, 3,0,1,2
136
+
137
+ line = Qt::Frame.new
138
+ line.setFrameShape(Qt::Frame::HLine)
139
+ line.setFrameShadow(Qt::Frame::Sunken)
140
+ @grid.addWidget line,2,0,1,2
141
+
140
142
 
141
143
  menu
142
144
 
@@ -161,8 +163,9 @@ module Idb
161
163
  }
162
164
  setting.exec
163
165
  }
164
- @menu_file = menuBar().addMenu "&File"
166
+ @menu_file = Qt::Menu.new "&File"
165
167
  @menu_file.addAction menu_item_settings
168
+ menuBar().addAction @menu_file.menuAction()
166
169
 
167
170
  @menu_item_screenshot = Qt::Action.new "&Screenshot", self
168
171
  @menu_item_screenshot.setEnabled(false)
@@ -175,15 +178,16 @@ module Idb
175
178
  ca = CAManagerDialog.new self
176
179
  ca.exec
177
180
  }
178
- @menu_tools = menuBar().addMenu "&Tools"
181
+ @menu_tools = Qt::Menu.new "&Tools"
179
182
  @menu_tools.addAction @menu_item_screenshot
180
183
  @menu_tools.addAction @menu_item_cert
184
+ menuBar.addAction @menu_tools.menuAction
181
185
 
182
186
 
183
187
  #Devices
184
188
  @sim_group = Qt::ActionGroup.new @menu_devices
185
189
 
186
- @menu_devices = menuBar().addMenu "&Devices"
190
+ @menu_devices = Qt::Menu.new "&Devices"
187
191
  @usb_device = Qt::Action.new "USB Device", self
188
192
  if $settings['device_connection_mode'] == "ssh"
189
193
  @usb_device.setText("SSH Device")
@@ -220,11 +224,7 @@ module Idb
220
224
  @device_status = DeviceStatusDialog.new
221
225
  @device_status.exec
222
226
  end
223
-
224
-
225
-
226
-
227
- @app_details.enable_select_app
227
+ @global_app_details.enable
228
228
  @device_details.update_device
229
229
  @menu_item_cert.setEnabled(true)
230
230
  @main_tabs.enableDeviceFunctions
@@ -233,6 +233,8 @@ module Idb
233
233
 
234
234
  progress.reset
235
235
  }
236
+
237
+
236
238
  menu_item = @menu_devices.addAction @usb_device
237
239
  @sim_group.addAction @usb_device
238
240
 
@@ -254,12 +256,11 @@ module Idb
254
256
  @menu_devices.addAction action
255
257
  }
256
258
 
257
-
259
+ menuBar.addAction @menu_devices.menuAction()
258
260
 
259
261
 
260
262
  end
261
263
 
262
-
263
264
  def center
264
265
  qdw = Qt::DesktopWidget.new
265
266
 
@@ -279,9 +280,7 @@ module Idb
279
280
  app.setApplicationName("idb")
280
281
 
281
282
  idb = Idb.new
282
- idb.setWindowState Qt::WindowActive
283
- idb.showMaximized
284
- idb.raise
283
+ app.setActiveWindow(idb)
285
284
  app.exec
286
285
 
287
286
  $log.info "Performing cleanup before exiting."
@@ -1,3 +1,3 @@
1
1
  module Idb
2
- VERSION = "2.1.0"
2
+ VERSION = "2.5.0"
3
3
  end
@@ -39,12 +39,15 @@ module Idb
39
39
  end
40
40
 
41
41
  def self.from_file(file_path)
42
+
42
43
  self.new(File.open(file_path, 'rb') {|f| f.read})
43
44
  end
44
45
 
45
46
  def png
46
47
  return @png if @png
47
48
 
49
+ all_idats = ""
50
+
48
51
  #Convert from cgbi, set instance var, return
49
52
  data = @cgbi.dup
50
53
  png = ""
@@ -89,14 +92,14 @@ module Idb
89
92
  #(1..@height).each do |y|
90
93
  # Copy over the filter type byte on each line
91
94
  # TODO: Might not be necessary for all filter types
92
- chunk[:data] << decompressed.slice!(0,1)
95
+ all_idats << decompressed.slice!(0,1)
93
96
  (1..@width).each do |x|
94
97
  # BGRA => RGBA
95
98
  b,g,r,a = decompressed.unpack("CCCC")
96
99
  decompressed.slice!(0,4).split(//)
97
100
 
98
101
  begin
99
- chunk[:data] += [r,g,b,a].pack("CCCC")
102
+ all_idats += [r,g,b,a].pack("CCCC")
100
103
  decompressed = nil if decompressed.length == 0
101
104
  rescue => e
102
105
  puts "Left: #{decompressed.inspect}"
@@ -104,20 +107,19 @@ module Idb
104
107
  end
105
108
  end
106
109
 
107
- # Deflate the IDAT chunk
108
- chunk[:type] = "IDAT"
109
- chunk[:data] = Zlib::Deflate.deflate(chunk[:data])
110
- chunk[:length] = [chunk[:data].length].pack("N")
111
- chunk[:crc] = [Zlib::crc32('IDAT' + chunk[:data])].pack("N")
112
-
113
- # store it away
114
- png << chunk[:length]
115
- png << chunk[:type]
116
- png << chunk[:data]
117
- png << chunk[:crc]
118
110
 
119
111
  when "IEND"
120
112
  raise "Data after IEND" unless data.empty?
113
+
114
+ #first write IDAT
115
+ # Deflate the IDAT chunk
116
+ compressed_idats = Zlib::Deflate.deflate(all_idats)
117
+ png << [compressed_idats.length].pack("N")
118
+ png << "IDAT"
119
+ png << compressed_idats
120
+ png << [Zlib::crc32('IDAT' + compressed_idats)].pack("N")
121
+
122
+
121
123
  png << [chunk[:length]].pack("N")
122
124
  png << chunk[:type]
123
125
  png << chunk[:data]
@@ -150,4 +152,7 @@ module Idb
150
152
  end
151
153
 
152
154
  end
155
+
156
+
153
157
  end
158
+
@@ -1,18 +1,34 @@
1
1
  require_relative 'plist_util'
2
2
  require_relative 'app_binary'
3
3
  require_relative 'CgBI'
4
+ require_relative 'ios8_last_launch_services_map_wrapper'
4
5
 
5
6
  module Idb
6
7
  class App
7
- attr_accessor :uuid, :app_dir, :binary, :cache_dir
8
+ attr_accessor :uuid, :app_dir, :binary, :cache_dir, :data_dir
8
9
 
9
10
 
10
11
  def initialize uuid
11
12
  @uuid = uuid
12
- @app_dir = "#{$device.apps_dir}/#{@uuid}"
13
13
  @cache_dir = "#{$tmp_path}/#{uuid}"
14
14
  FileUtils.mkdir_p @cache_dir unless Dir.exist? @cache_dir
15
+
16
+ @app_dir = "#{$device.apps_dir}/#{@uuid}"
15
17
  parse_info_plist
18
+
19
+ if $device.ios_version == 8
20
+ mapping_file = "/var/mobile/Library/MobileInstallation/LastLaunchServicesMap.plist"
21
+ local_mapping_file = cache_file mapping_file
22
+ mapper = IOS8LastLaunchServicesMapWrapper.new local_mapping_file
23
+
24
+ @data_dir = mapper.data_path_by_bundle_id @info_plist.bundle_identifier
25
+ @keychain_access_groups = mapper.keychain_access_groups_by_bundle_id @info_plist.bundle_identifier
26
+
27
+ else
28
+ @data_dir = @app_dir
29
+ end
30
+
31
+
16
32
  end
17
33
 
18
34
  def analyze
@@ -113,26 +129,41 @@ module Idb
113
129
  end
114
130
 
115
131
 
116
- def icon_path
132
+ def find_icon
133
+ # lets try the easy way first...
117
134
  icon_name = get_raw_plist_value('CFBundleIconFile')
135
+ if not icon_name.nil?
136
+ return icon_name
137
+ end
138
+
139
+ # lets try iphone icons
140
+ icon_name = get_raw_plist_value('CFBundleIcons')
141
+ unless icon_name.nil?
142
+ if not icon_name["CFBundlePrimaryIcon"].nil? and not icon_name["CFBundlePrimaryIcon"]["CFBundleIconFiles"].nil?
143
+ return icon_name["CFBundlePrimaryIcon"]["CFBundleIconFiles"].sort.last
144
+ end
145
+ end
118
146
 
119
- unless icon_name
120
- # If there's no icon specified, grab the first one from the array.
121
- # If it's large, this could make the app nonresponsive.
122
- icon_name = get_raw_plist_value('CFBundleIconFiles').first
123
- # NOTE: This still fails to find the icon for some apps that store it in odd places,
124
- # Like Netflix' plist_data['CFBundleIcons~ipad']['CFBundlePrimaryIcon']['CFBundleIconFiles']
147
+ # lets try ipad icons
148
+ icon_name = get_raw_plist_value('CFBundleIcons~ipad')
149
+ unless icon_name.nil?
150
+ if not icon_name["CFBundlePrimaryIcon"].nil? and not icon_name["CFBundlePrimaryIcon"]["CFBundleIconFiles"].nil?
151
+ return icon_name["CFBundlePrimaryIcon"]["CFBundleIconFiles"].sort.last
152
+ end
125
153
  end
154
+ end
126
155
 
156
+ def icon_path
127
157
  app_dir = Shellwords.escape(@app_dir)
158
+ icon_name = find_icon
128
159
 
129
160
  unless (icon_name[-4,4] == ".png")
130
161
  $log.debug "Appending extension to #{icon_name}"
131
- icon_name += ".png"
162
+ icon_name += "*.png"
132
163
  $log.debug "Now: #{icon_name}"
133
164
  end
134
165
 
135
- icon_file = $device.ops.execute("ls #{app_dir}/*app/#{icon_name}").strip
166
+ icon_file = $device.ops.execute("ls #{app_dir}/*app/#{icon_name}").split("\n").first.strip
136
167
 
137
168
  if not $device.ops.file_exists? icon_file
138
169
  $log.warn "Icon not found: #{icon_file}"
@@ -159,6 +190,22 @@ module Idb
159
190
  get_raw_plist_value 'CFBundleDisplayName'
160
191
  end
161
192
 
193
+ def keychain_access_groups
194
+ if @keychain_access_groups.nil?
195
+ "[iOS 8 specific]"
196
+ else
197
+ @keychain_access_groups.join "\n"
198
+ end
199
+ end
200
+
201
+ def data_directory
202
+ if $device.ios_version != 8
203
+ "[iOS 8 specific]"
204
+ else
205
+ @data_dir
206
+ end
207
+ end
208
+
162
209
  def platform_version
163
210
  get_raw_plist_value 'DTPlatformVersion'
164
211
  end
@@ -207,17 +254,37 @@ module Idb
207
254
 
208
255
  def find_plist_files
209
256
  $log.info "Looking for plist files..."
210
- $device.ops.dir_glob(@app_dir, "**/*plist")
257
+ app_dir_files = $device.ops.dir_glob(@app_dir, "**/*plist")
258
+ data_dir_files = Array.new
259
+
260
+ if app_dir != data_dir
261
+ data_dir_files = $device.ops.dir_glob(@data_dir, "**/*plist")
262
+ end
263
+ app_dir_files + data_dir_files
264
+
211
265
  end
212
266
 
213
267
  def find_sqlite_dbs
214
268
  $log.info "Looking for sqlite files..."
215
- $device.ops.dir_glob(@app_dir, "**/*sql**")
269
+ app_dir_files = $device.ops.dir_glob(@app_dir, "**/*sql**")
270
+ data_dir_files = Array.new
271
+
272
+ if app_dir != data_dir
273
+ data_dir_files = $device.ops.dir_glob(@data_dir, "**/*sql**")
274
+ end
275
+ app_dir_files + data_dir_files
276
+
216
277
  end
217
278
 
218
279
  def find_cache_dbs
219
280
  $log.info "Looking for Cache.db files..."
220
- $device.ops.dir_glob(@app_dir, "**/Cache.db")
281
+ app_dir_files = $device.ops.dir_glob(@app_dir, "**/Cache.db")
282
+ data_dir_files = Array.new
283
+
284
+ if app_dir != data_dir
285
+ data_dir_files = $device.ops.dir_glob(@data_dir, "**/Cache.db")
286
+ end
287
+ app_dir_files + data_dir_files
221
288
  end
222
289
 
223
290
  def get_url_handlers
@@ -7,10 +7,11 @@ require_relative 'usb_muxd_wrapper'
7
7
 
8
8
  module Idb
9
9
  class Device < AbstractDevice
10
- attr_accessor :usb_ssh_port, :mode, :tool_port
10
+ attr_accessor :usb_ssh_port, :mode, :tool_port, :ios_version
11
11
 
12
12
  def initialize username, password, hostname, port
13
- @apps_dir = '/private/var/mobile/Applications'
13
+
14
+
14
15
  @username = username
15
16
  @password = password
16
17
  @hostname = hostname
@@ -58,6 +59,28 @@ module Idb
58
59
  $log.debug "opening tool port #{@tool_port} for internal ssh connection"
59
60
  @usbmuxd.proxy @tool_port, $settings['ssh_port']
60
61
 
62
+
63
+
64
+ @apps_dir_ios_pre8 = '/private/var/mobile/Applications'
65
+ @apps_dir_ios_8 = '/private/var/mobile/Containers/Bundle/Application'
66
+ @data_dir_ios_8 = '/private/var/mobile/Containers/Data/Application'
67
+
68
+ if @ops.directory? @apps_dir_ios_pre8
69
+ @ios_version = 7 # 7 or earlier
70
+ @apps_dir = @apps_dir_ios_pre8
71
+ @data_dir = @apps_dir_ios_pre8
72
+
73
+ elsif @ops.directory? @apps_dir_ios_8
74
+ @ios_version = 8
75
+ @apps_dir = @apps_dir_ios_8
76
+ @data_dir = @data_dir_ios_8
77
+
78
+ else
79
+ $log.error "Unsupported iOS Version."
80
+ raise
81
+ end
82
+
83
+
61
84
  end
62
85
 
63
86
  start_port_forwarding
@@ -329,23 +352,17 @@ module Idb
329
352
  @ops.execute "killall -9 #{process_name}"
330
353
  end
331
354
 
332
- def DEVICE_ID
355
+ def device_id
356
+
333
357
  $log.error "Not implemented"
334
358
  nil
335
359
  end
336
360
 
337
361
  def configured?
338
- if $settings['devices'].nil?
339
- false
340
- elsif $settings['devices'][device_id].nil?
341
- false
342
- else
343
- true
344
- end
362
+ apt_get_installed? and open_installed? and openurl_installed? and dumpdecrypted_installed? and pbwatcher_installed? and pcviewer_installed? and keychain_dump_installed? and rsync_installed? and cycript_installed?
345
363
  end
346
364
 
347
365
 
348
-
349
366
  def cycript_installed?
350
367
  is_installed? :cycript
351
368
  end
@@ -0,0 +1,20 @@
1
+ require 'plist4r'
2
+
3
+ class IOS8LastLaunchServicesMapWrapper
4
+
5
+ def initialize plist_file
6
+ @plist_file = plist_file
7
+
8
+ @plist_data = Plist4r.open @plist_file
9
+ end
10
+
11
+
12
+ def data_path_by_bundle_id bundle_id
13
+ @plist_data.to_hash["User"][bundle_id]["Container"]
14
+ end
15
+
16
+
17
+ def keychain_access_groups_by_bundle_id bundle_id
18
+ @plist_data.to_hash["User"][bundle_id]["Entitlements"]["keychain-access-groups"]
19
+ end
20
+ end
@@ -13,7 +13,10 @@ module Idb
13
13
 
14
14
  @plutil = Pathname.new("/usr/bin/plutil")
15
15
  if(!@plutil.exist?)
16
- raise "plutil not found at #{@plutil}. aborting."
16
+ @plutil = Pathname.new("/usr/bin/plistutil")
17
+ if(!@plutil.exist?)
18
+ raise "plutil not found at #{@plutil}. aborting."
19
+ end
17
20
  end
18
21
 
19
22
  parse_plist_file
@@ -31,6 +34,15 @@ module Idb
31
34
  puts CodeRay.scan(doc.to_xml(:indent => 2), :xml).terminal
32
35
  end
33
36
 
37
+ def get_with_regex regex
38
+ ap @plist_data.to_hash
39
+ a = @plist_data.to_hash.find { |x|
40
+ not (x =~ regex).nil?
41
+ }
42
+ ap a
43
+ a
44
+ end
45
+
34
46
  private
35
47
  def parse_plist_file
36
48
  $log.info 'Parsing plist file..'
@@ -68,5 +80,6 @@ module Idb
68
80
 
69
81
 
70
82
 
83
+
71
84
  end
72
85
  end
@@ -4,8 +4,7 @@ require 'expect'
4
4
 
5
5
  module Idb
6
6
  class RsyncGitManager
7
- def initialize remote_path, local_path
8
- @remote_path = remote_path
7
+ def initialize local_path
9
8
  @local_path = local_path
10
9
  FileUtils.mkdir_p @local_path unless Dir.exist? @local_path
11
10
 
@@ -27,23 +26,15 @@ module Idb
27
26
  end
28
27
  end
29
28
 
30
- def sync_new_revision
31
- $log.info "Hard resetting work dir #{@local_path}..."
32
- begin
33
- @g.reset_hard
34
- rescue
35
- $log.error "Reset of repo failed. If this is the first time you run rsync+git for this app this may be okay."
36
- end
37
-
38
-
39
29
 
30
+ def sync_dir remote, local_relative
31
+ local = @local_path + "/" + local_relative
40
32
  if $settings['device_connection_mode'] == "ssh"
41
- cmd = "rsync -avz -e 'ssh -oStrictHostKeyChecking=no -p #{$settings.ssh_port}' #{$settings.ssh_username}@#{$settings.ssh_host}:#{Shellwords.escape(@remote_path)}/ #{Shellwords.escape(@local_path)}/"
33
+ cmd = "rsync -avz -e 'ssh -oStrictHostKeyChecking=no -p #{$settings.ssh_port}' #{$settings.ssh_username}@#{$settings.ssh_host}:#{Shellwords.escape(remote)}/ #{Shellwords.escape(local)}/"
42
34
  else
43
- cmd = "rsync -avz -e 'ssh -oStrictHostKeyChecking=no -p #{$device.tool_port}' root@localhost:#{Shellwords.escape(@remote_path)}/ #{Shellwords.escape(@local_path)}/"
35
+ cmd = "rsync -avz -e 'ssh -oStrictHostKeyChecking=no -p #{$device.tool_port}' root@localhost:#{Shellwords.escape(remote)}/ #{Shellwords.escape(local)}/"
44
36
  end
45
37
 
46
-
47
38
  $log.info "Executing rsync command #{cmd}"
48
39
  begin
49
40
  PTY.spawn(cmd) { |rsync_out, rsync_in, pid |
@@ -67,15 +58,28 @@ module Idb
67
58
  PTY.check
68
59
  }
69
60
  rescue
70
- $log.info "Rsync Done. committing to git."
71
- @g.add(:all=>true)
72
- begin
73
- @g.commit_all("Snapshot from #{Time.now.to_s}")
74
- rescue
75
- end
76
61
  end
77
62
 
78
63
  end
79
64
 
65
+
66
+ def commit_new_revision
67
+ $log.info "Rsync Done. committing to git."
68
+ @g.add(:all=>true)
69
+ begin
70
+ @g.commit_all("Snapshot from #{Time.now.to_s}")
71
+ rescue
72
+ end
73
+ end
74
+
75
+ def start_new_revision
76
+ $log.info "Hard resetting work dir #{@local_path}..."
77
+ begin
78
+ @g.reset_hard
79
+ rescue
80
+ $log.error "Reset of repo failed. If this is the first time you run rsync+git for this app this may be okay."
81
+ end
82
+ end
83
+
80
84
  end
81
85
  end
@@ -3,9 +3,10 @@ require_relative 'ssh_operations'
3
3
  module Idb
4
4
  class ScreenShotUtil
5
5
 
6
- def initialize app_path, ops, sim = true
7
- @app_path = app_path
8
- @snapshot_path = "#{@app_path}/Library/Caches/Snapshots"
6
+ def initialize data_path, ops, sim = true
7
+ @data_path = data_path
8
+ ap @data_path
9
+ @snapshot_path = "#{@data_path}/Library/Caches/Snapshots"
9
10
  @ops = ops
10
11
  @sim = sim
11
12
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: idb
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.1.0
4
+ version: 2.5.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Daniel A. Mayer
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-10-10 00:00:00.000000000 Z
11
+ date: 2014-11-05 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -258,6 +258,7 @@ files:
258
258
  - lib/gui/app_details_group_box.rb
259
259
  - lib/gui/app_list_dialog.rb
260
260
  - lib/gui/app_list_widget_item.rb
261
+ - lib/gui/app_tab_widget.rb
261
262
  - lib/gui/binary_strings_widget.rb
262
263
  - lib/gui/browse_filesystem_widget.rb
263
264
  - lib/gui/ca_manager_dialog.rb
@@ -270,6 +271,7 @@ files:
270
271
  - lib/gui/device_status_dialog.rb
271
272
  - lib/gui/file_system_events_widget.rb
272
273
  - lib/gui/fs_viewer_tab_widget.rb
274
+ - lib/gui/global_app_details_group_box.rb
273
275
  - lib/gui/i_device_syslog_thread.rb
274
276
  - lib/gui/images/check.png
275
277
  - lib/gui/images/folder.ico
@@ -318,6 +320,7 @@ files:
318
320
  - lib/lib/device_ca_interface.rb
319
321
  - lib/lib/host_file_wrapper.rb
320
322
  - lib/lib/i_device_diagnostics_wrapper.rb
323
+ - lib/lib/ios8_last_launch_services_map_wrapper.rb
321
324
  - lib/lib/keychain_plist_parser.rb
322
325
  - lib/lib/local_operations.rb
323
326
  - lib/lib/otool_wrapper.rb