idb 2.1.0 → 2.5.0

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 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