SlideShare a Scribd company logo
1 of 40
Android VM Internals
JVM, Dalvik, Art
By: Shaul Rosenzweig
What are JVM and Dalvik?
Java Virtual machines:
An abstract computing machines that enable
running of a Java program.
What is Art?
Application runtime environment that translates
application bytecode into native instructions, that
are later executed by it.
Java Virtual Machine
● Interprets Java bytecode instructions
● Stack based
● Stack based easy to interpret on many architectures
● Classloader loads, verifies, resolves and links .class files which contain
instructions on runtime
● Byte long opcodes, out of 255 possible, 198 are in use
● Many languages can be compiled to Java bytecode
Dalvik
● Class library based on Apache Harmony JVM, not Oracle JVM
● Developed by Dan Borenstein along with Android, named after town in
Iceland
● Register based: optimized for ARM platformance
● Low memory footprint, optimized for running several instances at the same
time
● .class files are compiled into .dx, resolved and merged into .dex files compile
time
● Longer instructions, less of them
● JIT added in Froyo (2.2) to improve performance
● JIT saves ODEX files in /data/dalvik-cache
Art
● Previewed in KitKat, replaced Dalvik in Lollipop
● No more JIT, uses AOT compilation
● Lower memory footprint, more disk used
● Same input bytecodes (DEX) as Dalvik, compiled into native (elf) executables
● Improved GC, power consumption and performance
● Art files: memory mapping is currently fixed (defeating ASLR)
● Not really 64 bit, VM architecture is 32 bit, getting there
● Art format constantly changing, undocumented and proprietary
● Supports ARM, ARM_64, x86 and Mips
Bytecode example: prep
private static int calculate() {
int ret = -321;
for(int i = 0; i < 10000 ; i++) {
ret += i%5;
}
return ret;
}
> javac -target 1.7 -source 1.7 Test.java
> dx --dex --output="Test.dex" "Test.class"
> r2 Test.class
> r2 Test.dex
Java bytecode
sipush 0xfebf
istore_0
iconst_0
istore_1
iload_1
sipush 0x2710
if_icmpge 0x02b6
iload_0
iload_1
iconst_5
irem
iadd
istore_0
iinc 1 1
goto 0x02a3
iload_0
ireturn
const/16 v1, 0xfebf
const/4 v0, 0
const/16 v2, 0x2710
if-ge v0, v2, 0x1f2
rem-int/lit8 v2, v0, 0x5
add-int/2addr v1, v2
add-int/lit8 v0, v0, 0x1
goto 0x000001de
return v1
DEX bytecode
Java bytecode execution
╒ (fcn) sym.Test.calculate 27
│ 0x0000029d 11febf sipush 65215 ; push short -321 to stack
│ 0x000002a0 3b istore_0 ; store stack value to int0
│ 0x000002a1 03 iconst_0 ; load value 0 to stack
│ 0x000002a2 3c istore_1 ; store to int1
│ ┌─> 0x000002a3 1b iload_1 ; push value of int1 to stack
│ │ 0x000002a4 112710 sipush 10000 ; push constant 10000 to stack
│ ┌──< 0x000002a7 a2000f if_icmpge 0x02b6 ; if top stack values >= goto add│
│ ││ 0x000002aa 1a iload_0 ; load int0 into stack
│ ││ 0x000002ab 1b iload_1 ; load int1 into stack
│ ││ 0x000002ac 08 iconst_5 ; load const 5 into stack
│ ││ 0x000002ad 70 irem ; reminder of topmost two and push
│ ││ 0x000002ae 60 iadd ; add topmost two and push
│ ││ 0x000002af 3b istore_0 ; store to int0
│ ││ 0x000002b0 840101 iinc 1 1 ; int1++
│ │└─< 0x000002b3 a7fff0 goto 0x02a3 ; back to start of loop
│ └──> 0x000002b6 1a iload_0 ; load int0 into stack
╘ 0x000002b7 ac ireturn ; return value on stack
-321
Operand stackVariables Operations:
Push -321 to operand stack
╒ (fcn) sym.Test.calculate 27
│ 0x0000029d 11febf sipush 65215 ; push short -321 to stack
│ 0x000002a0 3b istore_0 ; store stack value to int0
│ 0x000002a1 03 iconst_0 ; load value 0 to stack
│ 0x000002a2 3c istore_1 ; store to int1
│ ┌─> 0x000002a3 1b iload_1 ; push value of int1 to stack
│ │ 0x000002a4 112710 sipush 10000 ; push constant 10000 to stack
│ ┌──< 0x000002a7 a2000f if_icmpge 0x02b6 ; if top stack values >= goto add│
│ ││ 0x000002aa 1a iload_0 ; load int0 into stack
│ ││ 0x000002ab 1b iload_1 ; load int1 into stack
│ ││ 0x000002ac 08 iconst_5 ; load const 5 into stack
│ ││ 0x000002ad 70 irem ; reminder of topmost two and push
│ ││ 0x000002ae 60 iadd ; add topmost two and push
│ ││ 0x000002af 3b istore_0 ; store to int0
│ ││ 0x000002b0 840101 iinc 1 1 ; int1++
│ │└─< 0x000002b3 a7fff0 goto 0x02a3 ; back to start of loop
│ └──> 0x000002b6 1a iload_0 ; load int0 into stack
╘ 0x000002b7 ac ireturn ; return value on stack
Int0 = -321
Variables Operand stack Operations:
Pop topmost value on stack
and assign to int0
╒ (fcn) sym.Test.calculate 27
│ 0x0000029d 11febf sipush 65215 ; push short -321 to stack
│ 0x000002a0 3b istore_0 ; store stack value to int0
│ 0x000002a1 03 iconst_0 ; load value 0 to stack
│ 0x000002a2 3c istore_1 ; store to int1
│ ┌─> 0x000002a3 1b iload_1 ; push value of int1 to stack
│ │ 0x000002a4 112710 sipush 10000 ; push constant 10000 to stack
│ ┌──< 0x000002a7 a2000f if_icmpge 0x02b6 ; if top stack values >= goto add│
│ ││ 0x000002aa 1a iload_0 ; load int0 into stack
│ ││ 0x000002ab 1b iload_1 ; load int1 into stack
│ ││ 0x000002ac 08 iconst_5 ; load const 5 into stack
│ ││ 0x000002ad 70 irem ; reminder of topmost two and push
│ ││ 0x000002ae 60 iadd ; add topmost two and push
│ ││ 0x000002af 3b istore_0 ; store to int0
│ ││ 0x000002b0 840101 iinc 1 1 ; int1++
│ │└─< 0x000002b3 a7fff0 goto 0x02a3 ; back to start of loop
│ └──> 0x000002b6 1a iload_0 ; load int0 into stack
╘ 0x000002b7 ac ireturn ; return value on stack
0
Int0 = -321
Variables Operand stack Operations:
Push 0 to stack
╒ (fcn) sym.Test.calculate 27
│ 0x0000029d 11febf sipush 65215 ; push short -321 to stack
│ 0x000002a0 3b istore_0 ; store stack value to int0
│ 0x000002a1 03 iconst_0 ; load value 0 to stack
│ 0x000002a2 3c istore_1 ; store to int1
│ ┌─> 0x000002a3 1b iload_1 ; push value of int1 to stack
│ │ 0x000002a4 112710 sipush 10000 ; push constant 10000 to stack
│ ┌──< 0x000002a7 a2000f if_icmpge 0x02b6 ; if top stack values >= goto add│
│ ││ 0x000002aa 1a iload_0 ; load int0 into stack
│ ││ 0x000002ab 1b iload_1 ; load int1 into stack
│ ││ 0x000002ac 08 iconst_5 ; load const 5 into stack
│ ││ 0x000002ad 70 irem ; reminder of topmost two and push
│ ││ 0x000002ae 60 iadd ; add topmost two and push
│ ││ 0x000002af 3b istore_0 ; store to int0
│ ││ 0x000002b0 840101 iinc 1 1 ; int1++
│ │└─< 0x000002b3 a7fff0 goto 0x02a3 ; back to start of loop
│ └──> 0x000002b6 1a iload_0 ; load int0 into stack
╘ 0x000002b7 ac ireturn ; return value on stack
Int0 = -321
Int1 = 0
Variables Operand stack Operations:
Pop from stack and assign
to Int1
╒ (fcn) sym.Test.calculate 27
│ 0x0000029d 11febf sipush 65215 ; push short -321 to stack
│ 0x000002a0 3b istore_0 ; store stack value to int0
│ 0x000002a1 03 iconst_0 ; load value 0 to stack
│ 0x000002a2 3c istore_1 ; store to int1
│ ┌─> 0x000002a3 1b iload_1 ; push value of int1 to stack
│ │ 0x000002a4 112710 sipush 10000 ; push constant 10000 to stack
│ ┌──< 0x000002a7 a2000f if_icmpge 0x02b6 ; if top stack values >= goto add│
│ ││ 0x000002aa 1a iload_0 ; load int0 into stack
│ ││ 0x000002ab 1b iload_1 ; load int1 into stack
│ ││ 0x000002ac 08 iconst_5 ; load const 5 into stack
│ ││ 0x000002ad 70 irem ; reminder of topmost two and push
│ ││ 0x000002ae 60 iadd ; add topmost two and push
│ ││ 0x000002af 3b istore_0 ; store to int0
│ ││ 0x000002b0 840101 iinc 1 1 ; int1++
│ │└─< 0x000002b3 a7fff0 goto 0x02a3 ; back to start of loop
│ └──> 0x000002b6 1a iload_0 ; load int0 into stack
╘ 0x000002b7 ac ireturn ; return value on stack
0
Int0 = -321
Int1 = 0
Variables Operand stack Operations:
Push int1 to stack
╒ (fcn) sym.Test.calculate 27
│ 0x0000029d 11febf sipush 65215 ; push short -321 to stack
│ 0x000002a0 3b istore_0 ; store stack value to int0
│ 0x000002a1 03 iconst_0 ; load value 0 to stack
│ 0x000002a2 3c istore_1 ; store to int1
│ ┌─> 0x000002a3 1b iload_1 ; push value of int1 to stack
│ │ 0x000002a4 112710 sipush 10000 ; push constant 10000 to stack
│ ┌──< 0x000002a7 a2000f if_icmpge 0x02b6 ; if top stack values >= goto add│
│ ││ 0x000002aa 1a iload_0 ; load int0 into stack
│ ││ 0x000002ab 1b iload_1 ; load int1 into stack
│ ││ 0x000002ac 08 iconst_5 ; load const 5 into stack
│ ││ 0x000002ad 70 irem ; reminder of topmost two and push
│ ││ 0x000002ae 60 iadd ; add topmost two and push
│ ││ 0x000002af 3b istore_0 ; store to int0
│ ││ 0x000002b0 840101 iinc 1 1 ; int1++
│ │└─< 0x000002b3 a7fff0 goto 0x02a3 ; back to start of loop
│ └──> 0x000002b6 1a iload_0 ; load int0 into stack
╘ 0x000002b7 ac ireturn ; return value on stack
10000
0
Int0 = -321
Int1 = 0
Variables Operand stack Operations:
Push constant 10000 to
stack
╒ (fcn) sym.Test.calculate 27
│ 0x0000029d 11febf sipush 65215 ; push short -321 to stack
│ 0x000002a0 3b istore_0 ; store stack value to int0
│ 0x000002a1 03 iconst_0 ; load value 0 to stack
│ 0x000002a2 3c istore_1 ; store to int1
│ ┌─> 0x000002a3 1b iload_1 ; push value of int1 to stack
│ │ 0x000002a4 112710 sipush 10000 ; push constant 10000 to stack
│ ┌──< 0x000002a7 a2000f if_icmpge 0x02b6 ; if top stack values >= goto add│
│ ││ 0x000002aa 1a iload_0 ; load int0 into stack
│ ││ 0x000002ab 1b iload_1 ; load int1 into stack
│ ││ 0x000002ac 08 iconst_5 ; load const 5 into stack
│ ││ 0x000002ad 70 irem ; reminder of topmost two and push
│ ││ 0x000002ae 60 iadd ; add topmost two and push
│ ││ 0x000002af 3b istore_0 ; store to int0
│ ││ 0x000002b0 840101 iinc 1 1 ; int1++
│ │└─< 0x000002b3 a7fff0 goto 0x02a3 ; back to start of loop
│ └──> 0x000002b6 1a iload_0 ; load int0 into stack
╘ 0x000002b7 ac ireturn ; return value on stack
Int0 = -321
Int1 = 0
Variables Operand stack Operations:
Pop two values from stack
(0 and 10000), compare
them, if true jump to 0x02b6
╒ (fcn) sym.Test.calculate 27
│ 0x0000029d 11febf sipush 65215 ; push short -321 to stack
│ 0x000002a0 3b istore_0 ; store stack value to int0
│ 0x000002a1 03 iconst_0 ; load value 0 to stack
│ 0x000002a2 3c istore_1 ; store to int1
│ ┌─> 0x000002a3 1b iload_1 ; push value of int1 to stack
│ │ 0x000002a4 112710 sipush 10000 ; push constant 10000 to stack
│ ┌──< 0x000002a7 a2000f if_icmpge 0x02b6 ; if top stack values >= goto add│
│ ││ 0x000002aa 1a iload_0 ; load int0 into stack
│ ││ 0x000002ab 1b iload_1 ; load int1 into stack
│ ││ 0x000002ac 08 iconst_5 ; load const 5 into stack
│ ││ 0x000002ad 70 irem ; reminder of topmost two and push
│ ││ 0x000002ae 60 iadd ; add topmost two and push
│ ││ 0x000002af 3b istore_0 ; store to int0
│ ││ 0x000002b0 840101 iinc 1 1 ; int1++
│ │└─< 0x000002b3 a7fff0 goto 0x02a3 ; back to start of loop
│ └──> 0x000002b6 1a iload_0 ; load int0 into stack
╘ 0x000002b7 ac ireturn ; return value on stack
-321
Int0 = -321
Int1 = 0
Variables Operand stack Operations:
Push int0 into stack
╒ (fcn) sym.Test.calculate 27
│ 0x0000029d 11febf sipush 65215 ; push short -321 to stack
│ 0x000002a0 3b istore_0 ; store stack value to int0
│ 0x000002a1 03 iconst_0 ; load value 0 to stack
│ 0x000002a2 3c istore_1 ; store to int1
│ ┌─> 0x000002a3 1b iload_1 ; push value of int1 to stack
│ │ 0x000002a4 112710 sipush 10000 ; push constant 10000 to stack
│ ┌──< 0x000002a7 a2000f if_icmpge 0x02b6 ; if top stack values >= goto add│
│ ││ 0x000002aa 1a iload_0 ; load int0 into stack
│ ││ 0x000002ab 1b iload_1 ; load int1 into stack
│ ││ 0x000002ac 08 iconst_5 ; load const 5 into stack
│ ││ 0x000002ad 70 irem ; reminder of topmost two and push
│ ││ 0x000002ae 60 iadd ; add topmost two and push
│ ││ 0x000002af 3b istore_0 ; store to int0
│ ││ 0x000002b0 840101 iinc 1 1 ; int1++
│ │└─< 0x000002b3 a7fff0 goto 0x02a3 ; back to start of loop
│ └──> 0x000002b6 1a iload_0 ; load int0 into stack
╘ 0x000002b7 ac ireturn ; return value on stack
0
-321
Int0 = -321
Int1 = 0
Variables Operand stack Operations:
Push int1 into stack
╒ (fcn) sym.Test.calculate 27
│ 0x0000029d 11febf sipush 65215 ; push short -321 to stack
│ 0x000002a0 3b istore_0 ; store stack value to int0
│ 0x000002a1 03 iconst_0 ; load value 0 to stack
│ 0x000002a2 3c istore_1 ; store to int1
│ ┌─> 0x000002a3 1b iload_1 ; push value of int1 to stack
│ │ 0x000002a4 112710 sipush 10000 ; push constant 10000 to stack
│ ┌──< 0x000002a7 a2000f if_icmpge 0x02b6 ; if top stack values >= goto add│
│ ││ 0x000002aa 1a iload_0 ; load int0 into stack
│ ││ 0x000002ab 1b iload_1 ; load int1 into stack
│ ││ 0x000002ac 08 iconst_5 ; load const 5 into stack
│ ││ 0x000002ad 70 irem ; reminder of topmost two and push
│ ││ 0x000002ae 60 iadd ; add topmost two and push
│ ││ 0x000002af 3b istore_0 ; store to int0
│ ││ 0x000002b0 840101 iinc 1 1 ; int1++
│ │└─< 0x000002b3 a7fff0 goto 0x02a3 ; back to start of loop
│ └──> 0x000002b6 1a iload_0 ; load int0 into stack
╘ 0x000002b7 ac ireturn ; return value on stack
5
0
-321
Int0 = -321
Int1 = 0
Variables Operand stack Operations:
Push constant 5 into stack
╒ (fcn) sym.Test.calculate 27
│ 0x0000029d 11febf sipush 65215 ; push short -321 to stack
│ 0x000002a0 3b istore_0 ; store stack value to int0
│ 0x000002a1 03 iconst_0 ; load value 0 to stack
│ 0x000002a2 3c istore_1 ; store to int1
│ ┌─> 0x000002a3 1b iload_1 ; push value of int1 to stack
│ │ 0x000002a4 112710 sipush 10000 ; push constant 10000 to stack
│ ┌──< 0x000002a7 a2000f if_icmpge 0x02b6 ; if top stack values >= goto add│
│ ││ 0x000002aa 1a iload_0 ; load int0 into stack
│ ││ 0x000002ab 1b iload_1 ; load int1 into stack
│ ││ 0x000002ac 08 iconst_5 ; load const 5 into stack
│ ││ 0x000002ad 70 irem ; reminder of topmost two and push
│ ││ 0x000002ae 60 iadd ; add topmost two and push
│ ││ 0x000002af 3b istore_0 ; store to int0
│ ││ 0x000002b0 840101 iinc 1 1 ; int1++
│ │└─< 0x000002b3 a7fff0 goto 0x02a3 ; back to start of loop
│ └──> 0x000002b6 1a iload_0 ; load int0 into stack
╘ 0x000002b7 ac ireturn ; return value on stack
0
-321
Int0 = -321
Int1 = 0
Variables Operand stack Operations:
Pop two values from stack
(0 and 5), calculate modulo
and push to stack (0)
╒ (fcn) sym.Test.calculate 27
│ 0x0000029d 11febf sipush 65215 ; push short -321 to stack
│ 0x000002a0 3b istore_0 ; store stack value to int0
│ 0x000002a1 03 iconst_0 ; load value 0 to stack
│ 0x000002a2 3c istore_1 ; store to int1
│ ┌─> 0x000002a3 1b iload_1 ; push value of int1 to stack
│ │ 0x000002a4 112710 sipush 10000 ; push constant 10000 to stack
│ ┌──< 0x000002a7 a2000f if_icmpge 0x02b6 ; if top stack values >= goto add│
│ ││ 0x000002aa 1a iload_0 ; load int0 into stack
│ ││ 0x000002ab 1b iload_1 ; load int1 into stack
│ ││ 0x000002ac 08 iconst_5 ; load const 5 into stack
│ ││ 0x000002ad 70 irem ; reminder of topmost two and push
│ ││ 0x000002ae 60 iadd ; add topmost two and push
│ ││ 0x000002af 3b istore_0 ; store to int0
│ ││ 0x000002b0 840101 iinc 1 1 ; int1++
│ │└─< 0x000002b3 a7fff0 goto 0x02a3 ; back to start of loop
│ └──> 0x000002b6 1a iload_0 ; load int0 into stack
╘ 0x000002b7 ac ireturn ; return value on stack
-321
Int0 = -321
Int1 = 0
Variables Operand stack Operations:
Pop two values from stack
(0 and -321), add them and
push the result into stack
╒ (fcn) sym.Test.calculate 27
│ 0x0000029d 11febf sipush 65215 ; push short -321 to stack
│ 0x000002a0 3b istore_0 ; store stack value to int0
│ 0x000002a1 03 iconst_0 ; load value 0 to stack
│ 0x000002a2 3c istore_1 ; store to int1
│ ┌─> 0x000002a3 1b iload_1 ; push value of int1 to stack
│ │ 0x000002a4 112710 sipush 10000 ; push constant 10000 to stack
│ ┌──< 0x000002a7 a2000f if_icmpge 0x02b6 ; if top stack values >= goto add│
│ ││ 0x000002aa 1a iload_0 ; load int0 into stack
│ ││ 0x000002ab 1b iload_1 ; load int1 into stack
│ ││ 0x000002ac 08 iconst_5 ; load const 5 into stack
│ ││ 0x000002ad 70 irem ; reminder of topmost two and push
│ ││ 0x000002ae 60 iadd ; add topmost two and push
│ ││ 0x000002af 3b istore_0 ; store to int0
│ ││ 0x000002b0 840101 iinc 1 1 ; int1++
│ │└─< 0x000002b3 a7fff0 goto 0x02a3 ; back to start of loop
│ └──> 0x000002b6 1a iload_0 ; load int0 into stack
╘ 0x000002b7 ac ireturn ; return value on stack
Int0 = -321
Int1 = 0
Variables Operand stack Operations:
Pop topmost value from
stack and store into int0
╒ (fcn) sym.Test.calculate 27
│ 0x0000029d 11febf sipush 65215 ; push short -321 to stack
│ 0x000002a0 3b istore_0 ; store stack value to int0
│ 0x000002a1 03 iconst_0 ; load value 0 to stack
│ 0x000002a2 3c istore_1 ; store to int1
│ ┌─> 0x000002a3 1b iload_1 ; push value of int1 to stack
│ │ 0x000002a4 112710 sipush 10000 ; push constant 10000 to stack
│ ┌──< 0x000002a7 a2000f if_icmpge 0x02b6 ; if top stack values >= goto add│
│ ││ 0x000002aa 1a iload_0 ; load int0 into stack
│ ││ 0x000002ab 1b iload_1 ; load int1 into stack
│ ││ 0x000002ac 08 iconst_5 ; load const 5 into stack
│ ││ 0x000002ad 70 irem ; reminder of topmost two and push
│ ││ 0x000002ae 60 iadd ; add topmost two and push
│ ││ 0x000002af 3b istore_0 ; store to int0
│ ││ 0x000002b0 840101 iinc 1 1 ; int1++
│ │└─< 0x000002b3 a7fff0 goto 0x02a3 ; back to start of loop
│ └──> 0x000002b6 1a iload_0 ; load int0 into stack
╘ 0x000002b7 ac ireturn ; return value on stack
Int0 = -321
Int1 = 1
Variables Operand stack Operations:
Increment int1 by 1
╒ (fcn) sym.Test.calculate 27
│ 0x0000029d 11febf sipush 65215 ; push short -321 to stack
│ 0x000002a0 3b istore_0 ; store stack value to int0
│ 0x000002a1 03 iconst_0 ; load value 0 to stack
│ 0x000002a2 3c istore_1 ; store to int1
│ ┌─> 0x000002a3 1b iload_1 ; push value of int1 to stack
│ │ 0x000002a4 112710 sipush 10000 ; push constant 10000 to stack
│ ┌──< 0x000002a7 a2000f if_icmpge 0x02b6 ; if top stack values >= goto add│
│ ││ 0x000002aa 1a iload_0 ; load int0 into stack
│ ││ 0x000002ab 1b iload_1 ; load int1 into stack
│ ││ 0x000002ac 08 iconst_5 ; load const 5 into stack
│ ││ 0x000002ad 70 irem ; reminder of topmost two and push
│ ││ 0x000002ae 60 iadd ; add topmost two and push
│ ││ 0x000002af 3b istore_0 ; store to int0
│ ││ 0x000002b0 840101 iinc 1 1 ; int1++
│ │└─< 0x000002b3 a7fff0 goto 0x02a3 ; back to start of loop
│ └──> 0x000002b6 1a iload_0 ; load int0 into stack
╘ 0x000002b7 ac ireturn ; return value on stack
Int0 = -321
Int1 = 1
Variables Operand stack Operations:
Goto 0x2a3
10000 iterations later
╒ (fcn) sym.Test.calculate 27
│ 0x0000029d 11febf sipush 65215 ; push short -321 to stack
│ 0x000002a0 3b istore_0 ; store stack value to int0
│ 0x000002a1 03 iconst_0 ; load value 0 to stack
│ 0x000002a2 3c istore_1 ; store to int1
│ ┌─> 0x000002a3 1b iload_1 ; push value of int1 to stack
│ │ 0x000002a4 112710 sipush 10000 ; push constant 10000 to stack
│ ┌──< 0x000002a7 a2000f if_icmpge 0x02b6 ; if top stack values >= goto add│
│ ││ 0x000002aa 1a iload_0 ; load int0 into stack
│ ││ 0x000002ab 1b iload_1 ; load int1 into stack
│ ││ 0x000002ac 08 iconst_5 ; load const 5 into stack
│ ││ 0x000002ad 70 irem ; reminder of topmost two and push
│ ││ 0x000002ae 60 iadd ; add topmost two and push
│ ││ 0x000002af 3b istore_0 ; store to int0
│ ││ 0x000002b0 840101 iinc 1 1 ; int1++
│ │└─< 0x000002b3 a7fff0 goto 0x02a3 ; back to start of loop
│ └──> 0x000002b6 1a iload_0 ; load int0 into stack
╘ 0x000002b7 ac ireturn ; return value on stack
Value of int0
Int0 = {calculated in loop}
Int1 = 10000 {break condition}
Variables Operand stack Operations:
Push int1 into stack
╒ (fcn) sym.Test.calculate 27
│ 0x0000029d 11febf sipush 65215 ; push short -321 to stack
│ 0x000002a0 3b istore_0 ; store stack value to int0
│ 0x000002a1 03 iconst_0 ; load value 0 to stack
│ 0x000002a2 3c istore_1 ; store to int1
│ ┌─> 0x000002a3 1b iload_1 ; push value of int1 to stack
│ │ 0x000002a4 112710 sipush 10000 ; push constant 10000 to stack
│ ┌──< 0x000002a7 a2000f if_icmpge 0x02b6 ; if top stack values >= goto add│
│ ││ 0x000002aa 1a iload_0 ; load int0 into stack
│ ││ 0x000002ab 1b iload_1 ; load int1 into stack
│ ││ 0x000002ac 08 iconst_5 ; load const 5 into stack
│ ││ 0x000002ad 70 irem ; reminder of topmost two and push
│ ││ 0x000002ae 60 iadd ; add topmost two and push
│ ││ 0x000002af 3b istore_0 ; store to int0
│ ││ 0x000002b0 840101 iinc 1 1 ; int1++
│ │└─< 0x000002b3 a7fff0 goto 0x02a3 ; back to start of loop
│ └──> 0x000002b6 1a iload_0 ; load int0 into stack
╘ 0x000002b7 ac ireturn ; return value on stack
Value of int0
Int0 = {calculated in loop}
Int1 = 10000 {break condition}
Variables Operand stack Operations:
Return topmost value on the
stack
DEX bytecode execution
╒ (fcn) sym.static.Calculate.LTest_.Calculate.calculate 28
│ ; CALL XREF from 0x0000021e (entry0)
│ 0x000001d8 1301bffe const/16 v1, 0xfebf ;ret = -321
│ 0x000001dc 1200 const/4 v0, 0 ;i = 0
│ ┌─> 0x000001de 13021027 const/16 v2, 0x2710 ; 10000
│ ┌──< 0x000001e2 35200800 if-ge v0, v2, 0x1f2 ; if (gt) goto 0x1f2
│ ││ 0x000001e6 dc020005 rem-int/lit8 v2, v0, 0x5 ; v2 = i % 5
│ ││ 0x000001ea b021 add-int/2addr v1, v2 ; ret += v2
│ ││ 0x000001ec d8000001 add-int/lit8 v0, v0, 0x1 ; i++
│ │└─< 0x000001f0 28f7 goto 0x000001de ; goto start of loop
╘ └──> 0x000001f2 0f01 return v1 ; return ret;
Registers
V1 = -321
Operations:
Assign value -321 to register v1
╒ (fcn) sym.static.Calculate.LTest_.Calculate.calculate 28
│ ; CALL XREF from 0x0000021e (entry0)
│ 0x000001d8 1301bffe const/16 v1, 0xfebf ;ret = -321
│ 0x000001dc 1200 const/4 v0, 0 ;i = 0
│ ┌─> 0x000001de 13021027 const/16 v2, 0x2710 ; 10000
│ ┌──< 0x000001e2 35200800 if-ge v0, v2, 0x1f2 ; if (gt) goto 0x1f2
│ ││ 0x000001e6 dc020005 rem-int/lit8 v2, v0, 0x5 ; v2 = i % 5
│ ││ 0x000001ea b021 add-int/2addr v1, v2 ; ret += v2
│ ││ 0x000001ec d8000001 add-int/lit8 v0, v0, 0x1 ; i++
│ │└─< 0x000001f0 28f7 goto 0x000001de ; goto start of loop
╘ └──> 0x000001f2 0f01 return v1 ; return ret;
Registers:
V1 = -321
V0 = 0
Operations:
Assign value 0 to register v1
╒ (fcn) sym.static.Calculate.LTest_.Calculate.calculate 28
│ ; CALL XREF from 0x0000021e (entry0)
│ 0x000001d8 1301bffe const/16 v1, 0xfebf ;ret = -321
│ 0x000001dc 1200 const/4 v0, 0 ;i = 0
│ ┌─> 0x000001de 13021027 const/16 v2, 0x2710 ; 10000
│ ┌──< 0x000001e2 35200800 if-ge v0, v2, 0x1f2 ; if (gt) goto 0x1f2
│ ││ 0x000001e6 dc020005 rem-int/lit8 v2, v0, 0x5 ; v2 = i % 5
│ ││ 0x000001ea b021 add-int/2addr v1, v2 ; ret += v2
│ ││ 0x000001ec d8000001 add-int/lit8 v0, v0, 0x1 ; i++
│ │└─< 0x000001f0 28f7 goto 0x000001de ; goto start of loop
╘ └──> 0x000001f2 0f01 return v1 ; return ret;
Registers
V1 = -321
V0 = 0
V2 = 10000
Operations:
Assign value 10000 to register v2
╒ (fcn) sym.static.Calculate.LTest_.Calculate.calculate 28
│ ; CALL XREF from 0x0000021e (entry0)
│ 0x000001d8 1301bffe const/16 v1, 0xfebf ;ret = -321
│ 0x000001dc 1200 const/4 v0, 0 ;i = 0
│ ┌─> 0x000001de 13021027 const/16 v2, 0x2710 ; 10000
│ ┌──< 0x000001e2 35200800 if-ge v0, v2, 0x1f2 ; if (gt) goto 0x1f2
│ ││ 0x000001e6 dc020005 rem-int/lit8 v2, v0, 0x5 ; v2 = i % 5
│ ││ 0x000001ea b021 add-int/2addr v1, v2 ; ret += v2
│ ││ 0x000001ec d8000001 add-int/lit8 v0, v0, 0x1 ; i++
│ │└─< 0x000001f0 28f7 goto 0x000001de ; goto start of loop
╘ └──> 0x000001f2 0f01 return v1 ; return ret;
Registers
V1 = -321
V0 = 0
V2 = 10000
Operations:
If v2 is greater than v0, jump to
0x01f2
╒ (fcn) sym.static.Calculate.LTest_.Calculate.calculate 28
│ ; CALL XREF from 0x0000021e (entry0)
│ 0x000001d8 1301bffe const/16 v1, 0xfebf ;ret = -321
│ 0x000001dc 1200 const/4 v0, 0 ;i = 0
│ ┌─> 0x000001de 13021027 const/16 v2, 0x2710 ; 10000
│ ┌──< 0x000001e2 35200800 if-ge v0, v2, 0x1f2 ; if (gt) goto 0x1f2
│ ││ 0x000001e6 dc020005 rem-int/lit8 v2, v0, 0x5 ; v2 = i % 5
│ ││ 0x000001ea b021 add-int/2addr v1, v2 ; ret += v2
│ ││ 0x000001ec d8000001 add-int/lit8 v0, v0, 0x1 ; i++
│ │└─< 0x000001f0 28f7 goto 0x000001de ; goto start of loop
╘ └──> 0x000001f2 0f01 return v1 ; return ret;
Registers
V1 = -321
V0 = 0
V2 = 0
Operations:
Calculate v0 modulo constant 5
and store result into register v2
╒ (fcn) sym.static.Calculate.LTest_.Calculate.calculate 28
│ ; CALL XREF from 0x0000021e (entry0)
│ 0x000001d8 1301bffe const/16 v1, 0xfebf ;ret = -321
│ 0x000001dc 1200 const/4 v0, 0 ;i = 0
│ ┌─> 0x000001de 13021027 const/16 v2, 0x2710 ; 10000
│ ┌──< 0x000001e2 35200800 if-ge v0, v2, 0x1f2 ; if (gt) goto 0x1f2
│ ││ 0x000001e6 dc020005 rem-int/lit8 v2, v0, 0x5 ; v2 = i % 5
│ ││ 0x000001ea b021 add-int/2addr v1, v2 ; ret += v2
│ ││ 0x000001ec d8000001 add-int/lit8 v0, v0, 0x1 ; i++
│ │└─< 0x000001f0 28f7 goto 0x000001de ; goto start of loop
╘ └──> 0x000001f2 0f01 return v1 ; return ret;
Registers
V1 = -321
V0 = 0
V2 = 0
Operations:
Add values of V1 and V2 and store
the result into V1
╒ (fcn) sym.static.Calculate.LTest_.Calculate.calculate 28
│ ; CALL XREF from 0x0000021e (entry0)
│ 0x000001d8 1301bffe const/16 v1, 0xfebf ;ret = -321
│ 0x000001dc 1200 const/4 v0, 0 ;i = 0
│ ┌─> 0x000001de 13021027 const/16 v2, 0x2710 ; 10000
│ ┌──< 0x000001e2 35200800 if-ge v0, v2, 0x1f2 ; if (gt) goto 0x1f2
│ ││ 0x000001e6 dc020005 rem-int/lit8 v2, v0, 0x5 ; v2 = i % 5
│ ││ 0x000001ea b021 add-int/2addr v1, v2 ; ret += v2
│ ││ 0x000001ec d8000001 add-int/lit8 v0, v0, 0x1 ; i++
│ │└─< 0x000001f0 28f7 goto 0x000001de ; goto start of loop
╘ └──> 0x000001f2 0f01 return v1 ; return ret;
Registers
V1 = -321
V0 = 1
V2 = 0
Operations:
Increment value of V0 by 1
╒ (fcn) sym.static.Calculate.LTest_.Calculate.calculate 28
│ ; CALL XREF from 0x0000021e (entry0)
│ 0x000001d8 1301bffe const/16 v1, 0xfebf ;ret = -321
│ 0x000001dc 1200 const/4 v0, 0 ;i = 0
│ ┌─> 0x000001de 13021027 const/16 v2, 0x2710 ; 10000
│ ┌──< 0x000001e2 35200800 if-ge v0, v2, 0x1f2 ; if (gt) goto 0x1f2
│ ││ 0x000001e6 dc020005 rem-int/lit8 v2, v0, 0x5 ; v2 = i % 5
│ ││ 0x000001ea b021 add-int/2addr v1, v2 ; ret += v2
│ ││ 0x000001ec d8000001 add-int/lit8 v0, v0, 0x1 ; i++
│ │└─< 0x000001f0 28f7 goto 0x000001de ; goto start of loop
╘ └──> 0x000001f2 0f01 return v1 ; return ret;
Registers
V1 = -321
V0 = 1
V2 = 0
Operations:
Jump to 0x01de
10000 iterations later
╒ (fcn) sym.static.Calculate.LTest_.Calculate.calculate 28
│ ; CALL XREF from 0x0000021e (entry0)
│ 0x000001d8 1301bffe const/16 v1, 0xfebf ;ret = -321
│ 0x000001dc 1200 const/4 v0, 0 ;i = 0
│ ┌─> 0x000001de 13021027 const/16 v2, 0x2710 ; 10000
│ ┌──< 0x000001e2 35200800 if-ge v0, v2, 0x1f2 ; if (gt) goto 0x1f2
│ ││ 0x000001e6 dc020005 rem-int/lit8 v2, v0, 0x5 ; v2 = i % 5
│ ││ 0x000001ea b021 add-int/2addr v1, v2 ; ret += v2
│ ││ 0x000001ec d8000001 add-int/lit8 v0, v0, 0x1 ; i++
│ │└─< 0x000001f0 28f7 goto 0x000001de ; goto start of loop
╘ └──> 0x000001f2 0f01 return v1 ; return ret;
Registers
V1 = {calculated value}
V0 = 10000
V2 = {calculated value}
Operations:
Return value of v1
More
● Java bytecode: https://en.wikipedia.org/wiki/Java_bytecode_instruction_listings
● DEX bytecode: https://source.android.com/devices/tech/dalvik/dalvik-bytecode.html
● Radare2: http://rada.re/r/
○ https://play.google.com/store/apps/details?id=org.radare2.installer&hl=en
○ https://www.gitbook.com/book/radare/radare2book/details
○ https://www.gitbook.com/book/monosource/radare2-explorations/details
● IDA pro: https://www.hex-rays.com/products/ida/
● Dextra, new DEX decompiler: http://newandroidbook.com/tools/dextra.html
● Dan Borenstein, I/O ‘08: https://www.youtube.com/watch?v=ptjedOZEXPM
● I/O 2014 ART talk: https://www.youtube.com/watch?v=EBlTzQsUoOw

