views:

206

answers:

4

Is it possible to know the location of const variables within an exe? We were thinking of watermarking our program so that each user that downloads the program from our server will have some unique key embedded in the code.

Is there another way to do this?

A: 

I'm not sure what you mean by "location" of a const value. You can certainly use items like reflection to access a const field on a particular type. Const fields bind like any other non-instance field of the same accessibility. I don't know if that fits your definition of location though.

JaredPar
Well, the application is a collection of files that we will keep on a server. When a user has decided to download the application, I was hoping we could use PHP to modify the windows exe by overwriting a predetermined section within it. Thus we could watermark each exe before automatically zipping it up and providing a download link to te user. If the file ever shows up as an illegal torrent, we would know where it came from.
Pedery
Pedery, you can absolutely do this. Check my edited comment above. But i wonder if your strategy has been tried by anyone. i think that it might be a fairly simple hack to null out the watermark to hide the source. Like taking a serial number of a piece of equipment...
Paul Sasik
Sure, but this is of course not the *only* means of security we'll embed. It's simply a way to watermark each download and I'm fairly sure a hacker would never spot this since the area of the binary is never used. It will only provide us a means to find illegal downloads and pinpoint where they came from.
Pedery
+3  A: 

You could build a binary with a watermark that is a string representation of a GUID in a .net type as a constant. After you build, perform a search for the GUID string in the binary file to check its location. You can change this GUID value to another GUID value and then run the binary and actually see the changed value in code output.

Note: The formatting is important as the length would be very important since you're messing with a compiled binary. For example, you'll want to keep the leading zeros of a GUID so that all instances have the same char length when converted to a string.

i have actually done this sort of thing with Win32 DLLs and even the Sql Server 2000 Desktop exe. (There was a hack where you could switch the desktop edition into a full blown SQL server by flipping a switch in the binary.)

This process could then be automated and a new copy of a DLL would be programmatically altered by a small, server-side utility for each client download.

Also take a look at this: link

It discusses the use of storing settings in a .Net DLL and uses a class-based approach and embeds the app settings file and is configurable after compilation.

Paul Sasik
Yes, I was thinking of something along these lines before I started. Yet I wanted to hear if anyone had any experience with this and recomendations regarding best practices. Thanks for the answer.
Pedery
i have done it using a hex editor. Doing it programmatically should be no sweat. And for best practices??? This solution and any along these lines is a hack job. You're modifying a binary file after compilation! Unless Microsoft creates a space in a file header to hold and edit this kind of information specifically, there will never be a "best practice".
Paul Sasik
+1  A: 

In C++ (for example):

#define GUID_TO_REPLACE "CC7839EB7EC047B290D686C65F98E0F4"
printf(GUID_TO_REPLACE);

in PHP:

<?php
exec("sed -e 's/CC7839EB7EC047B290D686C65F98E0F4/replacedreplacedreplacedreplaced/g' TestApp.exe > TestAppTagged.exe");
?>

If you stick your compiled binary on the server, visit the php script, download the tagged exe, and run it...you'll see that it now prints the "replaced" string rather than the GUID :)

Note that the length of the replaced string must be identical to the original (32 in this case), so you'll need to pad the length if you want to tag it with something shorter.

Metal450
+1  A: 

Key consideration #1: Assembly signing

Since you are distributing your application, clearly you are signing it. As such, since you're modifying the binary contents, you'll have to integrate the signing process directly in the downloading process.

Key consideration #2: const or readonly

There is a key difference between const and readonly variables that many people do not know about. In particular, if I do the following:

private readonly int SomeValue = 3;

...
if (SomeValue > 0)
    ...

Then it will compile to byte code like the following:

ldsfld [SomeValue]
ldc.i4.0
ble.s

If you make the following:

private const int SomeValue = 3;

...
if (SomeValue > 0)
    ...

Then it will compile to byte code like the following:

{contents of if block here}

const variables are [allowed to be] substituted and evaluated by the compiler instead of at run time, where readonly variables are always evaluated at run time. This makes a big difference when you expose fields to other assemblies, as a change to a const variable is a breaking change that forces a recompile of all dependent assemblies.

My recommendation

I see two reasonably easy options for watermarking, though I'm not an expert in the area so don't know how "good" they are overall.

  1. Watermark the embedded splash screen or About box logo image.
  2. Watermark the symmetric key for loading your string resources. Keep a cache so only have to decode them once and it won't be a performance problem - this is a variable applied to a commonly used obfuscation technique. The strings are stored in the binary as UTF-8 encoded strings, and can be replaced in-line as long as the new string's null-terminated length is less than or equal to the length of the string currently found in the binary.

Finally, Google reported the following article on watermarking software that you might want to take a look at.

280Z28
Thanks! I wasn't aware of this difference. However in our example I think either a const or readonly will suffice. I'll seriously consider your advice though. +1
Pedery