Class: Driver
- Inherits:
-
Object
show all
- Includes:
- Logging
- Defined in:
- lib/dex-oracle/driver.rb
Constant Summary
collapse
- UNESCAPES =
{
'a' => "\x07", 'b' => "\x08", 't' => "\x09",
'n' => "\x0a", 'v' => "\x0b", 'f' => "\x0c",
'r' => "\x0d", 'e' => "\x1b", '\\' => '\\',
'"' => '"', "'" => "'"
}.freeze
- UNESCAPE_REGEX =
/\\(?:([#{UNESCAPES.keys.join}])|u([\da-fA-F]{4}))|\\0?x([\da-fA-F]{2})/
'===ORACLE DRIVER OUTPUT==='.freeze
- DRIVER_CLASS =
'org.cf.oracle.Driver'.freeze
Instance Method Summary
collapse
Methods included from Logging
included, logger, #logger, logger=
Constructor Details
#initialize(device_id, timeout = 60) ⇒ Driver
Returns a new instance of Driver.
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
|
# File 'lib/dex-oracle/driver.rb', line 23
def initialize(device_id, timeout = 60)
@device_id = device_id
@timeout = timeout
device_str = device_id.empty? ? '' : "-s #{@device_id} "
@adb_base = "adb #{device_str}%s"
@driver_dir = get_driver_dir
unless @driver_dir
logger.error 'Unable to find writable driver directory. Make sure /data/local or /data/local/tmp exists and is writable.'
exit -1
end
logger.debug "Using #{@driver_dir} as driver directory ..."
@cmd_stub = "export CLASSPATH=#{@driver_dir}/od.zip; app_process /system/bin #{DRIVER_CLASS}"
@cache = {}
end
|
Instance Method Details
#install(dex) ⇒ Object
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
|
# File 'lib/dex-oracle/driver.rb', line 40
def install(dex)
has_java = Utility.which('java')
raise 'Unable to find Java on the path.' unless has_java
begin
raise "#{Resources.dx} does not exist and is required for DexMerger" unless File.exist?(Resources.dx)
raise "#{Resources.driver_dex} does not exist" unless File.exist?(Resources.driver_dex)
logger.debug("Merging input DEX (#{dex.path}) and driver DEX (#{Resources.driver_dex}) ...")
tf = Tempfile.new(%w(oracle-driver .dex))
cmd = "java -cp #{Resources.dx} com.android.dx.merge.DexMerger #{tf.path} #{dex.path} #{Resources.driver_dex}"
stdout, stderr = exec(cmd)
if stderr.start_with?('Exception in thread "main"')
logger.error("Failure to merge input DEX and driver DEX:\n#{stderr}")
if stderr.include?('DexIndexOverflowException')
logger.error("Your input DEX inexplicably contains const-string and const-string/jumbo. This probably means someone fucked with it. In any case, it means DexMerge is failing because there are too many strings.\nTry this: baksmali the DEX, replace all const-string instructions with const-string/jumbo, then recompile with smali and use that DEX as input. Sorry, I don't want to do this for you. It's too complicated.")
end
exit -1
end
tf.close
logger.debug('Pushing merged driver to device ...')
tz = Tempfile.new(%w(oracle-driver .zip))
tempzip_path = tz.path
tz.close
Utility.create_zip(tempzip_path, 'classes.dex' => tf)
adb("push #{tz.path} #{@driver_dir}/od.zip")
rescue => e
puts "Error installing driver: #{e}\n#{e.backtrace.join("\n\t")}"
ensure
tf.close if tf
tf.unlink if tf
tz.close if tz
tz.unlink if tz
end
end
|
#make_target(class_name, signature, *args) ⇒ Object
126
127
128
129
130
131
132
133
134
135
136
137
|
# File 'lib/dex-oracle/driver.rb', line 126
def make_target(class_name, signature, *args)
method = SmaliMethod.new(class_name, signature)
target = {
className: method.class.tr('/', '.'),
methodName: method.name,
arguments: build_arguments(method.parameters, args)
}
target[:id] = Digest::SHA256.hexdigest(target.to_json)
target
end
|
#run(class_name, signature, *args) ⇒ Object
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
|
# File 'lib/dex-oracle/driver.rb', line 87
def run(class_name, signature, *args)
method = SmaliMethod.new(class_name, signature)
cmd = build_command(method.class, method.name, method.parameters, args)
output = nil
retries = 1
begin
output = drive(cmd)
rescue => e
raise e if retries > 3
logger.debug("Driver execution failed. Taking a quick nap and retrying, Zzzzz ##{retries} / 3 ...")
sleep 5
retries += 1
retry
end
output
end
|
#run_batch(batch) ⇒ Object
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
|
# File 'lib/dex-oracle/driver.rb', line 109
def run_batch(batch)
push_batch_targets(batch)
retries = 1
begin
drive("#{@cmd_stub} @#{@driver_dir}/od-targets.json", true)
rescue => e
raise e if retries > 3 || !e.message.include?('Segmentation fault')
logger.debug("Driver execution segfaulted. Taking a quick nap and retrying, Zzzzz ##{retries} / 3 ...")
sleep 5
retries += 1
retry
end
pull_batch_outputs
end
|