More Related Content

Similar to Android virtual machine internals

Bytes in the Machine: Inside the CPython interpreter
Bytes in the Machine: Inside the CPython interpreterBytes in the Machine: Inside the CPython interpreter
Bytes in the Machine: Inside the CPython interpreterakaptur
 
Javascript engine performance
Javascript engine performanceJavascript engine performance
Javascript engine performanceDuoyi Wu
 
Improving Android Performance at Mobiconf 2014
Improving Android Performance at Mobiconf 2014Improving Android Performance at Mobiconf 2014
Improving Android Performance at Mobiconf 2014Raimon Ràfols
 
The bytecode gobbledygook
The bytecode gobbledygookThe bytecode gobbledygook
The bytecode gobbledygookRaimon Ràfols
 
Lesson 24. Phantom errors
Lesson 24. Phantom errorsLesson 24. Phantom errors
Lesson 24. Phantom errorsPVS-Studio
 
Improving Java performance at JBCNConf 2015
Improving Java performance at JBCNConf 2015Improving Java performance at JBCNConf 2015
Improving Java performance at JBCNConf 2015Raimon Ràfols
 
EMBEDDED SYSTEMS 4&5
EMBEDDED SYSTEMS 4&5EMBEDDED SYSTEMS 4&5
EMBEDDED SYSTEMS 4&5PRADEEP
 
