Code Monkey home page Code Monkey logo

dexter's People

Contributors

arb33 avatar davidbrazdil avatar xurubin avatar

Stargazers

 avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar

Forkers

itant

dexter's Issues

App parsing becomes slower?

It only takes 6 seconds to load 056-const-string-jumbo.apk using older version 430de9dc474210d31deb1aaed6d98092ae5b15da, but the HEAD now spend more than 80 seconds on it.

Taint object assigned too late for external classes

Example:

new-instance v0, Ljava/util/ArrayList;
# ideally now want to create a new TaintExternal object
# but v0 cannot be referenced at this point
# so could create it but not cache it
const v1, 0xA
invoke-direct {v0, v1} Ljava/util/ArrayList;-><init>(I)V
# now v0 becomes valid, but it might be too late
# what if the constructor calls some internal code?

Init done on a copy of THIS ref doesn't initialize the other copies

Original code:

.method protected constructor <init>(Lcom/google/api/services/notes/Notes$Changes;Ljava/lang/String;Lcom/google/api/services/notes/model/InsertMedia;Lcom/google/api/client/http/AbstractInputStreamContent;)V
    .registers 11
    .parameter
    .parameter
    .parameter
    .parameter

    .prologue
    .line 331
    iput-object p1, p0, Lcom/google/api/services/notes/Notes$Changes$Insertmedia;->this$1:Lcom/google/api/services/notes/Notes$Changes;

    .line 332
    iget-object v1, p1, Lcom/google/api/services/notes/Notes$Changes;->this$0:Lcom/google/api/services/notes/Notes;

    const-string v2, "POST"

    new-instance v0, Ljava/lang/StringBuilder;

    invoke-direct {v0}, Ljava/lang/StringBuilder;-><init>()V

    const-string v3, "/upload/"

    invoke-virtual {v0, v3}, Ljava/lang/StringBuilder;->append(Ljava/lang/String;)Ljava/lang/StringBuilder;

    move-result-object v0

    iget-object v3, p1, Lcom/google/api/services/notes/Notes$Changes;->this$0:Lcom/google/api/services/notes/Notes;

    invoke-virtual {v3}, Lcom/google/api/services/notes/Notes;->getServicePath()Ljava/lang/String;

    move-result-object v3

    invoke-virtual {v0, v3}, Ljava/lang/StringBuilder;->append(Ljava/lang/String;)Ljava/lang/StringBuilder;

    move-result-object v0

    const-string v3, "media/{nodeId}"

    invoke-virtual {v0, v3}, Ljava/lang/StringBuilder;->append(Ljava/lang/String;)Ljava/lang/StringBuilder;

    move-result-object v0

    invoke-virtual {v0}, Ljava/lang/StringBuilder;->toString()Ljava/lang/String;

    move-result-object v3

    const-class v5, Lcom/google/api/services/notes/model/Blob;

    move-object v0, p0

    move-object v4, p3

    invoke-direct/range {v0 .. v5}, Lcom/google/api/services/notes/NotesRequest;-><init>(Lcom/google/api/services/notes/Notes;Ljava/lang/String;Ljava/lang/String;Ljava/lang/Object;Ljava/lang/Class;)V

    .line 333
    const-string v0, "Required parameter nodeId must be specified."

    invoke-static {p2, v0}, Lcom/google/api/client/util/Preconditions;->checkNotNull(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;

    move-result-object v0

    check-cast v0, Ljava/lang/String;

    iput-object v0, p0, Lcom/google/api/services/notes/Notes$Changes$Insertmedia;->nodeId:Ljava/lang/String;

    .line 334
    invoke-virtual {p0, p4}, Lcom/google/api/services/notes/Notes$Changes$Insertmedia;->initializeMediaUpload(Lcom/google/api/client/http/AbstractInputStreamContent;)V

    .line 335
    return-void
.end method

Instrumented:

0: sget-object a58, Luk/ac/cam/db538/dexter/aux/InvokeTaintStore$$1;->ARGS_PRIM:Luk/ac/cam/db538/dexter/aux/InvokeTaintStore$ThreadLocalPrimitiveArguments$$1;
1: invoke-virtual Ljava/lang/ThreadLocal;->get()Ljava/lang/Object; {a58}()
2: move-result-obj a58
3: check-cast a58, [I
4: sget-object a59, Luk/ac/cam/db538/dexter/aux/InvokeTaintStore$$1;->ARGS_REF:Luk/ac/cam/db538/dexter/aux/InvokeTaintStore$ThreadLocalReferenceArguments$$1;
5: invoke-virtual Ljava/lang/ThreadLocal;->get()Ljava/lang/Object; {a59}()
6: move-result-obj a59
7: check-cast a59, [Luk/ac/cam/db538/dexter/aux/struct/Taint$$1;
8: const a60, #0
9: const a61, #1
10: aget-object t7, {a59}[a61]
11: check-cast t7, Luk/ac/cam/db538/dexter/aux/struct/TaintInternal$$1;
12: const a61, #2
13: aget-object t8, {a59}[a61]
14: check-cast t8, Luk/ac/cam/db538/dexter/aux/struct/TaintExternal$$1;
15: const a61, #3
16: aget-object t9, {a59}[a61]
17: check-cast t9, Luk/ac/cam/db538/dexter/aux/struct/TaintInternal$$1;
18: const a61, #4
19: aget-object t10, {a59}[a61]
20: check-cast t10, Luk/ac/cam/db538/dexter/aux/struct/TaintInternal$$1;
21: 
22: TRYSTART0
23: iput-object v7, {v6}Lcom/google/api/services/notes/Notes$Changes$Insertmedia;->this$1:Lcom/google/api/services/notes/Notes$Changes;
24: TRYEND0
25: goto L0
26: CATCHALL0
27: move-exception a2
28: const a0, #0
29: invoke-static Luk/ac/cam/db538/dexter/aux/struct/TaintInternal$$1;->clearVisited()V ()
30: invoke-interface Luk/ac/cam/db538/dexter/aux/struct/Taint$$1;->get()I {t7}()
31: move-result a1
32: or-int a0, a0, a1
33: invoke-static Luk/ac/cam/db538/dexter/aux/struct/Assigner$$1;->lookupUndecidable(Ljava/lang/Object;I)Luk/ac/cam/db538/dexter/aux/struct/Taint$$1; (a2, a0)
34: move-result-obj a3
35: throw a2
36: L0
37: iput-object t7, {v6}Lcom/google/api/services/notes/Notes$Changes$Insertmedia;->t_this$1:Luk/ac/cam/db538/dexter/aux/struct/TaintInternal$$1;
38: 
39: TRYSTART1
40: iget-object v1, {v7}Lcom/google/api/services/notes/Notes$Changes;->this$0:Lcom/google/api/services/notes/Notes;
41: TRYEND1
42: goto L1
43: CATCHALL1
44: move-exception a6
45: const a4, #0
46: invoke-static Luk/ac/cam/db538/dexter/aux/struct/TaintInternal$$1;->clearVisited()V ()
47: invoke-interface Luk/ac/cam/db538/dexter/aux/struct/Taint$$1;->get()I {t7}()
48: move-result a5
49: or-int a4, a4, a5
50: invoke-static Luk/ac/cam/db538/dexter/aux/struct/Assigner$$1;->lookupUndecidable(Ljava/lang/Object;I)Luk/ac/cam/db538/dexter/aux/struct/Taint$$1; (a6, a4)
51: move-result-obj a7
52: throw a6
53: L1
54: iget-object t1, {v7}Lcom/google/api/services/notes/Notes$Changes;->t_this$0:Luk/ac/cam/db538/dexter/aux/struct/TaintInternal$$1;
55: 
56: const-string v2, "POST"
57: new-instance t2, Luk/ac/cam/db538/dexter/aux/struct/TaintExternal$$1;
58: invoke-direct Luk/ac/cam/db538/dexter/aux/struct/TaintExternal$$1;-><init>()V {t2}()
59: 
60: new-instance v0, Ljava/lang/StringBuilder;
61: 
62: const a8, #0
63: TRYSTART2
64: invoke-direct Ljava/lang/StringBuilder;-><init>()V {v0}()
65: TRYEND2
66: goto L2
67: CATCHALL2
68: move-exception a9
69: invoke-static Luk/ac/cam/db538/dexter/aux/struct/Assigner$$1;->lookupUndecidable(Ljava/lang/Object;I)Luk/ac/cam/db538/dexter/aux/struct/Taint$$1; (a9, a8)
70: move-result-obj a10
71: throw a9
72: L2
73: invoke-static Luk/ac/cam/db538/dexter/aux/struct/Assigner$$1;->newExternal(Ljava/lang/Object;I)Luk/ac/cam/db538/dexter/aux/struct/TaintExternal$$1; (v0, a8)
74: move-result-obj t0
75: 
76: const-string v3, "/upload/"
77: new-instance t3, Luk/ac/cam/db538/dexter/aux/struct/TaintExternal$$1;
78: invoke-direct Luk/ac/cam/db538/dexter/aux/struct/TaintExternal$$1;-><init>()V {t3}()
79: 
80: const a12, #0
81: invoke-static Luk/ac/cam/db538/dexter/aux/struct/TaintInternal$$1;->clearVisited()V ()
82: invoke-interface Luk/ac/cam/db538/dexter/aux/struct/Taint$$1;->get()I {t0}()
83: move-result a15
84: or-int a12, a12, a15
85: invoke-interface Luk/ac/cam/db538/dexter/aux/struct/Taint$$1;->get()I {t3}()
86: move-result a15
87: or-int a12, a12, a15
88: invoke-static Luk/ac/cam/db538/dexter/aux/struct/TaintInternal$$1;->clearVisited()V ()
89: if-eqz v0, L4
90: invoke-interface Luk/ac/cam/db538/dexter/aux/struct/Taint$$1;->set(I)V {t0}(a12)
91: L4
92: TRYSTART3
93: invoke-virtual Ljava/lang/StringBuilder;->append(Ljava/lang/String;)Ljava/lang/StringBuilder; {v0}(v3)
94: move-result-obj v0
95: TRYEND3
96: goto L3
97: CATCHALL3
98: move-exception a13
99: invoke-static Luk/ac/cam/db538/dexter/aux/struct/Assigner$$1;->lookupUndecidable(Ljava/lang/Object;I)Luk/ac/cam/db538/dexter/aux/struct/Taint$$1; (a13, a12)
100: move-result-obj a14
101: throw a13
102: L3
103: if-eqz v0, L5
104: invoke-static Luk/ac/cam/db538/dexter/aux/struct/Assigner$$1;->lookupExternal(Ljava/lang/Object;I)Luk/ac/cam/db538/dexter/aux/struct/TaintExternal$$1; (v0, a12)
105: move-result-obj t0
106: goto L6
107: L5
108: invoke-static Luk/ac/cam/db538/dexter/aux/struct/Assigner$$1;->newExternal(Ljava/lang/Object;I)Luk/ac/cam/db538/dexter/aux/struct/TaintExternal$$1; (v0, a12)
109: move-result-obj t0
110: L6
111: 
112: TRYSTART4
113: iget-object v3, {v7}Lcom/google/api/services/notes/Notes$Changes;->this$0:Lcom/google/api/services/notes/Notes;
114: TRYEND4
115: goto L7
116: CATCHALL4
117: move-exception a18
118: const a16, #0
119: invoke-static Luk/ac/cam/db538/dexter/aux/struct/TaintInternal$$1;->clearVisited()V ()
120: invoke-interface Luk/ac/cam/db538/dexter/aux/struct/Taint$$1;->get()I {t7}()
121: move-result a17
122: or-int a16, a16, a17
123: invoke-static Luk/ac/cam/db538/dexter/aux/struct/Assigner$$1;->lookupUndecidable(Ljava/lang/Object;I)Luk/ac/cam/db538/dexter/aux/struct/Taint$$1; (a18, a16)
124: move-result-obj a19
125: throw a18
126: L7
127: iget-object t3, {v7}Lcom/google/api/services/notes/Notes$Changes;->t_this$0:Luk/ac/cam/db538/dexter/aux/struct/TaintInternal$$1;
128: 
129: sget-object a20, Luk/ac/cam/db538/dexter/aux/InvokeTaintStore$$1;->ARGS_PRIM:Luk/ac/cam/db538/dexter/aux/InvokeTaintStore$ThreadLocalPrimitiveArguments$$1;
130: invoke-virtual Ljava/lang/ThreadLocal;->get()Ljava/lang/Object; {a20}()
131: move-result-obj a20
132: check-cast a20, [I
133: sget-object a21, Luk/ac/cam/db538/dexter/aux/InvokeTaintStore$$1;->ARGS_REF:Luk/ac/cam/db538/dexter/aux/InvokeTaintStore$ThreadLocalReferenceArguments$$1;
134: invoke-virtual Ljava/lang/ThreadLocal;->get()Ljava/lang/Object; {a21}()
135: move-result-obj a21
136: check-cast a21, [Luk/ac/cam/db538/dexter/aux/struct/Taint$$1;
137: const a22, #0
138: aput-object t3, {a21}[a22]
139: invoke-virtual Lcom/google/api/services/notes/Notes;->getServicePath()Ljava/lang/String; {v3}()
140: move-result-obj v3
141: sget-object t3, Luk/ac/cam/db538/dexter/aux/InvokeTaintStore$$1;->RES_REF:Luk/ac/cam/db538/dexter/aux/InvokeTaintStore$ThreadLocalReferenceResult$$1;
142: invoke-virtual Ljava/lang/ThreadLocal;->get()Ljava/lang/Object; {t3}()
143: move-result-obj t3
144: check-cast t3, Luk/ac/cam/db538/dexter/aux/struct/TaintExternal$$1;
145: 
146: const a23, #0
147: invoke-static Luk/ac/cam/db538/dexter/aux/struct/TaintInternal$$1;->clearVisited()V ()
148: invoke-interface Luk/ac/cam/db538/dexter/aux/struct/Taint$$1;->get()I {t0}()
149: move-result a26
150: or-int a23, a23, a26
151: invoke-interface Luk/ac/cam/db538/dexter/aux/struct/Taint$$1;->get()I {t3}()
152: move-result a26
153: or-int a23, a23, a26
154: invoke-static Luk/ac/cam/db538/dexter/aux/struct/TaintInternal$$1;->clearVisited()V ()
155: if-eqz v0, L9
156: invoke-interface Luk/ac/cam/db538/dexter/aux/struct/Taint$$1;->set(I)V {t0}(a23)
157: L9
158: TRYSTART5
159: invoke-virtual Ljava/lang/StringBuilder;->append(Ljava/lang/String;)Ljava/lang/StringBuilder; {v0}(v3)
160: move-result-obj v0
161: TRYEND5
162: goto L8
163: CATCHALL5
164: move-exception a24
165: invoke-static Luk/ac/cam/db538/dexter/aux/struct/Assigner$$1;->lookupUndecidable(Ljava/lang/Object;I)Luk/ac/cam/db538/dexter/aux/struct/Taint$$1; (a24, a23)
166: move-result-obj a25
167: throw a24
168: L8
169: if-eqz v0, L10
170: invoke-static Luk/ac/cam/db538/dexter/aux/struct/Assigner$$1;->lookupExternal(Ljava/lang/Object;I)Luk/ac/cam/db538/dexter/aux/struct/TaintExternal$$1; (v0, a23)
171: move-result-obj t0
172: goto L11
173: L10
174: invoke-static Luk/ac/cam/db538/dexter/aux/struct/Assigner$$1;->newExternal(Ljava/lang/Object;I)Luk/ac/cam/db538/dexter/aux/struct/TaintExternal$$1; (v0, a23)
175: move-result-obj t0
176: L11
177: 
178: const-string v3, "media/{nodeId}"
179: new-instance t3, Luk/ac/cam/db538/dexter/aux/struct/TaintExternal$$1;
180: invoke-direct Luk/ac/cam/db538/dexter/aux/struct/TaintExternal$$1;-><init>()V {t3}()
181: 
182: const a27, #0
183: invoke-static Luk/ac/cam/db538/dexter/aux/struct/TaintInternal$$1;->clearVisited()V ()
184: invoke-interface Luk/ac/cam/db538/dexter/aux/struct/Taint$$1;->get()I {t0}()
185: move-result a30
186: or-int a27, a27, a30
187: invoke-interface Luk/ac/cam/db538/dexter/aux/struct/Taint$$1;->get()I {t3}()
188: move-result a30
189: or-int a27, a27, a30
190: invoke-static Luk/ac/cam/db538/dexter/aux/struct/TaintInternal$$1;->clearVisited()V ()
191: if-eqz v0, L13
192: invoke-interface Luk/ac/cam/db538/dexter/aux/struct/Taint$$1;->set(I)V {t0}(a27)
193: L13
194: TRYSTART6
195: invoke-virtual Ljava/lang/StringBuilder;->append(Ljava/lang/String;)Ljava/lang/StringBuilder; {v0}(v3)
196: move-result-obj v0
197: TRYEND6
198: goto L12
199: CATCHALL6
200: move-exception a28
201: invoke-static Luk/ac/cam/db538/dexter/aux/struct/Assigner$$1;->lookupUndecidable(Ljava/lang/Object;I)Luk/ac/cam/db538/dexter/aux/struct/Taint$$1; (a28, a27)
202: move-result-obj a29
203: throw a28
204: L12
205: if-eqz v0, L14
206: invoke-static Luk/ac/cam/db538/dexter/aux/struct/Assigner$$1;->lookupExternal(Ljava/lang/Object;I)Luk/ac/cam/db538/dexter/aux/struct/TaintExternal$$1; (v0, a27)
207: move-result-obj t0
208: goto L15
209: L14
210: invoke-static Luk/ac/cam/db538/dexter/aux/struct/Assigner$$1;->newExternal(Ljava/lang/Object;I)Luk/ac/cam/db538/dexter/aux/struct/TaintExternal$$1; (v0, a27)
211: move-result-obj t0
212: L15
213: 
214: const a31, #0
215: invoke-static Luk/ac/cam/db538/dexter/aux/struct/TaintInternal$$1;->clearVisited()V ()
216: invoke-interface Luk/ac/cam/db538/dexter/aux/struct/Taint$$1;->get()I {t0}()
217: move-result a34
218: or-int a31, a31, a34
219: invoke-static Luk/ac/cam/db538/dexter/aux/struct/TaintInternal$$1;->clearVisited()V ()
220: if-eqz v0, L17
221: invoke-interface Luk/ac/cam/db538/dexter/aux/struct/Taint$$1;->set(I)V {t0}(a31)
222: L17
223: TRYSTART7
224: invoke-virtual Ljava/lang/StringBuilder;->toString()Ljava/lang/String; {v0}()
225: move-result-obj v3
226: TRYEND7
227: goto L16
228: CATCHALL7
229: move-exception a32
230: invoke-static Luk/ac/cam/db538/dexter/aux/struct/Assigner$$1;->lookupUndecidable(Ljava/lang/Object;I)Luk/ac/cam/db538/dexter/aux/struct/Taint$$1; (a32, a31)
231: move-result-obj a33
232: throw a32
233: L16
234: if-eqz v3, L18
235: invoke-static Luk/ac/cam/db538/dexter/aux/struct/Assigner$$1;->lookupExternal(Ljava/lang/Object;I)Luk/ac/cam/db538/dexter/aux/struct/TaintExternal$$1; (v3, a31)
236: move-result-obj t3
237: goto L19
238: L18
239: invoke-static Luk/ac/cam/db538/dexter/aux/struct/Assigner$$1;->newExternal(Ljava/lang/Object;I)Luk/ac/cam/db538/dexter/aux/struct/TaintExternal$$1; (v3, a31)
240: move-result-obj t3
241: L19
242: 
243: const-class v5, Lcom/google/api/services/notes/model/Blob;
244: new-instance t5, Luk/ac/cam/db538/dexter/aux/struct/TaintExternal$$1;
245: invoke-direct Luk/ac/cam/db538/dexter/aux/struct/TaintExternal$$1;-><init>()V {t5}()
246: 
247: move-obj v0, v6
248: 
249: move-obj t4, t9
250: move-obj v4, v9
251: 
252: sget-object a35, Luk/ac/cam/db538/dexter/aux/InvokeTaintStore$$1;->ARGS_PRIM:Luk/ac/cam/db538/dexter/aux/InvokeTaintStore$ThreadLocalPrimitiveArguments$$1;
253: invoke-virtual Ljava/lang/ThreadLocal;->get()Ljava/lang/Object; {a35}()
254: move-result-obj a35
255: check-cast a35, [I
256: sget-object a36, Luk/ac/cam/db538/dexter/aux/InvokeTaintStore$$1;->ARGS_REF:Luk/ac/cam/db538/dexter/aux/InvokeTaintStore$ThreadLocalReferenceArguments$$1;
257: invoke-virtual Ljava/lang/ThreadLocal;->get()Ljava/lang/Object; {a36}()
258: move-result-obj a36
259: check-cast a36, [Luk/ac/cam/db538/dexter/aux/struct/Taint$$1;
260: const a37, #1
261: aput-object t1, {a36}[a37]
262: const a37, #2
263: aput-object t2, {a36}[a37]
264: const a37, #3
265: aput-object t3, {a36}[a37]
266: const a37, #4
267: aput-object t4, {a36}[a37]
268: const a37, #5
269: aput-object t5, {a36}[a37]
270: invoke-direct Lcom/google/api/services/notes/NotesRequest;-><init>(Lcom/google/api/services/notes/Notes;Ljava/lang/String;Ljava/lang/String;Ljava/lang/Object;Ljava/lang/Class;)V {v0}(v1, v2, v3, v4, v5)
271: const a40, #0
272: const a39, #0
273: invoke-static Luk/ac/cam/db538/dexter/aux/struct/Assigner$$1;->newExternal(Ljava/lang/Object;I)Luk/ac/cam/db538/dexter/aux/struct/TaintExternal$$1; (a39, a40)
274: move-result-obj a38
275: iput-object a38, {v0}Lcom/google/api/services/notes/Notes$Changes$Insertmedia;->t_nodeId:Luk/ac/cam/db538/dexter/aux/struct/TaintExternal$$1;
276: invoke-static Luk/ac/cam/db538/dexter/aux/struct/Assigner$$1;->newInternal_NULL(I)Luk/ac/cam/db538/dexter/aux/struct/TaintInternal$$1; (a40)
277: move-result-obj a38
278: iput-object a38, {v0}Lcom/google/api/services/notes/Notes$Changes$Insertmedia;->t_this$1:Luk/ac/cam/db538/dexter/aux/struct/TaintInternal$$1;
279: invoke-static Luk/ac/cam/db538/dexter/aux/struct/Assigner$$1;->newInternal(Ljava/lang/Object;)Luk/ac/cam/db538/dexter/aux/struct/TaintInternal$$1; (v0)
280: move-result-obj t0
281: 
282: const-string v0, "Required parame..."
283: new-instance t0, Luk/ac/cam/db538/dexter/aux/struct/TaintExternal$$1;
284: invoke-direct Luk/ac/cam/db538/dexter/aux/struct/TaintExternal$$1;-><init>()V {t0}()
285: 
286: sget-object a41, Luk/ac/cam/db538/dexter/aux/InvokeTaintStore$$1;->ARGS_PRIM:Luk/ac/cam/db538/dexter/aux/InvokeTaintStore$ThreadLocalPrimitiveArguments$$1;
287: invoke-virtual Ljava/lang/ThreadLocal;->get()Ljava/lang/Object; {a41}()
288: move-result-obj a41
289: check-cast a41, [I
290: sget-object a42, Luk/ac/cam/db538/dexter/aux/InvokeTaintStore$$1;->ARGS_REF:Luk/ac/cam/db538/dexter/aux/InvokeTaintStore$ThreadLocalReferenceArguments$$1;
291: invoke-virtual Ljava/lang/ThreadLocal;->get()Ljava/lang/Object; {a42}()
292: move-result-obj a42
293: check-cast a42, [Luk/ac/cam/db538/dexter/aux/struct/Taint$$1;
294: const a43, #0
295: aput-object t8, {a42}[a43]
296: const a43, #1
297: aput-object t0, {a42}[a43]
298: invoke-static Lcom/google/api/client/util/Preconditions;->checkNotNull(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object; (v8, v0)
299: move-result-obj v0
300: sget-object t0, Luk/ac/cam/db538/dexter/aux/InvokeTaintStore$$1;->RES_REF:Luk/ac/cam/db538/dexter/aux/InvokeTaintStore$ThreadLocalReferenceResult$$1;
301: invoke-virtual Ljava/lang/ThreadLocal;->get()Ljava/lang/Object; {t0}()
302: move-result-obj t0
303: check-cast t0, Luk/ac/cam/db538/dexter/aux/struct/Taint$$1;
304: 
305: TRYSTART8
306: check-cast v0, Ljava/lang/String;
307: TRYEND8
308: goto L22
309: CATCHALL8
310: move-exception a47
311: const a45, #0
312: invoke-static Luk/ac/cam/db538/dexter/aux/struct/TaintInternal$$1;->clearVisited()V ()
313: invoke-interface Luk/ac/cam/db538/dexter/aux/struct/Taint$$1;->get()I {t0}()
314: move-result a46
315: or-int a45, a45, a46
316: invoke-static Luk/ac/cam/db538/dexter/aux/struct/Assigner$$1;->lookupUndecidable(Ljava/lang/Object;I)Luk/ac/cam/db538/dexter/aux/struct/Taint$$1; (a47, a45)
317: move-result-obj a48
318: throw a47
319: L22
320: if-eqz v0, L20
321: check-cast t0, Luk/ac/cam/db538/dexter/aux/struct/TaintExternal$$1;
322: goto L21
323: L20
324: invoke-interface Luk/ac/cam/db538/dexter/aux/struct/Taint$$1;->get()I {t0}()
325: move-result a44
326: invoke-static Luk/ac/cam/db538/dexter/aux/struct/Assigner$$1;->newExternal(Ljava/lang/Object;I)Luk/ac/cam/db538/dexter/aux/struct/TaintExternal$$1; (v0, a44)
327: move-result-obj t0
328: L21
329: 
330: TRYSTART9
331: iput-object v0, {v6}Lcom/google/api/services/notes/Notes$Changes$Insertmedia;->nodeId:Ljava/lang/String;
332: TRYEND9
333: goto L23
334: CATCHALL9
335: move-exception a51
336: const a49, #0
337: invoke-interface Luk/ac/cam/db538/dexter/aux/struct/Taint$$1;->get()I {t0}()
338: move-result a50
339: or-int a49, a49, a50
340: invoke-static Luk/ac/cam/db538/dexter/aux/struct/TaintInternal$$1;->clearVisited()V ()
341: invoke-interface Luk/ac/cam/db538/dexter/aux/struct/Taint$$1;->get()I {t6}()
342: move-result a50
343: or-int a49, a49, a50
344: invoke-static Luk/ac/cam/db538/dexter/aux/struct/Assigner$$1;->lookupUndecidable(Ljava/lang/Object;I)Luk/ac/cam/db538/dexter/aux/struct/Taint$$1; (a51, a49)
345: move-result-obj a52
346: throw a51
347: L23
348: iput-object t0, {v6}Lcom/google/api/services/notes/Notes$Changes$Insertmedia;->t_nodeId:Luk/ac/cam/db538/dexter/aux/struct/TaintExternal$$1;
349: 
350: sget-object a53, Luk/ac/cam/db538/dexter/aux/InvokeTaintStore$$1;->ARGS_PRIM:Luk/ac/cam/db538/dexter/aux/InvokeTaintStore$ThreadLocalPrimitiveArguments$$1;
351: invoke-virtual Ljava/lang/ThreadLocal;->get()Ljava/lang/Object; {a53}()
352: move-result-obj a53
353: check-cast a53, [I
354: sget-object a54, Luk/ac/cam/db538/dexter/aux/InvokeTaintStore$$1;->ARGS_REF:Luk/ac/cam/db538/dexter/aux/InvokeTaintStore$ThreadLocalReferenceArguments$$1;
355: invoke-virtual Ljava/lang/ThreadLocal;->get()Ljava/lang/Object; {a54}()
356: move-result-obj a54
357: check-cast a54, [Luk/ac/cam/db538/dexter/aux/struct/Taint$$1;
358: const a55, #0
359: aput-object t6, {a54}[a55]
360: const a55, #1
361: aput-object t10, {a54}[a55]
362: invoke-virtual Lcom/google/api/services/notes/Notes$Changes$Insertmedia;->initializeMediaUpload(Lcom/google/api/client/http/AbstractInputStreamContent;)V {v6}(v10)
363: 
364: return-void

Exception:

Exception in thread "main" java.lang.Error: java.lang.AssertionError: Cannot find definer for t6 inside basic block 341-341

Reason:
Fails because the IPUT on line 331 is (correctly) identified as being after the call to the superclass constructor on line 270. But that operates on a copy of the THIS reference in v0, rather than v6 (p0) used by the IPUT instruction. The newly generated TaintInternal object is therefore stored in t0 but not t6.

Note 1: Test should make sure that both the original and one other copy of the reference receive the Taint object.
Note 2: Modify TypeSolver to generate an equivalence class and do operations like areEquivalent on that.

JarSigner crashes on Android

I hope this can be solved somehow :-/

07-22 11:45:14.307  15902-15931/uk.ac.cam.db538.dexter.android E/AndroidRuntime: FATAL EXCEPTION: Thread-820
        java.lang.InternalError: Could not obtain X500Principal access
        at sun.security.x509.X500Name.<clinit>(X500Name.java:1403)
        at com.rx201.jarsigner.KeyGenerator.generateSigningKey(KeyGenerator.java:65)
        at com.rx201.jarsigner.KeyGenerator.getCertificateChain(KeyGenerator.java:36)
        at uk.ac.cam.db538.dexter.apk.Apk.produceAPK(Apk.java:108)
        at uk.ac.cam.db538.dexter.android.InstrumentActivity$2.run(InstrumentActivity.java:173)
        at java.lang.Thread.run(Thread.java:856)
        Caused by: java.security.PrivilegedActionException: java.lang.NoSuchMethodException: <init> [class sun.security.x509.X500Name]
        at java.security.AccessController.doPrivileged(AccessController.java:64)
        at sun.security.x509.X500Name.<clinit>(X500Name.java:1399)
        ... 5 more
        Caused by: java.lang.NoSuchMethodException: <init> [class sun.security.x509.X500Name]
        at java.lang.Class.getConstructorOrMethod(Class.java:460)
        at java.lang.Class.getDeclaredConstructor(Class.java:588)
        at sun.security.x509.X500Name$1.run(X500Name.java:1391)
        at sun.security.x509.X500Name$1.run(X500Name.java:1)
        at java.security.AccessController.doPrivileged(AccessController.java:60)
        ... 6 more

MONITOR_EXIT instruction has slightly unusual throwing semantics

Description of MONITOR_EXIT:

Release the monitor for the indicated object.
Note: If this instruction needs to throw an exception, it must do so as if the pc has already advanced past the instruction. It may be useful to think of this as the instruction successfully executing (in a sense), and the exception getting thrown after the instruction but before the next one gets a chance to run. This definition makes it possible for a method to use a monitor cleanup catch-all (e.g., finally) block as the monitor cleanup for that block itself, as a way to handle the arbitrary exceptions that might get thrown due to the historical implementation of Thread.stop(), while still managing to have proper monitor hygiene.

(from http://www.netmite.com/android/mydroid/dalvik/docs/dalvik-bytecode.html)

How does FILL_ARRAY_DATA work? Is this a relevant piece of code?

There seems to be very little documentation about the actual semantics of instructions. I'm currently looking at the FILL_ARRAY_DATA instruction which stores constants into primitive arrays. However, I'm having trouble figuring out what happens when there are more elements provided to the instruction than what is the length of the array.

I've managed to run a short piece of code that does this and it (unsurprisingly) throws an ArrayBounds exception. The question is whether the data in the lower indexes were overwritten (i.e. it works like a loop; seems more likely) or not (i.e. all-or-nothing semantics), which affects the choice of instrumentation. I've written the following piece of code to decide which it is:

    # create array
    const/4 v0, 3
    new-array v0, v0, [I

    # store (potentially tainted) argument in it
    const/4 v1, 0
    aput p1, v0, v1

    # now overwrite with the constant data
    :try_start
    fill-array-data v0, :array_data
    :try_end
    .catchall {:try_start .. :try_end} :handler

    # retrieve and return
    aget v0, v0, v1
    return v0

    :handler

    # print the content of the array
    const/4 v1, 0
    aget v0, v0, v1
    invoke-static {v0}, Ljava/lang/Integer;->toString(I)Ljava/lang/String;
    move-result v1
    invoke-static {v1, v1}, Landroid/util/Log;->d(Ljava/lang/String;Ljava/lang/String;)I

    return v0


    :array_data
    .array-data 0x4
        0x00t 0x11t 0x22t 0x33t
        0xfft 0xeet 0xddt 0xcct
        0xfft 0xeet 0xddt 0xcct
        0xfft 0xeet 0xddt 0xcct
    .end array-data

It has an array of length three, stores a tainted integer inside and then calls FILL_ARRAY_DATA with four elements which throws an exception. When that happens, the previously tainted element is retrieved and printed in the Log, which should show whether the value has changed or not.

However, pushing this through Dexter fails with this error:

CODE DUMP:
0: const v0, #3
1: new-array v0, [v0], [I
2: const v1, #0
3: aput-int-float v3, {v0}[v1]
4: TRYSTART1
5: fill-array-data v0, <data>
6: TRYEND1
7: aget-int-float v0, {v0}[v1]
8: return v0
9: CATCHALL1
10: const v1, #0
11: aget-int-float v0, {v0}[v1]
12: invoke-static Ljava/lang/Integer;->toString(I)Ljava/lang/String; (v0)
13: move-result v1
14: invoke-static Landroid/util/Log;->d(Ljava/lang/String;Ljava/lang/String;)I (v1, v1)
15: return v0
Exception in thread "main" java.lang.Error: java.lang.AssertionError: Cannot find definer for v0 inside basic block 9-11
    at com.rx201.dx.translator.DexCodeAnalyzer.analyze(DexCodeAnalyzer.java:100)
    at uk.ac.cam.db538.dexter.transform.taint.TaintTransform.doFirst(TaintTransform.java:140)
    at uk.ac.cam.db538.dexter.transform.Transform.apply(Transform.java:77)
    at uk.ac.cam.db538.dexter.transform.Transform.apply(Transform.java:53)
    at uk.ac.cam.db538.dexter.MainConsole.main(MainConsole.java:65)
Caused by: java.lang.AssertionError: Cannot find definer for v0 inside basic block 9-11
    at com.rx201.dx.translator.DexCodeAnalyzer.livenessAnalysis(DexCodeAnalyzer.java:133)
    at com.rx201.dx.translator.DexCodeAnalyzer.analyze(DexCodeAnalyzer.java:87)
    ... 4 more

which seems to be related to issue #13, though I am not sure whether this is a relevant piece of code or not, as it uses registers defined before an exception was caught. I've been trying to run this directly using dalvikvm command on the device, but I seem to have trouble running anything at all...

Taint object still created too late

This is an issue related to #9 that keeps us from executing Google Keep. Since the code comes from the Android Support library (intermediate layer that allows apps for Android 3+ to run on older devices), we should pay attention to it.

Scenerio is as follows: Class A is external and defines method foo which is called from its constructor. B is internal, extends A and overrides foo. B's instrumented constructor calls super() and then creates rhe corresponding Taint object. The order is given by the fact that the this reference (necessary to cache the Taint object) is "undefined" before the parent's constructor is called. Problem arises when foo is called from inside the parent's constructor (this is not undefined any more) but no Taint object can be found for it in the global cache when the method is entered.

Any ideas? I thought about the bug I found in Dalvik - by casting the this argument at the beginning of the constructor, it loses the "undefined" flag (and could therefore be used to create and cache the Taint object), but then the parent's constructor cannot be called on it any more (fails verification), so that won't work.

Handling null

Currently there is no way of handling null reference... deal with it...

APUT_OBJECT changed to APUT

The Test_ArrayPut_NULL class contains the following method:

.method public execute(Ljava/lang/Object;)V
    .registers 3

    check-cast p1, [Ljava/lang/Object;

    const/4 v0, 0x0
    const/4 v1, 0x0
    aput-object v0, p1, v1

    return-void

.end method

Recompilation (with instrumentation), however, changes the array instruction to simple 'aput', which makes the class fail verification... Instrumentation doesn't change the instruction at all - simply wraps it with TRY/CATCH and adds one more instruction after, so it must be the compiler thinking that v0 is an integer. CodeAnalyzer correctly analyzes the code before instrumentation, as the const/4 v0, 0x0 instruction is correctly instrumented as NULL.

Test APK:
https://www.dropbox.com/s/jpj37evl1nigos1/Dexter_Issue20.apk

CONST_STRING generates mutable Taint object

56: const-string v2, "POST"
57: new-instance t2, Luk/ac/cam/db538/dexter/aux/struct/TaintExternal$$1;
58: invoke-direct Luk/ac/cam/db538/dexter/aux/struct/TaintExternal$$1;-><init>()V {t2}()

Taint object conversions during external calls

Oh boy... You might remember me saying that there's still a runtime exception coming from the instrumentation when running Kakao. I've now had a closer look at it and it's a rather nasty problem.

The problematic code does something like this:

ArrayList<Foo> list = getListOfStuff();
Foo[] array = new Foo[list.size()];
list.toArray(array);
array[0].bar();

So what happens is that the instrumentation creates a new TaintArrayReference instance for array, which is initialized with taint objects for the elements of array, i.e. TaintImmutable objects for all the NULLs. Before toArray is called (external method), taint is propagated into the arguments, but the array won't accept any and, more importantly, won't convert the taint objects of the elements to the correct type. When bar is called (internal method), this is used with a TaintImmutable object even though it should be a TaintInternal object, and that throws an exception....

External static field taint not initialized

Data can be retrieved from external public static fields like android.os.Environment.DIRECTORY_DCIM. Their taint is stored in an auxiliary class but is uninitialized.

Possible solutions:

  • initialize it to Taint_External with empty taint
  • only create taint fields for primitives and look taint objects up for references

Taint interface method are too coarse

The Taint interface currently supports only two methods - get() and set(int taint). These are used to combine the taint of all values reachable through the corresponding object reference, for example during external method calls. However, there are situations when using these methods would be too conservative. An example could be this:

// Point is an external class in Android, two int fields X, Y
class MyPoint extends Point { 
  public int z;
}

void fn() {
  Point p = new MyPoint(); // create TaintInternal
  p.x = sensitiveInteger(); // calls Taint.set
  p.y = normalInteger();
  int y = p.y; // calls Taint.get, taints Y
  int z = ((MyPoint) p).z; // retrieves t_z that contains the taint
}

The expected behaviour of the example is that it taints the whole Point object, i.e. both X and Y will become tainted. This is the case, because TaintInternal stores TaintExternal for the external part of itself and taints it in Taint.set. However, it taints Z as well, which is not necessary.

By adding extra methods getExternal and setExternal to the Taint interface, this could be avoided.

Compiler constraint issue

Rubin, could you tell me what's wrong with this code?

0: new-instance a15, Ljava/lang/Throwable;
1: invoke-direct Ljava/lang/Throwable;-><init>()V {a15}()
2: invoke-virtual Ljava/lang/Throwable;->getStackTrace()[Ljava/lang/StackTraceElement; {a15}()
3: move-result-obj a16
4: const a17, #1
5: array-length a18, {a16}
6: if-le a18, a17, L4
7: aget-object a19, {a16}[a17]
8: invoke-virtual Ljava/lang/StackTraceElement;->getClassName()Ljava/lang/String; {a19}()
9: move-result-obj a14
10: goto L5
11: L4
12: const a14, #0
13: L5
14: if-eqz a14, L2
15: invoke-static Ljava/lang/Class;->forName(Ljava/lang/String;)Ljava/lang/Class; (a14)
16: move-result-obj a20
17: const-class a21, Luk/ac/cam/db538/dexter/aux/anno/InternalClass$$1;
18: invoke-virtual Ljava/lang/Class;->getAnnotation(Ljava/lang/Class;)Ljava/lang/annotation/Annotation; {a20}(a21)
19: move-result-obj a13
20: if-eqz a13, L2
21: sget-object a22, Luk/ac/cam/db538/dexter/aux/InvokeTaintStore$$1;->ARGS_PRIM:Luk/ac/cam/db538/dexter/aux/InvokeTaintStore$ThreadLocalPrimitiveArguments$$1;
22: invoke-virtual Ljava/lang/ThreadLocal;->get()Ljava/lang/Object; {a22}()
23: move-result-obj a22
24: check-cast a22, [I
25: sget-object a23, Luk/ac/cam/db538/dexter/aux/InvokeTaintStore$$1;->ARGS_REF:Luk/ac/cam/db538/dexter/aux/InvokeTaintStore$ThreadLocalReferenceArguments$$1;
26: invoke-virtual Ljava/lang/ThreadLocal;->get()Ljava/lang/Object; {a23}()
27: move-result-obj a23
28: check-cast a23, [Luk/ac/cam/db538/dexter/aux/struct/Taint$$1;
29: const a24, #0
30: const a25, #0
31: aget-object t2, {a23}[a25]
32: check-cast t2, Luk/ac/cam/db538/dexter/aux/struct/TaintInternal$$1;
33: const a25, #1
34: aget-int-float t3, {a22}[a25]
35: goto L3
36: L2
37: const a28, #0
38: const a29, #0
39: invoke-static Luk/ac/cam/db538/dexter/aux/struct/Assigner$$1;->lookupInternal(Ljava/lang/Object;I)Luk/ac/cam/db538/dexter/aux/struct/TaintInternal$$1; (v2, a28)
40: move-result-obj t2
41: const a29, #1
42: move t3, a28
43: L3
44: 
45: const t0, #0
46: const v0, #3
47: 
48: move a0, v0
49: new-array v0, [v0], [I
50: invoke-static Luk/ac/cam/db538/dexter/aux/struct/Assigner$$1;->newArrayPrimitive(Ljava/lang/Object;II)Luk/ac/cam/db538/dexter/aux/struct/TaintArrayPrimitive$$1; (v0, a0, t0)
51: move-result-obj t0
52: 
53: const t1, #0
54: const v1, #0
55: 
56: TRYSTART0
57: iget-object a1, {t0}Luk/ac/cam/db538/dexter/aux/struct/TaintArrayPrimitive$$1;->t_array:[I
58: aput-int-float t3, {a1}[v1]
59: aput-int-float v3, {v0}[v1]
60: TRYEND0
61: goto L0
62: CATCHALL0
63: move-exception a4
64: const a2, #0
65: invoke-interface Luk/ac/cam/db538/dexter/aux/struct/Taint$$1;->get()I {t0}()
66: move-result a3
67: or-int a2, a2, a3
68: or-int a2, a2, t3
69: or-int a2, a2, t1
70: invoke-static Luk/ac/cam/db538/dexter/aux/struct/Assigner$$1;->lookupExternal(Ljava/lang/Object;I)Luk/ac/cam/db538/dexter/aux/struct/TaintExternal$$1; (a4, a2)
71: move-result-obj a5
72: throw a4
73: L0
74: 
75: fill-array-data v0, <data>
76: 
77: TRYSTART1
78: aget-int-float v0, {v0}[v1]
79: iget-object t0, {t0}Luk/ac/cam/db538/dexter/aux/struct/TaintArrayPrimitive$$1;->t_array:[I
80: aget-int-float t0, {t0}[v1]
81: TRYEND1
82: goto L1
83: CATCHALL1
84: move-exception a9
85: const a7, #0
86: invoke-interface Luk/ac/cam/db538/dexter/aux/struct/Taint$$1;->get()I {t0}()
87: move-result a8
88: or-int a7, a7, a8
89: or-int a7, a7, t1
90: invoke-static Luk/ac/cam/db538/dexter/aux/struct/Assigner$$1;->lookupExternal(Ljava/lang/Object;I)Luk/ac/cam/db538/dexter/aux/struct/TaintExternal$$1; (a9, a7)
91: move-result-obj a10
92: throw a9
93: L1
94: 
95: invoke-static Ljava/lang/Integer;->valueOf(I)Ljava/lang/Integer; (t0)
96: move-result-obj a11
97: sget-object a12, Luk/ac/cam/db538/dexter/aux/InvokeTaintStore$$1;->RES_PRIM:Luk/ac/cam/db538/dexter/aux/InvokeTaintStore$ThreadLocalPrimitiveResult$$1;
98: invoke-virtual Ljava/lang/ThreadLocal;->set(Ljava/lang/Object;)V {a12}(a11)
99: return v0

It fails with:

Caused by: java.lang.AssertionError
    at com.rx201.dx.translator.TypeSolver.addConstraint(TypeSolver.java:91)
    at com.rx201.dx.translator.TypeSolver.propagate(TypeSolver.java:110)
    at com.rx201.dx.translator.TypeSolver.addConstraint(TypeSolver.java:97)
    at com.rx201.dx.translator.AnalyzedDexInstruction.initDefinitionConstraints(AnalyzedDexInstruction.java:184)
    at com.rx201.dx.translator.DexCodeAnalyzer.typeConstraintAnalysis(DexCodeAnalyzer.java:191)
    at com.rx201.dx.translator.DexCodeAnalyzer.analyze(DexCodeAnalyzer.java:92)
    ... 5 more

which is the "is not polymorphic" assertion:

        if (freeze) {
            assert !constraint.isPolymorphic();
            info.freezed = true;
            newType = constraint;
        }

Control flow graph building failure

Unit test of exception.apk:

java.util.NoSuchElementException: Element of InstructionList not found
at uk.ac.cam.db538.dexter.dex.code.InstructionList.getIndex(InstructionList.java:122)
at uk.ac.cam.db538.dexter.dex.code.InstructionList.isBetween(InstructionList.java:133)
at uk.ac.cam.db538.dexter.dex.code.insn.DexInstruction.getSurroundingTryBlock(DexInstruction.java:105)
at uk.ac.cam.db538.dexter.dex.code.insn.DexInstruction.cfgGetExceptionSuccessors(DexInstruction.java:95)
at uk.ac.cam.db538.dexter.dex.code.insn.DexInstruction.cfgGetSuccessors(DexInstruction.java:66)
at uk.ac.cam.db538.dexter.analysis.cfg.ControlFlowGraph.generateCFG(ControlFlowGraph.java:86)
at uk.ac.cam.db538.dexter.analysis.cfg.ControlFlowGraph.(ControlFlowGraph.java:28)
at com.rx201.dx.translator.DexCodeAnalyzer.buildInstructionList(DexCodeAnalyzer.java:205)
at com.rx201.dx.translator.DexCodeAnalyzer.(DexCodeAnalyzer.java:55)
at com.rx201.dx.translator.DexCodeGeneration.(DexCodeGeneration.java:92)
at uk.ac.cam.db538.dexter.dex.method.DexMethod.writeToFile(DexMethod.java:107)
at uk.ac.cam.db538.dexter.dex.DexClass.writeToFile(DexClass.java:220)
at uk.ac.cam.db538.dexter.dex.Dex.writeToFile(Dex.java:131)
at com.rx201.dx.translator.test.TranslationTest.test(TranslationTest.java:95)

Register colouring still producing invalid code

Original code: http://pastebin.com/5Emb4Fci
Instrumented code: http://pastebin.com/x1u1cGYs
Compiled code: http://pastebin.com/kNbd2Zct
APK: same as issue #22

The problem is at the very beginning of the method. The call to Intent.getComponent returns a result which is immediately used as an argument of ComponentName.getClassName. Instrumentation seems to lack non-throwing semantics for taint assignment of the result, which I'll fix later today, but it should not pose a problem in this particular case. The problem is that in the compiled code, the register (v3) is overwritten between the MOVE_RESULT and INVOKE (line 89), properly resuling in a verification error.

AssertionError in dexlib

Quite a few unit tests (009-instanceof2.apk) throw assertion errors:
java.lang.AssertionError
at org.jf.dexlib.ClassDefItem.internClassDefItem(ClassDefItem.java:118)
at uk.ac.cam.db538.dexter.dex.DexClass.writeToFile(DexClass.java:230)

Type inference could be more precise for exceptions

DexCodeAnalyzer does not infer that a thrown/caught object must be a Throwable, or even further analyze the potential throwing sites to narrow down the type of the register.

    :try_start
        div-int/lit16 v0, p1, 0x0
        return v0
    :try_end
    .catch Ljava/lang/ArithmeticException; {:try_start .. :try_end} :handler

    :handler
    move-exception v0
    invoke-virtual {v0}, Ljava/lang/Object;->hashCode()I
    move-result v0
    return v0

In the example above, the inferred type of v0 after :handler is Object, even though it clearly must be an instance of ArithmeticException.

InstanceGet parsing

008-instanceof.apk failed on:
java.lang.NullPointerException
at uk.ac.cam.db538.dexter.dex.code.insn.DexInstruction_InstanceGet.(DexInstruction_InstanceGet.java:38)
at uk.ac.cam.db538.dexter.dex.code.insn.DexInstruction_InstanceGet.parse(DexInstruction_InstanceGet.java:71)

When running the collection of unit tests. However it parses fine in a single standalone run, which makes me wonder if the app hierarchy building is acting weird.

022-interface fails to run

Two problems are exposed by this unit test. You can see them by diff between the disassembled dex file and original.

  1. The static field mWahoo is incorrectly set by the static initialiser.
    .field public static final mFloaty:F = 5.0f
    <.field public static final mWahoo:Ljava/lang/String;

    .field public static final mWahoo:Ljava/lang/String; = 5.0f

  2. Interface LIface2Sub1 is missing base interface Iface2, Cloneable.

Optimizer sometimes collapses simultaneously live registers

Hi, I know you've already identified this issue, but want to give you more testing data. The Kakao messenger now successfully compiles (!!!), though only with 2GB heap, but then fails on the verifier due to a typing issue.

The problematic method is the <clinit> of class Lcom/kakao/talk/application/GlobalApplication;. The instrumented code begins with initialization of the static taint fields:

0: const a19, #0
1: const a18, #0
2: invoke-static Luk/ac/cam/db538/dexter/aux/struct/Assigner$$1;->newExternal_NULL(I)Luk/ac/cam/db538/dexter/aux/struct/TaintExternal$$1; (a19)
3: move-result-obj a17
4: sput-object a17, Lcom/kakao/talk/application/GlobalApplication;->t_kly:Luk/ac/cam/db538/dexter/aux/struct/Taint$$1;
5: invoke-static Luk/ac/cam/db538/dexter/aux/struct/Assigner$$1;->newExternal_NULL(I)Luk/ac/cam/db538/dexter/aux/struct/TaintExternal$$1; (a19)
6: move-result-obj a17
7: sput-object a17, Lcom/kakao/talk/application/GlobalApplication;->t_jnc:Luk/ac/cam/db538/dexter/aux/struct/Taint$$1;
8: invoke-static Luk/ac/cam/db538/dexter/aux/struct/Assigner$$1;->newExternal_NULL(I)Luk/ac/cam/db538/dexter/aux/struct/TaintExternal$$1; (a19)
9: move-result-obj a17
10: sput-object a17, Lcom/kakao/talk/application/GlobalApplication;->t_gga:Luk/ac/cam/db538/dexter/aux/struct/Taint$$1;

You might notice that a18 is not used and therefore line 1 is dead. It would be used as NULL if some of the taint fields corresponded to a field of array type. (I might actually simplify this, but it is nonetheless a valid piece of code). The full method body is at http://pastebin.com/JtVYgh47

After compilation (and presumably due to the optimizer), this snippet becomes:

const/4 v0, 0x0
const/4 v0, 0x0

invoke-static {v0}, Luk/ac/cam/db538/dexter/aux/struct/Assigner$$1;->newExternal_NULL(I)Luk/ac/cam/db538/dexter/aux/struct/TaintExternal$$1;
move-result-object v0
sput-object v0, Lcom/kakao/talk/application/GlobalApplication;->t_jnc:Luk/ac/cam/db538/dexter/aux/struct/Taint$$1;

invoke-static {v0}, Luk/ac/cam/db538/dexter/aux/struct/Assigner$$1;->newExternal_NULL(I)Luk/ac/cam/db538/dexter/aux/struct/TaintExternal$$1;
move-result-object v0
sput-object v0, Lcom/kakao/talk/application/GlobalApplication;->t_gga:Luk/ac/cam/db538/dexter/aux/struct/Taint$$1;

invoke-static {v0}, Luk/ac/cam/db538/dexter/aux/struct/Assigner$$1;->newExternal_NULL(I)Luk/ac/cam/db538/dexter/aux/struct/TaintExternal$$1;
move-result-object v0
sput-object v0, Lcom/kakao/talk/application/GlobalApplication;->t_kly:Luk/ac/cam/db538/dexter/aux/struct/Taint$$1;

The problem is obvious: a17 and a19 were allocated into the same register r0, and therefore the second INVOKE will fail, because it tries to use a TaintExternal object as an int. It is, however, interesting that the second CONST is not identified as dead. Depending on when dead code removal happens, one of the CONSTs should have been removed. Full code again available at: http://pastebin.com/LNKb5Lxg

The original APK is at: https://www.dropbox.com/s/pjqhkrqmma0p66e/Dexter_Issue22.apk

InternalDataStructure handles inheritance wrong

The current implementation of getTaint and setTaint methods of the InternalDataStructure interface is incorrect, because it misbehaves when inheritance is involved.

Currently, the TaintInternal class holds the taint of the super class, regardless of it being external or internal, and therefore by calling .get() on an internal one will result in another call to InternalDataStructure.getTaint on the same object rather than the parent, due to the nature of dynamic dispatch.

It is therefore necessary to implement it through super.getTaint inside getTaint itself, and therefore distinguish the implementation of getTaint in classes with external/internal parents, just like was suggested in the original wiki entry.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.