[Soot-list] How transform local variables into class' s fields.

adriano cosimati agenteborghese at gmail.com
Thu Dec 30 01:33:26 EST 2010


I want to inspect the local variables of a method of a class of which I do
not have the source code.
I thought to turn the .class file into a .jimple file and then change the code,
and turn local variables into instance fields, so I can debug them.

This is the original java code of an example class:

package test;
import java.util.Vector;
public class Demo_local
{
  private Vector buffer;

   Demo_local() {
   buffer = new Vector();
   buffer.add("c");
   buffer.add("d");
   buffer.add("a");
    }
    public int getStringPos(String string) {

             for( int *counter* = 0; counter < buffer.size(); counter++)
        {
              String *curString* = (String)buffer.elementAt(counter);
            if(curString.equals(string))
            {
                buffer.remove(counter);
                return counter;
            }
        }
        return -1;
    }
}

( 'counter' and 'curString' are the variables of interest)

I compiled the code above with the javac -g:none option.


The resulting .jimple code is:


public class test.Demo_local extends java.lang.Object
{
    private java.util.Vector buffer;
    void <init>()
    {
        test.Demo_local r0;
        java.util.Vector $r1, $r2, $r3, $r4;
        r0 := @this: test.Demo_local;
        specialinvoke r0.<java.lang.Object: void <init>()>();
        $r1 = new java.util.Vector;
        specialinvoke $r1.<java.util.Vector: void <init>()>();
        r0.<test.Demo_local: java.util.Vector buffer> = $r1;
        $r2 = r0.<test.Demo_local: java.util.Vector buffer>;
        virtualinvoke $r2.<java.util.Vector: boolean
add(java.lang.Object)>("c");
        $r3 = r0.<test.Demo_local: java.util.Vector buffer>;
        virtualinvoke $r3.<java.util.Vector: boolean
add(java.lang.Object)>("d");
        $r4 = r0.<test.Demo_local: java.util.Vector buffer>;
        virtualinvoke $r4.<java.util.Vector: boolean
add(java.lang.Object)>("a");
        return;
    }
    public int getStringPos(java.lang.String)
    {
        test.Demo_local r0;
        java.lang.String r1, r2;
        int i0, $i1;
        java.util.Vector $r3, $r4, $r6;
        java.lang.Object $r5;
        boolean $z0;
        r0 := @this: test.Demo_local;
        r1 := @parameter0: java.lang.String;
        *i0* = 0;
     label0:
        $r3 = r0.<test.Demo_local: java.util.Vector buffer>;
        $i1 = virtualinvoke $r3.<java.util.Vector: int size()>();
        if i0 >= $i1 goto label2;
        $r4 = r0.<test.Demo_local: java.util.Vector buffer>;
        $r5 = virtualinvoke $r4.<java.util.Vector: java.lang.Object
elementAt(int)>(i0);
        *r2* = (java.lang.String) $r5;
        $z0 = virtualinvoke r2.<java.lang.String: boolean
equals(java.lang.Object)>(r1);
        if $z0 == 0 goto label1;
        $r6 = r0.<test.Demo_local: java.util.Vector buffer>;
        virtualinvoke $r6.<java.util.Vector: java.lang.Object
remove(int)>(i0);
        return i0;
     label1:
        i0 = i0 + 1;
        goto label0;
     label2:
        return -1;
    }
}

So i have made these changes:

public class test.Demo_local extends java.lang.Object
{
    private java.util.Vector buffer;
 private int *counter*;
 private java.lang.String *curString*;
    void <init>()
    {
        test.Demo_local r0;
        java.util.Vector $r1, $r2, $r3, $r4;
        r0 := @this: test.Demo_local;
        specialinvoke r0.<java.lang.Object: void <init>()>();
        $r1 = new java.util.Vector;
        specialinvoke $r1.<java.util.Vector: void <init>()>();
        r0.<test.Demo_local: java.util.Vector buffer> = $r1;
        $r2 = r0.<test.Demo_local: java.util.Vector buffer>;
        virtualinvoke $r2.<java.util.Vector: boolean
add(java.lang.Object)>("c");
        $r3 = r0.<test.Demo_local: java.util.Vector buffer>;
        virtualinvoke $r3.<java.util.Vector: boolean
add(java.lang.Object)>("d");
        $r4 = r0.<test.Demo_local: java.util.Vector buffer>;
        virtualinvoke $r4.<java.util.Vector: boolean
add(java.lang.Object)>("a");
        return;
    }
    public int getStringPos(java.lang.String)
    {
        test.Demo_local r0;
        java.lang.String r1, $r2;
        int $i0, $i1;
        java.util.Vector $r3, $r4, $r6;
        java.lang.Object $r5;
        boolean $z0;
        r0 := @this: test.Demo_local;
        r1 := @parameter0: java.lang.String;
       *$r2* = r0.<test.Demo_local: java.lang.String *curString*>;
        *$i0* = r0.<test.Demo_local: int *counter*>;
        $i0 = 0;
     label0:
        $r3 = r0.<test.Demo_local: java.util.Vector buffer>;
        $i1 = virtualinvoke $r3.<java.util.Vector: int size()>();
        if $i0 >= $i1 goto label2;
        $r4 = r0.<test.Demo_local: java.util.Vector buffer>;
        $r5 = virtualinvoke $r4.<java.util.Vector: java.lang.Object
elementAt(int)>($i0);
        $r2 = (java.lang.String) $r5;
        $z0 = virtualinvoke $r2.<java.lang.String: boolean
equals(java.lang.Object)>(r1);
        if $z0 == 0 goto label1;
        $r6 = r0.<test.Demo_local: java.util.Vector buffer>;
        virtualinvoke $r6.<java.util.Vector: java.lang.Object
remove(int)>($i0);
        return $i0;
     label1:
        $i0 = $i0 + 1;
        goto label0;
     label2:
        return -1;
    }
}

When i compile into the .class file, the corresponding .java source is the
same  i started from
(with a little optimization), but no trace of the two added instance's
fileds.
Where am I wrong ?
  Thanks in advance.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://mailman.cs.mcgill.ca/pipermail/soot-list/attachments/20101230/3896a113/attachment-0001.html 


More information about the Soot-list mailing list