All checks were successful
/ test_checkout (push) Successful in 1m48s
420 lines
8.9 KiB
Typst
420 lines
8.9 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[
|
|
Rasta 1
|
|
/*
|
|
#stack(dir: ltr,
|
|
scale(40%, reflow: true, get_figure(<tab:rasta-tools>)),
|
|
scale(55%, reflow: true, get_figure(<tab:rasta-sources>)),
|
|
)*/
|
|
]
|
|
|
|
#slide[
|
|
Rasta 2
|
|
|
|
]
|
|
|
|
#new-section-slide([Class Shadowing])
|
|
|
|
#slide[Shadow 1
|
|
|
|
]
|
|
#slide[Shadow 2
|
|
|
|
]
|
|
#slide[Shadow 3
|
|
|
|
]
|
|
|
|
#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")
|