I'm working with a couple of binaries in a Linux environment, and I'm trying to script my user input. For example, with the first program prog1.c:
void get_input() {
int i;
char buffer[32];
i = 0;
while (i < 3) {
memset(buffer, 0, 32);
printf("Enter input: ");
fgets(buffer, 31, stdin);
printf("Your input: %s\n", buffer);
i++;
}
}
I can either run prog1 and enter the input directly from console, or I can script the input and pipe it into the program.
Entering input directly from console:
# ./prog1
Enter input: Stuff1
Your input: Stuff1
Enter input: Stuff2
Your input: Stuff2
Enter input: Stuff3
Your input: Stuff3
#
Scripting input:
# perl -e 'print "Stuff1\n" . "Stuff2\n" . "Stuff3\n"' | ./prog1
Enter input: Your input: Stuff1
Enter input: Your input: Stuff2
Enter input: Your input: Stuff3
#
Although the formatting of the output is a little messed up, the program still displays the expected output.
My problem is with the second binary prog2.c:
void get_input() {
int i;
char buffer[32];
i = 0;
while (i < 3) {
memset(buffer, 0, 32);
printf("Enter input: ");
read(0, buffer, 31);
printf("Your input: %s\n", buffer);
i++;
}
}
When I can enter my input directly from console:
# ./prog2
Stuff1
Enter input: Your input: Stuff1
Stuff2
Enter input: Your input: Stuff2
Stuff3
Enter input: Your input: Stuff3
#
Not only does the prompt to enter input not show up until after I enter input, but I can't even script my input:
# perl -e 'print "Stuff1\n" . "Stuff2\n" . "Stuff3\n"' | ./prog2
Enter input: Your input: Stuff1
Stuff2
Stuff3
Enter input: Your input:
Enter input: Your input:
#
I did some research on the differences between fgets()
and read()
and discovered:
fgets()
is a C function, whereas read()
is a system call.fgets()
reads input until the newline character or EOF is encountered, whereas newline does not have the same effect on the read()
syscall.read()
employs some sort of buffering mechanism that fgets()
does not.I think points 2 and 3 are the most relevant to the issue at hand, but they don't hint to me at how to solve my problem.
The user input I need to give these programs involves non-printable hex bytes, which is why directly entering such input from console is insufficient. I also cannot modify the source code to the binaries, so there is no workaround to just use fgets()
to collect input.
My question is if there is any way to feed input into prog2 so that I get the same behavior as prog1.
Thank you.
I found a workaround to this issue. I still cannot interact with the binary the way I want to - scripting my input from the console - but I found a way to do it programmatically.
I'm using a Python library suite that serves as a wrapper to the subprocess
module, but you could simply write your own:
p = subprocess.Popen(prog2, stdout=subprocess.PIPE, stdin=subprocess.PIPE)
This will open the binary as a process, and then you can interact with it using send and receive functions from within the Python script.
I hope this helps anyone else who ever encounters a similar problem.