My thoughts and ideas.
How I lock my bike and why it doesn't matter
Thanks to the YouTube algorithm, I recently got into lockpicking. YouTube is full of channels like Lockpicking Lawyer and Bosnian Bill that teach how to open locks without the keys.
After binge watching probably hundreds of videos, I decided that it was time for me to give it a shot and pick some locks, so I ordered some picks and got to picking.
I started with regular pin tumbler locks like this one:
…A subtractive review of the Framework laptop
In audio, there’s this thing called subtractive synthesis, where you take a signal and subtract parts of it until you come up with a sick Acid Techno bass sound. Or some other sound, whatever. I’m going to review my Framework Laptop in the same way. In this analogy, the initial signal is going to be “a perfect laptop for me”, and I’m going to subtract things from that until the final sound is “the Framework laptop as perceived by me”.
…Bypassing Go visibility rules (with generics!)
(You can paste all snippets into the Go playground.)
Bypassing the visibility rules has always been easy for structs, and there are several approaches that I will explain in this post.
The first approach involves finding the offset of the field in the struct using reflection, then the unsafe package to create an arbitrary pointer to the field.
-- go.mod --
module tmp
go 1.18
-- unsafe/some_package/some_package.go --
package some_package
type S struct {
Number int32
Letter rune
secret string
}
func NewS() S {
return S{secret: "secret string"}
}
-- main.go --
package main
import (
"fmt"
"reflect"
"unsafe"
"tmp/unsafe/some_package"
)
func main() {
s := some_package.NewS()
// Find the "secret" field.
f, ok := reflect.TypeOf(s).FieldByName("secret")
if !ok {
panic("could not find field")
}
// Get the address of the struct.
ptr := unsafe.Pointer(&s)
// Add the offset of the field within the struct to
// the address of the struct, effectively getting the
// address of the field.
ptr = unsafe.Add(ptr, f.Offset)
// ptr now points to the address of "secret" in the
// struct, so it can be cast to *string and then
// dereferenced.
strp := (*string)(ptr)
fmt.Println(*strp)
// Or just:
fmt.Println(*(*string)(unsafe.Add(unsafe.Pointer(&s), f.Offset)))
// Or just use reflect.Value, which is basically the same:
fmt.Println(*(*string)(unsafe.Pointer(
reflect.
ValueOf(&s).
Elem().
FieldByName("secret").
Addr().
Pointer())))
}
This approach is fairly safe as the reflect package should be able to provide the exact offset of the field, and usage of the unsafe package is extremely easy to audit and reason about. It’s just wrong, you know. Like, philosophically.
…Reverse engineering UEFI firmware to lift evil hardware restrictions
I recently got a Lenovo ThinkCentre Tiny M93. It’s a cute little device that came with pension documents for several people and is doing great as a cheap NAS. However, the main reason I got it was to replace a Raspberry Pi that I was using as a WiFi access point running Pi-Hole, and the M93 didn’t have a WiFi card when I bought it. Easy enough, I thought, just get a decent Intel mini PCI Express card and some antennas.
…Drill Your Hard Drives
… after filling it with random data. And don’t sell them on eBay.
IN PARTICULAR, don’t be irresponsible enough to do this when you work for IT in something like a pension fund or a law firm.
What am I talking about then? Well, I wanted one of those cute, tiny, barebones, terminal business PC’s to replace a Raspberry Pi at home. I found a Lenovo ThinkCentre Tiny M93 on eBay, with a pretty nice 4th Gen Core i3 and 8GB of DDR3. This is enough, and was pretty damn cheap for what it is.
…Using Zig and STM32 CubeMX to drive soviet VFD tubes to display the time
I really like Zig. And I think it’s an awesome language to use for embedded stuff, from the way allocation is handled, to its awesome comptime feature, the build system, the “just-work"iness of it, etc. It’s also backed by LLVM and therefore is able to target the useful architectures that one should care about.
So I decided to rewrite the code for my IV-8 VFD clock, a libopencm3 STM32G0 C project in Zig to see how much nicer it would be.
…How to use STM32 CubeMX without losing your mind
CubeMX is kinda nice, but it also sucks donkey ass… But it’s kinda nice! But it really sucks absolute donkey ass!
It’s kinda nice because it lets you configure your stuff easily with a GUI and then generates some questionable code that actually configures your stuff (most of the time). It sucks donkey ass because of the way they chose to do the code generation thing. You’re reading this so I’m guessing you know. I know. It’s really dumb. Literally any other approach would have most likely sucked less.
…