diff --git a/main.typ b/main.typ index e35515d..2371373 100644 --- a/main.typ +++ b/main.typ @@ -71,7 +71,7 @@ year: 2025, month: 12, day: 9, - ).display("[year]-[month]-[day]"), + ).display("[year]-[month]-XX"), //[day]"), jury-content: jury-content, university: "CS", keywords-en: keywords-en, diff --git a/slides.typ b/slides.typ index 217a10b..70913c7 100644 --- a/slides.typ +++ b/slides.typ @@ -1,24 +1,19 @@ #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() +#show link: it => if type(it.dest) == label { + context { + if query(it.dest).len() == 0 { + it.body + } else { + it + } + } +} else { + it +} #set text(lang: "en") -#set list(marker: none) - #show: sns-polylux-template.with( txt-font: "New Computer Modern", title-font: "TeX Gyre Heros", @@ -29,8 +24,6 @@ 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"), // @@ -47,14 +40,6 @@ 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"), @@ -68,279 +53,18 @@ 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(, form: "prose"): systematic literature review for Android static analysis, lists open-sourced tools - - #cite(, 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 ) + foreground: { + ghost-5(dx: 10%, dy: 30pt) + ghost-4(dx: 95%, dy: 80%) + //ghost-4(dx: 45%, dy: 43%) } - 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?] - ]), - ) + Intro 1 ] #slide[ - #highlight-block(pb3-text) -] + Intro 2 -#slide[ - #highlight-block(pb1-text) - #highlight-block(pb2-text) - #highlight-block(pb3-text) ] #new-section-slide([Tool Reusability]) @@ -396,11 +120,13 @@ /* + #slide()[ #get_figure()) ] #slide()[ +/* #pl.toolbox.slide-number #context({ pl.toolbox.all-sections((sections, current) => { @@ -409,12 +135,67 @@ } }) }) + */ + #sections() +] + +// #toc-slide( title: [Outline] ) + + + +#slide( + title: [A slide without subtitle], +)[ + This slide does not have a subtitle, but belongs to the first section. +] + +#new-section-slide([Second section]) + +#slide( + title: [Title], + subtitle: [Subtitle], +)[ + plop +] + +#slide( + subtitle: [Hidden subtitle], +)[ + This slide however does not have a title. It belongs to the second section. +] + +#new-section-slide([Third section]) + +#focus-slide()[ + This is a _focus-slide_. +] + +#slide(new-sec: true, title: [Fourth section],)[ + A slide can also open a new section... +] + +#focus-slide(new-sec: [Fifth section],)[ + ... and also a focus-slide can do it! +] + +#empty-slide()[ + Ending slide ] */ +/* +* Notes: +* +* 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. +* +*/ + #pagebreak() #set page(height: auto, margin: 25mm) #bibliography("bibliography.bib") diff --git a/slides/imgs/apk-analysis.svg b/slides/imgs/apk-analysis.svg deleted file mode 100644 index 6ee3b9f..0000000 --- a/slides/imgs/apk-analysis.svg +++ /dev/null @@ -1,200 +0,0 @@ - - - - - - - - - - - - - - .APK - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/slides/imgs/dex_insertion.svg b/slides/imgs/dex_insertion.svg deleted file mode 100644 index 96efa89..0000000 --- a/slides/imgs/dex_insertion.svg +++ /dev/null @@ -1,1062 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - .DEX - - - - - - - - - - - - .DEX - - - - - - - - - app.apk - classes.dex - - - .DEX - - - - - - - - - classes2.dex - - - .DEX - - - - - - - - - classes.dex - lib.dex - - - .XML - - - - - - - AndroidManifest.xml - - - .XML - - - - - - - resources.arsc - lib/ - - - .DEX - - - - - - - - - classes2.dex - - - .DEX - - - - - - - - - classes5.dex - - - .DEX - - - - - - - - - classes6.dex - - - .DEX - - - - - - - - - classes3.dex - - - .DEX - - - - - - - - - classes4.dex - - - lib.jar - - - res/ - - - assets/ - - - - - Original Files - Added Files - - - - - diff --git a/slides/imgs/google.png b/slides/imgs/google.png deleted file mode 100644 index a0135df..0000000 Binary files a/slides/imgs/google.png and /dev/null differ diff --git a/slides/imgs/phone.png b/slides/imgs/phone.png deleted file mode 100644 index 8c31937..0000000 Binary files a/slides/imgs/phone.png and /dev/null differ diff --git a/slides/imgs/phone.png~ b/slides/imgs/phone.png~ deleted file mode 100644 index d866f2f..0000000 Binary files a/slides/imgs/phone.png~ and /dev/null differ diff --git a/slides/lib.typ b/slides/lib.typ index cd7e603..39066fa 100644 --- a/slides/lib.typ +++ b/slides/lib.typ @@ -1,8 +1,6 @@ #import "sns_polylux_template.typ": * #import "figures.typ": figures, get_figure -#import "../lib.typ": pb1-text, pb2-text, pb3-text - #let pirat-color = ( black: rgb("#000000"), white: rgb("#FFFFFF"), @@ -19,12 +17,6 @@ rgb("#E69426"), pirat-color.red, ) -#let highlight-block = block.with( - fill: pirat-color.blue, - width: 100%, - inset: 8pt, - radius: 4pt, -) #let colortest = [ #for th in ( @@ -38,60 +30,17 @@ pirat-color.red, } ] -#let highlight-color = pirat-color.blue.lighten(40%) - -/* don't work ? at least for raw block? -#let scale-down-to-page(body) = { - layout(size => { - let size_body = measure(body) - let ratio = if size_body.width == 0pt and size_body.height == 0pt { - none - } else if size_body.width == 0pt { - size.height / size_body.height - } else if size_body.height == 0pt { - size.width / size_body.width - } else { - let r_x = size.width / size_body.width - let r_y = size.height / size_body.height - calc.max(r_x, r_y) - } - if ratio == none or ratio >= 1 { - body - } else { - scale(ratio * 100%, body) - } - repr(size) - linebreak() - repr(size_body) - linebreak() - repr(ratio*100%) - }) -} -*/ - -#let ghost( - img, x: 0pt, - y: 0pt, - mirror: false, - rot: 0deg, - height: 100pt -) = context { +#let ghost(img, dx: 0pt, dy: 0pt, height: 100pt, ..args,) = context { let img = image(img, height: height) - if mirror { - img = scale(x: -100%, img) - } - if rot != 0deg { - img = rotate(rot, img) - } - let s = measure(img) let hx = s.width / 2 let hy = s.height / 2 place( bottom + left, - dx: x - hx, - dy: -y + hy, + dx: dx - hx, + dy: -dy + hy, + ..args, img ) } diff --git a/slides/sns_polylux_template.typ b/slides/sns_polylux_template.typ index 2e5a121..3ae4ff7 100644 --- a/slides/sns_polylux_template.typ +++ b/slides/sns_polylux_template.typ @@ -38,7 +38,6 @@ cmyk(25%,7%,0%,0%), #let sns-polylux-template_second-text-color = state("txt_color2", none) #let sns-polylux-template_title-text-color = state("title_color", none) #let sns-polylux-template_size = state("size", none) -#let sns-polylux-template_section-size = state("section-size",none) #let sns-polylux-template_title-size = state("title-size", none) // Data @@ -68,7 +67,6 @@ cmyk(25%,7%,0%,0%), txt-color2 : white, title-color : rgb("#444444"), size : 20pt, - section-size : 20pt, title-size : 64pt, bkgnd-color : white, @@ -95,7 +93,6 @@ cmyk(25%,7%,0%,0%), sns-polylux-template_title-text-color.update(title-color) sns-polylux-template_size.update(size) sns-polylux-template_title-size.update(title-size) - sns-polylux-template_section-size.update(section-size) sns-polylux-template_colormap.update(colormap) @@ -130,7 +127,7 @@ cmyk(25%,7%,0%,0%), context { //let section-pages = sns-polylux-template_section-pages.final() if not "END" in sns-polylux-template_section-pages.at(here()).keys() { - let page_num = counter("logical-slide").get() + let page_num = counter("logical-slide").at(here()) sns-polylux-template_section-pages.update(secpages => { secpages.insert("END", page_num) secpages @@ -141,7 +138,7 @@ cmyk(25%,7%,0%,0%), #let register-section(title, no_dedicated_slide: false) = context { // YUCKKKKK, but polylux don't allows access to integers soooooo - let page_num = counter("logical-slide").get() //sns-polylux-template_slide-pages.at(here()) + let page_num = counter("logical-slide").at(here()) //sns-polylux-template_slide-pages.at(here()) if no_dedicated_slide { page_num.at(0) += 1 } @@ -285,11 +282,9 @@ cmyk(25%,7%,0%,0%), counter("logical-slide").update( n => n - 1 ) } ) -#let sections(pos_before_slide) = context { +#let sections() = context { let section-pages = sns-polylux-template_section-pages.final() - let section-size = sns-polylux-template_section-size.at(pos_before_slide) - set text(size: section-size) - let pnum = counter("logical-slide").at(pos_before_slide).first() + 1 + let pnum = counter("logical-slide").at(here()).first() + 1 pl.toolbox.all-sections((sections, current) => { let beg-end-section = (:) let prev-sec = none @@ -388,8 +383,6 @@ cmyk(25%,7%,0%,0%), let progress_bar_height = 3pt let title_bar_height = 2cm - let pos_before_slide = here() - // HEADER let header = align(top, context( { let logo = sns-polylux-template_logo-2.at(here()) @@ -419,7 +412,7 @@ cmyk(25%,7%,0%,0%), align(horizon + center,text(fill: sns-polylux-template_second-text-color.at(here()), { v(-1em) - if hide-section { hide(sections(pos_before_slide)) } else { sections(pos_before_slide) } + if hide-section { hide(sections()) } else { sections() } })) ), grid.cell(colspan: columns.len(), progress-bar()),