thesis/slides.typ
Jean-Marie 'Histausse' Mineau 071a82ea56
All checks were successful
/ test_checkout (push) Successful in 1m50s
rasta and some cl
2025-10-19 04:05:54 +02:00

748 lines
16 KiB
Typst

#import "@preview/polylux:0.4.0": *
#import "slides/lib.typ": *
#import "@preview/codly:1.3.0": *
#import "@preview/codly-languages:0.1.1": *
#show: codly-init.with()
#let default-codly = (
display-name: false,
display-icon: false,
zebra-fill: none,
fill: luma(240),
radius: 1em,
inset: (y: 0.15em),
highlighted-default-color: highlight-color,
highlight-fill: it => it.lighten(40%), //highlight-color,
)
#codly-disable()
#set text(lang: "en")
#set list(marker: none)
#show: sns-polylux-template.with(
txt-font: "New Computer Modern",
title-font: "TeX Gyre Heros",
aspect-ratio : "16-9",
title : [From Large Scale Analysis to Dynamic Deobfuscation],
subtitle : [The Woes of Android Reverse Engineering],
event : [], //[PhD Defense],
short-title : [], //[PhD Defense],
//short-event : [Rennes, 2025/12/9],
title-size : 32pt,
section-size : 18pt,
size : 22pt,
//logo-1 : image("slides/imgs/logo_irisa.png"),
//logo-2 : image("slides/imgs/logo_pirat.png"),
//
colormap : sns-polylux-template_sns-pirat,
authors : (
{
set text(weight: "bold")
[MINEAU Jean-Marie]
v(1em)
},
[LALANDE Jean-François, PhD supervisor],
[VIET TRIEM TONG Valérie, PhD co-supervisor]
),
date : datetime(year: 2025, month: 12, day: 9),
)
/*
* Intro:
* Dear jury, gentle people of the audience, here and online, thank you for your presence.
* I am Jean-Marie Mineau, and today I will be defending my thesis about Android Application reverse engineering and the many difficulties a reverse engineer might encounter.
* This thesis was suppervised by Jean-François Lalande and Valerie Viet Triem Tong, within the PIRAT research team at IRISA.
*/
#title-slide(
logo: grid(columns: 2,
image("slides/imgs/logo_pirat.png"),
image(width: 500pt, "slides/imgs/logo_cs.png"),
image("slides/imgs/logo_irisa.png"),
image("slides/imgs/platypus.png"),
)
)
#slide(
new-sec: true,
title: [Introduction],
hide-title: true,
/*foreground: {
ghost-5(x: 10%, y: 30pt)
ghost-4(x: 95%, y: 80%)
//ghost-4(x: 45%, y: 43%)
}*/
)[
#set align(center+horizon)
#grid(
columns: (1fr, 1fr),
image("slides/imgs/google.png", width: 200pt),
image("slides/imgs/phone.png", height: 350pt)
)
#v(2em)
]
#counter("logical-slide").update( n => n - 1 )
#slide(
foreground: ghost-4(x: 60%, y: 25%, rot: 45deg)
)[
#set align(center+horizon)
#grid(
columns: (3fr, 2fr), stack(dir: ltr,
item-by-item[
- Personal Data and PII
- Computing Power
- Phone
- Mic, Camera, \ Geolocalisation
],
[ $ => $ ],
item-by-item()[
- Ransomware/Spyware
- Cryptojacker
- Expander (phone billing)
- Stalkerware
]
),
{
move(dx: 20pt, image("slides/imgs/phone.png", height: 350pt))
}
)
]
#slide(
title: [Analysing Applications: Which Tools?],
foreground: eye-3(x: 3%, y: 5%)
)[
#set align(center+horizon)
#move(dx: -50pt, image("slides/imgs/apk-analysis.svg", width: 300pt))
]
// something is broken, so hack to keep the page number at the same
#counter("logical-slide").update( n => n - 1 )
#slide(
title: [Analysing Applications: Which Tools?],
)[
#set list(spacing: 3em)
#item-by-item[
- #cite(<Li2017>, form: "prose"): systematic literature review for Android static analysis, lists open-sourced tools
- #cite(<reaves_droid_2016>, form: "prose"): tests analysis tools, raises concerns about reusability and analysis of
real-world applications
]
]
// something is broken, so hack to keep the page number at the same
#counter("logical-slide").update( n => n - 1 )
#slide(
title: [Analysing Applications: Which Tools?],
)[
#highlight-block(pb1-text)
]
#slide(
title: [Obfuscation],
//foreground: eye-1(x: 95%, y: 85%, mirror: true)
)[
#set list(marker: [-])
Applications might use *obfuscation* to either:
- protect their IP
- hide malicious behaviour
#v(1em)#uncover(2)[
We will focus on two techniques:
- *Dynamic Code Loading*
- *Reflection*
]
]
#for i in range(4) {
if i != 0 {
counter("logical-slide").update( n => n - 1 )
}
show: yes-codly
slide(
title: [Obfuscation],
subtitle: if i == 0 [Example] else if i == 1 [Dynamic Code Loading] else if i in (2, 3) [Reflection] else { none },
foreground: eye-1(x: 95%, y: 85%, mirror: true)
)[
#if i == 0 {
codly(..default-codly)
} else if i == 1 {
codly(
highlighted-lines: (1, 5, 6, 7, 8),
..default-codly
)
} else if i == 2 {
codly(
highlighted-lines: (2, 3),
highlights: (
(line: 10, start: 42, end: 59, fill: pirat-color.blue),
(line: 13, start: 3, end: 21, fill: pirat-color.blue),
),
..default-codly
)
} else if i == 3 {
codly(
highlighted-lines: (10,),
highlights: (
(line: 12, start: 14, end: 34, fill: pirat-color.blue),
(line: 15, start: 2, end: 19, fill: pirat-color.blue),
),
..default-codly
)
}
#scale(70%, reflow: true)[
```java
String DEX = "ZGV4CjA [...] EAAABEAwAA";
String className = "W5f3 [...] 3sls=";
String methodName = "n6WGYJzjDrUvR9cYljlNlw==";
ClassLoader cl = new InMemoryDexClassLoader(
ByteBuffer.wrap(Base64.decode(DEX, 2)),
Main.class.getClassLoader()
);
Class<?> loadedClass = this.cl.loadClass(decrypt(className));
Object obj = "FooBar";
Object ret = loadedClass.getMethod(
decrypt(methodName),
String.class
).invoke(null, obj);
```]
]
}
#counter("logical-slide").update( n => n - 1 )
#slide(
title: [Obfuscation],
subtitle: [Deobfuscated],
)[
#show: yes-codly
#codly(
skips: ((3, 10), (5, 10), (6, 10)),
..default-codly
)
#scale(100%)[
```java
public class Foo {
public static String bar(String arg) {
}
}
String ret = Foo.bar("FooBar");
```]
]
#slide(
title: [Class Loading],
)[
#set align(center)
#show: yes-codly
#grid(
columns: (2fr, 1em, 1fr),
scale(70%, reflow: true)[
#codly(
highlights: (
(line: 1, start: 0, end: 11, fill: pirat-color.blue),
(line: 1, start: 22, end: 43, fill: pirat-color.blue),
(line: 3, start: 14, end: 27, fill: pirat-color.blue),
(line: 6, start: 32, end: 40, fill: pirat-color.blue),
),
..default-codly
)
```java
ClassLoader cl = new InMemoryDexClassLoader(
ByteBuffer.wrap(Base64.decode(DEX, 2)),
Main.class.getClassLoader()
);
Class<?> loadedClass = this.cl.loadClass(decrypt(className));
```
], [], uncover(2, scale(70%, reflow: true)[
#codly(
..default-codly
)
```java
class A {
public static void foo() {
B b = new B();
b.bar();
}
}
```
Where is the class loader?
])
)
]
#counter("logical-slide").update( n => n - 1 )
#slide(
title: [Class Loading],
)[
#item-by-item[
- Used to select classes implementation
- More complexe than it looks
- Doubious documentation
- Not studied in the context of Android Static Analysis
]
]
#counter("logical-slide").update( n => n - 1 )
#slide(
title: [Class Loading],
)[
#highlight-block(pb2-text)
]
#slide(
foreground: ghost-5(x: 10%, y: 7%)
)[
#set align(center+horizon)
#grid(
columns: (1fr, 1fr),
gutter: 2em,
[
== Dynamic Analysis
#item-by-item[
- Run the application
- _See_ dynamically loaded bytecode
- _See_ reflection calls
- Limited by code coverage
]
],
[
== Static Analysis
#item-by-item(start: 5)[
- Do *not* run the application
- *Not* limited by code coverage
- Some values cannot be computed
]
],
grid.cell(colspan: 2, uncover(7)[
#text(size: 30pt)[Can we combine both?]
]),
)
]
#slide[
#highlight-block(pb3-text)
]
#slide[
#highlight-block(pb1-text)
#highlight-block(pb2-text)
#highlight-block(pb3-text)
]
#new-section-slide([Tool Reusability])
#slide(
title: [Methodology]
)[
#set align(center+horizon)
#show figure.caption: none
#scale(100%, get_figure(<fig:rasta-methodo-collection>))
#v(1em)
#text(size: 25pt)[22 tools selected, 2 we could not package]
/*
#stack(dir: ltr,
scale(40%, reflow: true, get_figure(<tab:rasta-tools>)),
scale(55%, reflow: true, get_figure(<tab:rasta-sources>)),
)*/
]
#slide(
title: [Methodology],
foreground: place(
bottom + left,
dx: 88%,
dy: -63%,
)[
#set align(center+horizon)
#set text(size: 15pt)
62 525 APKs #v(-1.5em) from #v(-1.5em) 2010 to 2023
]
)[
#set align(center+horizon)
#show figure.caption: none
#scale(90%, get_figure(<fig:rasta-overview>))
#text(size: 25pt)[We check if the results *exist* after running a tool]
]
#slide(
title: [Results],
foreground: ghost-2(x: 97%, y: 10%)
)[
#set align(center+horizon)
#show figure.caption: none
#scale(100%, get_figure(<fig:rasta-exit>))
//#text(size: 25pt)[We check if the results *exist* after running a tool]
]
#counter("logical-slide").update( n => n - 1 )
#slide(
title: [Results],
foreground: {
ghost-2(x: 97%, y: 10%)
let x_0 = 112pt
let y_0 = -117pt
let w = 21pt
let h = 235pt
let dx = 33.3
for i in range(20) {
let color = if i in (2, 4, 6, 7, 8, 9, 14, 16, 18, 19) {
white.transparentize(100%)
} else {
white.transparentize(10%)
}
place(
bottom + left,
dx: x_0 + i*dx*1pt,
dy: y_0,
rect(
width: w,
height: h,
//stroke: red,
fill: color,
)
)
}
place(bottom + left, line(
start: (x_0 - 20pt, y_0 - h/2),
end: (x_0 + dx * 20 * 1pt, y_0 - h/2),
stroke: pirat-color.red + 3pt
))
}
)[
#set align(center+horizon)
#show figure.caption: none
#scale(100%, get_figure(<fig:rasta-exit>))
]
#counter("logical-slide").update( n => n - 1 )
#slide(
title: [Results],
foreground: {
ghost-2(x: 97%, y: 10%)
let x_0 = 112pt
let y_0 = -117pt
let w = 21pt
let h = 235pt
let dx = 33.3
for i in range(20) {
let color = if i in (3, 10) {
white.transparentize(100%)
} else {
white.transparentize(10%)
}
place(
bottom + left,
dx: x_0 + i*dx*1pt,
dy: y_0,
rect(
width: w,
height: h,
//stroke: red,
fill: color,
)
)
}
place(bottom + left, line(
start: (x_0 - 20pt, y_0 - h/2),
end: (x_0 + dx * 20 * 1pt, y_0 - h/2),
stroke: pirat-color.red + 3pt
))
}
)[
#set align(center+horizon)
#show figure.caption: none
#scale(100%, get_figure(<fig:rasta-exit>))
]
#slide(
title: [Results over Time],
)[
#set align(center+horizon)
#show figure.caption: none
#scale(150%, get_figure(<fig:rasta-exit-evolution-java>))
]
#slide(
title: [Bytecode Size],
)[
#set align(center+horizon)
#show figure.caption: none
#scale(120%, get_figure(<fig:rasta-rate-evolution-java-2022>))
#text(size: 22pt)[Finishing rate as a function of the bytecode size, for APKs discovered in 2022]
]
#slide(
title: [Conclusion]
)[
#set align(center)
#item-by-item[
- Over 22 tools, 10 are usable (*less than half*)
- Newer applications are harder to analyse
- Applications with more bytecode are harder to analyse
- Applications targetting more recent versions of Android are harder to analyse
]
]
#slide[
#set align(center)
#text(size: 22pt)[21st International Conference on Software and Systems Reuse (ICSR 2024)]
#v(2em)
#show regex("\[\d+\]"): none
#cite(<rasta>, form: "full")
]
#new-section-slide([Class Shadowing])
#slide(
title: [Class Loading],
)[
#set align(center)
#show: yes-codly
#grid(
columns: (2fr, 1em, 1fr),
scale(70%, reflow: true)[
#codly(
highlights: (/*
(line: 1, start: 0, end: 11, fill: pirat-color.blue),
(line: 1, start: 22, end: 43, fill: pirat-color.blue),
(line: 3, start: 14, end: 27, fill: pirat-color.blue),
(line: 6, start: 32, end: 40, fill: pirat-color.blue),
*/),
..default-codly
)
```java
ClassLoader cl = new InMemoryDexClassLoader(
ByteBuffer.wrap(Base64.decode(DEX, 2)),
Main.class.getClassLoader()
);
Class<?> loadedClass = this.cl.loadClass(decrypt(className));
```
], [], scale(70%, reflow: true)[
#codly(
..default-codly
)
```java
class A {
public static void foo() {
B b = new B();
b.bar();
}
}
```
]
)
]
#slide(
title: [Android Ecosystem]
)[
#set align(center+horizon)
#show figure.caption: none
#grid(
columns: (3fr, 1fr),
scale(reflow: true, get_figure(<fig:cl-archisdk>)),
[
#set align(left)
#set text(size: 20pt)
#set list(marker: [-])
=== Types of classes:
- APK Classes
- Platform Classes
- SDK Classes
- Hidden APIs
]
)
// TODO: hightlight
]
#slide(
title: [Android ClassLoaders]
)[
#set align(center+horizon)
#show figure.caption: none
#scale(60%, reflow: true, get_figure(<fig:cl-class_loading_classes>))
]
#slide(
title: [MultiDex]
)[
#set align(center + horizon)
#only(1)[
#block(
fill: green.lighten(50%),
inset: 10pt,
radius: 12pt,
)[
#set align(left+top)
=== `app.apk`
#line(length: 30%)
```
AndroidManifest.xml
resources.arsc
META-INF/
res/
classes.dex
```
]
]
#only(2)[
#block(
fill: green.lighten(50%),
inset: 8pt,
radius: 8pt,
)[
#set align(left+top)
=== `app.apk`
#line(length: 50%)
#stack(dir: ltr,
```
AndroidManifest.xml
resources.arsc
META-INF/
res/
classes.dex
```,
h(2em),[
```
classes2.dex
classes3.dex
```
]
)
]
]
#only(3)[
#block(
fill: green.lighten(50%),
inset: 8pt,
radius: 8pt,
)[
#set align(left+top)
=== `app.apk`
#line(length: 75%)
#stack(dir:ltr,
```
AndroidManifest.xml
resources.arsc
META-INF/
res/
classes.dex
classes2.dex
classes3.dex
```, h(2em),
```
classes4.dex
classes5.dex
classes6.dex
classes7.dex
classes8.dex
classes9.dex
classes10.dex
```, h(2em),
```
classes11.dex
classes12.dex
classes13.dex
classes14.dex
classes15.dex
classes16.dex
...
```
)
]
#ghost-4(x: 2%, y: 2%, mirror: true)
]
]
#slide[
#set align(center)
#text(size: 22pt)[Digital Threats: Research and Practice]
#v(2em)
#show regex("\[\d+\]"): none
#cite(<classloaderinthemiddle>, form: "full")
]
#new-section-slide([The Application of Theseus])
#slide[Th 1
]
#slide[Th 2
]
#new-section-slide([Conclusion])
#slide[Conclusion 1
]
#slide[Conclusion 2
]
#empty-slide[
Questions
]
/*
#slide()[
#get_figure(<fig:th-cg-before-after>))
]
#slide()[
#pl.toolbox.slide-number
#context({
pl.toolbox.all-sections((sections, current) => {
for i in sections {
repr(i.at("body").at("text"))
}
})
})
]
*/
#pagebreak()
#set page(height: auto, margin: 25mm)
#bibliography("bibliography.bib")