SlideShare a Scribd company logo
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
 
The System of Automatic Searching for Vulnerabilities or how to use Taint Ana...
The System of Automatic Searching for Vulnerabilities or how to use Taint Ana...The System of Automatic Searching for Vulnerabilities or how to use Taint Ana...
The System of Automatic Searching for Vulnerabilities or how to use Taint Ana...Positive Hack Days
 

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
 
The System of Automatic Searching for Vulnerabilities or how to use Taint Ana...
The System of Automatic Searching for Vulnerabilities or how to use Taint Ana...The System of Automatic Searching for Vulnerabilities or how to use Taint Ana...
The System of Automatic Searching for Vulnerabilities or how to use Taint Ana...
 

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

how-to-download-files-safely-from-the-internet.pdf
how-to-download-files-safely-from-the-internet.pdfhow-to-download-files-safely-from-the-internet.pdf
how-to-download-files-safely-from-the-internet.pdfMehmet Akar
 
TROUBLESHOOTING 9 TYPES OF OUTOFMEMORYERROR
TROUBLESHOOTING 9 TYPES OF OUTOFMEMORYERRORTROUBLESHOOTING 9 TYPES OF OUTOFMEMORYERROR
TROUBLESHOOTING 9 TYPES OF OUTOFMEMORYERRORTier1 app
 
AI/ML Infra Meetup | Reducing Prefill for LLM Serving in RAG
AI/ML Infra Meetup | Reducing Prefill for LLM Serving in RAGAI/ML Infra Meetup | Reducing Prefill for LLM Serving in RAG
AI/ML Infra Meetup | Reducing Prefill for LLM Serving in RAGAlluxio, Inc.
 
Tree in the Forest - Managing Details in BDD Scenarios (live2test 2024)
Tree in the Forest - Managing Details in BDD Scenarios (live2test 2024)Tree in the Forest - Managing Details in BDD Scenarios (live2test 2024)
Tree in the Forest - Managing Details in BDD Scenarios (live2test 2024)Gáspár Nagy
 
KLARNA - Language Models and Knowledge Graphs: A Systems Approach
KLARNA -  Language Models and Knowledge Graphs: A Systems ApproachKLARNA -  Language Models and Knowledge Graphs: A Systems Approach
KLARNA - Language Models and Knowledge Graphs: A Systems ApproachNeo4j
 
A Guideline to Gorgias to to Re:amaze Data Migration
A Guideline to Gorgias to to Re:amaze Data MigrationA Guideline to Gorgias to to Re:amaze Data Migration
A Guideline to Gorgias to to Re:amaze Data MigrationHelp Desk Migration
 
How Does XfilesPro Ensure Security While Sharing Documents in Salesforce?
How Does XfilesPro Ensure Security While Sharing Documents in Salesforce?How Does XfilesPro Ensure Security While Sharing Documents in Salesforce?
How Does XfilesPro Ensure Security While Sharing Documents in Salesforce?XfilesPro
 
Implementing KPIs and Right Metrics for Agile Delivery Teams.pdf
Implementing KPIs and Right Metrics for Agile Delivery Teams.pdfImplementing KPIs and Right Metrics for Agile Delivery Teams.pdf
Implementing KPIs and Right Metrics for Agile Delivery Teams.pdfVictor Lopez
 
How to install and activate eGrabber JobGrabber
How to install and activate eGrabber JobGrabberHow to install and activate eGrabber JobGrabber
How to install and activate eGrabber JobGrabbereGrabber
 
GraphSummit Stockholm - Neo4j - Knowledge Graphs and Product Updates
GraphSummit Stockholm - Neo4j - Knowledge Graphs and Product UpdatesGraphSummit Stockholm - Neo4j - Knowledge Graphs and Product Updates
GraphSummit Stockholm - Neo4j - Knowledge Graphs and Product UpdatesNeo4j
 
IT Software Development Resume, Vaibhav jha 2024
IT Software Development Resume, Vaibhav jha 2024IT Software Development Resume, Vaibhav jha 2024
IT Software Development Resume, Vaibhav jha 2024vaibhav130304
 
