Sign in to follow this  
RogerThat123

Random CRC on Application Launch

Recommended Posts

Hello all, I am wondering how one may be able to change the CRC of a program on application launch. I know I can do it by recompiling m y program with minor code changes. But I need for each time I launch the application, its different from before, by CRC. Thanks, if any of you are able to help.

Share this post


Link to post
Share on other sites
CRC is not an intrinsic property of an application. It is simply an elaborate sum of all bytes of executable.

Random CRC computed from application executable does not make any sense. Just use rand() to obtain random number. It will be exactly the same thing.

Share this post


Link to post
Share on other sites
Yes I know what the CRC is. This is my situation, Im coding an add-on for a game.

And some people try to use cheats on this specific game add on. They are doing CRC

checks to see if my game has updated so they know to update their cheats so they

do not get banned. Ive seen this done before, changing the crc that is, and Im

thinking something along the lines of some sort of Packer/Crypter that modifies

some of the code, on assembly. Thus changing the CRC.

Is something like this possible? And how may I go about accomplishing it.

Share this post


Link to post
Share on other sites
Not really. Once your application launches, you cannot modify the executable since it's locked. This is why patchers need to restart.

You could make a launcher that starts the real executable, but first appends random bytes before launching. Or add a random section in build process, and write garbage into that. But if someone is capable of modifying an executable, they'll circumvent this in 2 seconds flat.

Simply put, once you start dealing with people who can modify actual executable via code injection, reverse engineering, or similar methods, client-side protection fails.


The only way is something like Blizzard does. Inside your application, run an interpreter of sorts. Server then sends a script, which does something with local state. Checks variables, offsets, file contents, etc... It reports checksum of that. If this checksum matches checksum of same test performed server side, the client is assumed to be legit. If not, disconnect them.

All that's left then is to develop test generator, something that generates unique test for each client each time they log on - to prevent reverse engineering of tests and responding with fake data.

This isn't trivial, but it's as close to reliable validation as you can get. Again, you are dealing with people who can interact with running application, not your generic clueless user.

Share this post


Link to post
Share on other sites
Quote:
Original post by Antheus
Not really. Once your application launches, you cannot modify the executable since it's locked. This is why patchers need to restart.

You could make a launcher that starts the real executable, but first appends random bytes before launching. Or add a random section in build process, and write garbage into that. But if someone is capable of modifying an executable, they'll circumvent this in 2 seconds flat.




What do you mean by add a random section in build process and write garbage. Im not worried about someone reversing anything, just that the CRC is random every time. How might this be done.

Share this post


Link to post
Share on other sites
The only way to make the CRC change is to make the program's binary image on disk change. The only way to do that without corrupting your program is to include "extra" areas in the program image that you can write random junk to each time. The problem with that, though, is that the hackers will just start excluding those areas of the DLL from their CRC check.

And if you have a "launcher" executable which modifies the CRC, the hackers will just disable the launcher so that it doesn't modify anything.

The only way, really, is to release - with significant changes - more often. Anything else that you do is just going to be an arms race where the hackers are always one step ahead.

That, or you give hackers less of an incentive to hack the game. That's a domain-specific problem, though.

Share this post


Link to post
Share on other sites
I am not worried about them excluding this "random" area of the code. That is no problem for me.

But what are these random areas where you put random junk in?

Can you give me an example?

Share this post


Link to post
Share on other sites
Quote:
Original post by RogerThat123
But what are these random areas where you put random junk in?
Under Win32 your safest bet is probably to set up a random, and otherwise unused, resource and update that (e.g. through the UpdateResource family of functions.) Unfortunately can't do it on a running executable so you'll either have to dynamically load and update a DLL, or go spawn a helper EXE for the update when terminating your application.

At any rate I wouldn't count on this method to protect you from any but the most inept of hackers.

Share this post


Link to post
Share on other sites
Quote:
Original post by RogerThat123
But what are these random areas where you put random junk in?

Can you give me an example?
Well, you can put extra data at the end of an exectuable and it is just ignored, so the simplest solution would be to write 100 (or so) bytes of random data to the end of the executable. A naive CRC check would change everytime you change that last 100 bytes.

But that doesn't actually solve the problem, because a hacker will just perform the CRC check on everything but that last 100 bytes.

You can get more tricky with where in the executable you write your random stuff, but where ever you write it, it's basically the same for the hacker - just exclude that area when they do their CRC check.

Share this post


Link to post
Share on other sites
Quote:
Original post by Codeka
Quote:
Original post by RogerThat123
But what are these random areas where you put random junk in?

Can you give me an example?
Well, you can put extra data at the end of an exectuable and it is just ignored, so the simplest solution would be to write 100 (or so) bytes of random data to the end of the executable. A naive CRC check would change everytime you change that last 100 bytes.

But that doesn't actually solve the problem, because a hacker will just perform the CRC check on everything but that last 100 bytes.

You can get more tricky with where in the executable you write your random stuff, but where ever you write it, it's basically the same for the hacker - just exclude that area when they do their CRC check.


Again what do you mean add random 100 bytes at the end. My application loads my DLL. My DLL is the file that needs to change the crc. SO, I can use my executable to do so because the executable does not matter to me.

