I was doing a CTF reversing challenge when I came across this C code in ghidra:
int main(void)
{
int iVar1;
char input[32];
fwrite("Password: ",1,10,stdout);
__isoc99_scanf("DoYouEven%sCTF",input);
iVar1 = strcmp(input,"__dso_handle");
if ((-1 < iVar1) && (iVar1 = strcmp(input,"__dso_handle"), iVar1 < 1)) {
printf("Try again!");
return 0;
}
iVar1 = strcmp(input,"_init");
if (iVar1 == 0) {
printf("Correct!");
}
else {
printf("Try again!");
}
return 0;
}
And upon making a my own similar code, I noticed that the program only saves in input
when my input starts with DoYouEven
and only saves whatever comes after it. And I am trying to understand the reasoning for this from the source code of scanf.c
and vfscanf.c
but I am unable to understand the actual logic behind this.
My snippet:
int main()
{
char input[32];
printf("Input: ");
int a = scanf("DoYouEven%sCTF",input);
printf("Input was: %s\n", input);
int iVar = strcmp(input,"__dsohandle");
printf("iVar: %d\n", iVar);
printf("strcmp __dsohandle > -1: %d\n", (-1 < iVar));
printf("strcmp __dso_handle: %d\n", iVar);
printf("strcmp _init: %d\n", strcmp(input,"_init"));
printf("%d\n",a);
return 0;
}
Output:
Enter your input: DoYouEvenByee
input is: Byee
iVar: -29
strcmp __dsohandle > -1: 0
strcmp __dso_handle: -29
strcmp _init: -29
1
Can anybody help me understand this through source code? I am not a master at understanding C libraries.
Thanks.
Answer
In short, this is how scanf
works.
Characters in the format string that are not either whitespace or part of a format specifier are expected to be matched exactly. If at any point reading the input there is a mismatch, it stops reading. So given this call:
scanf("DoYouEven%sCTF",input);
The string "DoYouEven" is expected to be read first. Assuming those characters are read in, the next sequence of characters up to the next whitespace will be stored in input
.