[Soot-list] Basic question

Henddher Pedroza hpedro2 at uic.edu
Mon Oct 15 10:52:02 EDT 2012


Here is the sample testcode that now works.

=================================

package edu.uic.cs.hpedro2;

import java.io.File;
import java.util.Arrays;

import junit.framework.TestCase;
import soot.FastHierarchy;
import soot.G;
import soot.Scene;
import soot.SootClass;
import soot.SootMethod;
import soot.options.Options;
import soot.util.Chain;

public class SootConfigTest extends TestCase {

     public void testSootConfig() {

         G.v().reset();

         String androidJarPath = "ANDROID_SDK_PATH/android.jar"; // 
update path accordingly
         String theAppPath = "ZXING_2.0_PATH/zxing.jar"; // // update 
path accordingly

         String sootclasspath = androidJarPath + File.pathSeparatorChar 
+ theAppPath;

         Options.v().set_soot_classpath(sootclasspath);
         Options.v().set_process_dir(Arrays.asList(theAppPath));

         // load classes
         try {
             Scene.v().loadNecessaryClasses();
         }
         catch (Exception e) {
             e.printStackTrace();
             fail("Failed to load necessary classes");
         }

         // load superclasses wanted
         String[] superClassNames = {
             "android.app.Activity",
             "android.database.sqlite.SQLiteOpenHelper",
         };
         SootClass[] superclasses = new SootClass[superClassNames.length];
         try {
             int i = 0;
             for (String cn : superClassNames) {
                 superclasses[i] = Scene.v().getSootClass(cn);
                 assert null != superclasses[i];
                 i++;
             }
         }
         catch (Exception e) {
             e.printStackTrace();
             fail("Failed to retrieve superclasses");
         }

         // load method Log.e(String, String)
         try {
             SootMethod logeMethod = 
Scene.v().getMethod("<android.util.Log: int 
e(java.lang.String,java.lang.String)>");
             assert null != logeMethod;
         }
         catch (Exception e) {
             e.printStackTrace();
             fail("Failed retrieving Log.e");
         }

         // Retrieve the class hierarchy
         FastHierarchy fastHierarchy = null;
         try {
             fastHierarchy = Scene.v().getOrMakeFastHierarchy();
             assert null != fastHierarchy;
         }
         catch (Exception e) {
             e.printStackTrace();
             fail("Failed to retrieve fast hierarchy");
         }

         // process all application classes
         Chain<SootClass> applicationClasses = null;
         try {
             applicationClasses = Scene.v().getApplicationClasses();
             assert null != applicationClasses && 
!applicationClasses.isEmpty();
             System.out.printf("%d application classes\n", 
applicationClasses.size());
         }
         catch (Exception e) {
             e.printStackTrace();
             fail("Failed to retrieve application classes");
         }
         for (SootClass ac : applicationClasses) {
             assert ac.getPackageName().startsWith("com.google.zxing");
             if (ac.isInterface()) {
                 continue; // skip interfaces since they can't be used 
as parent in fastHierarchy.isSubclass
             }
             for (SootClass spc : superclasses) {
                 try {
                     if (fastHierarchy.isSubclass(ac, spc)) {
                         System.out.println(ac + " -> " + spc);
                     }
                 }
                 catch (Exception e) {
                     e.printStackTrace();
                     fail("Failed to check class hierarchy of " + ac + " 
vs. " + spc);
                 }
             }
         }
     }
}

On 10/15/2012 09:48 AM, Henddher Pedroza wrote:
> Hello Eric.
>
> I figured out what was the issue:
> FastHierarchy.isSubclass throws exception when parent is an interface.
>
> In my configuration, I check hierarchy of all classes in 
> myandroidapp.jar. I just added a check in my code to avoid checking 
> hierarchy of application-classes that are interfaces - which is 
> explicitly noted in the javadocs.
>
> Originally, I was using getSubclassesOf() but it didn't resolve cases 
> like this:
> A <-  B <- C (A is superclass of B; B is superclass of C)
> fastHierarchy.getSubclassesOf(A); // returned only B but not C.
> (which I am still curious about)
> Hence, I switched to isSubclassOf but failed to realize the interface 
> limitation listed in javadoc.
>
> Once again, thanks a lot.
>
> - Henddher
>
> On 10/14/2012 11:17 PM, Eric Bodden wrote:
>> Ok, can you wrap this up for me into a test case and email it to me? I
>> will take a look as soon as I get the chance. Please include all the
>> command line options you use.
>>
>> Eric
>>
>>
>> On 15 October 2012 01:05, Henddher Pedroza <hpedro2 at uic.edu> wrote:
>>> Hello Eric
>>>
>>> The example I cited used addBasicClass(). And yes, I thought of 
>>> applying
>>> brute force and adding each class in "android.jar" to the list of soot
>>> classes before calling loadNecessaryClasses().
>>>
>>> But it turned out that this "brute force" approach is equivalent to 
>>> setting
>>> soot-classpath containing "android.jar" and "myandroidapp.jar".
>>>
>>> Here is my resulting configuration:
>>>
>>> Options.v().set_soot_classpath("android.jar:myandroidapp.jar");
>>> Options.v().set_process_dir(Arrays.asList("myandroidapp.jar"));
>>>          Scene.v().loadNecessaryClasses();
>>>
>>> And, unfortunately, it exposes the FastHierarchy.isSubclass() issue 
>>> I first
>>> reported. So I guess we can now rule out soot-classpath being 
>>> incorrect.
>>>
>>> So I am back to square one.
>>>
>>> java.lang.NullPointerException
>>>      at soot.FastHierarchy$Interval.isSubrange(FastHierarchy.java:83)
>>>      at soot.FastHierarchy.isSubclass(FastHierarchy.java:151)
>>>      at 
>>> edu.uic.cs.hpedro2.MiscTest.test_sootclasspath2(MiscTest.java:202)
>>>      at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
>>>      at
>>> sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57) 
>>>
>>>      at
>>> sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) 
>>>
>>>      at java.lang.reflect.Method.invoke(Method.java:601)
>>>      at junit.framework.TestCase.runTest(TestCase.java:154)
>>>      at junit.framework.TestCase.runBare(TestCase.java:127)
>>>
>>> (I'll reply to my 1st post to stay in topic)
>>>
>>>
>>> On 10/14/2012 03:59 PM, Eric Bodden wrote:
>>>> Hello.
>>>>
>>>>> Yesterday, I tried this successfully though it would be tedious to
>>>>> specify
>>>>> all classes found in the android.jar (and extensions).
>>>> What do you mean by "specifying all classes"? That's not the idea...
>>>>
>>>> Eric
>>>
>>
>>
>



More information about the Soot-list mailing list