CompTIA Security+ (Study Notes) for cs.pdf
CompTIA Security+ (Study Notes) for cs.pdfCompTIA Security+ (Study Notes) for cs.pdf
CompTIA Security+ (Study Notes) for cs.pdfFurqanuddin10
 
Facemoji Keyboard released its 2023 State of Emoji report, outlining the most...
Facemoji Keyboard released its 2023 State of Emoji report, outlining the most...Facemoji Keyboard released its 2023 State of Emoji report, outlining the most...
Facemoji Keyboard released its 2023 State of Emoji report, outlining the most...rajkumar669520
 
Crafting the Perfect Measurement Sheet with PLM Integration
Crafting the Perfect Measurement Sheet with PLM IntegrationCrafting the Perfect Measurement Sheet with PLM Integration
Crafting the Perfect Measurement Sheet with PLM IntegrationWave PLM
 
AI/ML Infra Meetup | Improve Speed and GPU Utilization for Model Training & S...
AI/ML Infra Meetup | Improve Speed and GPU Utilization for Model Training & S...AI/ML Infra Meetup | Improve Speed and GPU Utilization for Model Training & S...
AI/ML Infra Meetup | Improve Speed and GPU Utilization for Model Training & S...Alluxio, Inc.
 
StrimziCon 2024 - Transition to Apache Kafka on Kubernetes with Strimzi
StrimziCon 2024 - Transition to Apache Kafka on Kubernetes with StrimziStrimziCon 2024 - Transition to Apache Kafka on Kubernetes with Strimzi
StrimziCon 2024 - Transition to Apache Kafka on Kubernetes with Strimzisteffenkarlsson2
 
JustNaik Solution Deck (stage bus sector)
JustNaik Solution Deck (stage bus sector)JustNaik Solution Deck (stage bus sector)
JustNaik Solution Deck (stage bus sector)Max Lee
 
Agnieszka Andrzejewska - BIM School Course in Kraków
Agnieszka Andrzejewska - BIM School Course in KrakówAgnieszka Andrzejewska - BIM School Course in Kraków
Agnieszka Andrzejewska - BIM School Course in Krakówbim.edu.pl
 
AI/ML Infra Meetup | ML explainability in Michelangelo
AI/ML Infra Meetup | ML explainability in MichelangeloAI/ML Infra Meetup | ML explainability in Michelangelo
AI/ML Infra Meetup | ML explainability in MichelangeloAlluxio, Inc.
 
The Impact of PLM Software on Fashion Production
The Impact of PLM Software on Fashion ProductionThe Impact of PLM Software on Fashion Production
The Impact of PLM Software on Fashion ProductionWave PLM
 

Recently uploaded (20)

how-to-download-files-safely-from-the-internet.pdf
how-to-download-files-safely-from-the-internet.pdfhow-to-download-files-safely-from-the-internet.pdf
how-to-download-files-safely-from-the-internet.pdf
 
TROUBLESHOOTING 9 TYPES OF OUTOFMEMORYERROR
TROUBLESHOOTING 9 TYPES OF OUTOFMEMORYERRORTROUBLESHOOTING 9 TYPES OF OUTOFMEMORYERROR
TROUBLESHOOTING 9 TYPES OF OUTOFMEMORYERROR
 
AI/ML Infra Meetup | Reducing Prefill for LLM Serving in RAG
AI/ML Infra Meetup | Reducing Prefill for LLM Serving in RAGAI/ML Infra Meetup | Reducing Prefill for LLM Serving in RAG
AI/ML Infra Meetup | Reducing Prefill for LLM Serving in RAG
 
Tree in the Forest - Managing Details in BDD Scenarios (live2test 2024)
Tree in the Forest - Managing Details in BDD Scenarios (live2test 2024)Tree in the Forest - Managing Details in BDD Scenarios (live2test 2024)
Tree in the Forest - Managing Details in BDD Scenarios (live2test 2024)
 
KLARNA - Language Models and Knowledge Graphs: A Systems Approach
KLARNA -  Language Models and Knowledge Graphs: A Systems ApproachKLARNA -  Language Models and Knowledge Graphs: A Systems Approach
KLARNA - Language Models and Knowledge Graphs: A Systems Approach
 
