nix + spruce up

This commit is contained in:
Charlotte Som 2026-03-20 05:00:43 +00:00
parent 740a5c930c
commit 202d50be92
4 changed files with 137 additions and 65 deletions

81
cv.typ
View file

@ -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
View 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
View 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"
'';
};
};
}

View file

@ -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]
]
] ]
] ]