-
Notifications
You must be signed in to change notification settings - Fork 444
/
ideas.txt
182 lines (133 loc) · 6.5 KB
/
ideas.txt
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
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
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
# IDEA SCRATCH PAD
Better tests for class generation:
- inner classes and enclosing methods (needs more research)
- annotations
- source name (easy)
Add demos directory:
- Move example app there, possibly rename it
- Create another demo which executes method of a real app maybe
Add option to include JARs with classes that should be reflected. This could allow dex2jar + simplify to work together. Could also include Android framework JARs.
Architecture changes to make adding a debugger easier:
- Attach listeners with call backs for method and op execution to method and op execution
- Used for watching fields and registers
- Useful for debugger
- Listeners could define filters
- Add visitation strategy for methods to call them in the same order Android would
- Activities have methods called in a certain order and rely on class state setup by that order
- ex: simplify 7604399 -it 'PornApplication;->i2c1cqop3faop3cdhokggmd97ce\(\)'
ArrayLists are initialized in onCreate, but since that's not known, everything fails
MethodVisitor interface
SimpleMethodVisitor - executes each method in arbitrary order
AndroidLifecycleAwareMethodVisitor
// TODO: https://github.com/CalebFenton/simplify/issues/8
add tests and feature for moving exception from parent op
move-exception op
implement the throw op also
add some tests
also fix invoke op for getting graph of invoked method
peekThrowRegister() see if it's null
run instance-of tests
can you do primitive instanceof primitive?
primitive instance of object? (probably)
Debugger
next / previous(!)
show local code
set breakpoints
method address
line number
on field access
show vm info
loaded classes
stack trace
show method state info
registers
provide method parameters as serialized objects
Graphing
save control flow / execution flow graph before or after optimization
show line numbers and other debug info
Save Progress
on VM finalize, or when exiting, serialize graphs (perhaps gson)
--resume <directory with json graphs>
Theading
Because why not.
Hygene
move sideeffect out of op and into node
op shared between all nodes at address, should record sideeffect per execution
maybe smalivm shouldn't require trove
remove arrays and regular lists / sets instead
primitive unboxing probably isn't that bad
need some serious benchmarking
remove array data payloads that are unreferenced
Obfuscated example does this in reflected field lookups
Profiling Feature
record each method descriptor and the number of times it was called
filter for only method descriptors which have a pattern
record only methods that failed, methods that could be whitelisted
Making Hooking easier to do dynamically.
Emulate
System.exit() to halt the execution path
Ljava/lang/reflect/Method;->invoke(Ljava/lang/Object;[Ljava/lang/Object;)Ljava/lang/Object;
invoke ourselves or run emulated method
Emulate / spoof stack traces - requires call stack in context or similar
new-instance v1, Ljava/lang/Exception;
invoke-direct {v1}, Ljava/lang/Exception;-><init>()V
invoke-virtual {v1}, Ljava/lang/Exception;->getStackTrace()[Ljava/lang/StackTraceElement;
invoke-virtual {v1}, Ljava/lang/StackTraceElement;->getMethodName()Ljava/lang/String;
move-result-object v2
invoke-direct {v0, v2}, Ljava/lang/StringBuffer;-><init>(Ljava/lang/String;)V
invoke-virtual {v1}, Ljava/lang/StackTraceElement;->getClassName()Ljava/lang/String;
invoke-static {}, Ljava/lang/Thread;->currentThread()Ljava/lang/Thread;
move-result-object v2
invoke-virtual {v2}, Ljava/lang/Thread;->getStackTrace()[Ljava/lang/StackTraceElement;
sandbox/hubert/hubert_sample.apk -it 'Lcom/i_manager/ajroute/c;->a\(Ljava/lang/String;Ljava/lang/Boolean;Ljava/lang/Integer;\)Ljava/lang/Integer;' -v
has this, which should be considered dead, needs to be specifically white listed
v0 is "assigned" since it's an instance and could have changed, but v0 is never used
#@1f
invoke-virtual {v0}, Ljava/lang/StringBuilder;->toString()Ljava/lang/String;
During execution, the context has no awareness of the call stack. Knowing these things allows for:
1.) illegal access checks on fields, right now, no way to tell if the field is in the same class as the current method
2.) contextualized exception throwing with stack trace
* update - execution context of first op in method has callerContext and callerAddress, which can be traced back up to rebuild call stack
get stack trace, first element
from inside a method that's being optimized from main
the call stack *should* be ambiguous
but if it's not, could give away it's being virtually executed
*get first element would be a string, that would get constantized during optimization
wasRegisterRead unit test possibility!
# make sure v0 is not removed
const/4 v2, 0x5
invoke-static {v2}, Ljava/lang/Integer;->valueOf(I)Ljava/lang/Integer;
move-result v0
move-object v1, v0
invoke-static {v1}, Ldoes/not/exist;->howdy(Ljava/lang/Integer;)V
# make sure v0 IS REMOVED
const/4 v2, 0x5
invoke-static {v2}, Ljava/lang/Integer;->valueOf(I)Ljava/lang/Integer;
move-result v0
invoke-static {v2}, Ljava/lang/Integer;->valueOf(I)Ljava/lang/Integer;
move-result v1
invoke-static {v1}, Ldoes/not/exist;->howdy(Ljava/lang/Integer;)V
assumeMaxUnknown for invokeop wont work for LocalInstance.isInitialized == false, add tests
boolean isInitializing = methodDescriptor.contains(";-><init>(") && ((value instanceof UninitializedInstance));
test aput for non-Number values, e.g. boolean and character into an int array, but see if dalvik handles it properly first
simple test
throw an exception and catch it
inheritence test
throw a child exception and see if caught by exception parent
complex inheritence
throw a child exception, catch parent and grandparent and make sure parent handles
finally test
simple value set + test
unhandled exception + finally test
throw exception but make sure finally value set
handled exception + finally test
throw exception, handle it, make sure finally value set
consider unit testing
exceptionhandlerresolver - build unit with public method to resolve addresses given an
exception
current address
try catch blocks
Success stories:
* java -jar build/libs/simplify.jar sandbox/6e83dc38935db29123ff29dc9454b5969e4a472a -it 'D;->'
* java -Xmx6g -jar build/libs/simplify.jar sandbox/e99dd3229dc9ff70f6e768342ca27d984e796f1a -it '/smv;'
* java -jar build/libs/simplify.jar sandbox/44417221d3ef6db0fa8f0f80e462f1332a7204a3/ -it Acgt -v