yerassyl
yerassyl

Reputation: 3058

Segmentation fault 11 on Mac, C++ unsigned int declaration

I am trying to brute force a simple symmetric encryption algorithm. So I do this:

    #define MAX_LEN 100
        unsigned int i;
        char *message;
        char* cipher = readFileBytes("secret_msg.bin");
        for (i = 0; i <4294967295; i++){
                if (decrypt(cipher,i,message, 0) == true){
                    cout<<message<<endl;
                    cout<<"hacked!";
                    break;
                }
            }

I know that key is some unsigned integer. The problem is that I get Segmentation fault error, as I understood I am exceeding call stack size for allocation. If I comment the if statement and change it to cout<<i;, I can see that my for loop is running as expected.

Here is my decrypt code:

bool decrypt(char *c, unsigned int k,char *m){
    int i;
    for (i=0;i<MAX_LEN; i+=4){
        m[i] = c[i] ^ (k&0x00ff);
        m[i+1] = c[i+1] ^ (k >> 8);
        m[i+2] = c[i+2] ^ (k >> 16);
        m[i+3] = c[i+3] ^ (k >> 24);
    }
    string result(c);
    for (int i = 0; i < result.length(); i++) {
        if (result[i] == 'j' && result[i+1] == 'u' && result[i+2] == 's' && result[i+3] == 't') {
            return true;
        }
    }
    return false;
}

EDIT: If I comment out inner code of decrypt it works, I start getting the error when I add first for loop.

EDIT2: If I try to cout< I get Segmentation error, of course it is null here. I can cout<

Upvotes: 0

Views: 414

Answers (1)

Christophe
Christophe

Reputation: 73446

cipher and message seem to be arrays of characters. I guess that MAX_LEN is their size.

If so, you are going out of range in decrypt() : you address element i+3 of c and m, where i can be MAX_LEN-1. So you write 3 elements beyond the array's boundary. This is a buffer overflow and the most probable causes of your segfault.

To solve your issue, organize your loop to ensure that i<message_size-3, where message_size would be the real size of cipher's content.

Additional remarks:

Your last parameter of decrypt() is useless, because you reset it to 0 right at the begin of the loop.

You should communicate to decrypt() the real size of input : in your buffer, the encrypted message might be followed by garbage and it would be a waste of time to try to decrypt it.

In addition, keep in mind that with arrays, decrypt() has no way to know the size of of the buffer: sizeof(m) is the size of the pointer m. So I'd suggest to opt for std::string instead.

Note that the message output at the end of decrypt() probably wouldn't output much, because of this sizeof issue.

By the way, your decryption scheme uses apparently a block cipher, with a block length of 4. So it could make sense to check if message_size is a multiple of 4. Alternatively you could change the code in order to be able to work with incomplete blocks.

Upvotes: 2

Related Questions