Reverse Engineering Dojo: Enhancing Assembly Reading Skills
Reverse Engineering Dojo: Enhancing Assembly Reading SkillsReverse Engineering Dojo: Enhancing Assembly Reading Skills
Reverse Engineering Dojo: Enhancing Assembly Reading SkillsAsuka Nakajima
 
Vectorization on x86: all you need to know
Vectorization on x86: all you need to knowVectorization on x86: all you need to know
Vectorization on x86: all you need to knowRoberto Agostino Vitillo
 
Java Bytecode Crash Course [Code One 2019]
Java Bytecode Crash Course [Code One 2019]Java Bytecode Crash Course [Code One 2019]
Java Bytecode Crash Course [Code One 2019]David Buck
 
The Ring programming language version 1.5.2 book - Part 74 of 181
The Ring programming language version 1.5.2 book - Part 74 of 181The Ring programming language version 1.5.2 book - Part 74 of 181
The Ring programming language version 1.5.2 book - Part 74 of 181Mahmoud Samir Fayed
 
Windbg랑 친해지기
Windbg랑 친해지기Windbg랑 친해지기
Windbg랑 친해지기Ji Hun Kim
 
DEP/ASLR bypass without ROP/JIT
DEP/ASLR bypass without ROP/JITDEP/ASLR bypass without ROP/JIT
DEP/ASLR bypass without ROP/JITArtem I. Baranov
 
