Thread: Simple Xor Encryption help

  1. #1
    Registered User
    Join Date
    Aug 2006
    Posts
    19

    Simple Xor Encryption help

    Hello, I am having trouble understanding the following Xor enryption method written in C:

    Code:
    void gamespyxor(u_char *data, int len) {
        u_char  gamespy[] = "gamespy",
                *gs;
    
        for(gs = gamespy; len; len--, gs++, data++) {
            if(!*gs) gs = gamespy;
            *data ^= *gs;
        }
    }
    I would like to get PHP code or VB code that would convert whatever string of data I want using the method above. The person who wrote that code hasn't been able to explain it very well to me, and takes a long time to answer my questions, so I have come here for help with it. He did say the following though:

    It's very very simple, XORing is the base for any encryption algorithm.
    Each byte of the string must be XORed with "gamespy"
    So I am trying to get PHP or VB to replicate the code above, and XOR any piece of text or string I want by the term 'gamespy'. However I just can't figure out exactly how to do it, or seem to understand what is really going on (in easy terms). I have been playing around with XOR functions all day in VB and php, and no matter what I do I cant get my strings to convert into what they should be. Here are some before/after examples of what SHOULD be happening when I convert a string. These types of strings are the ones I will be working with:

    Example 1:
    Before: \unok\cd\81dc9bdb52d04dc20036dbd8313ed055\skey\125 7\errmsg\Invalid CD Key

    After: ;....,%..1]B.. ^...FB.WU..A@ITW ...HJVR..CEL;... .,HUTZ9......9:. .....S3=G*..
    Example 2:
    Before: \unok\cd\202cb962ac59075b964b07152d234b70\skey\151 9\errmsg\Invalid CD Key

    After: ;....,%..1WCB. .X[W..L^QZP.IOS. ]RBEK.S^Q.GI;... .,HRPT9......9:. .....S3=G*..
    No worries though, no important data is being encrypted here, I am only doing this because the particular server I am working with requires text to first be XORd by the term "gamespy" or it will not communicate with a client. It also sends its replies encrypted this way, so I will have to learn how to encode/decode anything string I need to.

    Hope that explains my question, thank you very much for the help! Post if you need more information.

  2. #2
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,660
    Moved to windows board.
    Whilst it is a pure C question, the translate to "VB" makes it windows specific.

    Do you know for example what the keyword in VB is for exclusive-or ?
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  3. #3
    Registered User
    Join Date
    Aug 2006
    Posts
    19
    The one for VB is simply Xor (or the one I was playing with).

    And the one for PHP is a simple ^. Except these wern't giving me the results I should have.

  4. #4
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,660
    Maybe post your attempt ?
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  5. #5
    Registered User
    Join Date
    Aug 2006
    Posts
    19
    Here was one attempt, this I beleive would try to convert the whole string as one... didnt output what I need. Used double \ for every \ because php makes you.

    PHP Code:
    <?php
    $string 
    '\\unok\\cd\\81dc9bdb52d04dc20036dbd8313ed055\\skey\\1257\\errmsg\\Invalid CD Key';
    $key 'gamespy';
    echo 
    $string $key;
    ?>
    This attempt was another I tried, no-where close to the output I should get.
    PHP Code:
    <?php
    function x_Encrypt($string$key)
    {
      for(
    $i=0$i<strlen($string); $i++)
      {
        for(
    $j=0$j<strlen($key); $j++)
        {
          
    $string[$i] = $string[$i]^$key[$j];
        }
      }
      return 
    $string;
    }

    $string '\\unok\\cd\\81dc9bdb52d04dc20036dbd8313ed055\\skey\\1257\\errmsg\\Invalid CD Key';
    $key 'gamespy';
    echo 
    x_Encrypt($string$key);

    ?>
    I didnt save anything from the VB because I just tinkered with it, got nowhere though.

  6. #6
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,660
    > echo x_Encrypt($string, $key);
    If you have $string = 'gamespy' as well, then what you should be getting back is a string of 7 nul (\0 or \0x00) characters.

    The result is not necessarily printable.

    Does PHP have a means of printing the characters in hex (which would be unambiguous).
    Is it even capable of storing a string of \0 characters?

    Your translation looks good, providing PHP can store \0 characters properly (for example), and that you can print a string in hex.

    Another way to check is that
    PHP Code:
    echo x_Encrypt(x_Encrypt($string$key), $key); 
    gets you back to where you started. If it does, then it should be working.
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  7. #7
    int x = *((int *) NULL); Cactus_Hugger's Avatar
    Join Date
    Jul 2003
    Location
    Banks of the River Styx
    Posts
    902
    Your second attempt fails because you xor each plaintext character with every character in the key. The C version only xors with one character of the plaintext. Here's a PHP version that works:
    PHP Code:
    <?php
    function x_Encrypt($string$key)
    {
      for(
    $i=0$i<strlen($string); $i++)
      {
        
    $string[$i] = $string[$i] ^ $key[$i strlen($key)];
      }
      return 
    $string;
    }

    $string '\\unok\\cd\\81dc9bdb52d04dc20036dbd8313ed055\\skey\\1257\\errmsg\\Invalid CD Key';
    $key 'gamespy';
    echo 
    bin2hex(x_Encrypt($string$key));

    ?>
    Code:
    C:\My Documents>php stringxor.php
    X-Powered-By: PHP/4.4.1
    Content-type: text/html
    
    3b14030a182c1a033d555417134005050f5041144953050e5743404a51050f014b43485404095546
    4525140a081c2f414b525631000102141406312c1d06180b0809453034592c0414
    C:\My Documents>stringxor
    3B14030A182C1A033D555417134005050F5041144953050E5743404A51050F014B43485404095546
    4525140A081C2F414B525631000102141406312C1D06180B0809453034592C0414
    C:\My Documents>
    And it seems that PHP is ok with binary data in strings. I've also read binary files into strings before with no problems.

    And the board software keeps telling me to surround my code in [code] tags... it's PHP, and it's in [php] tags. >.<

    Edit: And echo x_Encrypt(x_Encrypt($string, $key), $key); gives the original too. Yay...
    Last edited by Cactus_Hugger; 10-15-2006 at 06:15 PM.
    long time; /* know C? */
    Unprecedented performance: Nothing ever ran this slow before.
    Any sufficiently advanced bug is indistinguishable from a feature.
    Real Programmers confuse Halloween and Christmas, because dec 25 == oct 31.
    The best way to accelerate an IBM is at 9.8 m/s/s.
    recursion (re - cur' - zhun) n. 1. (see recursion)

  8. #8
    Reverse Engineer maxorator's Avatar
    Join Date
    Aug 2005
    Location
    Estonia
    Posts
    2,318
    PHP has done miracles to me, too.
    If I need something that doesn't necessarily need to be a program and can be on a web site, I use PHP.
    I've used it to make converters, encrypters, decrypters, calculators and other such things.

    I would say that PHP is sooo easy to use and that makes it a great tool. Also it 's code is not ugly.
    "The Internet treats censorship as damage and routes around it." - John Gilmore

  9. #9
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,660
    Works for me

    In C
    Code:
    #include <stdio.h>
    #include <string.h>
    
    typedef unsigned char u_char;
    
    void gamespyxor(u_char *data, int len) {
        u_char  gamespy[] = "gamespy",
                *gs;
    
        for(gs = gamespy; len; len--, gs++, data++) {
            if(!*gs) gs = gamespy;
            *data ^= *gs;
        }
    }
    
    int main ( ) {
        u_char  enc[1000];
        u_char  dec[1000];
        char    msg[] = "\\unok\\cd\\81dc9bdb52d04dc20036dbd8313ed055\\skey\\1257\\errmsg\\Invalid CD Key";
        int     len = strlen(msg);
    
        printf("The encrypt is the decrypt\n");
        printf( "%s\n", msg );
        memcpy( enc, msg, len );
        gamespyxor( enc, len );
        memcpy( dec, enc, len );
        gamespyxor( dec, len );
        printf( "%s\n", dec );
        return 0;
    }
    
    $ gcc foo.c && ./a.exe
    The encrypt is the decrypt
    \unok\cd\81dc9bdb52d04dc20036dbd8313ed055\skey\1257\errmsg\Invalid CD Key
    \unok\cd\81dc9bdb52d04dc20036dbd8313ed055\skey\1257\errmsg\Invalid CD Key
    In PHP
    PHP Code:
    <?php
    function x_Encrypt($string$key)
    {
      for(
    $i=0$i<strlen($string); $i++)
      {
        for(
    $j=0$j<strlen($key); $j++)
        {
          
    $string[$i] = $string[$i]^$key[$j];
        }
      }
      return 
    $string;
    }

    $string '\\unok\\cd\\81dc9bdb52d04dc20036dbd8313ed055\\skey\\1257\\errmsg\\Invalid CD Key';
    $key 'gamespy';

    echo 
    "The encrypt is the decrypt\n";
    echo 
    $string,"\n";
    echo 
    x_Encrypt(x_Encrypt($string$key), $key);

    ?>
    Code:
    C:\Program Files\php>php -f \gash\foo.php
    The encrypt is the decrypt
    \unok\cd\81dc9bdb52d04dc20036dbd8313ed055\skey\1257\errmsg\Invalid CD Key
    \unok\cd\81dc9bdb52d04dc20036dbd8313ed055\skey\1257\errmsg\Invalid CD Key
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  10. #10
    Registered User
    Join Date
    Aug 2006
    Posts
    19
    I am not mainly concerned with getting the string back to it's original form, but instead the correct form that the server I am working with wants. This is what should be happening:

    You submit a string: "SimpleMessage"

    It should be XORd by the term gamespy as follows:

    S XOR g
    i XOR a
    m XOR m
    p XOR e
    l XOR s
    e XOR p
    M XOR y
    e XOR g
    s XOR a
    s XOR m
    a XOR e
    g XOR s
    e XOR p

    ...etc until the message is complete.

    I have manually XORd the character \ with the first letter of gamespy (g):
    PHP Code:
    echo '\\' 'g'
    which gives the correct result of ;

    I then made the string to be XORd in your guys' code the same thing: \\, and the result was ( and not ; like it should be.

    So I need code that will XOR a string by the term gamespy 1 character at a time as I described above, for any string I need. Thanks for the help so far

  11. #11
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,660
    > I then made the string to be XORd in your guys' code the same thing: \\, and the result was ( and not ; like it should be.
    Paste what you did to get the bad result (actual commands and output, not a description).

    As far as I'm concerned, the fact that the round trip gets you back to where you're starting shows that the algorithm is basically working. The only thing which can change the expected return characters are
    - the algorithm you posted is basically wrong
    - the key you specified is wrong

    Also, '\\' in C and PHP is a single character - look at the output in my previous post.
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  12. #12
    Registered User
    Join Date
    Aug 2006
    Posts
    19
    I will also add something that might help you guys help me. This is code that I got from another forum that XORs each character in a string by 'g' and echo's the result:

    PHP Code:
    $string 'SimpleMessage';
    $lens strlen($string);
    for (
    $i=0$i $lens$i++) {
        echo 
    $string{$i} ^ 'g';

    If we could get that code to XOR it the way my previous post mentioned (instead of all the characters by g as in this example), we'd have it solved! So we just need to get it to go through each character and XOR it by 'gamespy' like so:

    S ^ g
    i ^ a
    m ^ m
    p ^ e
    l ^ s
    e ^ p
    M ^ y
    e ^ g
    s ^ a
    s ^ m
    a ^ e
    g ^ s
    e ^ p

    Almost there, appriciate the help! Thanks again!

  13. #13
    Registered User
    Join Date
    Aug 2006
    Posts
    19
    Quote Originally Posted by Salem
    > I then made the string to be XORd in your guys' code the same thing: \\, and the result was ( and not ; like it should be.
    Paste what you did to get the bad result (actual commands and output, not a description).

    As far as I'm concerned, the fact that the round trip gets you back to where you're starting shows that the algorithm is basically working. The only thing which can change the expected return characters are
    - the algorithm you posted is basically wrong
    - the key you specified is wrong

    Also, '\\' in C and PHP is a single character - look at the output in my previous post.
    Sure the algorithm works fine, but its not the correct form that the server wants. Read my post more carefully and you will see what I am looking for.

    The method you posted does not do it correctly. Sure it works, but its not what I need. The code:
    PHP Code:
    <?php
    function x_Encrypt($string$key)
    {
      for(
    $i=0$i<strlen($string); $i++)
      {
        for(
    $j=0$j<strlen($key); $j++)
        {
          
    $string[$i] = $string[$i]^$key[$j];
        }
      }
      return 
    $string;
    }
    $string '\\unok\\cd\\81dc9bdb52d04dc20036dbd8313ed055\\skey\\1257\\errmsg\\Invalid CD Key';
    $key 'gamespy';
    echo 
    x_Encrypt($string$key);
    ?>
    .. outputs a long XORd string as it should. But the first character of this XORd string should be ; and not ( as it outputs. Why? Because '\\' ^ 'g' = ;

    Why g? Because it's the first character of gamespy, and \\ is the first character in the string. If it cant even start out by XORing the first character of the string correctly, why in the world do you think the code is correct?

    Do it for yourself, write the code: echo '\\' ^ 'g'; and tell me if you get ; or (

    I thank you for the help Salem, but calling the method correct and trying to defend it does not help me. It's not like I'm not trying to argue with you about it, I just want to get this figured out.

  14. #14
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,660
    Actually, I copied your PHP version (which is wrong).

    Try using Cactus_Hugger's version, which on the face of it seems like it's the same as the original C you posted.
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. creating very simple text editor using c
    By if13121 in forum C Programming
    Replies: 9
    Last Post: 10-19-2010, 05:26 PM
  2. Simple message encryption
    By Vicious in forum C++ Programming
    Replies: 10
    Last Post: 11-07-2004, 11:48 PM
  3. Binary Search Trees Part III
    By Prelude in forum A Brief History of Cprogramming.com
    Replies: 16
    Last Post: 10-02-2004, 03:00 PM
  4. Simple simple program
    By Ryback in forum C++ Programming
    Replies: 10
    Last Post: 09-09-2004, 05:48 AM
  5. Need help with simple DAQ program
    By canada-paul in forum C++ Programming
    Replies: 12
    Last Post: 03-15-2002, 08:52 AM