A Guideline to Gorgias to to Re:amaze Data Migration
A Guideline to Gorgias to to Re:amaze Data MigrationA Guideline to Gorgias to to Re:amaze Data Migration
A Guideline to Gorgias to to Re:amaze Data Migration
 
How Does XfilesPro Ensure Security While Sharing Documents in Salesforce?
How Does XfilesPro Ensure Security While Sharing Documents in Salesforce?How Does XfilesPro Ensure Security While Sharing Documents in Salesforce?
How Does XfilesPro Ensure Security While Sharing Documents in Salesforce?
 
Implementing KPIs and Right Metrics for Agile Delivery Teams.pdf
Implementing KPIs and Right Metrics for Agile Delivery Teams.pdfImplementing KPIs and Right Metrics for Agile Delivery Teams.pdf
Implementing KPIs and Right Metrics for Agile Delivery Teams.pdf
 
How to install and activate eGrabber JobGrabber
How to install and activate eGrabber JobGrabberHow to install and activate eGrabber JobGrabber
How to install and activate eGrabber JobGrabber
 
GraphSummit Stockholm - Neo4j - Knowledge Graphs and Product Updates
GraphSummit Stockholm - Neo4j - Knowledge Graphs and Product UpdatesGraphSummit Stockholm - Neo4j - Knowledge Graphs and Product Updates
GraphSummit Stockholm - Neo4j - Knowledge Graphs and Product Updates
 
IT Software Development Resume, Vaibhav jha 2024
IT Software Development Resume, Vaibhav jha 2024IT Software Development Resume, Vaibhav jha 2024
IT Software Development Resume, Vaibhav jha 2024
 
CompTIA Security+ (Study Notes) for cs.pdf
CompTIA Security+ (Study Notes) for cs.pdfCompTIA Security+ (Study Notes) for cs.pdf
CompTIA Security+ (Study Notes) for cs.pdf
 
Facemoji Keyboard released its 2023 State of Emoji report, outlining the most...
Facemoji Keyboard released its 2023 State of Emoji report, outlining the most...Facemoji Keyboard released its 2023 State of Emoji report, outlining the most...
Facemoji Keyboard released its 2023 State of Emoji report, outlining the most...
 
Crafting the Perfect Measurement Sheet with PLM Integration
Crafting the Perfect Measurement Sheet with PLM IntegrationCrafting the Perfect Measurement Sheet with PLM Integration
Crafting the Perfect Measurement Sheet with PLM Integration
 
AI/ML Infra Meetup | Improve Speed and GPU Utilization for Model Training & S...
AI/ML Infra Meetup | Improve Speed and GPU Utilization for Model Training & S...AI/ML Infra Meetup | Improve Speed and GPU Utilization for Model Training & S...
AI/ML Infra Meetup | Improve Speed and GPU Utilization for Model Training & S...
 
StrimziCon 2024 - Transition to Apache Kafka on Kubernetes with Strimzi
StrimziCon 2024 - Transition to Apache Kafka on Kubernetes with StrimziStrimziCon 2024 - Transition to Apache Kafka on Kubernetes with Strimzi
StrimziCon 2024 - Transition to Apache Kafka on Kubernetes with Strimzi
 
JustNaik Solution Deck (stage bus sector)
JustNaik Solution Deck (stage bus sector)JustNaik Solution Deck (stage bus sector)
JustNaik Solution Deck (stage bus sector)
 
Agnieszka Andrzejewska - BIM School Course in Kraków
Agnieszka Andrzejewska - BIM School Course in KrakówAgnieszka Andrzejewska - BIM School Course in Kraków
Agnieszka Andrzejewska - BIM School Course in Kraków
 
AI/ML Infra Meetup | ML explainability in Michelangelo
AI/ML Infra Meetup | ML explainability in MichelangeloAI/ML Infra Meetup | ML explainability in Michelangelo
AI/ML Infra Meetup | ML explainability in Michelangelo
 
The Impact of PLM Software on Fashion Production
The Impact of PLM Software on Fashion ProductionThe Impact of PLM Software on Fashion Production
The Impact of PLM Software on Fashion Production
 

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