Breaking SecuROM 7 – A Dissection
lostfilearchives.github.io
lostfilearchives.github.io
Also iirc after this tutorial deroko wrote another one one breaking the Securom VM obfuscation. It was great work, one of the first public tutorials at the time on breaking such obfuscation. I wonder if its also been archived.
Finally, it should be noted that Securom is a predecessor to Denuvo. I remember debugging early versions of Denuvo and being struck by how similar they are. I wonder how much of the code and techniques are in common between the two, especially now in 2024.
The old reversing scene has changed. I guess everyone grew up and got families and jobs. But when I see what the kids are up to in the multiplayer cheating forums, I see the spirit is still alive and well. Cheers and happy debugging.
The EFI-based cheats, or even the DMA PCI-e hardware streaming memory data out to a second computer are fascinating, to get around ring-0 anticheats like Vanguard
…which makes me wonder if anything’s running in SME mode instead thesedays.
This second computer is connected to the first computer by usb, to spoof a HID (mouse, keyboard, controller etc). It reads the data from the pci card on the first computer and sends inputs via usb.
Done right, and it can’t be detected via software. Behaviour analysis still works for aim hacks.
Now days I think there are even devices that will tap the hdmi stream and use the video data to calculate inputs and the send the input via usb/hid/controller. This works on console I think!
At least for Vanguard specifically, nope you'll get pinged if you try that naively; mainly because Vanguard looks for funky USB devices (among other things)
Now the way to approach it is to spoof USB hardware IDs and data streams, so you can then use approaches like what you've described, and some even use that to inject HID/mouse movement back into the host PC.
Basically allows cheats with nothing more than a micro-controller and a second PC, but it is still more detectable/cat-and-mouse than PCIe DMA devices + second PCs (and video muxing/overlay devices to put the ESP/whatever over the existing "clean" host PC's output)
Also if you're running Windows 11, Vanguard requires TPM 2.0 + Secure Boot which makes some things a lot more painful
I wonder if a look into the leaked Windows kernel source code files (I _think_ the most current dump is still old Win2k?) could help out to decipher what these two RESERVED flags are used for?
PEB_LDR_DATA still has them named as RESERVED1/2 [1].
[1] https://learn.microsoft.com/de-de/windows/win32/api/winternl...
The layout of PEB_LDR_DATA “leaked” long time ago in public PDBs.
More context: It has nothing to do with debugging. However, if you attach to the process early enough, you might see the flag as 0 and eventually it would switch to 1. That is probably what threw him off.
Sorry, noob question: Were there easy avaiable tools (in the debugger), to monitor a variable like this and have the debugger stop exactly when it was going to change, so you could see which thread and function did it and why?
Depending on the platform and the debugger, these can be implemented using CPU architecture-specific debugging features, or in software, by single-step program execution and checking watched addresses for changes after each step.
[1] https://sourceware.org/gdb/current/onlinedocs/gdb.html/Set-W...
I didn't check any of the rest of the links, figuring they were in the same boat of "too obscure to have been preserved"
I have more experience with SecuROM 8. Did you guys know there is a hidden flag that is parsed on executable running that initializes a separate application which generates a file you can send to the authors of SecuROM that holds the version of SecuROM and quite a lot of other details?
Opaque predicates, VM, simple code integrity checks(int 3), xchg used as control flow obfuscation? It was all there. It took me a while to get the program running under a debugger. Once I did there were a bunch of threads running which would detect tampering or pausing of the threads and kill the process. After suspending those I could do whatever I want.
The DRM used a lot of control flow methods, especially hardware breakpoints and UD2 instruction.
At the time of Unicorn engine's popularity I made a custom plugin to emulate the zlib code embedded inside to search for hidden API calls, unfortunately due to the way QEMU emitted some instructions for the helpers some instructon hooks were called a few times more e.g those with a rep prefix severely skewing instruction counting.
Anyway, VM hunting was difficult. The VM had quite a few single-threaded VM contexts so it could run a lot of programs. From then on it was a matter of reverse engineering the opcodes. at the time I used Olly to trace and log the instruction handlers and opcodes and then using Notepad++ magic I could clean it up from the control flow in a single coherent picture.
Honestly I've forgotten most of it now.
But a few years ago I did write my own Control flow graph generator in Java just to find the 20 or 30 thousand code integrity checks and trace them statically and then was going to use it on the VM.
The most unusual thing is, I often communicated with one of the devs of SecuROM on IRC, of course I did not ask him anything nor did he reveal anything, that is of course illegal. I remember asking him about the little "Cut my life into pieces" tidbit he left just after VMEnter.
Needless to say it is thanks to SecuROM that I gained an interest in RE. Yes I was a novice and dived deep down into a commercial DRM. Thanks to it I learned a lot and is helping me even today, yep as I type this I am working on a SH2 architecture firmware.
But back in the day SecuROM inspired me to write this little ugly thing https://github.com/farmdve/TextVM
mov imm, reg
would get translated in 20-30 instructions most of them junk, but they were not laid out contiguously, you would execute one junk instruction and then return to the dispatcher to get to the next one, if I remember correctly. This made the VM and tracing dog slow. Additionally it used a small 256 or 1024 byte scratch buffer for the virtual registers that held data. I've forgotten now how it was exactly.
The entire VM used only jmp instructions which was how you would spot it.
I wonder if modern AI could solve that for you. "Oh look, that huge block essentially just set some variable to 127".
A 93.8% reduction... That's brutal.