commit 9c3ddfa96d2f382d4bd21db736ec7a4d890d30bd Author: videogame hacker Date: Mon Jul 3 22:35:25 2023 +0100 Initial commit. First page done diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 0000000..3838095 --- /dev/null +++ b/.editorconfig @@ -0,0 +1,9 @@ +root = true + +[*] +indent_style = space +indent_size = 2 +end_of_line = lf +charset = utf-8 +trim_trailing_whitespace = false +insert_final_newline = true diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..a136337 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +*.pdf diff --git a/README.md b/README.md new file mode 100644 index 0000000..d4fdc54 --- /dev/null +++ b/README.md @@ -0,0 +1,3 @@ +# curriculum-vitae + +Charlotte's CV (in Typst) diff --git a/cv.typ b/cv.typ new file mode 100644 index 0000000..0088876 --- /dev/null +++ b/cv.typ @@ -0,0 +1,116 @@ +#import "layout.typ": cv, event, article, divider + +#show: doc => cv( + name: "Charlotte Som", + tagline: "Systems programmer, videogame cheat developer, reverse engineer, multispecialist.", + links: ( + (icon: "email", link: "mailto:charlotte@som.codes", text: "charlotte@som.codes"), + (icon: "github", link: "https://github.com/char", text: "@char"), + (icon: "link", link: "https://som.codes", text: "som.codes"), + (icon: "link", link: "https://hackery.site", text: "hackery.site"), + ), + doc, +) + +#grid(columns: (1fr, 2fr), column-gutter: 1cm, [ +== Competitions + +#event[Google Hash Code 2020][Google][February 2020][] + +Worldwide intractable problem optimization competition. Competed as part of a globally-distributed team of three. + +- *UK*: 6#super[th] place out of 406 teams. +- *USA*: 13#super[th] place out of 619 teams. +- *Canada*: 3#super[rd] place out of 135 teams. +- *Worldwide*: 252#super[nd] place out of 10724 teams. + +#divider() + +#event[Deloitte UK CTF][Deloitte][December 2020][London] + +UK-wide infosec competition, organised by Deloitte. +Participated as a university team of six. + +- *Qualifiers*: 10#super[th] place. +- *London finals*: 7#super[th] place. + +#divider() + +#event[BLĂ…HAJ CTF Team][][2021 -- Present][] + +Casual infosec competition team. Since I joined: + +- *Hack-A-Sat 2 CTF*: Organised by the _US Air Force & US Space Force_. Placed 15#super[th] out of 697 teams. +- *corCTF 2021*: Placed 11#super[th] out of 904 teams. + +== Writing + +#article(title: "Circumventing the JVM Classfile Verifier", date: 2019, url: "som.codes/jvm-force-no-verify") +#divider() +#article(title: "Reverse Engineering GTA V's Stunt Jumps", date: 2021, url: "hackery.site/writing/gta-v-stunt-jumps") +#divider() +#article(title: "Circumventing Cisco Duo's Authenticator App", date: 2021, url: "som.codes/cisco-duo-bypass") +#divider() +#article(title: "CyberDiscovery's 'Valhalla'", date: 2019, url: "hackery.site/writing/cyberdiscovery-valhalla") + +], [ +== Experience + +#event[Multiplayer game technology][WorldQL Corporation][April 2022 -- Present][] + +I currently work at WorldQL, building technology to reduce the barrier between singleplayer and multiplayer game development techniques. + +The work is varied and has involved machine learning models, image processing pipelines, high-performance networking software, and 3D programming. + +I mainly work with *Rust*, *TypeScript*, *Python*, *PyTorch*, *CUDA*, and *ONNX*. + +#divider() + +#event[Game modding / game-hacking][Self-employed][2016 -- Present][] + +- _GTA Online_: *C++*, Rust +- _Minecraft_: *Java*, Kotlin, Scala, JVM Bytecode +- _Counter-Strike: Global Offensive_: *C++*, Rust +- Various Unity3D: *C\#*, .NET MSIL, C++ (for `il2cpp` games) + +Professionally, I used to sell a custom client for Minecraft +(5-figure USD revenue from 2016 -- 2019), +and a subscription trainer menu for GTA Online +(4-figure annually recurring USD revenue until 2020). + +#divider() + +#event(company_newline: true)[Commercial obfuscator for JVM programs][paramorphism.dev (Self-employed)][2017 -- 2022][] + +Java bytecode is one of my specialist areas. + +Involved writing the product itself and internal tooling around JVM bytecode to aid debugging. +Working primarily with *Kotlin* and *Java*. + +- _Paramorphism_: Bytecode obfuscator for JVM programs written in *Kotlin*. +- _libparamorphism_: Optional native runtime opaque library for programs + obfuscated by Paramorphism written in *Zig* and *Rust*. +- _Koffee_: Domain-specific language for *Kotlin* for Java classfile generation. +- _Aksara_ (internal): Bytecode assembly language and assembly/disassembly toolchain written in *Kotlin*. +- _Katon_ (internal): Bytecode viewer and editor with a GUI written in *Rust* and interfacing via *Java Native Interface* to *Kotlin* (_Aksara_) and *Java* (_Fernflower_). + +#divider() + +#event["Splashforce"][Force Software LLC][November 2020 -- October 2021][] + +At Force Software, I was a "Software developer and strategy coordinator". +The flagship "Splashforce" product is an end-user e-commerce automation suite +for various sneaker sites. My duties included: + +- `cronet`: Custom patches for & isolation of Chromium's HTTP stack. + (To evade TLS fingerprinting.) +- Pairing an Electron (node.js / web *JavaScript*) frontend to a *Go* backend. +- Anti-piracy, reverse-engineer-deterrent releases for the *Go* backend. + (Code virtualization, `cgo` FFI bindings, etc.). +- Reverse engineering bot protection measures on websites. +- Reverse engineering & circumventing bot prevention measures on Android apps. (*Java*, *Smali*, etc). +]) + +#pagebreak() + +TODO: PAGE 2 diff --git a/icons/calendar.svg b/icons/calendar.svg new file mode 100644 index 0000000..ec28e4a --- /dev/null +++ b/icons/calendar.svg @@ -0,0 +1,7 @@ + + + + diff --git a/icons/email.svg b/icons/email.svg new file mode 100644 index 0000000..550f895 --- /dev/null +++ b/icons/email.svg @@ -0,0 +1,7 @@ + + + + diff --git a/icons/github.svg b/icons/github.svg new file mode 100644 index 0000000..535bd83 --- /dev/null +++ b/icons/github.svg @@ -0,0 +1,7 @@ + + + + diff --git a/icons/link.svg b/icons/link.svg new file mode 100644 index 0000000..efcca35 --- /dev/null +++ b/icons/link.svg @@ -0,0 +1,7 @@ + + + + diff --git a/icons/location.svg b/icons/location.svg new file mode 100644 index 0000000..9ff80c3 --- /dev/null +++ b/icons/location.svg @@ -0,0 +1,7 @@ + + + + diff --git a/layout.typ b/layout.typ new file mode 100644 index 0000000..3f816fc --- /dev/null +++ b/layout.typ @@ -0,0 +1,132 @@ +#let icon(name, shift: 0.25em) = { + box( + baseline: shift, + height: 1.25em, + image("icons/" + name + ".svg", alt: name) + ) + h(0.35em) +} + +#let cv( + name: "", + tagline: "", + links: (), + paper: "a4", + accent: rgb("#870c66"), + heading_font: "Inter", + body_font: "Inter", + mono_font: "BerkeleyMono", + doc, +) = { + set text(size: 9pt, font: body_font, weight: "medium") + set page(paper, margin: (x: 0.8cm, y: 0.8cm)) + set par(justify: true) + + show raw: it => text(size: 1.2em, font: mono_font, baseline: -0.05em)[#it] + + show heading.where(level: 1): it => text( + size: 1.6em, + font: heading_font, + tracking: 0.1pt, + weight: "semibold", + block[ + #{it.body} + ] + ) + + show heading.where(level: 2): it => text( + fill: accent, + font: heading_font, + tracking: 0.1pt, + weight: "bold", + size: 1.35em, + [ + #{it.body} + #v(-0.85em) + #line(length: 100%, stroke: 1pt + accent) + #v(0.2em) + ] + ) + + show heading.where(level: 3): it => text( + size: 1.2em, + weight: "semibold", + block[#it] + ) + + [= #name] + + text( + font: body_font, + fill: accent, + size: 1.2em, + weight: "semibold", + block[#{tagline}] + ) + + v(-0.5em) + + links.map(l => { + link(l.link)[ + #set text(weight: "medium") + #icon(l.icon) + #if "text" in l.keys() { l.text } else { l.link } + ] + h(1em) + }).join() + + doc +} + +#let divider(accent: rgb("#870c66")) = { + line(length: 100%, stroke: (paint: accent, thickness: 1pt, dash: "dotted")) +} + +#let event( + accent: rgb("#870c66"), company_newline: false, + title, company, period, location +) = [ + #text(1.2em)[ + #text(weight: "semibold")[#title] + #h(1fr) + #if not company_newline { + text(fill: accent, weight: "bold", size: 0.8em, baseline: -0.125em)[_#[#company]_] + } else { + text(fill: accent, weight: "bold", size: 0.8em)[\ + _#[#company]_] + } + ]\ + #text(1em)[ + #if period != [] { + icon("calendar", shift: 0.18em) + [_#[#period]_] + } + #h(1fr) + #if location != [] { + icon("location") + location + } + ] +] + +#let article( + accent: rgb("#870c66"), + title: "", date: "", url: "" +) = [ + #par(justify: false)[ + #text(weight: "semibold")[ + #text(size: 1.2em)["#title"] + ]\ + #text(size: 0.85em, style: "italic", weight: "bold", tracking: -0.025em, fill: accent)[ + #icon("link", shift: 0.25em) + #h(-0.25em) + #link("https://" + url)[#url] + ] + #v(-0.85em) + #text(size: 0.85em, style: "italic", weight: "semibold", tracking: -0.025em)[ + #icon("calendar", shift: 0.15em) + #h(0.1em) + #date + ] + ] +]