2.1 ### uVision Project, (C) Keil Software .docx
2.1   ### uVision Project, (C) Keil Software    .docx2.1   ### uVision Project, (C) Keil Software    .docx
2.1 ### uVision Project, (C) Keil Software .docxtarifarmarie
 
How to recover malare assembly codes
How to recover malare assembly codesHow to recover malare assembly codes
How to recover malare assembly codesFACE
 
Csw2016 wheeler barksdale-gruskovnjak-execute_mypacket
Csw2016 wheeler barksdale-gruskovnjak-execute_mypacketCsw2016 wheeler barksdale-gruskovnjak-execute_mypacket
Csw2016 wheeler barksdale-gruskovnjak-execute_mypacketCanSecWest
 

Similar to Android virtual machine internals (20)

Bytes in the Machine: Inside the CPython interpreter
Bytes in the Machine: Inside the CPython interpreterBytes in the Machine: Inside the CPython interpreter
Bytes in the Machine: Inside the CPython interpreter
 
C++InputOutput.pptx
C++InputOutput.pptxC++InputOutput.pptx
C++InputOutput.pptx
 
Vhdl lab manual
Vhdl lab manualVhdl lab manual
Vhdl lab manual
 
Javascript engine performance
Javascript engine performanceJavascript engine performance
Javascript engine performance
 
Improving Android Performance at Mobiconf 2014
Improving Android Performance at Mobiconf 2014Improving Android Performance at Mobiconf 2014
Improving Android Performance at Mobiconf 2014
 
C++InputOutput.PPT
C++InputOutput.PPTC++InputOutput.PPT
C++InputOutput.PPT
 
The bytecode gobbledygook
The bytecode gobbledygookThe bytecode gobbledygook
The bytecode gobbledygook
 
Lesson 24. Phantom errors
Lesson 24. Phantom errorsLesson 24. Phantom errors
Lesson 24. Phantom errors
 
Improving Java performance at JBCNConf 2015
Improving Java performance at JBCNConf 2015Improving Java performance at JBCNConf 2015
Improving Java performance at JBCNConf 2015
 
EMBEDDED SYSTEMS 4&5
EMBEDDED SYSTEMS 4&5EMBEDDED SYSTEMS 4&5
EMBEDDED SYSTEMS 4&5
 
Reverse Engineering Dojo: Enhancing Assembly Reading Skills
Reverse Engineering Dojo: Enhancing Assembly Reading SkillsReverse Engineering Dojo: Enhancing Assembly Reading Skills
Reverse Engineering Dojo: Enhancing Assembly Reading Skills
 
Vectorization on x86: all you need to know
Vectorization on x86: all you need to knowVectorization on x86: all you need to know
Vectorization on x86: all you need to know
 
Programs of VHDL
Programs of VHDLPrograms of VHDL
Programs of VHDL
 
Java Bytecode Crash Course [Code One 2019]
Java Bytecode Crash Course [Code One 2019]Java Bytecode Crash Course [Code One 2019]
Java Bytecode Crash Course [Code One 2019]
 
The Ring programming language version 1.5.2 book - Part 74 of 181
The Ring programming language version 1.5.2 book - Part 74 of 181The Ring programming language version 1.5.2 book - Part 74 of 181
The Ring programming language version 1.5.2 book - Part 74 of 181
 
Windbg랑 친해지기
Windbg랑 친해지기Windbg랑 친해지기
Windbg랑 친해지기
 
DEP/ASLR bypass without ROP/JIT
DEP/ASLR bypass without ROP/JITDEP/ASLR bypass without ROP/JIT
DEP/ASLR bypass without ROP/JIT
 
2.1 ### uVision Project, (C) Keil Software .docx
2.1   ### uVision Project, (C) Keil Software    .docx2.1   ### uVision Project, (C) Keil Software    .docx
2.1 ### uVision Project, (C) Keil Software .docx
 
How to recover malare assembly codes
How to recover malare assembly codesHow to recover malare assembly codes
How to recover malare assembly codes
 
Csw2016 wheeler barksdale-gruskovnjak-execute_mypacket
Csw2016 wheeler barksdale-gruskovnjak-execute_mypacketCsw2016 wheeler barksdale-gruskovnjak-execute_mypacket
Csw2016 wheeler barksdale-gruskovnjak-execute_mypacket
 

More from Shaul Rosenzwieg

More from Shaul Rosenzwieg (8)

Brainstorming: Manage your ideas like a pro
Brainstorming: Manage your ideas like a proBrainstorming: Manage your ideas like a pro
Brainstorming: Manage your ideas like a pro
 
Kotlin Coroutines and Rx
Kotlin Coroutines and RxKotlin Coroutines and Rx
Kotlin Coroutines and Rx
 
Android Open Accessory
Android Open AccessoryAndroid Open Accessory
Android Open Accessory
 
Lifecycle of a pixel
Lifecycle of a pixelLifecycle of a pixel
Lifecycle of a pixel
 
Secure Android Development
Secure Android DevelopmentSecure Android Development
Secure Android Development
 
Binder: Android IPC
Binder: Android IPCBinder: Android IPC
Binder: Android IPC
 
Why learn Internals?
Why learn Internals?Why learn Internals?
Why learn Internals?
 
Introduction to kotlin
Introduction to kotlinIntroduction to kotlin
Introduction to kotlin
 

Recently uploaded

Adobe Marketo Engage Deep Dives: Using Webhooks to Transfer Data
Adobe Marketo Engage Deep Dives: Using Webhooks to Transfer DataAdobe Marketo Engage Deep Dives: Using Webhooks to Transfer Data
Adobe Marketo Engage Deep Dives: Using Webhooks to Transfer DataBradBedford3
 
Unveiling the Tech Salsa of LAMs with Janus in Real-Time Applications
Unveiling the Tech Salsa of LAMs with Janus in Real-Time ApplicationsUnveiling the Tech Salsa of LAMs with Janus in Real-Time Applications
Unveiling the Tech Salsa of LAMs with Janus in Real-Time ApplicationsAlberto González Trastoy
 
DNT_Corporate presentation know about us
DNT_Corporate presentation know about usDNT_Corporate presentation know about us
DNT_Corporate presentation know about usDynamic Netsoft
 
The Essentials of Digital Experience Monitoring_ A Comprehensive Guide.pdf
The Essentials of Digital Experience Monitoring_ A Comprehensive Guide.pdfThe Essentials of Digital Experience Monitoring_ A Comprehensive Guide.pdf
The Essentials of Digital Experience Monitoring_ A Comprehensive Guide.pdfkalichargn70th171
 
Short Story: Unveiling the Reasoning Abilities of Large Language Models by Ke...
Short Story: Unveiling the Reasoning Abilities of Large Language Models by Ke...Short Story: Unveiling the Reasoning Abilities of Large Language Models by Ke...
Short Story: Unveiling the Reasoning Abilities of Large Language Models by Ke...kellynguyen01
 
