6

I've developed a c++ project with visual studio 2015. The output of my project is a single executable that must have a unique ID for every client and this ID must be accessible inside the code. A simple approach is to just define a constant variable inside the code and change its value for every client and build it many times but I have a Linux server and I'm not sure I can build it simply because I've used many Winapi libraries. I was thinking that maybe there is another way to change or add some constant value to the output like manipulating the executable. For example:

#include <string>
#include <iostream>
#include <Windows.h>


const std::string ID = "some unique ID";

int main() {
    std::cout << "Your ID: " << ID << std::endl;
    getchar();
    return(0);
}
Masoud Rahimi
  • 5,785
  • 15
  • 39
  • 67
  • 1
    Put the id in a configuration file? Pass it as an argument to the program? – Some programmer dude May 23 '18 at 03:58
  • @Someprogrammerdude My project output must be a single executable and should not have any files besides it. Can you explain a little more, which configuration? Thanks – Masoud Rahimi May 23 '18 at 03:59
  • prepend and append some searchable strings and use sed/python to replace the ID between those in the binary? – alo Malbarez May 23 '18 at 04:01
  • @aloMalbarez I think this would work but how can I implement that, should I define the constant and open the binary and search for it? – Masoud Rahimi May 23 '18 at 04:03
  • humm not much a fan of regexp, maybe some bash guru can build up a solution? but yeah the idea is to know where to find the ID and replace it (binary file, known length, etc..) – alo Malbarez May 23 '18 at 04:07
  • @MasoudR. *My project output must be a single executable and should not have any files besides it.* -- So how does your client install your program? Isn't an installation program used? In that installation script, that is when you can alter the executable. – PaulMcKenzie May 23 '18 at 04:09
  • @PaulMcKenzie Actually the executable is not directly fed to a client, it is a part of another application and If I wanted that way wouldn't ask here. – Masoud Rahimi May 23 '18 at 04:12
  • 1
    well I assumed he will provide a download link to a custom executable wich has the ID assigned to that particular downloader, so hot patching a standard executable could be an alternative to recompile the whole thing (btw the ID could be also being encrypted at patch time and decrypted at runtime) – alo Malbarez May 23 '18 at 04:14
  • @aloMalbarez Thanks, is there any example for this way? – Masoud Rahimi May 23 '18 at 04:19
  • 2
    @MasoudR. -- First, is this a Windows program? If so, you can create a [string resource](https://msdn.microsoft.com/en-us/library/windows/desktop/aa381050%28v=vs.85%29.aspx) and change it directly in the executable. I know this violates your rule of not having another program, but [just to illustrate that it can be done](http://www.angusj.com/resourcehacker/). You just need to figure out the mechanism to do it. – PaulMcKenzie May 23 '18 at 04:22
  • 1
    maybe this link can help http://everydaywithlinux.blogspot.com.ar/2012/11/patch-strings-in-binary-files-with-sed.html – alo Malbarez May 23 '18 at 04:28
  • @PaulMcKenzie Yes it is a windows program. Thank you I will get into it. – Masoud Rahimi May 23 '18 at 04:28
  • @aloMalbarez I will try to post a sample here. Thanks. – Masoud Rahimi May 23 '18 at 04:31
  • XD just realized, once you know the offset you just write a patcher in c that opens the file lseek, write and close. if the executable is signed it will invalidate the thing, but normal executables should work. – alo Malbarez May 23 '18 at 04:49
  • @aloMalbarez The link you provided is too complicated for me, I think there might be a simpler way to just search in the binary file for "some unique id" and replace it with "new unique id". – Masoud Rahimi May 23 '18 at 04:54
  • yup some default ID (that won't work) but can be replaced by a valid ID – alo Malbarez May 23 '18 at 04:57
  • 1
    here try this one https://unix.stackexchange.com/a/214824/258399 – alo Malbarez May 23 '18 at 05:00
  • @aloMalbarez Thanks It worked for me. I try to create a simple bash script. – Masoud Rahimi May 23 '18 at 05:18

3 Answers3

2

It seems that there are only two approaches. One is just building the project inside a Linux environment which is a better method but must be used some tools like Mono XBuild link here. Another option which may be simpler is just open the binary file and manipulate the specific string. As @aloMalbarez comment Here is a simple script based on this. Suppose this example: (I used 50 ms as a fixed length for my ID)

#include <string>
#include <iostream>
#include <Windows.h>

#define ID "mmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmm"


using namespace std;

int main() {
    cout << "Your ID: " << ID << "\nlen:" << strlen(ID) <<  endl;
    getchar();
    return(0);
}

After generating the executable use the following script to create output. I'm not a Linux guy so you can help me improve this. ./build.sh input.exe output.exe "myfixedID"

#!/bin/bash
# build.sh input_file output_file <ID>


input_file=$1
output_file=$2
ID=$3


if [ -z "$1" ] || [ -z "$2" ] || [ -z "$3" ]; then
  echo "wrong parameters"
  echo "build.sh input_file output_file <ID>"
  exit 1
fi

# use fixed string (ID) in the source file
# this creates 50 of "m"s
search_value=$(printf 'm%.0s' {1..50})

extension=".back"
temp_file="$input_file$extension"
tmpstring_file="./tmp"
null_termin='\0'


echo "copying the original file..."
yes | cp -rf $input_file $temp_file

address=$(strings -t d $temp_file | grep $search_value | grep -o '[0-9]*')

echo "Address:"
echo $address
if ! [[ $address =~ ^[0-9]+$ ]]; then
  echo "cannot find valid ID in executable"
  echo "removing temps"
  rm $temp_file
  exit 1
fi


# make the tempstring file
printf "$ID$null_termin" > $tmpstring_file

dd if=$tmpstring_file of=$temp_file obs=1 seek=$address conv=notrunc

echo "make new file"
yes | cp -rf $temp_file $output_file

echo "removing temps"

rm $temp_file $tmpstring_file

echo "Done!"
Masoud Rahimi
  • 5,785
  • 15
  • 39
  • 67
1

In init function of your program. Generate a unique id based of SHA-1 hash of current time, IP address, username (same more). you can do whatever you want to do in that program afterward (i.e save in database). Will that work ?

code707
  • 1,663
  • 1
  • 8
  • 20
  • Thanks, but the ID is constant and must be known to the server, and It is not a good idea to build 1000 times for every possible client. – Masoud Rahimi May 23 '18 at 04:49
  • Can client and server generate ID based on same information. For example, based on username, email address, userid (using hash function like SHA-1)? so, server can know client without explicting passing information ? – code707 May 23 '18 at 04:56
  • @ You are right and it would possible in that way but the server has no idea what is a client and need to just make the executable with a unique id and that is it. – Masoud Rahimi May 23 '18 at 04:59
-4

A Constant is not a Variable, they are opposite types. A Constant is an element that is assigned a particular value that does not change, thus the word constant, unchanging.
A Variable on the other hand is an element that is stored in memory as a changeable value, as your program runs, the VARIABLE can change it's current value.

In Visual Studio, you can create a configuration file that passes set values to your program, these values are variable, and can be changed programmatically and manually. But, as you stated you do not want a separate file to look up information from.

If you want to track users by their Unique ID, then you must have a database somewhere that can record new users and issue a unique ID, or, you can create a unique ID based on the date and time that the account is created, if you are creating a unique executable for each one, the date/time information is included in the file creation information, so you would simply use that, since every file is created at a unique date/time, that would always indicate the ID. You could keep the same name for each file, or incorporate the date/time into the filename, like myPro20180522183231.exe which would be year 2018 month 05 day 22 hour 18 minutes 32 seconds 31 and this could be confirmed through the date/time information of the file creation data.

KeyWizard
  • 1
  • 1