https://momo5502.com/posts/2024-03-31-bypassing-denuvo-in-hogwarts-legacy/ Maurice's Blog Home >> Posts Bypassing Denuvo in Hogwarts Legacy March 31, 2024 * 7 min * Maurice Heumann [cover] When I announced my Black Ops 3 integrity bypass, someone commented that my research was not impressive and I should try analyzing Denuvo instead. That kinda stuck with me, so I did what everyone would do and spent the last 5 months of my life reverse engineering and bypassing the Denuvo DRM in Hogwarts Legacy. I am obviously not as skilled and experienced as EMPRESS, who managed to do it within days, but that's ok How does Denuvo work?# [denuvo-tok] The game collects hardware/software features into a fingerprint and generates a Steam Ticket (proof of game ownership). Fingerprint and Ticket are then sent to Denuvo Servers. From there the Steam Ticket is sent to Steam to make sure the user really owns the game (I obviously don't know what's going on in their servers, so this is only an assumption, but it should be accurate enough). If the user really owns the game, a Denuvo Token is generated, that only works on a PC with the exact fingerprint. Using that token, the player can now run the game. The game can not run without the token, as it is used to e.g. decrypt certain values at runtime and similar things. Ontop of using the token to decrypt values, Denuvo regularly verifies the hardware features for the fingerprint still match with the token, at runtime. What was my goal?# Cracking the game was not a goal I had. I like Hogwarts Legacy and thus causing any harm is not my intention. I wanted to do research purely for myself. Therefore this post is going to be intentionally vague and not going to show how I analyzed and patched the game in detail, because I don't need anymore legal trouble than I already have. The actual goal I had in mind was to find all features the game uses to derive the fingerprint and to patch them. Ontop of that, I want to patch most of the runtime checks. For a real crack, it is obviously needed to patch all of the runtime checks. Finding all of them is still an extremely time consuming task, so everyone who has achieved that deserves my utmost respect. However, I do believe that once I have patched some/most of the runtime checks and discovered all hardware features, I would be capable to patch all of them with enough time and motivation. The real challenge I saw for myself was to analyze the protection to discover all the bindings it uses for the fingerprint. How did I do it?# Using a Denuvo Token on a PC that has a mismatching fingerprint shows the following dialog: [bad-token] Therefore the goal is to get past that dialog. This is the part I wish I could talk more about, but I don't think that's a good idea. Instead I will roughly scratch the surface and at least outline the tools I used. To figure out what features the game collects I used the Qiling reverse engineering framework. Qiling emulates any kind of binary allowing to fully instrument it. It is truly a powerful framework: Qiling However, it requires a whole lot of scripting and adaption. It is by far not a tool that does all the work for you out-of-the-box. In fact, it even has quite a lot of bugs (e.g. wrongly emulated Windows APIs) and lacks quite a few essential features: I had to implement so many basics that I expected the framework to handle, e.g. TLS support . It feels like it is mainly designed for Linux, so maybe one day I can either upstream my patches/fixes or write my own framework. Who knows. But even with all these flaws, I can not stress enough how helpful of a tool it was. Getting fully accomodated to Qiling and finding most of the fingerprint features took me about two months. Discovering the last one took the remaining 3 months and I only discovered it on accident. To verify that a certain feature really is part of the fingerprint, I patched/spoofed it and checked that my previously valid Denuvo Token is now invalid and shows the error dialog. For most of my patches, I had to use quite a lot of runtime disassembling to dynamically build my hooks and stubs, which lead me to discover quite a few bugs in various disassemblers . However, as making a portable crack was not a goal, I made extensive use of my own hypervisor. I used it for example to install EPT hooks at a few locations that were otherwise too tedious to patch manually. With all features at hand, I forced the game to generate a token on my PC, using a fingerprint for my PC. Using all my patches and hooks (~2000 in total), I now wanted to run the game on my laptop using the token generated for my PC. After some time, I managed to get it to run until the start screen: [running] This is the point I wanted to reach. The game can now launch with a token issued for a different machine and I am absolutely happy. The game obviously still crashes here and there with the PC token. Sometimes I can launch into the game and play, sometimes it crashes. This is where one would need to patch all runtime checks. Knowing how the game performs these, it is just a matter of time and motivation. However, as previously mentioned, this is still a huge task task to pull off, so everyone who managed to do that deserves my utmost respect. What about performance?# Everyone knows the rumors that Denuvo kills performance, but is that actually true? With all hooks to disable (most) runtime validations in place, it is now time to do some performance measurements: Note that this analysis only applies to Hogwarts Legacy. I don't know if any of that applies to other games protected by Denuvo! Every time the console prints [MOMO] OVERHEAD one of my hooks triggers. This essentially means Denuvo intervenes in the execution of the game (that I had to patch). This in turn means Denuvo causes at least "some" (non-zero) performance overhead during those times. One can see that Denuvo does indeed intervene from time to time, but from what it seems, it doesn't do that very often. Only when major things happen, scene switches, loading screens or similar, the logs accumulate. Potential frame drops in those occasions don't seem relevant to me though. I was really surprised how few OVERHEAD lines were logged, as I expected the rumors to be true and tons of lines to be spamed, but this was not the case! Of course that's no absolute proof that Denuvo does not kill the performance. There might be interactions Denuvo does, which didn't require a patch and thus won't get logged. However, I wasn't able to find any indicators of any kind of relevant performance kills caused by Denuvo that would require a more thorough analysis. I would even argue that anyone who says Denuvo kills performance hasn't done any research to sustain their claims. (Again, only applicable to Hogwarts Legacy!) It seems the protection is very well integrated into the game. Being a DRM developer myself, I know this is often a super tough challenge and definitely requires the protection to be manually integrated and adapted for the game. Summary# This was the last thing I currently had on my bucket list and I'm so happy to cross that one off. It is to note that Denuvo could have done things a bit differently that would have made my analysis a lot harder. However, I still have to admit that it's an extremely strong protection. There was definitely more than one occasion when I was about to give up. On top of its protection, it seems to be very well integrated into the game and I was not able to measure any relevant performance overheads caused by it. Developing DRMs is always a super challenging task. Whether the use of DRMs is good or not, whether it feeds capitalism or just protects the hard work done by developers is something I can't decide. After all though, I don't think Denuvo deserves all the hate it gets. (c) 2024 Maurice's Blog Powered by Hugo & PaperMod