The Real-World Challenges of Medical Device Cybersecurity- Mitigating Vulnera...
The Real-World Challenges of Medical Device Cybersecurity- Mitigating Vulnera...The Real-World Challenges of Medical Device Cybersecurity- Mitigating Vulnera...
The Real-World Challenges of Medical Device Cybersecurity- Mitigating Vulnera...ICS
 
The Ultimate Test Automation Guide_ Best Practices and Tips.pdf
The Ultimate Test Automation Guide_ Best Practices and Tips.pdfThe Ultimate Test Automation Guide_ Best Practices and Tips.pdf
The Ultimate Test Automation Guide_ Best Practices and Tips.pdfkalichargn70th171
 
ODSC - Batch to Stream workshop - integration of Apache Spark, Cassandra, Pos...
ODSC - Batch to Stream workshop - integration of Apache Spark, Cassandra, Pos...ODSC - Batch to Stream workshop - integration of Apache Spark, Cassandra, Pos...
ODSC - Batch to Stream workshop - integration of Apache Spark, Cassandra, Pos...Christina Lin
 
Reassessing the Bedrock of Clinical Function Models: An Examination of Large ...
Reassessing the Bedrock of Clinical Function Models: An Examination of Large ...Reassessing the Bedrock of Clinical Function Models: An Examination of Large ...
Reassessing the Bedrock of Clinical Function Models: An Examination of Large ...harshavardhanraghave
 
A Secure and Reliable Document Management System is Essential.docx
A Secure and Reliable Document Management System is Essential.docxA Secure and Reliable Document Management System is Essential.docx
A Secure and Reliable Document Management System is Essential.docxComplianceQuest1
 
Unlocking the Future of AI Agents with Large Language Models
Unlocking the Future of AI Agents with Large Language ModelsUnlocking the Future of AI Agents with Large Language Models
Unlocking the Future of AI Agents with Large Language Modelsaagamshah0812
 
Steps To Getting Up And Running Quickly With MyTimeClock Employee Scheduling ...
Steps To Getting Up And Running Quickly With MyTimeClock Employee Scheduling ...Steps To Getting Up And Running Quickly With MyTimeClock Employee Scheduling ...
Steps To Getting Up And Running Quickly With MyTimeClock Employee Scheduling ...MyIntelliSource, Inc.
 
Optimizing AI for immediate response in Smart CCTV
Optimizing AI for immediate response in Smart CCTVOptimizing AI for immediate response in Smart CCTV
Optimizing AI for immediate response in Smart CCTVshikhaohhpro
 
Asset Management Software - Infographic
Asset Management Software - InfographicAsset Management Software - Infographic
Asset Management Software - InfographicHr365.us smith
 
Learn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdf
Learn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdfLearn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdf
Learn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdfkalichargn70th171
 
Russian Call Girls in Karol Bagh Aasnvi ➡️ 8264348440 💋📞 Independent Escort S...
Russian Call Girls in Karol Bagh Aasnvi ➡️ 8264348440 💋📞 Independent Escort S...Russian Call Girls in Karol Bagh Aasnvi ➡️ 8264348440 💋📞 Independent Escort S...
Russian Call Girls in Karol Bagh Aasnvi ➡️ 8264348440 💋📞 Independent Escort S...soniya singh
 
Der Spagat zwischen BIAS und FAIRNESS (2024)
Der Spagat zwischen BIAS und FAIRNESS (2024)Der Spagat zwischen BIAS und FAIRNESS (2024)
Der Spagat zwischen BIAS und FAIRNESS (2024)OPEN KNOWLEDGE GmbH
 
TECUNIQUE: Success Stories: IT Service provider
TECUNIQUE: Success Stories: IT Service providerTECUNIQUE: Success Stories: IT Service provider
TECUNIQUE: Success Stories: IT Service providermohitmore19
 
why an Opensea Clone Script might be your perfect match.pdf
why an Opensea Clone Script might be your perfect match.pdfwhy an Opensea Clone Script might be your perfect match.pdf
why an Opensea Clone Script might be your perfect match.pdfjoe51371421
 

Recently uploaded (20)

Adobe Marketo Engage Deep Dives: Using Webhooks to Transfer Data
Adobe Marketo Engage Deep Dives: Using Webhooks to Transfer DataAdobe Marketo Engage Deep Dives: Using Webhooks to Transfer Data
Adobe Marketo Engage Deep Dives: Using Webhooks to Transfer Data
 
Unveiling the Tech Salsa of LAMs with Janus in Real-Time Applications
Unveiling the Tech Salsa of LAMs with Janus in Real-Time ApplicationsUnveiling the Tech Salsa of LAMs with Janus in Real-Time Applications
Unveiling the Tech Salsa of LAMs with Janus in Real-Time Applications
 
DNT_Corporate presentation know about us
DNT_Corporate presentation know about usDNT_Corporate presentation know about us
DNT_Corporate presentation know about us
 
The Essentials of Digital Experience Monitoring_ A Comprehensive Guide.pdf
The Essentials of Digital Experience Monitoring_ A Comprehensive Guide.pdfThe Essentials of Digital Experience Monitoring_ A Comprehensive Guide.pdf
The Essentials of Digital Experience Monitoring_ A Comprehensive Guide.pdf
 
Call Girls In Mukherjee Nagar 📱 9999965857 🤩 Delhi 🫦 HOT AND SEXY VVIP 🍎 SE...
Call Girls In Mukherjee Nagar 📱  9999965857  🤩 Delhi 🫦 HOT AND SEXY VVIP 🍎 SE...Call Girls In Mukherjee Nagar 📱  9999965857  🤩 Delhi 🫦 HOT AND SEXY VVIP 🍎 SE...
Call Girls In Mukherjee Nagar 📱 9999965857 🤩 Delhi 🫦 HOT AND SEXY VVIP 🍎 SE...
 
Short Story: Unveiling the Reasoning Abilities of Large Language Models by Ke...
Short Story: Unveiling the Reasoning Abilities of Large Language Models by Ke...Short Story: Unveiling the Reasoning Abilities of Large Language Models by Ke...
Short Story: Unveiling the Reasoning Abilities of Large Language Models by Ke...
 
The Real-World Challenges of Medical Device Cybersecurity- Mitigating Vulnera...
The Real-World Challenges of Medical Device Cybersecurity- Mitigating Vulnera...The Real-World Challenges of Medical Device Cybersecurity- Mitigating Vulnera...
The Real-World Challenges of Medical Device Cybersecurity- Mitigating Vulnera...
 
The Ultimate Test Automation Guide_ Best Practices and Tips.pdf
The Ultimate Test Automation Guide_ Best Practices and Tips.pdfThe Ultimate Test Automation Guide_ Best Practices and Tips.pdf
The Ultimate Test Automation Guide_ Best Practices and Tips.pdf
 
ODSC - Batch to Stream workshop - integration of Apache Spark, Cassandra, Pos...
ODSC - Batch to Stream workshop - integration of Apache Spark, Cassandra, Pos...ODSC - Batch to Stream workshop - integration of Apache Spark, Cassandra, Pos...
ODSC - Batch to Stream workshop - integration of Apache Spark, Cassandra, Pos...
 
Reassessing the Bedrock of Clinical Function Models: An Examination of Large ...
Reassessing the Bedrock of Clinical Function Models: An Examination of Large ...Reassessing the Bedrock of Clinical Function Models: An Examination of Large ...
Reassessing the Bedrock of Clinical Function Models: An Examination of Large ...
 
A Secure and Reliable Document Management System is Essential.docx
A Secure and Reliable Document Management System is Essential.docxA Secure and Reliable Document Management System is Essential.docx
A Secure and Reliable Document Management System is Essential.docx
 
Unlocking the Future of AI Agents with Large Language Models
Unlocking the Future of AI Agents with Large Language ModelsUnlocking the Future of AI Agents with Large Language Models
Unlocking the Future of AI Agents with Large Language Models
 
Steps To Getting Up And Running Quickly With MyTimeClock Employee Scheduling ...
Steps To Getting Up And Running Quickly With MyTimeClock Employee Scheduling ...Steps To Getting Up And Running Quickly With MyTimeClock Employee Scheduling ...
Steps To Getting Up And Running Quickly With MyTimeClock Employee Scheduling ...
 
Optimizing AI for immediate response in Smart CCTV
Optimizing AI for immediate response in Smart CCTVOptimizing AI for immediate response in Smart CCTV
Optimizing AI for immediate response in Smart CCTV
 
Asset Management Software - Infographic
Asset Management Software - InfographicAsset Management Software - Infographic
Asset Management Software - Infographic
 
Learn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdf
Learn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdfLearn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdf
Learn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdf
 
Russian Call Girls in Karol Bagh Aasnvi ➡️ 8264348440 💋📞 Independent Escort S...
Russian Call Girls in Karol Bagh Aasnvi ➡️ 8264348440 💋📞 Independent Escort S...Russian Call Girls in Karol Bagh Aasnvi ➡️ 8264348440 💋📞 Independent Escort S...
Russian Call Girls in Karol Bagh Aasnvi ➡️ 8264348440 💋📞 Independent Escort S...
 
Der Spagat zwischen BIAS und FAIRNESS (2024)
Der Spagat zwischen BIAS und FAIRNESS (2024)Der Spagat zwischen BIAS und FAIRNESS (2024)
Der Spagat zwischen BIAS und FAIRNESS (2024)
 
TECUNIQUE: Success Stories: IT Service provider
TECUNIQUE: Success Stories: IT Service providerTECUNIQUE: Success Stories: IT Service provider
TECUNIQUE: Success Stories: IT Service provider
 
why an Opensea Clone Script might be your perfect match.pdf
why an Opensea Clone Script might be your perfect match.pdfwhy an Opensea Clone Script might be your perfect match.pdf
why an Opensea Clone Script might be your perfect match.pdf
 