But yes, what do you mean, random 100 bytes at the end. Thanks

Share this post


Link to post
Share on other sites
Quote:
Original post by RogerThat123
But yes, what do you mean, random 100 bytes at the end. Thanks
Maybe some pseudocode will explain better:

char buffer[100];
for(int i = 0; i < 100; i++)
buffer[i] = rand();

HANDLE h = ::CreateFile("MyDll.dll", ...);
::SetFilePointer(h, 0, 0, FILE_END);
::WriteFile(h, buffer, 100, ...);
::CloseHandle(h);

The extra data is ignored by the windows loader when it goes to load the DLL, and a naive CRC check on that file would then return a different value each time.

Share this post


Link to post
Share on other sites
brbbbb

bacK:


char buffer[100];
for(int i = 0; i < 100; i++)
buffer[i] = rand();

HANDLE h = ::CreateFile("Test.dll", GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);

OVERLAPPED osWrite = {0};
DWORD dwWritten;

::SetFilePointer(h, 0, 0, FILE_END);
::WriteFile(h, buffer, 100, &dwWritten, &osWrite);
::CloseHandle(h);


I am doing like you say, but each time the CRC is still identical, even after writing the extra 100 bytes onto the end.

Share this post


Link to post
Share on other sites
http://www34.brinkster.com/dizzyk/crc32.asp

Using that program there.

Is there an alternative way to what you showed me, and I am passing the correct values into writefile?

Share this post


Link to post
Share on other sites
maybe try using blocks of random variables (say a block consists of 10 ints) that are initialized randomly on load.

That could possibly change the CRC

Share this post


Link to post
Share on other sites
Quote:
Original post by godsenddeath
maybe try using blocks of random variables (say a block consists of 10 ints) that are initialized randomly on load.

That could possibly change the CRC


Do you mean just creating random variables inside the application itself such as


int random[10];
for (i= 0; i < 10; i++)
random[i] = rand()%100;


This will have no affect on the programs crc

I still cant believe what codeka suggested doesnt work.

Share this post


Link to post
Share on other sites
Yes, there doesn't seem to be any reason why what you've posted would not work. I guess there must be something wrong somewhere, because I believe the method is sound. The only thing which springs to mind is that the "Test.dll" passed to CreateFile is different to the one that you're actually expecting.

In particular, note that LoadLibrary uses a different search algorithm for finding files than CreateFile uses (in particular, LoadLibrary looks in the same directory as the executable (and several other places) before it looks in the current working directory, whereas CreateFile only looks in the current working directory - unless you specify the full path). I suggest you try specifying the full path to the DLL in your call to CreateFile and see how that goes.

Share this post


Link to post
Share on other sites
Codeka, you were right. You need to specify the FULL path. However theres a problem, at least now I know its being modified.

But, its not rewriting what I had originally. My DLL before, is 900 kb. And after, its just 1 kb. Which is weird I think considering we are writing to the end of the file if Im not mistaken.

Share this post


Link to post
Share on other sites
Quote:
Original post by RogerThat123
But, its not rewriting what I had originally. My DLL before, is 900 kb. And after, its just 1 kb. Which is weird I think considering we are writing to the end of the file if Im not mistaken.
Whoops, I missed your parameters to the CreateFile function. It should be OPEN_EXISTING, not CREATE_ALWAYS (OPEN_EXISTING will open an existing file, and give you an error if the file doesn't exist; CREATE_ALWAYS will create the file if it doesn't exist, and overwrite the existing file if it does).

Share this post


Link to post
Share on other sites
yeah I started looking at that for a sec.

Ok so we have progress now, with the OPEN_EXISTING , we are reading it correctly.

And the first time my .exe is launched. The File changes its CRC perfect. But anytime after, it is identical. And the program is not growing in size slowly either.

EDIT: Damn, my DLL doesnt load properly when we write extra data to the end of it like this, it just doesnt load at all. I really thought this method was going to work @#$%.

Share this post


Link to post
Share on other sites
Quote:
Original post by RogerThat123
EDIT: Damn, my DLL doesnt load properly when we write extra data to the end of it like this, it just doesnt load at all. I really thought this method was going to work @#$%.


I vaguely remember a discussion here a long time ago about problems encountered when hand-modifying EXEs or DLLs. I believe the solution had to do with a size-of-EXE (or possibly size-of-section) field somewhere in the header that needed to be updated correctly.

(Edit) Found it: Link

Share this post


Link to post
Share on other sites
Thanks for the reply.

Would you happen to know how to change this value

After launching my exe that modifies my DLL. I try opening the modified DLL in PE Explorer, but it fails because it now says its not a valid library file.

19.08.2009 00:50:29 : Open File: C:\Users\Me\Desktop\Test.dll
19.08.2009 00:50:32 : File size: 553984 bytes.
19.08.2009 00:50:32 : Error: This is NOT EXE or DLL File! Processing cancelled.
19.08.2009 00:50:32 : Error! (Step: Examining File Headers)
19.08.2009 00:50:32 : Done.


[Edited by - RogerThat123 on August 18, 2009 11:09:49 PM]

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this