Reputation: 11
In the code below, which should be self-explanatory from the comments, instead of printing the string tmp
, it actually prints the value of argv[2]
. I have run it through LLDB and everything is working fine, all intermedia values are correct and tmp
is holding the correct string after the call to long2hex
but it is not being printed to the screen. I can just about get by in LLDB, to check variables and so on, but no idea how to debug something like this, even after some extensive Googling. Does anyone have any ideas why argv[2]
is being printed, or can direct me to using LLDB to debug the behaviour?
The program is being run with two command-line arguments argv[1]="1c0111001f010100061a024b53535009181c"
and argv[2]="686974207468652062756c6c277320657965"
If anyone is interested, it is one of the matasano crypto challenges! Set 1, Problem 2. There is probably an easier way to do it, but this is what I have come up with!
Here is the code:
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <math.h>
/* Converts a character to the corresponding integer value */
uint8_t char2hex (const char a_char) {
uint8_t rv = 0;
if (a_char >= 48 && a_char <= 57) /* '0'-'9' */
rv = (uint8_t)a_char - 48;
else if (a_char >= 65 && a_char <=70) /* 'A'-'F' */
rv = (uint8_t)a_char - 55;
else if (a_char >= 97 && a_char <= 102) /* 'a'-'f' */
rv = (uint8_t)a_char - 87;
return rv;
}
/* Converts an integer value to its corresponding hex character */
char hex2char (uint8_t a_hex) {
char rv;
if (a_hex >= 0 && a_hex <= 9)
rv = a_hex + 48;
else if (a_hex >= 10 && a_hex <= 15)
rv = a_hex + 87;
else
rv = 'z';
return rv;
}
/* Coverts an unsigned 32-bit integer value into its hexadecimal representation */
void long2hex (uint32_t val, char result[9]) {
char hex[9];
int j = 0;
for (int i = 0; i < 4; i++,j+=2){
uint8_t tmpVal;
tmpVal = (val>>((3-i)*8));
hex[j] = hex2char((tmpVal >> 4) & 0x0F);
hex[j+1] = hex2char(tmpVal & 0x0F);
}
hex[8] = '\0';
result = hex;
}
/* Converts an 8 character hex string into its unsigned integer form */
uint32_t hex2int32(uint8_t h[8]) {
uint32_t b = 0;
for (int i = 0; i < 8; i++)
b += (h[i]) << (4*(7-i));
return b;
}
/* Splits a string into 8 character chunks */
char ** split_hex_8 (const char * hex_string, int * num_strings) {
int string_length = strlen(hex_string);
int num_blocks = (int)ceil((double)string_length / 8);
char ** split_hex = (char **) malloc(num_blocks * sizeof(char*));
int length_counter = string_length;
for (int i = 0; i < num_blocks; i++) {
split_hex[i] = (char *) malloc(9);
if (length_counter < 8) {
memcpy(split_hex[i], hex_string+(i*8), length_counter);
for (int j=length_counter; j < 8; j++)
(split_hex[i])[j] = '0';
} else
memcpy(split_hex[i], hex_string+(i*8), 8);
(split_hex[i])[8] = '\0';
}
*num_strings = num_blocks;
return split_hex;
}
int main (int argc, char * argv[]) {
char * hex_str_1 = argv[1];
char * hex_str_2 = argv[2];
int len1 = strlen(argv[1]);
int len2 = strlen(argv[2]);
char ** hex_split_1, ** hex_split_2;
int num_blocks_1, num_blocks_2;
/* Split the input strings */
hex_split_1 = split_hex_8(hex_str_1,&num_blocks_1);
hex_split_2 = split_hex_8(hex_str_2,&num_blocks_2);
/* For each of the inputs, xor them together by xoring the individual 32-bit unsigned integers together */
for (int i = 0; i < num_blocks_1; i++) {
uint32_t val1, val2, xor;
uint8_t hex1[8] = {0};
uint8_t hex2[8] = {0};
for (int j = 0; j < 8; j++){ /* convert each hex character in each string to its integer equivalent */
hex1[j] = char2hex((hex_split_1[i])[j]);
hex2[j] = char2hex((hex_split_2[i])[j]);
}
free(hex_split_1[i]); /* We are now done with this memory, so free it. */
free(hex_split_2[i]);
/* Shift in all of the 8-bit decoded hex into a 32-bit integer - gets the unsigned 32 bit representation of each 8 byte block of input */
val1 = hex2int32(hex1);
val2 = hex2int32(hex2);
/* Create some temporary storage for the new hex string */
char * tmp;
tmp = malloc(9);
xor = val1^val2;
/* convert this xor-ed value to it's corresponding hex representation, store it in tmp */
long2hex(xor,tmp);
/* print tmp to the screen */
/* THIS IS THE ERROR: instead of printing tmp to the screen, it ends up printing out argv[2]. */
printf("%s",tmp);
/* done with tmp! */
free(tmp);
}
/* don't forget to free the containers for the split hex */
free(hex_split_1);
free(hex_split_2);
return 0;
}
Upvotes: 0
Views: 50
Reputation: 14046
result = hex
;
That's your problem. result
is a local variable. Assigning to it does not propagate back to the caller. you want:
strncpy(result, hex, sizeof(result));
Upvotes: 2