Android virtual machine internals

  • 1. Android VM Internals JVM, Dalvik, Art By: Shaul Rosenzweig
  • 2. What are JVM and Dalvik? Java Virtual machines: An abstract computing machines that enable running of a Java program.
  • 3. What is Art? Application runtime environment that translates application bytecode into native instructions, that are later executed by it.
  • 4. Java Virtual Machine ● Interprets Java bytecode instructions ● Stack based ● Stack based easy to interpret on many architectures ● Classloader loads, verifies, resolves and links .class files which contain instructions on runtime ● Byte long opcodes, out of 255 possible, 198 are in use ● Many languages can be compiled to Java bytecode
  • 5. Dalvik ● Class library based on Apache Harmony JVM, not Oracle JVM ● Developed by Dan Borenstein along with Android, named after town in Iceland ● Register based: optimized for ARM platformance ● Low memory footprint, optimized for running several instances at the same time ● .class files are compiled into .dx, resolved and merged into .dex files compile time ● Longer instructions, less of them ● JIT added in Froyo (2.2) to improve performance ● JIT saves ODEX files in /data/dalvik-cache
  • 6.
  • 7. Art ● Previewed in KitKat, replaced Dalvik in Lollipop ● No more JIT, uses AOT compilation ● Lower memory footprint, more disk used ● Same input bytecodes (DEX) as Dalvik, compiled into native (elf) executables ● Improved GC, power consumption and performance ● Art files: memory mapping is currently fixed (defeating ASLR) ● Not really 64 bit, VM architecture is 32 bit, getting there ● Art format constantly changing, undocumented and proprietary ● Supports ARM, ARM_64, x86 and Mips
  • 8. Bytecode example: prep private static int calculate() { int ret = -321; for(int i = 0; i < 10000 ; i++) { ret += i%5; } return ret; } > javac -target 1.7 -source 1.7 Test.java > dx --dex --output="Test.dex" "Test.class" > r2 Test.class > r2 Test.dex
  • 9. Java bytecode sipush 0xfebf istore_0 iconst_0 istore_1 iload_1 sipush 0x2710 if_icmpge 0x02b6 iload_0 iload_1 iconst_5 irem iadd istore_0 iinc 1 1 goto 0x02a3 iload_0 ireturn const/16 v1, 0xfebf const/4 v0, 0 const/16 v2, 0x2710 if-ge v0, v2, 0x1f2 rem-int/lit8 v2, v0, 0x5 add-int/2addr v1, v2 add-int/lit8 v0, v0, 0x1 goto 0x000001de return v1 DEX bytecode
  • 11. ╒ (fcn) sym.Test.calculate 27 │ 0x0000029d 11febf sipush 65215 ; push short -321 to stack │ 0x000002a0 3b istore_0 ; store stack value to int0 │ 0x000002a1 03 iconst_0 ; load value 0 to stack │ 0x000002a2 3c istore_1 ; store to int1 │ ┌─> 0x000002a3 1b iload_1 ; push value of int1 to stack │ │ 0x000002a4 112710 sipush 10000 ; push constant 10000 to stack │ ┌──< 0x000002a7 a2000f if_icmpge 0x02b6 ; if top stack values >= goto add│ │ ││ 0x000002aa 1a iload_0 ; load int0 into stack │ ││ 0x000002ab 1b iload_1 ; load int1 into stack │ ││ 0x000002ac 08 iconst_5 ; load const 5 into stack │ ││ 0x000002ad 70 irem ; reminder of topmost two and push │ ││ 0x000002ae 60 iadd ; add topmost two and push │ ││ 0x000002af 3b istore_0 ; store to int0 │ ││ 0x000002b0 840101 iinc 1 1 ; int1++ │ │└─< 0x000002b3 a7fff0 goto 0x02a3 ; back to start of loop │ └──> 0x000002b6 1a iload_0 ; load int0 into stack ╘ 0x000002b7 ac ireturn ; return value on stack -321 Operand stackVariables Operations: Push -321 to operand stack
  • 12. ╒ (fcn) sym.Test.calculate 27 │ 0x0000029d 11febf sipush 65215 ; push short -321 to stack │ 0x000002a0 3b istore_0 ; store stack value to int0 │ 0x000002a1 03 iconst_0 ; load value 0 to stack │ 0x000002a2 3c istore_1 ; store to int1 │ ┌─> 0x000002a3 1b iload_1 ; push value of int1 to stack │ │ 0x000002a4 112710 sipush 10000 ; push constant 10000 to stack │ ┌──< 0x000002a7 a2000f if_icmpge 0x02b6 ; if top stack values >= goto add│ │ ││ 0x000002aa 1a iload_0 ; load int0 into stack │ ││ 0x000002ab 1b iload_1 ; load int1 into stack │ ││ 0x000002ac 08 iconst_5 ; load const 5 into stack │ ││ 0x000002ad 70 irem ; reminder of topmost two and push │ ││ 0x000002ae 60 iadd ; add topmost two and push │ ││ 0x000002af 3b istore_0 ; store to int0 │ ││ 0x000002b0 840101 iinc 1 1 ; int1++ │ │└─< 0x000002b3 a7fff0 goto 0x02a3 ; back to start of loop │ └──> 0x000002b6 1a iload_0 ; load int0 into stack ╘ 0x000002b7 ac ireturn ; return value on stack Int0 = -321 Variables Operand stack Operations: Pop topmost value on stack and assign to int0
  • 13. ╒ (fcn) sym.Test.calculate 27 │ 0x0000029d 11febf sipush 65215 ; push short -321 to stack │ 0x000002a0 3b istore_0 ; store stack value to int0 │ 0x000002a1 03 iconst_0 ; load value 0 to stack │ 0x000002a2 3c istore_1 ; store to int1 │ ┌─> 0x000002a3 1b iload_1 ; push value of int1 to stack │ │ 0x000002a4 112710 sipush 10000 ; push constant 10000 to stack │ ┌──< 0x000002a7 a2000f if_icmpge 0x02b6 ; if top stack values >= goto add│ │ ││ 0x000002aa 1a iload_0 ; load int0 into stack │ ││ 0x000002ab 1b iload_1 ; load int1 into stack │ ││ 0x000002ac 08 iconst_5 ; load const 5 into stack │ ││ 0x000002ad 70 irem ; reminder of topmost two and push │ ││ 0x000002ae 60 iadd ; add topmost two and push │ ││ 0x000002af 3b istore_0 ; store to int0 │ ││ 0x000002b0 840101 iinc 1 1 ; int1++ │ │└─< 0x000002b3 a7fff0 goto 0x02a3 ; back to start of loop │ └──> 0x000002b6 1a iload_0 ; load int0 into stack ╘ 0x000002b7 ac ireturn ; return value on stack 0 Int0 = -321 Variables Operand stack Operations: Push 0 to stack
  • 14. ╒ (fcn) sym.Test.calculate 27 │ 0x0000029d 11febf sipush 65215 ; push short -321 to stack │ 0x000002a0 3b istore_0 ; store stack value to int0 │ 0x000002a1 03 iconst_0 ; load value 0 to stack │ 0x000002a2 3c istore_1 ; store to int1 │ ┌─> 0x000002a3 1b iload_1 ; push value of int1 to stack │ │ 0x000002a4 112710 sipush 10000 ; push constant 10000 to stack │ ┌──< 0x000002a7 a2000f if_icmpge 0x02b6 ; if top stack values >= goto add│ │ ││ 0x000002aa 1a iload_0 ; load int0 into stack │ ││ 0x000002ab 1b iload_1 ; load int1 into stack │ ││ 0x000002ac 08 iconst_5 ; load const 5 into stack │ ││ 0x000002ad 70 irem ; reminder of topmost two and push │ ││ 0x000002ae 60 iadd ; add topmost two and push │ ││ 0x000002af 3b istore_0 ; store to int0 │ ││ 0x000002b0 840101 iinc 1 1 ; int1++ │ │└─< 0x000002b3 a7fff0 goto 0x02a3 ; back to start of loop │ └──> 0x000002b6 1a iload_0 ; load int0 into stack ╘ 0x000002b7 ac ireturn ; return value on stack Int0 = -321 Int1 = 0 Variables Operand stack Operations: Pop from stack and assign to Int1
  • 15. ╒ (fcn) sym.Test.calculate 27 │ 0x0000029d 11febf sipush 65215 ; push short -321 to stack │ 0x000002a0 3b istore_0 ; store stack value to int0 │ 0x000002a1 03 iconst_0 ; load value 0 to stack │ 0x000002a2 3c istore_1 ; store to int1 │ ┌─> 0x000002a3 1b iload_1 ; push value of int1 to stack │ │ 0x000002a4 112710 sipush 10000 ; push constant 10000 to stack │ ┌──< 0x000002a7 a2000f if_icmpge 0x02b6 ; if top stack values >= goto add│ │ ││ 0x000002aa 1a iload_0 ; load int0 into stack │ ││ 0x000002ab 1b iload_1 ; load int1 into stack │ ││ 0x000002ac 08 iconst_5 ; load const 5 into stack │ ││ 0x000002ad 70 irem ; reminder of topmost two and push │ ││ 0x000002ae 60 iadd ; add topmost two and push │ ││ 0x000002af 3b istore_0 ; store to int0 │ ││ 0x000002b0 840101 iinc 1 1 ; int1++ │ │└─< 0x000002b3 a7fff0 goto 0x02a3 ; back to start of loop │ └──> 0x000002b6 1a iload_0 ; load int0 into stack ╘ 0x000002b7 ac ireturn ; return value on stack 0 Int0 = -321 Int1 = 0 Variables Operand stack Operations: Push int1 to stack
  • 16. ╒ (fcn) sym.Test.calculate 27 │ 0x0000029d 11febf sipush 65215 ; push short -321 to stack │ 0x000002a0 3b istore_0 ; store stack value to int0 │ 0x000002a1 03 iconst_0 ; load value 0 to stack │ 0x000002a2 3c istore_1 ; store to int1 │ ┌─> 0x000002a3 1b iload_1 ; push value of int1 to stack │ │ 0x000002a4 112710 sipush 10000 ; push constant 10000 to stack │ ┌──< 0x000002a7 a2000f if_icmpge 0x02b6 ; if top stack values >= goto add│ │ ││ 0x000002aa 1a iload_0 ; load int0 into stack │ ││ 0x000002ab 1b iload_1 ; load int1 into stack │ ││ 0x000002ac 08 iconst_5 ; load const 5 into stack │ ││ 0x000002ad 70 irem ; reminder of topmost two and push │ ││ 0x000002ae 60 iadd ; add topmost two and push │ ││ 0x000002af 3b istore_0 ; store to int0 │ ││ 0x000002b0 840101 iinc 1 1 ; int1++ │ │└─< 0x000002b3 a7fff0 goto 0x02a3 ; back to start of loop │ └──> 0x000002b6 1a iload_0 ; load int0 into stack ╘ 0x000002b7 ac ireturn ; return value on stack 10000 0 Int0 = -321 Int1 = 0 Variables Operand stack Operations: Push constant 10000 to stack
  • 17. ╒ (fcn) sym.Test.calculate 27 │ 0x0000029d 11febf sipush 65215 ; push short -321 to stack │ 0x000002a0 3b istore_0 ; store stack value to int0 │ 0x000002a1 03 iconst_0 ; load value 0 to stack │ 0x000002a2 3c istore_1 ; store to int1 │ ┌─> 0x000002a3 1b iload_1 ; push value of int1 to stack │ │ 0x000002a4 112710 sipush 10000 ; push constant 10000 to stack │ ┌──< 0x000002a7 a2000f if_icmpge 0x02b6 ; if top stack values >= goto add│ │ ││ 0x000002aa 1a iload_0 ; load int0 into stack │ ││ 0x000002ab 1b iload_1 ; load int1 into stack │ ││ 0x000002ac 08 iconst_5 ; load const 5 into stack │ ││ 0x000002ad 70 irem ; reminder of topmost two and push │ ││ 0x000002ae 60 iadd ; add topmost two and push │ ││ 0x000002af 3b istore_0 ; store to int0 │ ││ 0x000002b0 840101 iinc 1 1 ; int1++ │ │└─< 0x000002b3 a7fff0 goto 0x02a3 ; back to start of loop │ └──> 0x000002b6 1a iload_0 ; load int0 into stack ╘ 0x000002b7 ac ireturn ; return value on stack Int0 = -321 Int1 = 0 Variables Operand stack Operations: Pop two values from stack (0 and 10000), compare them, if true jump to 0x02b6
  • 18. ╒ (fcn) sym.Test.calculate 27 │ 0x0000029d 11febf sipush 65215 ; push short -321 to stack │ 0x000002a0 3b istore_0 ; store stack value to int0 │ 0x000002a1 03 iconst_0 ; load value 0 to stack │ 0x000002a2 3c istore_1 ; store to int1 │ ┌─> 0x000002a3 1b iload_1 ; push value of int1 to stack │ │ 0x000002a4 112710 sipush 10000 ; push constant 10000 to stack │ ┌──< 0x000002a7 a2000f if_icmpge 0x02b6 ; if top stack values >= goto add│ │ ││ 0x000002aa 1a iload_0 ; load int0 into stack │ ││ 0x000002ab 1b iload_1 ; load int1 into stack │ ││ 0x000002ac 08 iconst_5 ; load const 5 into stack │ ││ 0x000002ad 70 irem ; reminder of topmost two and push │ ││ 0x000002ae 60 iadd ; add topmost two and push │ ││ 0x000002af 3b istore_0 ; store to int0 │ ││ 0x000002b0 840101 iinc 1 1 ; int1++ │ │└─< 0x000002b3 a7fff0 goto 0x02a3 ; back to start of loop │ └──> 0x000002b6 1a iload_0 ; load int0 into stack ╘ 0x000002b7 ac ireturn ; return value on stack -321 Int0 = -321 Int1 = 0 Variables Operand stack Operations: Push int0 into stack
  • 19. ╒ (fcn) sym.Test.calculate 27 │ 0x0000029d 11febf sipush 65215 ; push short -321 to stack │ 0x000002a0 3b istore_0 ; store stack value to int0 │ 0x000002a1 03 iconst_0 ; load value 0 to stack │ 0x000002a2 3c istore_1 ; store to int1 │ ┌─> 0x000002a3 1b iload_1 ; push value of int1 to stack │ │ 0x000002a4 112710 sipush 10000 ; push constant 10000 to stack │ ┌──< 0x000002a7 a2000f if_icmpge 0x02b6 ; if top stack values >= goto add│ │ ││ 0x000002aa 1a iload_0 ; load int0 into stack │ ││ 0x000002ab 1b iload_1 ; load int1 into stack │ ││ 0x000002ac 08 iconst_5 ; load const 5 into stack │ ││ 0x000002ad 70 irem ; reminder of topmost two and push │ ││ 0x000002ae 60 iadd ; add topmost two and push │ ││ 0x000002af 3b istore_0 ; store to int0 │ ││ 0x000002b0 840101 iinc 1 1 ; int1++ │ │└─< 0x000002b3 a7fff0 goto 0x02a3 ; back to start of loop │ └──> 0x000002b6 1a iload_0 ; load int0 into stack ╘ 0x000002b7 ac ireturn ; return value on stack 0 -321 Int0 = -321 Int1 = 0 Variables Operand stack Operations: Push int1 into stack
  • 20. ╒ (fcn) sym.Test.calculate 27 │ 0x0000029d 11febf sipush 65215 ; push short -321 to stack │ 0x000002a0 3b istore_0 ; store stack value to int0 │ 0x000002a1 03 iconst_0 ; load value 0 to stack │ 0x000002a2 3c istore_1 ; store to int1 │ ┌─> 0x000002a3 1b iload_1 ; push value of int1 to stack │ │ 0x000002a4 112710 sipush 10000 ; push constant 10000 to stack │ ┌──< 0x000002a7 a2000f if_icmpge 0x02b6 ; if top stack values >= goto add│ │ ││ 0x000002aa 1a iload_0 ; load int0 into stack │ ││ 0x000002ab 1b iload_1 ; load int1 into stack │ ││ 0x000002ac 08 iconst_5 ; load const 5 into stack │ ││ 0x000002ad 70 irem ; reminder of topmost two and push │ ││ 0x000002ae 60 iadd ; add topmost two and push │ ││ 0x000002af 3b istore_0 ; store to int0 │ ││ 0x000002b0 840101 iinc 1 1 ; int1++ │ │└─< 0x000002b3 a7fff0 goto 0x02a3 ; back to start of loop │ └──> 0x000002b6 1a iload_0 ; load int0 into stack ╘ 0x000002b7 ac ireturn ; return value on stack 5 0 -321 Int0 = -321 Int1 = 0 Variables Operand stack Operations: Push constant 5 into stack
  • 21. ╒ (fcn) sym.Test.calculate 27 │ 0x0000029d 11febf sipush 65215 ; push short -321 to stack │ 0x000002a0 3b istore_0 ; store stack value to int0 │ 0x000002a1 03 iconst_0 ; load value 0 to stack │ 0x000002a2 3c istore_1 ; store to int1 │ ┌─> 0x000002a3 1b iload_1 ; push value of int1 to stack │ │ 0x000002a4 112710 sipush 10000 ; push constant 10000 to stack │ ┌──< 0x000002a7 a2000f if_icmpge 0x02b6 ; if top stack values >= goto add│ │ ││ 0x000002aa 1a iload_0 ; load int0 into stack │ ││ 0x000002ab 1b iload_1 ; load int1 into stack │ ││ 0x000002ac 08 iconst_5 ; load const 5 into stack │ ││ 0x000002ad 70 irem ; reminder of topmost two and push │ ││ 0x000002ae 60 iadd ; add topmost two and push │ ││ 0x000002af 3b istore_0 ; store to int0 │ ││ 0x000002b0 840101 iinc 1 1 ; int1++ │ │└─< 0x000002b3 a7fff0 goto 0x02a3 ; back to start of loop │ └──> 0x000002b6 1a iload_0 ; load int0 into stack ╘ 0x000002b7 ac ireturn ; return value on stack 0 -321 Int0 = -321 Int1 = 0 Variables Operand stack Operations: Pop two values from stack (0 and 5), calculate modulo and push to stack (0)
  • 22. ╒ (fcn) sym.Test.calculate 27 │ 0x0000029d 11febf sipush 65215 ; push short -321 to stack │ 0x000002a0 3b istore_0 ; store stack value to int0 │ 0x000002a1 03 iconst_0 ; load value 0 to stack │ 0x000002a2 3c istore_1 ; store to int1 │ ┌─> 0x000002a3 1b iload_1 ; push value of int1 to stack │ │ 0x000002a4 112710 sipush 10000 ; push constant 10000 to stack │ ┌──< 0x000002a7 a2000f if_icmpge 0x02b6 ; if top stack values >= goto add│ │ ││ 0x000002aa 1a iload_0 ; load int0 into stack │ ││ 0x000002ab 1b iload_1 ; load int1 into stack │ ││ 0x000002ac 08 iconst_5 ; load const 5 into stack │ ││ 0x000002ad 70 irem ; reminder of topmost two and push │ ││ 0x000002ae 60 iadd ; add topmost two and push │ ││ 0x000002af 3b istore_0 ; store to int0 │ ││ 0x000002b0 840101 iinc 1 1 ; int1++ │ │└─< 0x000002b3 a7fff0 goto 0x02a3 ; back to start of loop │ └──> 0x000002b6 1a iload_0 ; load int0 into stack ╘ 0x000002b7 ac ireturn ; return value on stack -321 Int0 = -321 Int1 = 0 Variables Operand stack Operations: Pop two values from stack (0 and -321), add them and push the result into stack
  • 23. ╒ (fcn) sym.Test.calculate 27 │ 0x0000029d 11febf sipush 65215 ; push short -321 to stack │ 0x000002a0 3b istore_0 ; store stack value to int0 │ 0x000002a1 03 iconst_0 ; load value 0 to stack │ 0x000002a2 3c istore_1 ; store to int1 │ ┌─> 0x000002a3 1b iload_1 ; push value of int1 to stack │ │ 0x000002a4 112710 sipush 10000 ; push constant 10000 to stack │ ┌──< 0x000002a7 a2000f if_icmpge 0x02b6 ; if top stack values >= goto add│ │ ││ 0x000002aa 1a iload_0 ; load int0 into stack │ ││ 0x000002ab 1b iload_1 ; load int1 into stack │ ││ 0x000002ac 08 iconst_5 ; load const 5 into stack │ ││ 0x000002ad 70 irem ; reminder of topmost two and push │ ││ 0x000002ae 60 iadd ; add topmost two and push │ ││ 0x000002af 3b istore_0 ; store to int0 │ ││ 0x000002b0 840101 iinc 1 1 ; int1++ │ │└─< 0x000002b3 a7fff0 goto 0x02a3 ; back to start of loop │ └──> 0x000002b6 1a iload_0 ; load int0 into stack ╘ 0x000002b7 ac ireturn ; return value on stack Int0 = -321 Int1 = 0 Variables Operand stack Operations: Pop topmost value from stack and store into int0
  • 24. ╒ (fcn) sym.Test.calculate 27 │ 0x0000029d 11febf sipush 65215 ; push short -321 to stack │ 0x000002a0 3b istore_0 ; store stack value to int0 │ 0x000002a1 03 iconst_0 ; load value 0 to stack │ 0x000002a2 3c istore_1 ; store to int1 │ ┌─> 0x000002a3 1b iload_1 ; push value of int1 to stack │ │ 0x000002a4 112710 sipush 10000 ; push constant 10000 to stack │ ┌──< 0x000002a7 a2000f if_icmpge 0x02b6 ; if top stack values >= goto add│ │ ││ 0x000002aa 1a iload_0 ; load int0 into stack │ ││ 0x000002ab 1b iload_1 ; load int1 into stack │ ││ 0x000002ac 08 iconst_5 ; load const 5 into stack │ ││ 0x000002ad 70 irem ; reminder of topmost two and push │ ││ 0x000002ae 60 iadd ; add topmost two and push │ ││ 0x000002af 3b istore_0 ; store to int0 │ ││ 0x000002b0 840101 iinc 1 1 ; int1++ │ │└─< 0x000002b3 a7fff0 goto 0x02a3 ; back to start of loop │ └──> 0x000002b6 1a iload_0 ; load int0 into stack ╘ 0x000002b7 ac ireturn ; return value on stack Int0 = -321 Int1 = 1 Variables Operand stack Operations: Increment int1 by 1
  • 25. ╒ (fcn) sym.Test.calculate 27 │ 0x0000029d 11febf sipush 65215 ; push short -321 to stack │ 0x000002a0 3b istore_0 ; store stack value to int0 │ 0x000002a1 03 iconst_0 ; load value 0 to stack │ 0x000002a2 3c istore_1 ; store to int1 │ ┌─> 0x000002a3 1b iload_1 ; push value of int1 to stack │ │ 0x000002a4 112710 sipush 10000 ; push constant 10000 to stack │ ┌──< 0x000002a7 a2000f if_icmpge 0x02b6 ; if top stack values >= goto add│ │ ││ 0x000002aa 1a iload_0 ; load int0 into stack │ ││ 0x000002ab 1b iload_1 ; load int1 into stack │ ││ 0x000002ac 08 iconst_5 ; load const 5 into stack │ ││ 0x000002ad 70 irem ; reminder of topmost two and push │ ││ 0x000002ae 60 iadd ; add topmost two and push │ ││ 0x000002af 3b istore_0 ; store to int0 │ ││ 0x000002b0 840101 iinc 1 1 ; int1++ │ │└─< 0x000002b3 a7fff0 goto 0x02a3 ; back to start of loop │ └──> 0x000002b6 1a iload_0 ; load int0 into stack ╘ 0x000002b7 ac ireturn ; return value on stack Int0 = -321 Int1 = 1 Variables Operand stack Operations: Goto 0x2a3
  • 27. ╒ (fcn) sym.Test.calculate 27 │ 0x0000029d 11febf sipush 65215 ; push short -321 to stack │ 0x000002a0 3b istore_0 ; store stack value to int0 │ 0x000002a1 03 iconst_0 ; load value 0 to stack │ 0x000002a2 3c istore_1 ; store to int1 │ ┌─> 0x000002a3 1b iload_1 ; push value of int1 to stack │ │ 0x000002a4 112710 sipush 10000 ; push constant 10000 to stack │ ┌──< 0x000002a7 a2000f if_icmpge 0x02b6 ; if top stack values >= goto add│ │ ││ 0x000002aa 1a iload_0 ; load int0 into stack │ ││ 0x000002ab 1b iload_1 ; load int1 into stack │ ││ 0x000002ac 08 iconst_5 ; load const 5 into stack │ ││ 0x000002ad 70 irem ; reminder of topmost two and push │ ││ 0x000002ae 60 iadd ; add topmost two and push │ ││ 0x000002af 3b istore_0 ; store to int0 │ ││ 0x000002b0 840101 iinc 1 1 ; int1++ │ │└─< 0x000002b3 a7fff0 goto 0x02a3 ; back to start of loop │ └──> 0x000002b6 1a iload_0 ; load int0 into stack ╘ 0x000002b7 ac ireturn ; return value on stack Value of int0 Int0 = {calculated in loop} Int1 = 10000 {break condition} Variables Operand stack Operations: Push int1 into stack
  • 28. ╒ (fcn) sym.Test.calculate 27 │ 0x0000029d 11febf sipush 65215 ; push short -321 to stack │ 0x000002a0 3b istore_0 ; store stack value to int0 │ 0x000002a1 03 iconst_0 ; load value 0 to stack │ 0x000002a2 3c istore_1 ; store to int1 │ ┌─> 0x000002a3 1b iload_1 ; push value of int1 to stack │ │ 0x000002a4 112710 sipush 10000 ; push constant 10000 to stack │ ┌──< 0x000002a7 a2000f if_icmpge 0x02b6 ; if top stack values >= goto add│ │ ││ 0x000002aa 1a iload_0 ; load int0 into stack │ ││ 0x000002ab 1b iload_1 ; load int1 into stack │ ││ 0x000002ac 08 iconst_5 ; load const 5 into stack │ ││ 0x000002ad 70 irem ; reminder of topmost two and push │ ││ 0x000002ae 60 iadd ; add topmost two and push │ ││ 0x000002af 3b istore_0 ; store to int0 │ ││ 0x000002b0 840101 iinc 1 1 ; int1++ │ │└─< 0x000002b3 a7fff0 goto 0x02a3 ; back to start of loop │ └──> 0x000002b6 1a iload_0 ; load int0 into stack ╘ 0x000002b7 ac ireturn ; return value on stack Value of int0 Int0 = {calculated in loop} Int1 = 10000 {break condition} Variables Operand stack Operations: Return topmost value on the stack
  • 30. ╒ (fcn) sym.static.Calculate.LTest_.Calculate.calculate 28 │ ; CALL XREF from 0x0000021e (entry0) │ 0x000001d8 1301bffe const/16 v1, 0xfebf ;ret = -321 │ 0x000001dc 1200 const/4 v0, 0 ;i = 0 │ ┌─> 0x000001de 13021027 const/16 v2, 0x2710 ; 10000 │ ┌──< 0x000001e2 35200800 if-ge v0, v2, 0x1f2 ; if (gt) goto 0x1f2 │ ││ 0x000001e6 dc020005 rem-int/lit8 v2, v0, 0x5 ; v2 = i % 5 │ ││ 0x000001ea b021 add-int/2addr v1, v2 ; ret += v2 │ ││ 0x000001ec d8000001 add-int/lit8 v0, v0, 0x1 ; i++ │ │└─< 0x000001f0 28f7 goto 0x000001de ; goto start of loop ╘ └──> 0x000001f2 0f01 return v1 ; return ret; Registers V1 = -321 Operations: Assign value -321 to register v1
  • 31. ╒ (fcn) sym.static.Calculate.LTest_.Calculate.calculate 28 │ ; CALL XREF from 0x0000021e (entry0) │ 0x000001d8 1301bffe const/16 v1, 0xfebf ;ret = -321 │ 0x000001dc 1200 const/4 v0, 0 ;i = 0 │ ┌─> 0x000001de 13021027 const/16 v2, 0x2710 ; 10000 │ ┌──< 0x000001e2 35200800 if-ge v0, v2, 0x1f2 ; if (gt) goto 0x1f2 │ ││ 0x000001e6 dc020005 rem-int/lit8 v2, v0, 0x5 ; v2 = i % 5 │ ││ 0x000001ea b021 add-int/2addr v1, v2 ; ret += v2 │ ││ 0x000001ec d8000001 add-int/lit8 v0, v0, 0x1 ; i++ │ │└─< 0x000001f0 28f7 goto 0x000001de ; goto start of loop ╘ └──> 0x000001f2 0f01 return v1 ; return ret; Registers: V1 = -321 V0 = 0 Operations: Assign value 0 to register v1
  • 32. ╒ (fcn) sym.static.Calculate.LTest_.Calculate.calculate 28 │ ; CALL XREF from 0x0000021e (entry0) │ 0x000001d8 1301bffe const/16 v1, 0xfebf ;ret = -321 │ 0x000001dc 1200 const/4 v0, 0 ;i = 0 │ ┌─> 0x000001de 13021027 const/16 v2, 0x2710 ; 10000 │ ┌──< 0x000001e2 35200800 if-ge v0, v2, 0x1f2 ; if (gt) goto 0x1f2 │ ││ 0x000001e6 dc020005 rem-int/lit8 v2, v0, 0x5 ; v2 = i % 5 │ ││ 0x000001ea b021 add-int/2addr v1, v2 ; ret += v2 │ ││ 0x000001ec d8000001 add-int/lit8 v0, v0, 0x1 ; i++ │ │└─< 0x000001f0 28f7 goto 0x000001de ; goto start of loop ╘ └──> 0x000001f2 0f01 return v1 ; return ret; Registers V1 = -321 V0 = 0 V2 = 10000 Operations: Assign value 10000 to register v2
  • 33. ╒ (fcn) sym.static.Calculate.LTest_.Calculate.calculate 28 │ ; CALL XREF from 0x0000021e (entry0) │ 0x000001d8 1301bffe const/16 v1, 0xfebf ;ret = -321 │ 0x000001dc 1200 const/4 v0, 0 ;i = 0 │ ┌─> 0x000001de 13021027 const/16 v2, 0x2710 ; 10000 │ ┌──< 0x000001e2 35200800 if-ge v0, v2, 0x1f2 ; if (gt) goto 0x1f2 │ ││ 0x000001e6 dc020005 rem-int/lit8 v2, v0, 0x5 ; v2 = i % 5 │ ││ 0x000001ea b021 add-int/2addr v1, v2 ; ret += v2 │ ││ 0x000001ec d8000001 add-int/lit8 v0, v0, 0x1 ; i++ │ │└─< 0x000001f0 28f7 goto 0x000001de ; goto start of loop ╘ └──> 0x000001f2 0f01 return v1 ; return ret; Registers V1 = -321 V0 = 0 V2 = 10000 Operations: If v2 is greater than v0, jump to 0x01f2
  • 34. ╒ (fcn) sym.static.Calculate.LTest_.Calculate.calculate 28 │ ; CALL XREF from 0x0000021e (entry0) │ 0x000001d8 1301bffe const/16 v1, 0xfebf ;ret = -321 │ 0x000001dc 1200 const/4 v0, 0 ;i = 0 │ ┌─> 0x000001de 13021027 const/16 v2, 0x2710 ; 10000 │ ┌──< 0x000001e2 35200800 if-ge v0, v2, 0x1f2 ; if (gt) goto 0x1f2 │ ││ 0x000001e6 dc020005 rem-int/lit8 v2, v0, 0x5 ; v2 = i % 5 │ ││ 0x000001ea b021 add-int/2addr v1, v2 ; ret += v2 │ ││ 0x000001ec d8000001 add-int/lit8 v0, v0, 0x1 ; i++ │ │└─< 0x000001f0 28f7 goto 0x000001de ; goto start of loop ╘ └──> 0x000001f2 0f01 return v1 ; return ret; Registers V1 = -321 V0 = 0 V2 = 0 Operations: Calculate v0 modulo constant 5 and store result into register v2
  • 35. ╒ (fcn) sym.static.Calculate.LTest_.Calculate.calculate 28 │ ; CALL XREF from 0x0000021e (entry0) │ 0x000001d8 1301bffe const/16 v1, 0xfebf ;ret = -321 │ 0x000001dc 1200 const/4 v0, 0 ;i = 0 │ ┌─> 0x000001de 13021027 const/16 v2, 0x2710 ; 10000 │ ┌──< 0x000001e2 35200800 if-ge v0, v2, 0x1f2 ; if (gt) goto 0x1f2 │ ││ 0x000001e6 dc020005 rem-int/lit8 v2, v0, 0x5 ; v2 = i % 5 │ ││ 0x000001ea b021 add-int/2addr v1, v2 ; ret += v2 │ ││ 0x000001ec d8000001 add-int/lit8 v0, v0, 0x1 ; i++ │ │└─< 0x000001f0 28f7 goto 0x000001de ; goto start of loop ╘ └──> 0x000001f2 0f01 return v1 ; return ret; Registers V1 = -321 V0 = 0 V2 = 0 Operations: Add values of V1 and V2 and store the result into V1
  • 36. ╒ (fcn) sym.static.Calculate.LTest_.Calculate.calculate 28 │ ; CALL XREF from 0x0000021e (entry0) │ 0x000001d8 1301bffe const/16 v1, 0xfebf ;ret = -321 │ 0x000001dc 1200 const/4 v0, 0 ;i = 0 │ ┌─> 0x000001de 13021027 const/16 v2, 0x2710 ; 10000 │ ┌──< 0x000001e2 35200800 if-ge v0, v2, 0x1f2 ; if (gt) goto 0x1f2 │ ││ 0x000001e6 dc020005 rem-int/lit8 v2, v0, 0x5 ; v2 = i % 5 │ ││ 0x000001ea b021 add-int/2addr v1, v2 ; ret += v2 │ ││ 0x000001ec d8000001 add-int/lit8 v0, v0, 0x1 ; i++ │ │└─< 0x000001f0 28f7 goto 0x000001de ; goto start of loop ╘ └──> 0x000001f2 0f01 return v1 ; return ret; Registers V1 = -321 V0 = 1 V2 = 0 Operations: Increment value of V0 by 1
  • 37. ╒ (fcn) sym.static.Calculate.LTest_.Calculate.calculate 28 │ ; CALL XREF from 0x0000021e (entry0) │ 0x000001d8 1301bffe const/16 v1, 0xfebf ;ret = -321 │ 0x000001dc 1200 const/4 v0, 0 ;i = 0 │ ┌─> 0x000001de 13021027 const/16 v2, 0x2710 ; 10000 │ ┌──< 0x000001e2 35200800 if-ge v0, v2, 0x1f2 ; if (gt) goto 0x1f2 │ ││ 0x000001e6 dc020005 rem-int/lit8 v2, v0, 0x5 ; v2 = i % 5 │ ││ 0x000001ea b021 add-int/2addr v1, v2 ; ret += v2 │ ││ 0x000001ec d8000001 add-int/lit8 v0, v0, 0x1 ; i++ │ │└─< 0x000001f0 28f7 goto 0x000001de ; goto start of loop ╘ └──> 0x000001f2 0f01 return v1 ; return ret; Registers V1 = -321 V0 = 1 V2 = 0 Operations: Jump to 0x01de
  • 39. ╒ (fcn) sym.static.Calculate.LTest_.Calculate.calculate 28 │ ; CALL XREF from 0x0000021e (entry0) │ 0x000001d8 1301bffe const/16 v1, 0xfebf ;ret = -321 │ 0x000001dc 1200 const/4 v0, 0 ;i = 0 │ ┌─> 0x000001de 13021027 const/16 v2, 0x2710 ; 10000 │ ┌──< 0x000001e2 35200800 if-ge v0, v2, 0x1f2 ; if (gt) goto 0x1f2 │ ││ 0x000001e6 dc020005 rem-int/lit8 v2, v0, 0x5 ; v2 = i % 5 │ ││ 0x000001ea b021 add-int/2addr v1, v2 ; ret += v2 │ ││ 0x000001ec d8000001 add-int/lit8 v0, v0, 0x1 ; i++ │ │└─< 0x000001f0 28f7 goto 0x000001de ; goto start of loop ╘ └──> 0x000001f2 0f01 return v1 ; return ret; Registers V1 = {calculated value} V0 = 10000 V2 = {calculated value} Operations: Return value of v1
  • 40. More ● Java bytecode: https://en.wikipedia.org/wiki/Java_bytecode_instruction_listings ● DEX bytecode: https://source.android.com/devices/tech/dalvik/dalvik-bytecode.html ● Radare2: http://rada.re/r/ ○ https://play.google.com/store/apps/details?id=org.radare2.installer&hl=en ○ https://www.gitbook.com/book/radare/radare2book/details ○ https://www.gitbook.com/book/monosource/radare2-explorations/details ● IDA pro: https://www.hex-rays.com/products/ida/ ● Dextra, new DEX decompiler: http://newandroidbook.com/tools/dextra.html ● Dan Borenstein, I/O ‘08: https://www.youtube.com/watch?v=ptjedOZEXPM ● I/O 2014 ART talk: https://www.youtube.com/watch?v=EBlTzQsUoOw