mankee mankee - 7 days ago 5
Python Question

Python Generated String in C

I need to generate the following string in C:

$(python -c "print('\x90' * a + 'blablabla' + '\x90' * b + 'h\xef\xff\xbf')")


where a and b are arbitrary integers and blablabla represents an arbitrary string. I am attempting to do this by first creating

char str1[size];


and then doing:

for (int i = 0; i < a; i+=1) {

strcat(str1, "\x90");

}


Next I use strcat again:

strcat(str1, "blablabla");


and I run the loop again, this time
b
times, to concatenate the next
b
x90
characters. Finally, I use strcat once more as follows:

strcat(str1, "h\xef\xff\xbf");


However, these two strings do not match. Is there a more efficient way of replicating the behaviour of python's
*
in C? Or am I missing something?

Answer
char str1[size];

Even assuming you calculated size correctly, I recommend using

char * str = malloc(size);

Either way, after you get the needed memory for the string one way or the other, you gonna have to initialize it by first doing

str[0]=0;

if you intend in using strcat.

for (int i = 0; i < a; i+=1) {
    strcat(str1, "\x90");
}

This is useful, if "\x90" actually is a string (i.e. something composed of more than one character). Here, as John Coleman already suggested, memset is a better way to do it.

memset(str, '\x90', a);

Because you know the location, where "blablabla" shall be stored, just store it there using strcpy instead of strcat

// strcat(str1, "blablabla");
strcpy(str + a, "blablabla");

However, you need the address of the character after "blablabla" (one way or the other). So I would not even do it that way but instead like this:

const char * add_str = "blablabla";
size_t sl = strlen(add_str);
memcpy(str + a, add_str, sl);

Then, instead of your second loop, use another memset:

memset(str + a + sl, '\x90', b);

Last but not least, instead of strcat again strcpy is better (here, memcpy doesn't help):

strcpy(str + a + sl + b, "h\xef\xff\xbf");

But you need it's size for the size calculation at the beginning, so better do it like the blablabla string.

Finally, I would put all this code into a function like this:

char * gen_string(int a, int b) { const char * add_str_1 = "blablabla"; size_t sl_1 = strlen(add_str_1); const char * add_str_2 = "h\xef\xff\xbf"; size_t sl_2 = strlen(add_str_2);

size_t size = a + sl_1 + b + sl_2 + 1; // The + 1 is important for the '\0' at the end

char * str = malloc(size);
if (!str) {
    return NULL;
}
memset(str, '\x90', a);
memcpy(str + a, add_str_1, sl_1);
memset(str + a + sl, '\x90', b);
strcpy(str + a + sl + b, "h\xef\xff\xbf");

return str;

}

Remember to free() the retval of gen_string at some point.