diff --git a/5_theseus/5_results.typ b/5_theseus/5_results.typ index 9247936..5e9ca66 100644 --- a/5_theseus/5_results.typ +++ b/5_theseus/5_results.typ @@ -294,7 +294,7 @@ Although self-explanatory, verifying the code of those methods indeed confirms t caption: none, kind: "th-cg-cmp-andro", supplement: none, -) +) For a higher-level view of the method, we can also look at its call graph. We used Androguard to generate the call graphs in @fig:th-cg-before and @fig:th-cg-after#footnote[We manually edited the generated .dot files for readability.]. 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 764a398..16fd024 100644 --- a/slides.typ +++ b/slides.typ @@ -1,3 +1,6 @@ +#import "@preview/polylux:0.4.0": * +#import "slides/lib.typ": * + #show link: it => if type(it.dest) == label { context { if query(it.dest).len() == 0 { @@ -10,26 +13,117 @@ it } -#let get_figures(body) = { - if type(body) == array { - body.map(get_figures).flatten() - } else if type(body) == dictionary { - body.values().map(get_figures).flatten() - } else if type(body) != content { - () - }else if body.func() == figure { - (body,) - } else { - body.fields().values().map(get_figures).flatten() - } -} +#set text(lang: "en") +#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, + //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), +) + +#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( + title: [Test], + subtitle: [Test Slide], +)[ + #stack(dir: ltr, + scale(40%, reflow: true, get_figure()), + scale(55%, reflow: true, get_figure()), + ) +] + +#slide()[ + #get_figure()) +] + +#slide()[ +/* + #pl.toolbox.slide-number + #context({ + pl.toolbox.all-sections((sections, current) => { + for i in sections { + repr(i.at("body").at("text")) + } + }) + }) + */ + #sections() +] + +// #toc-slide( title: [Outline] ) + + +#new-section-slide([First section]) + +#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 +] + + + -#let main = include("./main.typ") -#let figs = get_figures(main) -// #repr(figs) -#for f in figs { - f -} /* * Notes: diff --git a/slides/figures.typ b/slides/figures.typ new file mode 100644 index 0000000..8e758ae --- /dev/null +++ b/slides/figures.typ @@ -0,0 +1,30 @@ +#let get_figures(body) = { + if type(body) == array { + body.map(get_figures).flatten() + } else if type(body) == dictionary { + body.values().map(get_figures).flatten() + } else if type(body) != content { + () + }else if body.func() == figure { + (body,) + } else { + body.fields().values().map(get_figures).flatten() + } +} + +#let main = include("../main.typ") +#let figures = { + let figures = (:) + for fig in get_figures(main) { + let fields = fig.fields() + assert("label" in fields, message: "no 'label' in " + repr(fields)) + let lab = fields.remove("label") + let body = fields.remove("body") + figures.insert(str(lab), figure(..fields, body)) + } + figures +} + +#let get_figure(label) = { + figures.at(str(label)) +} diff --git a/slides/imgs/logo_cs.png b/slides/imgs/logo_cs.png new file mode 100644 index 0000000..6b8e3c6 Binary files /dev/null and b/slides/imgs/logo_cs.png differ diff --git a/slides/imgs/logo_inria.png b/slides/imgs/logo_inria.png new file mode 100755 index 0000000..0aae860 Binary files /dev/null and b/slides/imgs/logo_inria.png differ diff --git a/slides/imgs/logo_irisa.png b/slides/imgs/logo_irisa.png new file mode 100644 index 0000000..c07894f Binary files /dev/null and b/slides/imgs/logo_irisa.png differ diff --git a/slides/imgs/logo_pirat.png b/slides/imgs/logo_pirat.png new file mode 100644 index 0000000..bfaad59 Binary files /dev/null and b/slides/imgs/logo_pirat.png differ diff --git a/slides/imgs/platypus.png b/slides/imgs/platypus.png new file mode 100644 index 0000000..08cd08b Binary files /dev/null and b/slides/imgs/platypus.png differ diff --git a/slides/lib.typ b/slides/lib.typ new file mode 100644 index 0000000..a5265da --- /dev/null +++ b/slides/lib.typ @@ -0,0 +1,31 @@ +#import "sns_polylux_template.typ": * +#import "figures.typ": figures, get_figure + +#let pirat-color = ( + black: rgb("#000000"), + white: rgb("#FFFFFF"), + red: rgb("#E33d1C"), + blue: rgb("#4AC3CB"), +) + +#let sns-polylux-template_sns-pirat = ( +pirat-color.blue.darken(30%), //rgb("#00728D"), +pirat-color.blue.darken(50%), +pirat-color.blue.darken(80%), +rgb("#AB3502"), +rgb("#E69426"), +pirat-color.red, +) + + +#let colortest = [ + #for th in ( + sns-polylux-template_sns-pirat, + sns-polylux-template_sns-colormap, + sns-polylux-template_unipi-colormap, + ) { + stack(dir: ltr, ..for c in th { + (rect(width: 30pt, height: 30pt, fill: c),) + }) + } +] diff --git a/slides/sns_polylux_template.typ b/slides/sns_polylux_template.typ new file mode 100644 index 0000000..42a0f9e --- /dev/null +++ b/slides/sns_polylux_template.typ @@ -0,0 +1,625 @@ +/*************************************************************** + * A polylux theme by martino barbieri (https://mbarbieri.it) * + * https://gitlab.com/martino.barbieri/polylux-sns-template/ * + * Patched for the PhD defence of Jean-Marie Mineau * + * LICENSE: MIT-0 * + ***************************************************************/ + +#import "@preview/polylux:0.4.0" as pl: * + +/* PER TEMPLATE SNS */ +// Background and decorations +#let sns-polylux-template_sns-colormap = ( +rgb("#00728D"), +rgb("#183F56"), +rgb("#4D4E4F"), +rgb("#AB3502"), +rgb("#E69426"), +rgb("#9CD7F3"), +) + +/* PER TEMPLATE UNIPI */ +#let sns-polylux-template_unipi-colormap = ( +cmyk(100%,57%,0%,9%), +cmyk(100%,57%,0%,38%), +rgb("#444444"), +rgb("#AB3502"), +rgb("#E69426"), +cmyk(25%,7%,0%,0%), +) + +#let sns-polylux-template_colormap = state("colormap", none) + +// Text and Fonts +#let sns-polylux-template_text-font = state("txt-font", none) +#let sns-polylux-template_title-font = state("title-font", none) +#let sns-polylux-template_background-color = state("bkg_color1", none) +#let sns-polylux-template_main-text-color = state("txt_color1", none) +#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_title-size = state("title-size", none) + +// Data +#let sns-polylux-template_title = state("title", none) +#let sns-polylux-template_short-title = state("short-title", none) +#let sns-polylux-template_subtitle = state("subtitle", none) +#let sns-polylux-template_event = state("event", none) +#let sns-polylux-template_short-event = state("short-event", none) +#let sns-polylux-template_authors = state("authors", none) + +#let sns-polylux-template_logo-1 = state("logo-1", none) +#let sns-polylux-template_logo-2 = state("logo-2", none) + +#let sns-polylux-template_date = state("date", none) + +#let sns-polylux-template_section-pages = state("section-pages", ("plop": 0)) +#let sns-polylux-template_slide-pages = state("slide-pages", 0) + +// Init +#let sns-polylux-template( + // General parameters + aspect-ratio : "16-9", + + txt-font : ("Roboto", "Fira Sans", "DejaVu Sans"), + title-font : ("Raleway", "PT Sans", "DejaVu Sans"), + txt-color1 : black, + txt-color2 : white, + title-color : rgb("#444444"), + size : 20pt, + title-size : 64pt, + bkgnd-color : white, + + colormap : sns-polylux-template_sns-colormap, + + // Data + title : none, + subtitle : none, + short-title : none, + event : none, + short-event : none, + logo-2 : none, + logo-1 : none, + authors : none, + date : none, + // Stuff + body +) = { + sns-polylux-template_text-font.update(txt-font) + sns-polylux-template_title-font.update(title-font) + sns-polylux-template_background-color.update(bkgnd-color) + sns-polylux-template_main-text-color.update(txt-color1) + sns-polylux-template_second-text-color.update(txt-color2) + 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_colormap.update(colormap) + + set page( + paper : "presentation-" + aspect-ratio, + fill : bkgnd-color, + margin : 0pt, + header : none, + footer : none, + header-ascent : 0pt, + footer-descent : 0pt, + ) + set text( + fill : txt-color1, + size : size, + font : txt-font, + ) + sns-polylux-template_title.update(title) + sns-polylux-template_subtitle.update(subtitle) + if short-title != none { sns-polylux-template_short-title.update(short-title) } + else { sns-polylux-template_short-title.update(title) } + sns-polylux-template_event.update(event) + if short-event != none { sns-polylux-template_short-event.update(short-event) } + else { sns-polylux-template_short-event.update(event) } + sns-polylux-template_logo-2.update(logo-2) + sns-polylux-template_logo-1.update(logo-1) + sns-polylux-template_authors.update(authors) + sns-polylux-template_date.update(date) + + body +} + +#let register-section(title) = context { + // YUCKKKKK, but polylux don't allows access to integers soooooo + let page_num = counter("logical-slide").at(here()) //sns-polylux-template_slide-pages.at(here()) + sns-polylux-template_section-pages.update(secpages => { + secpages.insert(repr(title), page_num) + secpages + }) + pl.toolbox.register-section(title) +} + +#let progress-bar() = pl.toolbox.progress-ratio( ratio => { + let colormap = sns-polylux-template_colormap.at(here()) + let height = 3pt + stack(dir: ltr, + rect(width: ratio * 100%, height: height, fill: colormap.at(5)), + rect(width: (1-ratio) * 100%, height: height, fill: colormap.at(0)), + ) +}) + +// Slides +#let title-slide( + body : none, + logo : none, +) = context( { + let content = align(top + center, context( { + let title = sns-polylux-template_title.at(here()) + let subtitle = sns-polylux-template_subtitle.at(here()) + let event = sns-polylux-template_event.at(here()) + let authors = sns-polylux-template_authors.at(here()) + let title-size = sns-polylux-template_title-size.at(here()) + let logo = { + if logo == none { sns-polylux-template_logo-1.at(here()) } + else { logo } + } + let date = sns-polylux-template_date.at(here()) + + // Background + place( + bottom + right, + polygon( + fill : sns-polylux-template_colormap.at(here()).at(2), + stroke : none, + (0%, 42%),(100%, 42%),(100%, 0%), + ), + ) + place( + bottom + right, + polygon( + fill : sns-polylux-template_colormap.at(here()).at(1), + stroke : none, + (0%, 29%),(0%, 37%),(100%, 37%),(100%, 0%), + ), + ) + place( + bottom + right, + polygon( + fill : sns-polylux-template_colormap.at(here()).at(0), + stroke : none, + (0%, 20%),(0%, 30%),(100%, 30%),(100%, 0%), + ), + ) + place( + top + left, + polygon( + fill : sns-polylux-template_colormap.at(here()).at(2), + stroke : none, + (0%, 0%),(0%, 16%),(75%, 0%), + ), + ) + place( + top + left, + polygon( + fill : sns-polylux-template_colormap.at(here()).at(0), + stroke : none, + (0%, 0%),(0%, 15%),(75%, 0%), + ), + ) + place( + bottom + center, + dy: -1cm, + text(fill: sns-polylux-template_background-color.at(here()), size: 22pt, event) + ) + if logo != none { + place( + bottom + right, + dx: -0.5cm, + dy: -0.3cm, + scale(page.height/measure(logo).height*22%, reflow: true, logo) + ) + } + + // Contents + set align(center+top) + v(17%) + text( + font : sns-polylux-template_title-font.at(here()), + size : title-size, + fill: sns-polylux-template_title-text-color.at(here()), + weight: "bold", + title + ) + linebreak() + v(0em) + text( + font : sns-polylux-template_title-font.at(here()), + size : 22pt, + fill: sns-polylux-template_title-text-color.at(here()), + subtitle + ) + //v(-0.9em) + line(length: 90%, stroke: (paint: sns-polylux-template_colormap.at(here()).at(5), thickness: 4pt)) + v(1em) + set text( + size: 24pt, + top-edge: 0pt, + bottom-edge: 0pt, + fill: sns-polylux-template_main-text-color.at(here()) + ) + { + set align(left) + for i in range(authors.len()) { + h(1em) + authors.at(i) + v(0.5em) + //move(dx: 2% * ( i - ( authors.len() - 1 ) / 2 ), authors.at(i)) + } + if date != none { + v(1em) + h(1em) + date.display() + } + } + body + } )) + + pl.slide({ content }) + + counter("logical-slide").update( n => n - 1 ) +} ) + +#let sections() = context { + let section-pages = sns-polylux-template_section-pages.final() + let pnum = counter("logical-slide").at(here()).first() + pl.toolbox.all-sections((sections, current) => { + let pnum_i = 0 + let section_names = () + let section_pages = () + for s in sections { + let pages = () + let pnum_max = section-pages.at(repr(s.at("body"))).first() + while pnum_i < pnum_max and pnum_i < pnum - 1 { + pages.push(sym.circle.filled) + pnum_i += 1 + } + if pnum_i == pnum { + pages.push(sym.ast.circle) + pnum_i += 1 + } + while pnum_i < pnum_max { + pages.push(sym.circle.dotted) + pnum_i += 1 + } + + /* + if s == current { + strong(s + " " + str(pnum)) + } else { + s + " " + str(pnum) + }*/ + section_names.push(s) + section_pages.push(pages.join([])) + } + grid( + columns: (auto,)*section_names.len(), + column-gutter: 1fr, + row-gutter: 12pt, + ..section_names, ..section_pages, + ) + }) +} + +/* +#let small-sections(show-sec-name: true) = context( { + set text(bottom-edge: "descender") + if show-sec-name {pl.toolbox.current-section;" "} + + pl.toolbox.all-sections( + (sections, current) => { + let over_current = false + for i in sections { + if current == i {$ast.circle$; over_current = true} + else if (over_current or current not in sections) { + $circle.dotted$ + } else {$circle.filled$} + } + } + ) +} ) + +#let big-sections = context( { + set align(horizon + right) + grid( + box(height: 40%, inset: 0.8cm)[#small-sections(show-sec-name: false)], + box(height: 60%, inset: 0.8cm)[ + #pl.toolbox.current-section + ]) +} ) +*/ + +#let slide( + title : none, + subtitle : none, + new-sec : false, + page-number : true, + hide-section : false, + body +) = context( { + let sections_height = 1.5cm + let progress_bar_height = 3pt + let title_bar_height = 2cm + + // HEADER + let header = align(top, context( { + let logo = sns-polylux-template_logo-2.at(here()) + + // If new-sec is false, do nothing + // If new-sec is true, new section's name is the slide title + // Else the new-sec name is new-sec + if type(new-sec)==bool { + if new-sec { + register-section(title) + } + } else { + register-section(new-sec) + } + + place(top + left, { + let columns = if logo != none { (auto, 1fr,) } else { (1fr,) }; + grid( + columns: columns, + gutter: 0pt, + + if logo != none { pad(logo, x: 0.3cm, top: 0.2cm) } else { [] }, + rect( + width: 100%, height: sections_height, + inset: 0.8cm, outset: 0pt, + fill: sns-polylux-template_colormap.at(here()).at(1), + + align(horizon + center,text(fill: sns-polylux-template_second-text-color.at(here()), { + v(-1em) + if hide-section { hide(sections()) } else { sections() } + })) + ), + grid.cell(colspan: columns.len(), progress-bar()), + if title != none { + rect( + width: 100%, height: title_bar_height, + inset: 0.8cm, outset: 0pt, + fill: sns-polylux-template_colormap.at(here()).at(0), + + align(horizon + center, { + text( + fill: sns-polylux-template_second-text-color.at(here()), + font: sns-polylux-template_title-font.at(here()), + size: 32pt, + weight: "bold", + title + ) + if subtitle != none { + smallcaps(text( + fill: sns-polylux-template_second-text-color.at(here()), + font: sns-polylux-template_title-font.at(here()), + size: 24pt, + " — " + subtitle + )) + } + }) + ) + } else { [] } + ) + }) // closes `place(top+left, {` + } )) // closes `let header = ...` + + // FOOTER + let footer = align(top + center, context( { + let short-title = sns-polylux-template_short-title.at(here()) + let short-event = sns-polylux-template_short-event.at(here()) + + place(top + center, line(length: 100%-2cm, stroke: (paint: sns-polylux-template_colormap.at(here()).at(1), thickness: 2pt))) + + set text(bottom-edge: "descender") + + block( + height: 100%, + width: 100%, + inset: (x: 0.8cm), + align(horizon,text(fill: sns-polylux-template_colormap.at(here()).at(2), size: 16pt, + grid( + gutter: 0.8cm, + columns: (0.7fr, 1fr, 0.7fr), + align(left, short-title), + align(center, smallcaps(short-event)), + align(right, if page-number [#toolbox.slide-number/#toolbox.last-slide-number]), + )) + )) + } )) + + let top-margin = if title != none { + sections_height + progress_bar_height + title_bar_height + } else { + sections_height + progress_bar_height + }; + + set page( + margin: (top: top-margin, bottom: 1cm), + header: header, + footer: footer, + ) + + pl.slide({ + set align(horizon) + set text(size: sns-polylux-template_size.at(here()), top-edge: 20pt, bottom-edge: 0pt) + show: block.with(inset: (x: 1.2cm, y:.2cm), width: 100%) + body + }) + + if not page-number { counter("logical-slide").update( n => n - 1 ) } +} ) + +#let focus-slide( + new-sec : none, + page-number : true, + hide-section : false, + body +) = context( { + set page( + margin: (top: 2.5cm, bottom: 0cm), + footer: none, + fill: sns-polylux-template_colormap.at(here()).at(1), + ) + + pl.slide({ + set align(horizon + center) + set text( + size: sns-polylux-template_size.at(here())*1.5, + fill: sns-polylux-template_second-text-color.at(here()), + style: "italic" + ) + show: block.with(inset: (x: 1.2cm, y:.2cm), width: 100%) + body + }) + + if not page-number { counter("logical-slide").update( n => n - 1 ) } +} ) + +#let empty-slide( + body +) = context( { + // HEADER + let header = align(top, context( { + let logo = sns-polylux-template_logo-1.at(here()) + + place( + top + left, + box( + height: 2.5cm, + if logo != none { pad(logo, x: 0.3cm, top: 0.2cm) } + ) + ) + } )) + + set page( + margin: (top: 0cm, bottom: 0cm), + foreground: header, + footer: none, + fill: sns-polylux-template_colormap.at(here()).at(1), + ) + + pl.slide({ + set align(horizon + center) + set text( + size: sns-polylux-template_size.at(here())*1.5, + fill: sns-polylux-template_second-text-color.at(here()), + ) + show: block.with(inset: (x: 1.2cm, y:.2cm), width: 100%) + body + }) + + counter("logical-slide").update( n => n - 1 ) +} ) + +#let new-section-slide(name) = context( { + // HEADER + let header = align(top, context( { + let logo = sns-polylux-template_logo-1.at(here()) + + place( + top + left, + box( + height: 2.5cm, + if logo != none { pad(logo, x: 0.3cm, top: 0.2cm) } + ) + ) + } )) + + set page( + margin: (top: 0cm, bottom: 0cm), + foreground: header, + footer: none, + fill: sns-polylux-template_colormap.at(here()).at(1), + ) + + // TOC + /* + let content = context( { + pl.toolbox.all-sections( (sections, current) => { + set text(weight: "regular") + let over_current = false + for i in sections { + if (current == i) {[ + + #text(weight: "black", i) + ]; over_current = true} + else if (over_current) [ + + #text(weight: "thin", i) + ] + else [ + + #text(i) + ] + } + } ) + } ) + */ + + pl.slide({ + set align(horizon + center) + set text( + size: sns-polylux-template_size.at(here())*1.5, + fill: sns-polylux-template_second-text-color.at(here()), + ) + register-section(name) + + show: pad.with(20%) + + name + progress-bar() + + }) + + counter("logical-slide").update( n => n - 1 ) +} ) + +#let toc-slide(title: none) = context( { + // HEADER + let header = align(top, { + let logo = sns-polylux-template_logo-1.at(here()) + + place( + top + left, + box( + height: 2.5cm, + if logo != none { pad(logo, x: 0.3cm, top: 0.2cm) } + ) + ) + } ) + + set page( + margin: (top: 0cm, bottom: 0cm), + foreground: header, + footer: none, + fill: sns-polylux-template_colormap.at(here()).at(1), + ) + + // TOC + let content = { + if title != none { align(center,text(weight: "bold", title)); v(-0.2em) } + pl.toolbox.all-sections( (sections, current) => { + for i in sections [ + + #text(i) + ] + } ) + } + + pl.slide({ + set align(horizon + center) + set text( + size: sns-polylux-template_size.at(here())*1.5, + fill: sns-polylux-template_second-text-color.at(here()), + ) + + show: box.with() + set align(left) + content + }) + + counter("logical-slide").update( n => n - 1 ) +} ) + +