-
Overwatch Crashes on ReadProcessMemory
This information pertains to Overwatch 1.0.4.29372, the version shipped on release after the open beta. Tested while sitting on the login screen.
I have observed that performing ReadProcessMemory on a particular region of memory causes the client to crash. I don't know how many of these regions are there but there seems to always be at least one. I have also observed that the region in question is always Commited, Readable, Writable, not Executable, Private and Not Guarded (RPM on guard pages has no effect). In all instances, RPM causes Overwatch to crash, regardless of whether it came from an application running in administrator mode or normal mode. I have yet to find an explanation but I urge everybody reversing the client to exercise caution. I will continue my investigation but would appreciate any information the community has regarding this phenomenon.
-
Okay so I came across this article which seemed promising but I'm not entirely sure this is what they're using. I wrote a small application to dump the debug register values of all threads running in the game but came up with nothing. So they're probably doing something else. The search continues I guess.
-
I tried injecting a DLL that would read the memory byte-by-byte directly, without using any system calls. About 4161 bytes in, the game client crashed. The region I was scanning was 4 pages long (16384 bytes) with the same protections as mentioned above. There were no additional page flags that I could find. So we can conclude that it has nothing to do with RPM but with the way the memory was protected itself, as I suspected before. Furthermore, the memory is protected in such a way that RPM also triggers an exception. Very strange.
-
Contributor
I think I read somewhere something about them having their own veh. Possibly you are reading memory and getting into that veh somehow?
-
As mentioned above, the likely cause is they have the game install its own vectored exception handler, and then set hardware breakpoints either on specific locations in memory, or on randomized locations in memory intermittently. If an exception is raised from within the process address space, they continue. Otherwise, they pass the exception through and it causes a crash.
At least, this would be my assumption, having not looked at it myself.
-
So I've been poking around a bit more and wanted to give everybody an update on my findings so far. To start, I have to mention that the security in Overwatch continues to astound me, now more than ever. Blizzard is really doing a good job keeping people like me away from their game. Well done. With that said, I have conducted a few more tests on this mysterious memory reading protection that I want share with you.
To recap, we already know that there's a region that, when read, causes the game to throw an exception and crash. This crash happens regardless of how the memory is read, whether it be direct access via injected DLL or ReadProcessMemory. What I want to know is if there is some way of reading the memory without having it be detected by the game. In this post, I will discuss my experience with using kernel-mode drivers to try and sidestep the issue.
Now the problem with kernel-mode drivers is that they're a pain in the ass to write and set up. But luckily, I was able to use BlackBone to do most of the heavily lifting. I wrote a quick test application which used the BlackBone driver to read the memory of the game but no matter how many times I read it, the game refused to crash. I thought all my problems were solved, but no, it turned out that all my custom (RPM) tools worked, regardless of how many times I used them to scan the memory. The only thing that caused the game to crash was CheatEngine, and even then, it wasn't all the time.
It's worth mentioning that I'm running Windows in Test Mode and using version 1.0.4.29666 of the game (the latest, as of this post). So compared to the time when the game was crashing all the time, I think there's a pretty good chance that Blizzard changed something. Either way, I had to downgrade my copy of the game but the problem is that none of my earlier versions of Overwatch.exe worked with the current data files. So I had to use 1.0.4.29567 which was the only version I could get working (I made a copy of the data files now in case something like this happens again).
Anyways, 29567 behaves similarly to what we've seen before. I launched it and gave my driver another shot. Sadly, the game crashed. So what conclusions could we draw from this? If this post is any indication then both the BlackBone method of using MmCopyMemory and the posts' method of using RtlCopyMemory won't actually solve the problem. In fact, it might be even more dangerous now since they might be hiding this trigger from us or even toggling it randomly. So go ahead and grab an older version of the game if you want a consistent test environment before it's too late.
-
Post Thanks / Like - 3 Thanks
-
Private
Originally Posted by
Torpedoes
I tried injecting a DLL that would read the memory byte-by-byte directly, without using any system calls. About 4161 bytes in, the game client crashed. The region I was scanning was 4 pages long (16384 bytes) with the same protections as mentioned above. There were no additional page flags that I could find. So we can conclude that it has nothing to do with RPM but with the way the memory was protected itself, as I suspected before. Furthermore, the memory is protected in such a way that RPM also triggers an exception. Very strange.
Careful with injecting DLLs, you tend to get banned for that on overwatch.
-
Originally Posted by
hazedoff
Careful with injecting DLLs, you tend to get banned for that on overwatch.
I'm sure there are ways around that. Is there any information as to what Blizzard uses for the screenshots? Like... is it a directx call? Does warden have its own method? Wondering if anyone has looked into preventing the screenshot detection
Last edited by Sychotix; 06-22-2016 at 03:39 PM.
-
Originally Posted by
Sychotix
Is there any information as to what Blizzard uses for the screenshots? Like... is it a directx call? Does warden have its own method?
My money would be on BitBlt but I have no idea.
-
Private
Originally Posted by
Sychotix
I'm sure there are ways around that. Is there any information as to what Blizzard uses for the screenshots? Like... is it a directx call? Does warden have its own method? Wondering if anyone has looked into preventing the screenshot detection
I have a family member who use to work for blizzard, granted he was only a GM in WoW a few years ago but I can ask if he knows anything regarding it, very doubtful though.
-
Originally Posted by
hazedoff
I have a family member who use to work for blizzard, granted he was only a GM in WoW a few years ago but I can ask if he knows anything regarding it, very doubtful though.
So actually, we already know what they're doing but I was just too lazy to do another write up, but not anymore.
Basically, as DarthTon explained, they allocate some pages with no physical backing until the page is accessed. This means that any access whatsoever (even in kernel mode) will validate the page, thus allowing Blizzard to see that it's validated and promptly crash the game. To avoid this, you can use QueryWorkingSetEx or NtQueryVirtualMemory and if the "valid" property of the returned structure is zero, then you probably shouldn't be reading that page. A small note, however, if you're using the Nt flavor of this function, know that you'll have to pass it undocumented parameters, specifically: MemoryWorkingSetExList. Although many of these pages can be found, the only ones I found to crash the game are the ones where the entire region of pages come up as invalid.
See this thread for more information.
P.S. This information is based purely on my tests, I don't actually know if this is what they're doing. But what I do know is that the above method worked 100% of the time to detect and prevent the crashing of the client as a result of a memory scan.