De-obfuscating cable1.c

December 31, 2014
Home

This code is one of the winners of the 22nd International Obfuscated C Code Contest. It takes 3 arguments: the last name of any of the last 31 US Presidents, the string “republican” and the string “democrat”. The program then prints out either “republican” or “democrat” depending on which political party the president was affiliated with. The code is surprisingly small, which means it shouldn’t be too difficult to figure out how it works.

main(int riguing,char**acters){puts(1[acters-~!(*(int*)1[acters]%4796%275%riguing)]);}

The first thing to do is rename the variables to sensible names and add some standard main() code.

int main(int argc, char **argv) {
	puts(1[argv-~!(*(int*)1[argv]%4796%275%argc)]);
	return 0;
}

In C var[1] and 1[var] are equivalent, so let’s swap it around to look more normal.

int main(int argc, char **argv) {
	puts((argv-~!(*(int*)argv[1]%4796%275%argc))[1]);
	return 0;
}

The next step is to pull out the magic math into a separate statement. And since argc is always 4, replace it with that constant.

int main(int argc, char **argv) {
	int i = *(int*)argv[1]%4796%275%4;
	puts((argv-~!(i))[1]);
	return 0;
}

This helps with understanding what the magic math is doing. The integer i is either 0 or 1, which is then used to print out either the 2nd or 3rd argument to the program. What I did was hard code the strings “democrat” and “republican” so that it isn’t necessary to pass them as arguments.

int main(int argc, char **argv) {
	int i = *(int*)argv[1]%4796%275%4;
	if (i == 0) {
		puts("democrat");
	} else {
		puts("republican");
	}
	return 0;
}

The integer i is made up of the first 4 characters of the President’s name, the next step is to replace the pointer casting with more explicit steps.

int main(int argc, char **argv) {
	char *name = argv[1];
	int i = name[0]<<0 | name[1]<<8 | name[2]<<16 | name[3]<<24;
	i = i%4796%275%4;
	if (i == 0) {
		puts("democrat");
	} else {
		puts("republican");
	}
	return 0;
}

This is about as clear as the code can be. The only mystery left is why the constants 4796, 275 and 4 were chosen. I imagine that the original author ran a bruteforce calculation to determine what numbers would cause the correct division between the names.