<html><head><meta http-equiv="Content-Type" content="text/html; charset=utf-8"></head><body style="word-wrap: break-word; -webkit-nbsp-mode: space; line-break: after-white-space;" class="">One follow up to this:<div class=""><br class=""></div><div class="">We cloned and rebuild soot from source, but commented out this line [1] inside <span style="caret-color: rgb(0, 0, 0); color: rgb(0, 0, 0);" class="">DexBody.java, and this solved the problem.</span></div><div class=""><span style="caret-color: rgb(0, 0, 0); color: rgb(0, 0, 0);" class=""><br class=""></span></div><div class=""><span style="caret-color: rgb(0, 0, 0); color: rgb(0, 0, 0);" class="">Basically, we avoid that the LocalPacker transforms the jimple body to minimize the use of local variables.</span></div><div class=""><span style="caret-color: rgb(0, 0, 0); color: rgb(0, 0, 0);" class=""><br class=""></span></div><div class=""><span style="caret-color: rgb(0, 0, 0); color: rgb(0, 0, 0);" class="">I am not sure this is the best strategy in general, but I am also not sure how LocalPacker can be disabled without patching the code.</span></div><div class=""><span style="caret-color: rgb(0, 0, 0); color: rgb(0, 0, 0);" class=""><br class=""></span></div><div class=""><font color="#000000" class="">Maybe I should run some transformation after I inject the tracing code to ensure this local variable is not reused? Something like LocalSplitter?</font></div><div class=""><font color="#000000" class=""><br class=""></font></div><div class=""><font color="#000000" class="">Any thoughts are welcome.</font></div><div class=""><font color="#000000" class=""><br class=""></font></div><div class=""><font color="#000000" class=""><span style="caret-color: rgb(0, 0, 0);" class="">Best</span></font></div><div class=""><font color="#000000" class=""><span style="caret-color: rgb(0, 0, 0);" class=""><br class=""></span></font></div><div class=""><span style="caret-color: rgb(0, 0, 0); color: rgb(0, 0, 0);" class=""><br class=""></span></div><div class=""><font color="#000000" class=""><span style="caret-color: rgb(0, 0, 0);" class="">— Alessio</span></font></div><div class=""><br class=""></div><div class="">[1] <a href="https://github.com/soot-oss/soot/blob/59931576784b910a7d38f81910b7313aa2feafea/src/main/java/soot/dexpler/DexBody.java#L868" class="">https://github.com/soot-oss/soot/blob/59931576784b910a7d38f81910b7313aa2feafea/src/main/java/soot/dexpler/DexBody.java#L868</a><br class=""><div><br class=""><blockquote type="cite" class=""><div class="">On 23. Mar 2021, at 08:44, Alessio Gambi <<a href="mailto:alessio.gambi@uni-passau.de" class="">alessio.gambi@uni-passau.de</a>> wrote:</div><br class="Apple-interchange-newline"><div class="">
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" class=""><div style="word-wrap: break-word; -webkit-nbsp-mode: space; line-break: after-white-space;" class="">Hi Marc,<div class=""><br class=""></div><div class="">maybe you are right, but the same pattern of code works fine with other apps.</div><div class=""><br class=""></div><div class="">Best</div><div class=""><br class=""></div><div class="">— Alessio <br class=""><div class=""><br class=""><blockquote type="cite" class=""><div class="">On 22. Mar 2021, at 18:29, Marc Miltenberger <<a href="mailto:marcmiltenberger@gmail.com" class="">marcmiltenberger@gmail.com</a>> wrote:</div><br class="Apple-interchange-newline"><div class=""><div dir="ltr" class=""><div class="">Hello Dr. Gambi,</div><div class=""><br class=""></div><div class="">I see one issue in this line:<br class=""></div><div class="">$r0 := @caughtexception</div><div class=""><br class=""></div><div class="">This does not seem right since $r0 is of type com.orgzly.android.util.Encoding. This should actually be some sort of throwable.</div><div class=""><br class=""></div><div class="">Best regards,</div><div class="">Marc Miltenberger<br class=""></div><div class=""><br class=""></div><div class=""><br class=""></div></div><br class=""><div class="gmail_quote"><div dir="ltr" class="gmail_attr">Am Mo., 22. März 2021 um 18:24 Uhr schrieb Alessio Gambi <<a href="mailto:alessio.gambi@uni-passau.de" class="">alessio.gambi@uni-passau.de</a>>:<br class=""></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div style="overflow-wrap: break-word;" class="">Dear All,<div class=""><br class=""></div><div class="">I am facing a weird problem while instrumenting a Kotlin data class using soot [1].</div><div class=""><br class=""></div><div class="">The problem is that after instrumenting the class, the byte code verifier rejects the class.</div><div class=""><br class=""></div><div class="">The method causing this seems to be “copy” that contains those units:</div><div class=""><br class=""></div><div class=""><div class="">r0 := @this: com.orgzly.android.util.Encoding</div><div class="">$r1 := @parameter0: java.lang.String</div><div class="">$r2 := @parameter1: java.lang.String</div><div class="">$r3 := @parameter2: java.lang.String</div><div class="">staticinvoke <kotlin.jvm.internal.Intrinsics: void checkNotNullParameter(java.lang.Object,java.lang.String)>($r1, "used")</div><div class="">r0 = new com.orgzly.android.util.Encoding</div><div class="">specialinvoke r0.<com.orgzly.android.util.Encoding: void <init>(java.lang.String,java.lang.String,java.lang.String)>($r1, $r2, $r3)</div><div class="">return r0</div></div><div class=""><br class=""></div><div class="">The same method after the instrumentation looks like the one reported below (I simplified it), where the units marked with ** are the code injected via soot.</div><div class=""><br class=""></div><div class="">The instrumentations </div><div class=""><span style="white-space:pre-wrap" class="">    </span>- encapsulates all the parameters of method calls into generic arrays of objects</div><div class=""><span style="white-space:pre-wrap" class="">   </span>- invokes a Monitor class to track method invocations (before/after) and captures return values</div><div class=""><span style="white-space:pre-wrap" class="">    </span>- wraps the method with a generic try-catch-all where the catch block logs the captured exception before rethrowing it</div><div class=""><br class=""></div><div class="">Now the weirdness (IMHO) is that r0 is assigned first to @this and then to something different (<span style="" class="">r0 = new com.orgzly.android.util.Encoding).</span></div><div class=""><font class="">This is part of the original code (see above), but I am afraid it might break the instrumented code because we pass r0 as parameter to other invocations in the catch block,</font></div><div class=""><font class="">under the assumption it points to “this”, </font><span style="" class="">while in reality it points to another instance of the same type.</span></div><div class=""><font class="">Consequently, </font><font class="">the </font><span style="" class="">bytecode verifier reports the first call using it </span><span style="" class=""> in the catch block </span><span style="" class="">(</span><span style="" class="">staticinvoke <Monitor: void onAppMethodCaptureException</span><span style="" class="">)  as invalid (with </span><span style="" class="">type conflict)</span></div><div class=""><span style="" class=""><br class=""></span></div><div class=""><span style="" class="">Maybe someone has experiences something similar and/or can suggest a work around? Assuming this is indeed the problem, the only option I see at the moment</span></div><div class=""><span style="" class=""> is to assign the return of </span><span style="" class=""> </span><span style="" class="">r0 = new com.orgzly.android.util.Encoding to a fresh local variable (rX)</span></div><div class=""><span style="" class=""><br class=""></span></div><div class=""><span style="" class="">Any help is appreciated !</span></div><div class=""><span style="" class=""><br class=""></span></div><div class=""><span style="" class="">Best</span></div><div class=""><span style="" class=""><br class=""></span></div><div class=""><font class=""><span class="">— Dr. Alessio Gambi</span></font></div><div class=""><font class=""><span class="">Chair for SE 2</span></font></div><div class=""><font class=""><span class="">University of Passau</span></font></div><div class=""><br class=""></div><div class=""><br class=""></div><div class="">—————</div><div class=""><span style="" class="">[1] </span><a href="https://github.com/orgzly/orgzly-android/blob/master/app/src/main/java/com/orgzly/android/util/Encoding.kt" target="_blank" class="">https://github.com/orgzly/orgzly-android/blob/master/app/src/main/java/com/orgzly/android/util/Encoding.kt</a></div><div class=""><br class=""></div><div class=""><div class="">INSTRUMENTED CODE:</div><div class="">                 r0 := @this: com.orgzly.android.util.Encoding</div><div class="">                 $r1 := @parameter0: java.lang.String</div><div class="">                 $r2 := @parameter1: java.lang.String</div><div class="">                 $r3 := @parameter2: java.lang.String</div><div class="">**               $r5 = newarray (java.lang.Object)[3]</div><div class="">**               $r5[0] = $r1</div><div class="">**               $r5[1] = $r2</div><div class="">**               $r5[2] = $r3</div><div class="">**               staticinvoke <Monitor: void onAppMethodCall(java.lang.String,java.lang.Object,java.lang.String,java.lang.Object[])>("com.orgzly", r0, "<com.orgzly.android.util.Encoding: com.orgzly.android.util.Encoding copy(java.lang.String,java.lang.String,java.lang.String)>", $r5)</div><div class="">**               $r6 = newarray (java.lang.Object)[2]</div><div class="">**               $r6[0] = $r1</div><div class="">**               $r6[1] = "used"</div><div class="">**               staticinvoke <Monitor: void onLibMethodCall(java.lang.Object,java.lang.String,java.lang.String,java.lang.Object[])>(null, "<kotlin.jvm.internal.Intrinsics: void checkNotNullParameter(java.lang.Object,java.lang.String)>", "<com.orgzly.android.util.Encoding: com.orgzly.android.util.Encoding copy(java.lang.String,java.lang.String,java.lang.String)>", $r6)</div><div class="">                 staticinvoke <kotlin.jvm.internal.Intrinsics: void checkNotNullParameter(java.lang.Object,java.lang.String)>($r1, "used")</div><div class="">**               staticinvoke <Monitor: void onLibMethodReturnNormally(java.lang.Object,java.lang.String,java.lang.String,java.lang.Object)>(null, "<kotlin.jvm.internal.Intrinsics: void checkNotNullParameter(java.lang.Object,java.lang.String)>", "<com.orgzly.android.util.Encoding: com.orgzly.android.util.Encoding copy(java.lang.String,java.lang.String,java.lang.String)>", null)</div><div class=""><br class=""></div><div class="">                 r0 = new com.orgzly.android.util.Encoding</div><div class="">                 specialinvoke r0.<com.orgzly.android.util.Encoding: void <init>(java.lang.String,java.lang.String,java.lang.String)>($r1, $r2, $r3)</div><div class="">**               staticinvoke <Monitor: void onAppMethodReturnNormally(java.lang.Object,java.lang.String,java.lang.String,java.lang.Object)>(r0, "<com.orgzly.android.util.Encoding: com.orgzly.android.util.Encoding copy(java.lang.String,java.lang.String,java.lang.String)>", "<com.orgzly.android.util.Encoding: com.orgzly.android.util.Encoding copy(java.lang.String,java.lang.String,java.lang.String)>", r0)</div><div class="">                 return r0</div><div class=""><br class=""></div><div class="">**               $r0 := @caughtexception</div><div class="">**               $r7 = $r0</div><div class="">**               staticinvoke <Monitor: void onAppMethodCaptureException(java.lang.Object,java.lang.String,java.lang.String,java.lang.Object)>(r0, "<com.orgzly.android.util.Encoding: com.orgzly.android.util.Encoding copy(java.lang.String,java.lang.String,java.lang.String)>", "<com.orgzly.android.util.Encoding: com.orgzly.android.util.Encoding copy(java.lang.String,java.lang.String,java.lang.String)>", $r0)</div><div class="">**               $r4 = $r0</div><div class="">**               staticinvoke <Monitor: void onAppMethodThrowException(java.lang.Object,java.lang.String,java.lang.String,java.lang.Object)>(r0, "<com.orgzly.android.util.Encoding: com.orgzly.android.util.Encoding copy(java.lang.String,java.lang.String,java.lang.String)>", "<com.orgzly.android.util.Encoding: com.orgzly.android.util.Encoding copy(java.lang.String,java.lang.String,java.lang.String)>", $r4)</div><div class="">**               staticinvoke <Monitor: void onAppMethodReturnExceptionally(java.lang.Object,java.lang.String,java.lang.String,java.lang.Object)>(r0, "<com.orgzly.android.util.Encoding: com.orgzly.android.util.Encoding copy(java.lang.String,java.lang.String,java.lang.String)>", "<com.orgzly.android.util.Encoding: com.orgzly.android.util.Encoding copy(java.lang.String,java.lang.String,java.lang.String)>", $r4)</div><div class="">**               throw $r4</div></div><div class=""><br class=""></div><div class=""><br class=""></div></div>_______________________________________________<br class="">
Soot-list mailing list<br class="">
<a href="mailto:Soot-list@CS.McGill.CA" target="_blank" class="">Soot-list@CS.McGill.CA</a><br class="">
<a href="https://mailman.cs.mcgill.ca/mailman/listinfo/soot-list" rel="noreferrer" target="_blank" class="">https://mailman.CS.McGill.CA/mailman/listinfo/soot-list</a><br class="">
</blockquote></div>
</div></blockquote></div><br class=""></div></div>_______________________________________________<br class="">Soot-list mailing list<br class=""><a href="mailto:Soot-list@CS.McGill.CA" class="">Soot-list@CS.McGill.CA</a><br class="">https://mailman.CS.McGill.CA/mailman/listinfo/soot-list<br class=""></div></blockquote></div><br class=""></div></body></html>