HNHacker News
TopNewBestAskShowJobs

apple1417

54 karma · joined January 18, 2025

https://apple1417.dev
submissionscomments
apple1417··on It is not a compiler error (2017)
> For regular programmers, if your machine won't boot up, you are having a bad day. For embedded developers, that's just a typical Tuesday, and your only debugging option may be staring at the code and thinking hard.

Of course where it becomes even more fun is when it's a customer's unit in Peru and you can't replicate it locally :). But oh how I love it. I have definitely spent many a day staring at code piecing things together with what limited info we have.

But to get back on topic, I can definitely confer on the quality of most embedded compilers. It's a great day when I can just use normal old gcc. I've never run into anything explicitly wrong, but I see so many bits of weird codegen or missed optimisations that I keep the disassembly view open permanently, as a sanity check. The assembly never lies to you - until you find a silicon bug at least.

apple1417··on NAT Is the Enemy of Low Power Devices
I have worked on a device with this exact same "send a tiny sensor reading every 30 minutes" use case, and this has not been my experience at all. We can run an STM32 and a few sensors at single digit microamps, add an LCD display and a few other niceties and it's one or two dozen. Simply turning on a modem takes hundreds of microamps, if not milliamps. In my experience it's always been better for power consumption to completely shut down the modem and start from scratch each time [1] - which means you're paying to start a new session every time anyway. Now I'll agree it's still inefficient to start up a full TLS session, a protocol like in the post will have it's uses, but I wouldn't blame it on NAT.

[1] Doing this of course kills any chance at server-to-device comms, you can only ever apply changes when the device next checks in. This does cause us complaints from time to time, especially for those with longer intervals.

apple1417··on Reverse engineering Call of Duty anti-cheat
You can actually usually get a pretty good starting point from just a single build, and only refine it once you find a build it breaks on. It's essentially just finding a unique substring. In my experience this almost always involves some wildcard sections, so the signature in the parent got lucky not to need them. I like to think about it as more of matching the shape of the original instructions than matching them verbatim.

To manually construct a signature, you basically just take what the existing instructions encode to, and wildcard out the bits which are likely to change between builds. Then you'll see if it's still a unique match, and if not add a few more instructions on. This will be things like absolute addresses, larger pointer offsets, the length of relative jumps, and sometimes even what registers the instructions operate on. Here's an example of mine that needed all of those:

  "48 8B ?? ????????",        // mov rcx, [rdi+000001D0]
  "48 85 C9",                 // test rcx, rcx
  "74 ??",                    // je Talos2-Win64-Shipping.exe+25EE729
  "E8 ????????",              // call Talos2-Win64-Shipping.exe+25E45F0
  "48 63 ?? ????????",        // movsxd rax, dword ptr [rbx+000005D0]
  "8D 70 FF"                  // lea esi, [rax-01]

Now since making a signature is essentially just finding a unique substring, with a handful of extra rules for wildcards, you can also automate it. Here's a ghidra script (not my own) which I've found quite handy.

https://github.com/nosoop/ghidra_scripts/blob/master/makesig...

← PreviousPage 2 of 2