nix + spruce up
This commit is contained in:
parent
740a5c930c
commit
202d50be92
4 changed files with 137 additions and 65 deletions
81
cv.typ
81
cv.typ
|
|
@ -2,7 +2,7 @@
|
||||||
|
|
||||||
#show: doc => cv(
|
#show: doc => cv(
|
||||||
name: "Charlotte Som",
|
name: "Charlotte Som",
|
||||||
tagline: "Systems programmer, videogame cheat developer, reverse engineer, multispecialist.",
|
tagline: [Systems programmer, videogame cheat developer, #linebreak() reverse engineer, multispecialist.],
|
||||||
links: (
|
links: (
|
||||||
(icon: "email", link: "mailto:charlotte@som.codes", text: "charlotte@som.codes"),
|
(icon: "email", link: "mailto:charlotte@som.codes", text: "charlotte@som.codes"),
|
||||||
(icon: "github", link: "https://github.com/char", text: "@char"),
|
(icon: "github", link: "https://github.com/char", text: "@char"),
|
||||||
|
|
@ -13,6 +13,16 @@
|
||||||
)
|
)
|
||||||
|
|
||||||
#grid(columns: (1fr, 2fr), column-gutter: 1cm, [
|
#grid(columns: (1fr, 2fr), column-gutter: 1cm, [
|
||||||
|
== Writing
|
||||||
|
|
||||||
|
#article(title: "Circumventing the JVM Classfile Verifier", date: 2019, url: "som.codes/jvm-force-no-verify")
|
||||||
|
#divider()
|
||||||
|
#article(title: "Game Science: GTA V's Stunt Jumps", date: 2021, url: "som.codes/gta-v-stunt-jumps")
|
||||||
|
#divider()
|
||||||
|
#article(title: "Circumventing Cisco Duo's Authenticator App", date: 2021, url: "som.codes/cisco-duo-bypass")
|
||||||
|
#divider()
|
||||||
|
#article(title: "Extracting API Keys from a Minecraft Launcher", date: 2022, url: "som.codes/mmc-msaclientid")
|
||||||
|
|
||||||
== Competitions
|
== Competitions
|
||||||
|
|
||||||
#event[Google Hash Code 2020][Google][February 2020][]
|
#event[Google Hash Code 2020][Google][February 2020][]
|
||||||
|
|
@ -36,79 +46,74 @@ Participated as a university team of six.
|
||||||
|
|
||||||
#divider()
|
#divider()
|
||||||
|
|
||||||
#event[BLÅHAJ CTF Team][][2021 -- Present][]
|
#event[BLÅHAJ CTF Team][][2021 -- 2022][]
|
||||||
|
|
||||||
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.
|
- *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.
|
- *corCTF 2021*: Placed 11#super[th] out of 904 teams.
|
||||||
|
|
||||||
== Writing
|
== Languages
|
||||||
|
|
||||||
#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: "Extracting API Keys from a Minecraft Launcher", date: 2022, url: "som.codes/mmc-msaclientid")
|
|
||||||
|
|
||||||
|
- *English* (native, primary)
|
||||||
|
- *French* (maternal)
|
||||||
|
- *Spanish* (since 2013)
|
||||||
|
- *Korean* (since 2016)
|
||||||
], [
|
], [
|
||||||
== Experience
|
== Experience
|
||||||
|
|
||||||
#event[Multiplayer game technology][WorldQL Corporation][April 2022 -- Present][]
|
#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.
|
I currently work at WorldQL, where the mission is to reduce the barrier between singleplayer and multiplayer game development.
|
||||||
|
|
||||||
The work is varied and has involved machine learning models, image processing pipelines, high-performance networking software, and 3D programming.
|
Here, I've worked on EVM-based transaction processing / smart contracts (writing a hot wallet transaction scheduler in Rust),
|
||||||
|
written a multiplayer web game engine in TypeScript (with several interesting netcode paradigms) & backend web services in Rust
|
||||||
|
(at one point embedding `deno_core` in a Rust application for sandboxed multitenant user code exec on the server-side)
|
||||||
|
as well as a (Git-based) beginner-oriented version control system.
|
||||||
|
|
||||||
I mainly work with *Rust*, *TypeScript*, *Python*, *PyTorch*, *CUDA*, and *ONNX*.
|
To facilitate prototype art we also experimented with Blender automation and machine learning in production,
|
||||||
|
so I've also written & deployed Python / CUDA / ONNX backed services.
|
||||||
|
|
||||||
#divider()
|
#divider()
|
||||||
|
|
||||||
#event[Game modding / game-hacking][Self-employed][2016 -- Present][]
|
#event[Game modding / game-hacking][Self-employed][2016 -- 2025][]
|
||||||
|
|
||||||
- _GTA Online_: *C++*, Rust
|
- _GTA Online_: C++ (primarily), Rust
|
||||||
- _Minecraft_: *Java*, Kotlin, Scala, JVM Bytecode
|
- _Minecraft_: Java, Kotlin (primarily), Scala, JVM Bytecode
|
||||||
- _Counter-Strike: Global Offensive_: *C++*, Rust
|
- _Counter-Strike: Global Offensive_: C++ (primarily), Rust
|
||||||
- Various Unity3D: *C\#*, .NET MSIL, C++ (for `il2cpp` games)
|
- Unity3D (various): C\# (primarily), .NET MSIL, and C++ (for `il2cpp` games)
|
||||||
|
|
||||||
Professionally, I used to sell a custom client for Minecraft
|
In my teens, I used to sell a custom client for Minecraft
|
||||||
(5-figure USD revenue from 2016 -- 2019),
|
(5-figure USD revenue from 2016 -- 2019),
|
||||||
and a subscription trainer menu for GTA Online
|
and a subscription trainer menu for GTA Online.
|
||||||
(4-figure annually recurring USD revenue until 2020).
|
|
||||||
|
|
||||||
#divider()
|
#divider()
|
||||||
|
|
||||||
#event(company_newline: true)[Commercial obfuscator for JVM programs][paramorphism.dev (Self-employed)][2017 -- 2022][]
|
#event(company_newline: true)[Commercial obfuscator for JVM programs][paramorphism.dev (Self-employed)][2017 -- 2022][]
|
||||||
|
|
||||||
Java bytecode is one of my specialist areas.
|
This solo project involved writing the product itself, internal tooling around JVM bytecode to aid debugging,
|
||||||
|
and the sales site in SvelteKit (then-_Sapper_, actually).
|
||||||
|
|
||||||
Involved writing the product itself and internal tooling around JVM bytecode to aid debugging.
|
- _Paramorphism_: Bytecode obfuscator for JVM programs written in Kotlin.
|
||||||
Working primarily with *Kotlin* and *Java*.
|
|
||||||
|
|
||||||
- _Paramorphism_: Bytecode obfuscator for JVM programs written in *Kotlin*.
|
|
||||||
- _libparamorphism_: Optional native runtime opaque library for programs
|
- _libparamorphism_: Optional native runtime opaque library for programs
|
||||||
obfuscated by Paramorphism written in *Zig* and *Rust*.
|
obfuscated by Paramorphism written in Rust first and then Zig later.
|
||||||
- _Koffee_: Domain-specific language for *Kotlin* for Java classfile generation.
|
- _Koffee_: Domain-specific language for Kotlin for Java classfile generation.
|
||||||
- _Aksara_ (internal): Bytecode assembly language and assembly/disassembly toolchain written in *Kotlin*.
|
- _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_).
|
- _Katon_ (internal): Bytecode viewer and editor with a GUI written in Rust and interfacing via Java Native Interface to Kotlin (_Aksara_) and Java (_Fernflower_).
|
||||||
|
- _Citadel_: An experimental custom-instruction-set VM with a _libparamorphism_-backed native executor (+ some compilers), focusing on self-modifying code.
|
||||||
|
|
||||||
#divider()
|
#divider()
|
||||||
|
|
||||||
#event["Splashforce"][Force Software LLC][November 2020 -- October 2021][]
|
#event["Splashforce"][Force Software LLC][November 2020 -- October 2021][]
|
||||||
|
|
||||||
At Force Software, I was a "Software developer and strategy coordinator".
|
The flagship "Splashforce" product was an end-user e-commerce automation suite
|
||||||
The flagship "Splashforce" product is an end-user e-commerce automation suite
|
|
||||||
for various sneaker sites. My duties included:
|
for various sneaker sites. My duties included:
|
||||||
|
|
||||||
- `cronet`: Custom patches for & isolation of Chromium's HTTP stack.
|
- `cronet`: Custom patches for & isolation of Chromium's HTTP stack.
|
||||||
(To evade TLS fingerprinting.)
|
(To evade TLS fingerprinting.)
|
||||||
- Pairing an Electron (node.js / web *JavaScript*) frontend to a *Go* backend.
|
- Pairing an Electron (node.js / web JavaScript) frontend to a Go backend.
|
||||||
- Anti-piracy, reverse-engineer-deterrent releases for the *Go* backend.
|
- Anti-piracy, reverse-engineer-deterrent releases for the Go backend.
|
||||||
(Code virtualization, `cgo` FFI bindings, etc.).
|
(Code virtualization, `cgo` FFI bindings, etc.).
|
||||||
- Reverse engineering bot protection measures on websites.
|
- Reverse engineering bot protection measures on websites.
|
||||||
- Reverse engineering & circumventing bot prevention measures on Android apps. (*Java*, *Smali*, etc).
|
- Reverse engineering & circumventing bot prevention measures on Android apps. (Java, Smali, etc).
|
||||||
])
|
])
|
||||||
|
|
||||||
#pagebreak()
|
#pagebreak()
|
||||||
|
|
|
||||||
27
flake.lock
Normal file
27
flake.lock
Normal file
|
|
@ -0,0 +1,27 @@
|
||||||
|
{
|
||||||
|
"nodes": {
|
||||||
|
"nixpkgs": {
|
||||||
|
"locked": {
|
||||||
|
"lastModified": 1773628058,
|
||||||
|
"narHash": "sha256-hpXH0z3K9xv0fHaje136KY872VT2T5uwxtezlAskQgY=",
|
||||||
|
"owner": "NixOS",
|
||||||
|
"repo": "nixpkgs",
|
||||||
|
"rev": "f8573b9c935cfaa162dd62cc9e75ae2db86f85df",
|
||||||
|
"type": "github"
|
||||||
|
},
|
||||||
|
"original": {
|
||||||
|
"owner": "NixOS",
|
||||||
|
"ref": "nixpkgs-unstable",
|
||||||
|
"repo": "nixpkgs",
|
||||||
|
"type": "github"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"root": {
|
||||||
|
"inputs": {
|
||||||
|
"nixpkgs": "nixpkgs"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"root": "root",
|
||||||
|
"version": 7
|
||||||
|
}
|
||||||
26
flake.nix
Normal file
26
flake.nix
Normal file
|
|
@ -0,0 +1,26 @@
|
||||||
|
{
|
||||||
|
description = "Typst CV document";
|
||||||
|
|
||||||
|
inputs = {
|
||||||
|
nixpkgs.url = "github:NixOS/nixpkgs/nixpkgs-unstable";
|
||||||
|
};
|
||||||
|
|
||||||
|
outputs =
|
||||||
|
{ self, nixpkgs }:
|
||||||
|
let
|
||||||
|
system = "x86_64-linux";
|
||||||
|
pkgs = nixpkgs.legacyPackages.${system};
|
||||||
|
in
|
||||||
|
{
|
||||||
|
devShells.${system}.default = pkgs.mkShell {
|
||||||
|
packages = with pkgs; [
|
||||||
|
typst
|
||||||
|
inter
|
||||||
|
];
|
||||||
|
|
||||||
|
shellHook = ''
|
||||||
|
export TYPST_FONT_PATHS="${pkgs.inter}/share/fonts:/x/fonts/tx02"
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
||||||
68
layout.typ
68
layout.typ
|
|
@ -15,7 +15,7 @@
|
||||||
accent: rgb("#870c66"),
|
accent: rgb("#870c66"),
|
||||||
heading_font: "Inter",
|
heading_font: "Inter",
|
||||||
body_font: "Inter",
|
body_font: "Inter",
|
||||||
mono_font: "BerkeleyMono",
|
mono_font: "TX-02",
|
||||||
doc,
|
doc,
|
||||||
) = {
|
) = {
|
||||||
set text(size: 9pt, font: body_font, weight: "medium")
|
set text(size: 9pt, font: body_font, weight: "medium")
|
||||||
|
|
@ -54,32 +54,46 @@
|
||||||
block[#it]
|
block[#it]
|
||||||
)
|
)
|
||||||
|
|
||||||
[= #name]
|
[
|
||||||
|
#grid(
|
||||||
text(
|
columns: (1fr, 1fr),
|
||||||
font: body_font,
|
gutter: 1em,
|
||||||
fill: accent,
|
{
|
||||||
size: 1.2em,
|
[= #name]
|
||||||
weight: "semibold",
|
|
||||||
block[#{tagline}]
|
text(
|
||||||
)
|
font: body_font,
|
||||||
|
size: 1em,
|
||||||
v(-0.5em)
|
block[#{tagline}]
|
||||||
|
)
|
||||||
links.map(l => {
|
},
|
||||||
link(l.link)[
|
[
|
||||||
#set text(weight: "medium")
|
#box[
|
||||||
#icon(l.icon)
|
#h(4em)
|
||||||
#if "text" in l.keys() { l.text } else { l.link }
|
#grid(
|
||||||
]
|
columns: 2,
|
||||||
h(1em)
|
gutter: 0.75em,
|
||||||
}).join()
|
..links.map(l => {
|
||||||
|
[#h(2em)]
|
||||||
|
link(l.link)[
|
||||||
|
#set text(weight: "medium")
|
||||||
|
#icon(l.icon)
|
||||||
|
#if "text" in l.keys() { l.text } else { l.link }
|
||||||
|
]
|
||||||
|
})
|
||||||
|
)
|
||||||
|
]
|
||||||
|
]
|
||||||
|
)
|
||||||
|
]
|
||||||
|
|
||||||
doc
|
doc
|
||||||
}
|
}
|
||||||
|
|
||||||
#let divider(accent: rgb("#870c66")) = {
|
#let divider(accent: rgb("#870c66")) = {
|
||||||
|
v(-0.25em)
|
||||||
line(length: 100%, stroke: (paint: accent, thickness: 1pt, dash: "dotted"))
|
line(length: 100%, stroke: (paint: accent, thickness: 1pt, dash: "dotted"))
|
||||||
|
v(-0.25em)
|
||||||
}
|
}
|
||||||
|
|
||||||
#let event(
|
#let event(
|
||||||
|
|
@ -117,16 +131,16 @@
|
||||||
#text(weight: "semibold")[
|
#text(weight: "semibold")[
|
||||||
#text(size: 1.2em)["#title"]
|
#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)[
|
#text(size: 0.85em, style: "italic", weight: "semibold", tracking: -0.025em)[
|
||||||
#icon("calendar", shift: 0.15em)
|
#icon("calendar", shift: 0.15em)
|
||||||
#h(0.1em)
|
#h(0.1em)
|
||||||
#date
|
#date
|
||||||
]
|
]
|
||||||
|
#h(0.75em)
|
||||||
|
#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]
|
||||||
|
]
|
||||||
]
|
]
|
||||||
]
|
]
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue