Well after a month I finally made progress. Turns out the error code 2001 I was getting was caused by GetTickCount returning 0 or a unreasonable value. After fixing this I got an error code value of 8011, then I patched the ProcessDebugFlags check(0x1f on NtQueryProcessInformation) and the game now runs under a debugger.
Obviously this is good news, but far from the expected result. Where is the VM? What does it do? What kind of anti-dumping techniques are used? Many more questions to be answered.
Wednesday, June 25, 2014
Friday, June 20, 2014
This is what SecuROM v8.10.008 packs so far.
I've identified the following anti-debug techniques.
ZwQueryInformationProcess, the parent process PID is stored in the InheritedFromUniqueProcessId field of the _PROCESS_BASIC_INFORMATION structure, which is then used in an OpenProcess call, which opens the parent process. No idea what happens when the call is made.
CreateFileA on the parent process, afterwards call to ReadFile, SecuROM tries to read the PE header supposedly.
Then we have various calls to CreateFileA on various files like ntice,sice,jcdspy etc.
FindWindow searching for various applications's windows, some of which are at or over 10 years old.
A call to EnumWindows with a custom callback function.
NtQueryObject call to check for the DebugObject.
ZwQuerySystemInformation with the SystemKernelDebuggerInformation class(0x23) which doesn't seem to indicate a debugger under Windows 7 x64.
And obviously, calls to IsDebuggerPresent,CheckRemoteDebuggerPresent,GetTickCount,QueryPerformanceCounter,GetSystemTime.
This is by far an exhaustive list. I've barely scratched the surface.
On a sidenote, GetTickCount is proving to be much more difficult to beat. Because if GetTickCount is patched to return 0, I end up getting an error code value of 2001 meaning Win95 not supported, oddly, GetTickCount was introduced in Windows 2000.
ZwQueryInformationProcess, the parent process PID is stored in the InheritedFromUniqueProcessId field of the _PROCESS_BASIC_INFORMATION structure, which is then used in an OpenProcess call, which opens the parent process. No idea what happens when the call is made.
CreateFileA on the parent process, afterwards call to ReadFile, SecuROM tries to read the PE header supposedly.
Then we have various calls to CreateFileA on various files like ntice,sice,jcdspy etc.
FindWindow searching for various applications's windows, some of which are at or over 10 years old.
A call to EnumWindows with a custom callback function.
NtQueryObject call to check for the DebugObject.
ZwQuerySystemInformation with the SystemKernelDebuggerInformation class(0x23) which doesn't seem to indicate a debugger under Windows 7 x64.
And obviously, calls to IsDebuggerPresent,CheckRemoteDebuggerPresent,GetTickCount,QueryPerformanceCounter,GetSystemTime.
This is by far an exhaustive list. I've barely scratched the surface.
On a sidenote, GetTickCount is proving to be much more difficult to beat. Because if GetTickCount is patched to return 0, I end up getting an error code value of 2001 meaning Win95 not supported, oddly, GetTickCount was introduced in Windows 2000.
Labels:
8,
8.10,
8.10.008,
antidebug,
GetTickCount,
securom,
securom v7,
securom v8,
version,
virtual machine,
vm
Monday, June 9, 2014
Process Virtual Machines.
Understanding SecuROM takes time, but even with time I still cannot understand the VM implementation it utilizes, no idea when it enters the vm, when it exits, or how to follow what it does. At this point I am unsure how to analyze SecuROM further.
If anybody has any tips about Process Virtual Machines, something that will be useful in unpacking this, comments are welcome.
And after asking a person, he told me the SecuROM version used in Crysis 3 is 8.10.008.
If anybody has any tips about Process Virtual Machines, something that will be useful in unpacking this, comments are welcome.
And after asking a person, he told me the SecuROM version used in Crysis 3 is 8.10.008.
Friday, June 6, 2014
SecuROM is a tough beast.
I've been battling the protection of Crysis 3 for 3 days straight, no progress whatsoever. I have olly loaded up with many different anti anti-debug plugins and none of them seem to work against SecuROM.
[8/6/2014] A small edit to clarify if it wasn't clear, I removed the EADRM protection, it was easy as pie, but at the OEP where I would've expected Crysis 3's code to start I ended up with the SecuROM code.
RELOADED/SKiDROW, if you are reading this(and it's very likely that you aren't). Am I to understand that you never managed to beat SecuROM in Crysis 3? Because SecuROM is still there in your cracks and you only exploit the license manager to make the game work.
Sorry, my ego got the best of me.
[8/6/2014] A small edit to clarify if it wasn't clear, I removed the EADRM protection, it was easy as pie, but at the OEP where I would've expected Crysis 3's code to start I ended up with the SecuROM code.
Sorry, my ego got the best of me.
Labels:
assembly,
disassembly,
drm,
ea,
eadrm,
electronic arts,
gaming,
opcode,
origin,
rce,
re,
reverse code engineering,
reverse engineering,
reverseengineering,
securom,
unpacking,
virtual machine,
vm,
x86,
yates
Regarding EADRM in general.
So while I was writing my Crysis 2 articles, I found out something, the OEP for what I can assume is every game released in the past few years via Origin, is stored in the actual .exe, near the end of the file, just after the four characters IREW(all capital), as in the 4 bytes after IREW is the OEP. So writing those down, adding to them the image base(and working out any relocation that might happen), you are at OEP, you put a HW breakpoint for instance on execution on the OEP, once you break you can just dump, all that's left is to fix imports.
That said, Crysis 2 was easy as pie to unpack, but Crysis 3 after unpacking has another layer of protection, this time much more advanced for the average joe(aka me) to unpack. Robert Yates, the guy who cracked SecuROM a while back told me that Crysis 3 uses an older version of SecuROM, obviously not that old, probably 8.X.
For now, SecuROM is beyond me.
Addendum: Fixed typo, it was IREW and not IWER.
Update 8d/2m/2016. The information above is no longer relevant, Origin have updated their DRM.
That said, Crysis 2 was easy as pie to unpack, but Crysis 3 after unpacking has another layer of protection, this time much more advanced for the average joe(aka me) to unpack. Robert Yates, the guy who cracked SecuROM a while back told me that Crysis 3 uses an older version of SecuROM, obviously not that old, probably 8.X.
For now, SecuROM is beyond me.
Addendum: Fixed typo, it was IREW and not IWER.
Update 8d/2m/2016. The information above is no longer relevant, Origin have updated their DRM.
Wednesday, June 4, 2014
Reverse Engineering. Unpacking Crysis 2! The actual stuff.
Before I continue, I want to stress that I legally own both Crysis 2, and Crysis 3 on Origin.
Now, I want to first say that my experience with RE is very limited, I don't really know ASM as well I should, nor do I know anything about the PE(Portable Executable) format. Or anti-debugging techniques and how to bypass them.
The tools used by me:
Much of our work will be done using Ollydbg 2.01, since Ollydbg 1.10 doesn't seem to like some patches that will be required. And much of our work will be done on the file called awc.dll, located in the Core folder, it's part of EADRM. It's responsible for unpacking and launching Crysis 2.
A few important abbreviations to remember before we begin:
Now, I want to first say that my experience with RE is very limited, I don't really know ASM as well I should, nor do I know anything about the PE(Portable Executable) format. Or anti-debugging techniques and how to bypass them.
The tools used by me:
- Ollydbg 1.10 with the following plugins: HideOD,StrongOD,phant0m,HideDebugger. Can't tell you which combo of options(anti anti-debug options) work, just try them all, until the executable does not crash, gives exceptions, exits etc.
- Ollydbg 2.01 with OllydumpEX for 2.x, no other plugins.
- Hex Editor
Much of our work will be done using Ollydbg 2.01, since Ollydbg 1.10 doesn't seem to like some patches that will be required. And much of our work will be done on the file called awc.dll, located in the Core folder, it's part of EADRM. It's responsible for unpacking and launching Crysis 2.
A few important abbreviations to remember before we begin:
- OEP - Original Entry Point.
- IAT - Import Address Table.
- EP - Entry Point.
- EIP - Extended Instruction Pointer.
- RVA - Relative Virtual Address.
- VA - Virtual Address.
- JMP - Jump Instruction.
When it comes to packing/unpacking, OEP refers to the entry point the way it was BEFORE the executable was packed. Most packers though, also destroy the Import Table and the executable does not know where to find say, the function Sleep, or say CreateProcess. So the unpacker stub basically does a few calls to LoadLibrary and GetProcAddress and rebuilds it, this doesn't mean it's as simple as using Import Reconstructor to fix things. In our case, it might require manual work to fix this.
I highly recommend reading this short article http://dreamofareverseengineer.blogspot.com/2011/10/unpacking-custom-packers.html
[Deleted]
Reverse Engineering. Unpacking Crysis 2!
It has been a long time since I wrote anything in the blog, thought it might be time to share some experience.
So, what is so special about Crysis 2? Isn't it a really old 2011 game? It's special in my heart, it all started in February of 2011, Crytek had released the DEMO Multiplayer of Crysis 2 and after having tried it for the first time, I fell in love immediately with the multiplayer component. Here came March 21st and March 22nd, the game came out, but I couldn't buy it then, so I patiently waited for a cracked version to appear, astonishingly, it took 2-3 days for somebody to release a crack, meanwhile there was a non-cracked version available.
So, what did I do? Well, I tried to crack it myself, of course! Did I succeed? Absolutely not! I didn't know a thing about RE(Reverse Engineering) or ASM(Assembly), but I still tried for a while.
I played the Singleplayer, after a cracked version was released, I loved how spooky and eerie the story felt, because it was saying the suit was alive and could think for itself. The story was all about the suit. Graphics were as always, pretty good. But the AI was dumb, really dumb.
After I finished the singleplayer, I kept wondering, how do I play the multiplayer? I couldn't. After a while(a month or two?), something amazing was released, something I didn't believe was even possible. A multiplayer crack! However strange as it may seem, it only worked in limited hours, between 16-21PM UTC. I never figured out how it worked.
Did I play? Yes, oh my god yes, the multiplayer was really competitive, it took skill to aim. After a while, I found a website that was selling Crysis 2 serial keys for just $16 dollars, even as low as $11. Should have noticed the signs. The key was legit, it worked fine up to the moment GameSpy shutdown in 2014 May. Yes, from the $11 dollar price of a game not even 2 months old, the sign was obvious, it was dying and sure enough, after about 3 months, Crytek stopped patching it, abruptly, and there was ZERO communication from them TILL the Crysis 3 announcement in the summer of 2012. I must stress the word ZERO.
The game was left unpatched, with various GAMEBREAKING bugs, such as the infamous Scar+Laser bug, which made you strafe faster and was abused a lot. And cheaters, that could bypass the votekick system easily, very easily.
Hint: Same thing happened to Crysis 3.
So, there you have it. Much of 2011 and 2012 was Bitcoin and Crysis 2, mine and play and play and mine. Those were the days!
Actual unpacking bits in next article.
So, what is so special about Crysis 2? Isn't it a really old 2011 game? It's special in my heart, it all started in February of 2011, Crytek had released the DEMO Multiplayer of Crysis 2 and after having tried it for the first time, I fell in love immediately with the multiplayer component. Here came March 21st and March 22nd, the game came out, but I couldn't buy it then, so I patiently waited for a cracked version to appear, astonishingly, it took 2-3 days for somebody to release a crack, meanwhile there was a non-cracked version available.
So, what did I do? Well, I tried to crack it myself, of course! Did I succeed? Absolutely not! I didn't know a thing about RE(Reverse Engineering) or ASM(Assembly), but I still tried for a while.
I played the Singleplayer, after a cracked version was released, I loved how spooky and eerie the story felt, because it was saying the suit was alive and could think for itself. The story was all about the suit. Graphics were as always, pretty good. But the AI was dumb, really dumb.
After I finished the singleplayer, I kept wondering, how do I play the multiplayer? I couldn't. After a while(a month or two?), something amazing was released, something I didn't believe was even possible. A multiplayer crack! However strange as it may seem, it only worked in limited hours, between 16-21PM UTC. I never figured out how it worked.
Did I play? Yes, oh my god yes, the multiplayer was really competitive, it took skill to aim. After a while, I found a website that was selling Crysis 2 serial keys for just $16 dollars, even as low as $11. Should have noticed the signs. The key was legit, it worked fine up to the moment GameSpy shutdown in 2014 May. Yes, from the $11 dollar price of a game not even 2 months old, the sign was obvious, it was dying and sure enough, after about 3 months, Crytek stopped patching it, abruptly, and there was ZERO communication from them TILL the Crysis 3 announcement in the summer of 2012. I must stress the word ZERO.
The game was left unpatched, with various GAMEBREAKING bugs, such as the infamous Scar+Laser bug, which made you strafe faster and was abused a lot. And cheaters, that could bypass the votekick system easily, very easily.
Hint: Same thing happened to Crysis 3.
So, there you have it. Much of 2011 and 2012 was Bitcoin and Crysis 2, mine and play and play and mine. Those were the days!
Actual unpacking bits in next article.
Thursday, January 2, 2014
Location of the ATI ATOMBIOS!
After having a chat with some guys developing the open source radeon driver on freenode, and with the reverse engineering of GPU-Z I found where the ATI ATOMBIOS is located.
Pretty simple actually, you take the BAR2(Base Address Register #2) and XOR it with 0x80000 afterwards you AND the result with 0xFFFE0000.
In practical terms
atombiosaddress = (BAR2 ^ 0x80000) & 0xFFFE0000.
Also, the VBIOS of the primary card can also be located at physical address 0xc0000 like radentool has specified.
EDIT: I did a binary comparison of my dump of my card vs the one from GPU-Z and mine seems to contain different data at certain locations. So not quite there yet.
Something interesting I discovered is that the location of the ATOMBIOS on the primary card is not always available at the address using the formula above, the address is valid, however the GPU-Z driver does something to make the card map the BIOS to that location, after it's done the address is valid, just doesn't contain anything. It works on non-primary cards though.
Pretty simple actually, you take the BAR2(Base Address Register #2) and XOR it with 0x80000 afterwards you AND the result with 0xFFFE0000.
In practical terms
atombiosaddress = (BAR2 ^ 0x80000) & 0xFFFE0000.
Also, the VBIOS of the primary card can also be located at physical address 0xc0000 like radentool has specified.
EDIT: I did a binary comparison of my dump of my card vs the one from GPU-Z and mine seems to contain different data at certain locations. So not quite there yet.
Something interesting I discovered is that the location of the ATOMBIOS on the primary card is not always available at the address using the formula above, the address is valid, however the GPU-Z driver does something to make the card map the BIOS to that location, after it's done the address is valid, just doesn't contain anything. It works on non-primary cards though.
Monday, December 30, 2013
Disassembly of GPU-Z, I2C and GPUs in between part 2
I decided to focus on something easy this time, I wanted to figure out where on the memory of the card is the ATI ATOMBIOS stored, so I followed GPU-Z stepping into, for at least 2 hours and found something only for GPU-Z to trick me and give me false leads.
The line where it says "Writes bios byte by byte" is a bit misleading, since I found out that only the header of the ATOMBIOS was written to the buffer, odd as that may be. After stepping into the functions I suddenly found an address that pointed to where the BIOS was mapped to but how or when it got set, was a mystery to me.
However, what I did find is that for >=HD5k series of graphics cards, GPU-Z assumes a size of 0x20000(131072 bytes) for the BIOS.
After studying the tool radeontool, there is an interesting function here
void radeon_rom_tables(const char * file)
{
#define _64K (64*1024)
unsigned char bios[_64K];
char *biosmem;
int fd, hdr, atom;
if (strcmp(file, "mmap") == 0) {
fd = open("/dev/mem", O_RDWR);
biosmem = mmap(0, _64K, PROT_READ, MAP_SHARED, fd, 0xc0000);
if (biosmem == MAP_FAILED) {
perror("can't mmap bios");
return;
}
memset(bios, 0, _64K);
memcpy(bios, biosmem, _64K);
munmap(biosmem, _64K);
close(fd);
}
It might indicate that the rom is located at offset 0xc0000 in physical memory. However is this also true for multiple graphics cards?
Sunday, December 29, 2013
Disassembly of GPU-Z, I2C and GPUs
It's been a while since I've written anything, I wasn't going to but I did want to share some findings.
Now, I am not exactly versed in programming, I still struggle at the basics, linked lists let alone x86 assembly, but I delved into GPU-Z, a tool used to monitor vital sensors inside any modern graphics card. What sets it apart from other general purpose tools like AIDA64,HWMon,Open Hardware Monitor is that it specializes only in GPUs and is therefore very thorough, displaying information like VRM temperatures and currents. AIDA64 is the only one that also displays this data, but not all of the sensors.
When I first started disassembling GPU-Z with OllyDbg 2, I was greeted with a warning that it's likely packed, and indeed it was. As of version 0.7.5 the packer used is PECompact 2.x or 3.x, it's apparently easy to unpack a PECompact packed executable, but after trying it, I must have got it wrong somewhere and didn't get a multitude of functions imported correctly and after running the executable I got an error stating "floating point support not loaded". I gave up after a couple of more tries and used Nacho_dj's pecompact unpacker to unpack it, it worked.
How exactly does the Temperature component of GPU-Z work? It works by mapping physical memory to userspace and doing bit-banging on the I2C bus. Here is where it gets tricky, under Linux it's trivial to map physical memory to userspace(root and mmap roughly), but under Windows you need a driver, and not just any driver, but a kernel mode driver, and not just any kernel mode driver, a digitally signed driver to do this, usually only for x64 but may also apply to x86(32-bit Windows). Digital signatures cost a minimum of $100, may be cheaper somewhere but it costs money regardless. Lucky, it's possible to enable Test-mode in Windows and allow the running of unsigned drivers, but this makes your installation extremely vulnerable. But where do you get such a driver?
Luckily for you and me, an open source driver is available and it can be compiled to work with Windows 7 x64 as well. It's called PhyMem. I will not go into details how it works, because I myself have not yet figured that out.
Does GPU-Z use this driver? Probably not, GPU-Z predates this driver. It however uses it's own driver which is stored in the executable itself and is written in %temp% during runtime where it's executed from and removed.
Here is the GPU-Z(not source code) driver if you want it http://www.filedropper.com/gpu-z.
In part 2 I will try to explain what is being mapped, how much of it and explain more of what I found in GPU-Z.
Now, I am not exactly versed in programming, I still struggle at the basics, linked lists let alone x86 assembly, but I delved into GPU-Z, a tool used to monitor vital sensors inside any modern graphics card. What sets it apart from other general purpose tools like AIDA64,HWMon,Open Hardware Monitor is that it specializes only in GPUs and is therefore very thorough, displaying information like VRM temperatures and currents. AIDA64 is the only one that also displays this data, but not all of the sensors.
When I first started disassembling GPU-Z with OllyDbg 2, I was greeted with a warning that it's likely packed, and indeed it was. As of version 0.7.5 the packer used is PECompact 2.x or 3.x, it's apparently easy to unpack a PECompact packed executable, but after trying it, I must have got it wrong somewhere and didn't get a multitude of functions imported correctly and after running the executable I got an error stating "floating point support not loaded". I gave up after a couple of more tries and used Nacho_dj's pecompact unpacker to unpack it, it worked.
How exactly does the Temperature component of GPU-Z work? It works by mapping physical memory to userspace and doing bit-banging on the I2C bus. Here is where it gets tricky, under Linux it's trivial to map physical memory to userspace(root and mmap roughly), but under Windows you need a driver, and not just any driver, but a kernel mode driver, and not just any kernel mode driver, a digitally signed driver to do this, usually only for x64 but may also apply to x86(32-bit Windows). Digital signatures cost a minimum of $100, may be cheaper somewhere but it costs money regardless. Lucky, it's possible to enable Test-mode in Windows and allow the running of unsigned drivers, but this makes your installation extremely vulnerable. But where do you get such a driver?
Luckily for you and me, an open source driver is available and it can be compiled to work with Windows 7 x64 as well. It's called PhyMem. I will not go into details how it works, because I myself have not yet figured that out.
Does GPU-Z use this driver? Probably not, GPU-Z predates this driver. It however uses it's own driver which is stored in the executable itself and is written in %temp% during runtime where it's executed from and removed.
Here is the GPU-Z(not source code) driver if you want it http://www.filedropper.com/gpu-z.
In part 2 I will try to explain what is being mapped, how much of it and explain more of what I found in GPU-Z.
Subscribe to:
Posts (Atom)