rand and rands implementation in python

0

I need an implementation of rand and rands from c++ in python to re-encrypt a bunch of files. But can't seem to get it right.

I have a exe that un-encrypts a file into text, I also have to source code, after editing the file I need to encrypt it using the same method.

Since I don't know how to write c++ code, I opted to write in python. Trying first to decrypt it to know the method is the same.


The following code is the c++ code that un-encrypted the files, where "buff" is the beginning of the encrypted block and "len" length of said block.

static const char KEY[] = "KF4QHcm2";
static const unsigned long KEY_LEN = sizeof(KEY) - 1;

void unobfuscate(unsigned char* buff, unsigned long len) {
  srand((char)buff[len - 1]);

  for (unsigned long i = 0; i < len - 2; i += 2) {
    buff[i] ^= KEY[rand() % KEY_LEN];
  }
}

From what I understand it takes the last character of the encrypted block as the seed, and from the beginning every 2 bytes it xors the value with an element of the KEY array, this index is determined by the remainder of a random number divided by the KEY length.

Searching around the web, I find that c++ uses a simple Linear Congruential Generator that shouldn't be used for encryption, but can't seem to make it work.

I found one example of the code and tried to implement the other but either don't seem to work.

#My try at implementing it
def rand():
  global seed
  seed = (((seed * 1103515245) + 12345) & 0x7FFFFFFF)

  return seed

I also read that the rand function is between 0 and RAND_MAX, but can't find the value of RAND_MAX, if I found it maybe random.randrange() could be used.

It can also be the way I set the seed since it seems in c++ a char works but in python I'm setting it to the value of the character.

Here is what I observe when un-encrypting the file using the various methods. This is just the first 13 bytes, so if someone needs to check if it works it is possible to do so.

The block ends with the sequence: 4C 0A 54 C4 this means C4 is the seed
Example encrypted:
77 43 35 69 26 6B 0C 6E 3A 74 4B 33 71     wC5i&k.n:tK3q
Example un-encrypted using c++:
24 43 6C 69 63 6B 49 6E 69 74 0A 33 34     $ClickInit.34
Example un-encrypted using python example:
1A 43 7E 69 77 6B 38 6E 0E 74 1A 33 3A     .C~iwk8n.t.3:
Example un-encrypted using python implementation:
3C 43 73 69 6E 6B 4A 6E 0E 74 1A 33 37     <CsinkJn.t.37

I can also have something wrong in my python script, so here is the file in case it has any errors:

import os

def srand(s):
  global seed
  seed = s

def rand():
    global seed
    #Example code
    #seed = (seed * 214013 + 2531011) % 2**64

    #return (seed >> 16)&0x7fff

    #Implementation code
    seed = (((seed * 1103515245) + 12345) & 0x7FFFFFFF)

    return seed

KEY = ['K','F','4','Q','H','c','m','2']
KEY_LEN = len(KEY) - 1

for filename in os.listdir("."):
    if filename.endswith(".dat"):
        print("    Decoding " + filename)

        #open file
        file = open(filename, "rb")

        #set file attributes
        file_length = os.path.getsize(filename)
        file_buffer = [0] * file_length

        #copy contents of file to array
        for i in range(file_length):
            file_buffer[i] = int.from_bytes(file.read(1), 'big')

        #close file
        file.close()

        print("    Random Seed: " + chr(file_buffer[-1]))

        #set random generator seed
        srand(file_buffer[-1])

        #decrypt the file
        for i in range(3600, file_length, 2):
            file_buffer[i] ^= ord(KEY[rand() % KEY_LEN])

        #print to check if output is un-encrypted
        for i in range(3600, 3613, 1):
            print(file_buffer[i])
            print(chr(file_buffer[i]))

        continue
    else:
        #Do not try to un-encrypt the python script
        print("/!\ Can't decode " + filename)
    continue

If anyone can help me figure this out I would be grateful, if possible I would love this to work in python but, from what I can gather, it seems like I will have to learn c++ to get it to work.

python
c++
python-3.x
random
asked on Stack Overflow Sep 4, 2019 by megacrazyman

1 Answer

1

rand is not a cryptographic function.

rand's algorithm is not stable between systems compilers or anything else.

If you have no choice, your best bet is to use python-C/C++ interoperability techniques and actually run rand() and srand(). That will suck, but it will suck as much as the original code did.


User contributions licensed under CC BY-SA 3.0