32
32
import java .io .File ;
33
33
import java .io .IOException ;
34
34
import java .util .ArrayList ;
35
+ import java .util .Arrays ;
35
36
import java .util .Collections ;
36
37
import java .util .HashMap ;
37
38
import java .util .HashSet ;
53
54
import org .jf .dexlib2 .iface .TryBlock ;
54
55
import org .jf .dexlib2 .iface .debug .DebugItem ;
55
56
import org .jf .dexlib2 .iface .instruction .Instruction ;
57
+ import org .jf .dexlib2 .immutable .debug .ImmutableEndLocal ;
56
58
import org .jf .dexlib2 .immutable .debug .ImmutableLineNumber ;
59
+ import org .jf .dexlib2 .immutable .debug .ImmutableRestartLocal ;
60
+ import org .jf .dexlib2 .immutable .debug .ImmutableStartLocal ;
57
61
import org .jf .dexlib2 .util .MethodUtil ;
58
62
import org .slf4j .Logger ;
59
63
import org .slf4j .LoggerFactory ;
@@ -154,6 +158,31 @@ public class DexBody {
154
158
protected final DexEntry <? extends DexFile > dexEntry ;
155
159
protected final Method method ;
156
160
161
+ /**
162
+ * An entry of debug information for a register from the dex file.
163
+ *
164
+ * @author Zhenghao Hu
165
+ */
166
+ protected class RegDbgEntry {
167
+ public int startAddress ;
168
+ public int endAddress ;
169
+ public int register ;
170
+ public String name ;
171
+ public Type type ;
172
+ public String signature ;
173
+
174
+ public RegDbgEntry (int sa , int ea , int reg , String nam , String ty , String sig ) {
175
+ this .startAddress = sa ;
176
+ this .endAddress = ea ;
177
+ this .register = reg ;
178
+ this .name = nam ;
179
+ this .type = DexType .toSoot (ty );
180
+ this .signature = sig ;
181
+ }
182
+ }
183
+
184
+ private final Map <Integer , LinkedList <RegDbgEntry >> localDebugs ;
185
+
157
186
// detect array/instructions overlapping obfuscation
158
187
protected List <PseudoInstruction > pseudoInstructionData = new ArrayList <PseudoInstruction >();
159
188
@@ -204,6 +233,8 @@ protected DexBody(DexEntry<? extends DexFile> dexFile, Method method, RefType de
204
233
205
234
instructions = new ArrayList <DexlibAbstractInstruction >();
206
235
instructionAtAddress = new HashMap <Integer , DexlibAbstractInstruction >();
236
+ localDebugs = new HashMap <Integer , LinkedList <RegDbgEntry >>();
237
+
207
238
registerLocals = new Local [numRegisters ];
208
239
209
240
extractDexInstructions (code );
@@ -224,6 +255,43 @@ protected DexBody(DexEntry<? extends DexFile> dexFile, Method method, RefType de
224
255
continue ;
225
256
}
226
257
ins .setLineNumber (ln .getLineNumber ());
258
+ } else if (di instanceof ImmutableStartLocal
259
+ || di instanceof ImmutableRestartLocal ) {
260
+ LinkedList <RegDbgEntry > lds ;
261
+ int reg , codeAddr ;
262
+ String type , signature , name ;
263
+ if (di instanceof ImmutableStartLocal ) {
264
+ ImmutableStartLocal sl = (ImmutableStartLocal ) di ;
265
+ reg = sl .getRegister ();
266
+ codeAddr = sl .getCodeAddress ();
267
+ name = sl .getName ();
268
+ type = sl .getType ();
269
+ signature = sl .getSignature ();
270
+ } else {
271
+ ImmutableRestartLocal sl = (ImmutableRestartLocal ) di ;
272
+ reg = sl .getRegister ();
273
+ codeAddr = sl .getCodeAddress ();
274
+ name = sl .getName ();
275
+ type = sl .getType ();
276
+ signature = sl .getSignature ();
277
+ }
278
+ lds = localDebugs .get (reg );
279
+ RegDbgEntry dbgEntry = new RegDbgEntry (codeAddr , -1 /* endAddress */ , reg , name , type , signature );
280
+ if (lds == null ) {
281
+ localDebugs .put (reg ,
282
+ new LinkedList <RegDbgEntry >(Collections .singletonList (dbgEntry )));
283
+ } else {
284
+ lds .add (dbgEntry );
285
+ }
286
+ } else if (di instanceof ImmutableEndLocal ) {
287
+ ImmutableEndLocal el = (ImmutableEndLocal ) di ;
288
+ LinkedList <RegDbgEntry > lds = localDebugs .get (el .getRegister ());
289
+ if (lds == null || lds .isEmpty ()) {
290
+ // Invalid debug info
291
+ continue ;
292
+ } else {
293
+ lds .getLast ().endAddress = el .getCodeAddress ();
294
+ }
227
295
}
228
296
}
229
297
@@ -420,6 +488,10 @@ public Body jimplify(Body b, SootMethod m) {
420
488
int thisRegister = numRegisters - numParameterRegisters - 1 ;
421
489
422
490
Local thisLocal = jimple .newLocal ("$u" + thisRegister , unknownType ); // generateLocal(UnknownType.v());
491
+ //thisLocal.setType(jBody.getMethod().getDeclaringClass().getType());
492
+ if (localDebugs .containsKey (thisRegister )) {
493
+ thisLocal .setName ("this" );
494
+ }
423
495
jBody .getLocals ().add (thisLocal );
424
496
425
497
registerLocals [thisRegister ] = thisLocal ;
@@ -458,6 +530,9 @@ public Body jimplify(Body b, SootMethod m) {
458
530
}
459
531
460
532
Local gen = jimple .newLocal (localName , localType );
533
+ if (localDebugs .containsKey (parameterRegister )) {
534
+ gen .setName (localDebugs .get (parameterRegister ).getFirst ().name );
535
+ }
461
536
jBody .getLocals ().add (gen );
462
537
463
538
registerLocals [parameterRegister ] = gen ;
@@ -478,6 +553,9 @@ public Body jimplify(Body b, SootMethod m) {
478
553
// may only use UnknownType here because the local may be reused with a different
479
554
// type later (before splitting)
480
555
Local g = jimple .newLocal ("$u" + parameterRegister , unknownType );
556
+ if (localDebugs .containsKey (parameterRegister )) {
557
+ g .setName (localDebugs .get (parameterRegister ).getFirst ().name );
558
+ }
481
559
jBody .getLocals ().add (g );
482
560
registerLocals [parameterRegister ] = g ;
483
561
}
@@ -489,6 +567,9 @@ public Body jimplify(Body b, SootMethod m) {
489
567
490
568
for (int i = 0 ; i < (numRegisters - numParameterRegisters - (isStatic ? 0 : 1 )); i ++) {
491
569
registerLocals [i ] = jimple .newLocal ("$u" + i , unknownType );
570
+ if (localDebugs .containsKey (i )) {
571
+ registerLocals [i ].setName (localDebugs .get (i ).getFirst ().name );
572
+ }
492
573
jBody .getLocals ().add (registerLocals [i ]);
493
574
}
494
575
0 commit comments