[Soot-list] java.lang.VerifyError and byte code execution trace
Yongzhi Wang
wang.yongzhi2009 at gmail.com
Mon Sep 16 13:09:40 EDT 2013
Dear All,
Sorry for not giving you enough information. The example is as follows:
Suppose I want to transform the following program into flatten control flow:
public static String process(String s){
return s+":"+s.length();
}
The error message I get while executing the program is as follows:
wpc-10-108-5-230:sootOutput yongzhiwang$ java Test
Exception in thread "main" java.lang.VerifyError: (class: Test, method:
process signature: (Ljava/lang/String;)Ljava/lang/String;) Register 5
contains wrong type
The class file I get after transformation is as follows:
public static java.lang.String process(java.lang.String);
Signature: (Ljava/lang/String;)Ljava/lang/String;
Code:
0: bipush 6
2: istore 7
4: iload 7
6: tableswitch{ //0 to 7
0: 52;
1: 65;
2: 76;
3: 85;
4: 99;
5: 113;
6: 124;
7: 134;
default: 52 }
52: aload 5
54: invokevirtual #10; //Method
java/lang/StringBuilder.toString:()Ljava/lang/String;
57: astore 6
59: iconst_2
60: istore 7
62: goto 4
65: aload_0
66: invokestatic #31; //Method
java/lang/String.valueOf:(Ljava/lang/Object;)Ljava/lang/String;
69: astore_2
70: iconst_5
71: istore 7
73: goto 4
76: aload 6
78: areturn
79: iconst_m1
80: istore 7
82: goto 4
85: aload_3
86: iload 4
88: invokevirtual #14; //Method
java/lang/StringBuilder.append:(I)Ljava/lang/StringBuilder;
91: astore 5
93: iconst_0
94: istore 7
96: goto 4
99: aload_1
100: ldc #38; //String :
102: invokevirtual #15; //Method
java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
105: astore_3
106: bipush 7
108: istore 7
110: goto 4
113: aload_1
114: aload_2
115: invokespecial #26; //Method
java/lang/StringBuilder."<init>":(Ljava/lang/String;)V
118: iconst_4
119: istore 7
121: goto 4
124: new #19; //class java/lang/StringBuilder
127: astore_1
128: iconst_1
129: istore 7
131: goto 4
134: aload_0
135: invokevirtual #44; //Method java/lang/String.length:()I
138: istore 4
140: iconst_3
141: istore 7
143: goto 4
}
I guess the java verifier give the error because it see the instruction
52: aload 5
before
91: astore 5
Please let me know your opinion. Thanks!
Best regards,
Yongzhi
On Mon, Sep 16, 2013 at 8:48 AM, Bodden, Eric <eric.bodden at sit.fraunhofer.de
> wrote:
> Dear Yongzhi,
>
> without knowing more about the code you generate it's hard to help you.
> The error suggests that you are causing a control flow that loads into
> register 3 a value of some type that is then later-on used as a value of
> another type. In other words, you generate incorrect code and should fix
> your transformation. -noverify should not be an option.
>
> Cheers,
> Eric
>
>
>
> On 14.09.2013, at 05:44, Yongzhi Wang <wang.yongzhi2009 at gmail.com> wrote:
>
> > Dear All,
> >
> > Thanks for your suggestion. I am transforming class files into other
> form at the jimple level. However, the transfromation is about control flow
> and it is a little unusual. I am trying to "flattening" the control flow: I
> chop each original function into multiple blocks and makes them accessible
> to a big switch. The control flow is preserved by the variable of big
> switch. The idea is explained in the following webpage and the example is
> as follows:
> >
> >
> http://reverseengineering.stackexchange.com/questions/2221/what-is-a-control-flow-flattening-obfuscation-technique
> >
> > Suppose I have original function as follows:
> >
> > int a = 1;
> > int b = 2;
> > int c = a+b;
> > return;
> >
> > The transformation result is as follows:
> >
> > int l = 0;
> > while (true){
> > switch(l){
> > case 0: goto L1;break;
> > case 1: goto L2; break;
> > case 2: goto L3; break;
> > case 3: goto L4; break;
> > }
> >
> > L1: int a = 1; l = 1;
> > L2: int b = 2; l = 2;
> > L3: int c = a+b;l = 3;
> > L4: return;
> > }
> >
> > I guess the "Register 3 contains wrong type" error is because that my
> transformed class file has instruction aload_3 appears before astore_3. If
> that's the case, do we have some tricks to pass the verifier.
> >
> > When I run the program with "-noverify" option, The program give me the
> following JVM crash error message:
> >
> > #
> > # A fatal error has been detected by the Java Runtime Environment:
> > #
> > # Internal Error
> (/BUILD_AREA/jdk6_25/hotspot/src/share/vm/gc_interface/collectedHeap.inline.hpp:256),
> pid=28705, tid=1904704400
> > # assert(!Universe::heap()->is_gc_active()) failed: Allocation during
> gc not allowed
> > #
> > # JRE version: 6.0_25-b03
> > # Java VM: Java HotSpot(TM) Client VM (20.0-b10-fastdebug interpreted
> mode linux-x86 )
> > # If you would like to submit a bug report, please visit:
> > # http://java.sun.com/webapps/bugreport/crash.jsp
> > #
> >
> > I observe that the bytecode "newarray byte" is executed. I assume this
> will allocate memory, while the gc is performed. But I have no clue why
> does this happen. The original program will also execute "newarray byte".
> But no such error happens.
> >
> > Best regards,
> > Yongzhi
> >
> >
> > On Fri, Sep 13, 2013 at 1:33 AM, John Jorgensen <
> jorgensen.john at gmail.com> wrote:
> >
> > My knowledge of this topic is stale, but ten years ago when I modified
> Soot's exceptional control flow analysis, I ran into circumstances where
> improving the precision of exception analysis could lead Soot to generate
> unverifiable code by basing its optimizations on more precise analyses than
> those available to the bytecode verifier.
> >
> > In that case, the unverifiable code resulted because the bytecode
> verifier assumed that every instruction within the scope of an exception
> handler might have that handler as its successor, even if the instruction
> could not possibly throw an exception that the handler would catch. That
> meant that if Soot made optimizations based on knowing that some
> instructions could not throw particular exceptions, it was possible that
> the verifier could judge the resulting code unsafe, because it would think
> the code might lead the exception handler to be executed with the VM in an
> improper state (for example that some instruction in the handler might be
> executed when "Register 3 contains wrong type"). See sections 2.6 and 3.4
> of the Sable Technical Report 2003-3 for more detail.
> >
> > So in your example, it is conceivable that the verifier is not smart
> enough to determine that astore_3 is always executed before aload_3, even
> though you can see that it is. Or maybe there is dead code that wants to
> read a different type from register 3, but the verifier can't tell it is
> dead.
> >
> > But as I said before, my knowledge of this subject is outdated (as I
> just confirmed by glancing at the current JVM spec's description of
> verification: I don't remember it including any Prolog in the old days).
> >
> >
> >
> >
> > On Thu, Sep 12, 2013 at 11:29 PM, John Jorgensen <
> jorgensen.john at gmail.com> wrote:
> > My knowledge of this topic is stale, but ten years ago when I modified
> Soot's exceptional control flow analysis, I ran into circumstances where
> improving the precision of exception analysis could lead Soot to generate
> unverifiable code by basing its optimizations on more precise analyses than
> those available to the bytecode verifier.
> >
> > In that case, the unverifiable code resulted because the bytecode
> verifier assumed that every instruction within the scope of an exception
> handler might have that handler as its successor, even if the instruction
> could not possibly throw an exception that the handler would catch. That
> meant that if Soot made optimizations based on knowing that some
> instructions could not throw particular exceptions, it was possible that
> the verifier could judge the resulting code unsafe, because it would think
> the code might lead the exception handler to be executed with the VM in an
> improper state (for example that some instruction in the handler might be
> executed when "Register 3 contains wrong type"). See sections 2.6 and 3.4
> of the Sable Technical Report 2003-3 for more detail.
> >
> > So in your example, it is conceivable that the verifier is not smart
> enough to determine that astore_3 is always executed before aload_3, even
> though you can see that it is. Or maybe there is dead code that wants to
> read a different type from register 3, but the verifier can't tell it is
> dead.
> >
> > But as I said before, my knowledge of this subject is outdated (as I
> just confirmed by glancing at the current JVM spec's description of
> verification: I don't remember it including any Prolog in the old days).
> >
> >
> >
> > On Thu, Sep 12, 2013 at 7:27 PM, Yongzhi Wang <
> wang.yongzhi2009 at gmail.com> wrote:
> > Dear All,
> >
> > I am stucked by the byte code that I generate with soot. I am using soot
> to transform the control flow of java class. The transformed program should
> behave same as the original program. However, my generated class file
> cannot be executed without the "-noverify" option.
> >
> > If I run the class file in java without "-noverify" option, I got the
> following error message:
> > java.lang.VerifyError: (class: Test, method: main signature:
> ([Ljava/lang/String;)V) Register 3 contains wrong type
> >
> > If I run the class file in java with "-noverify" option, some test
> program will run correctly. But some test programs will be pending. I
> suspect the program is in a dead loop given my transformed control flow.
> >
> > My question is:
> >
> > 1. What is the usual reason of "Register contains wrong type" error? I
> can observe that my transformed class file has instruction aload_3 appears
> before astore_3, even though I use goto instruction to control the control
> flow to make sure astore_3 is executed before aloud_3. Is that the reason?
> If so, what's the trick to fix this problem?
> >
> > 2. I suspect the test program is in a dead loop. How can I trace the
> bytecode instruction execution sequence from JVM? Is there any tool or JVM
> option I can use?
> >
> > Thanks!
> > Best regards,
> > Yongzhi
> >
> > _______________________________________________
> > Soot-list mailing list
> > Soot-list at sable.mcgill.ca
> > http://mailman.cs.mcgill.ca/mailman/listinfo/soot-list
> >
> >
> >
> >
> > _______________________________________________
> > Soot-list mailing list
> > Soot-list at sable.mcgill.ca
> > http://mailman.cs.mcgill.ca/mailman/listinfo/soot-list
>
> --
> Prof. Eric Bodden, Ph.D., http://sse.ec-spride.de/ http://bodden.de/
> Head of Secure Software Engineering at Fraunhofer SIT, TU Darmstadt and
> EC SPRIDE
> Tel: +49 6151 16-75422 Fax: +49 6151 16-72051
> Room 3.2.14, Mornewegstr. 30, 64293 Darmstadt
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://mailman.cs.mcgill.ca/pipermail/soot-list/attachments/20130916/791e1c01/attachment-0001.html
More information about the Soot-list
mailing list