Fill argv[1] in C with max input - c

I am trying figure out a simple way to fill argv[1] with an extremely large string of input to see how much input my program can handle. Any ideas on the simplest way to do this?

If you're using a POSIX shell (Like Bash on Linux or similar) then you could use a simply Python script to "fill" an argument, and call it using the shell back-tick to execute commands "inline":
./your_program `python -c "print('A'*100)"`
The above will create a string of 100 A characters as the first argument to the program.

If you are calling your program from a shell, you typically take the advantage of that.
For instance, for POSIX, something like:
./program `printf '%*s' 500 | tr ' ' x`
(Taken from Creating string of repeated characters in shell script)
You can also create the string dynamically over a loop to test the program until it crashes, etc.
If you want a C solution (without spawning another process, e.g. using something like system or OS-specific APIs), I would suggest you rename your main() into a different function, and then write a new main() that calls the old one with an argv customized however you like:
int old_main(int argc, char *argv[]) { ... }
int main()
{
int argc = 2;
char *argv[2] = {
"program",
"xxxxxxxxxxxxxxxxxxxxxxx",
};
return old_main(argc, argv);
}

Related

Parse a argv in c to a command in unix

I am new to unix and require some help.
I have another program call projectc which is an suid program located on another user call userb . userb has a directory pass that only has permission for write and read for its owner (userb)
I am trying to use the printf to do a command printf(system("cat /home/userb/pass")) through the argv argument.
I am able to do it in the c code printf(system("cat /home/userb/pass")) directly but doing it in the argv argument, i am unable to do it).
Is there anyway to parse the argv[1] parameter into a command?
this is my c program that I was trying to run in unix.
int main( int argc, char **argv){
printf(argv[1]);
return 0;
}
printf(system("cat /home/userb/pass"))
The reason this seemed to work is because the spawned subprocess printed on the screen. The printf was not only unnecessary but actually a bug. The first parameter to printf is a string (char*), while the retrn value from systemis an int.
A correct call would be:
int success = system("cat /home/userb/pass");
If argv[1] is the command you want to run you can just call:
int status = system(argv[1]);
You could then run your program like this:
myprogram "cat /home/userb/pass"
Note the double quotes - they ensure that the entire command is passed as a single parameter. Without the quotes it would be divided into two parameters.
And please turn up your compiler warning level. printf(system("cat /home/userb/pass")) should give some big warnings/errors when you compile.

unix: main() interactive, command line, piping & redirection in C?

While there is an easy way of using both file redirection and piping, as well as interactive user input reading , with main(), as shown in this C code snippet...
#define SIZ 1024
#include <stdio.h>
extern void do_something_with_the_array(float *a[], int *n);
int main(int argc, const char * argv[])
{
float f[SIZ];
int k = 0;
while ((scanf("%f", &f[k]) == 1)&&(k < SIZ)) {
k++;
}
do_something_with_the_array(f, k);
return 0;
}
… I'm not sure if there is a modern UNIX source compatible and easy way of programmatically achieving any of the three possibilities in a main() in C, depending on the context ?
interactive reading of a string of numbers as user input
reading of the same string of numbers as command line arguments
file redirection and piping
I understand piping and redirection "belong" to the shell which intercepts the program before it even starts executing, while command line arguments and interactive reading "belong" to the main() itself and therefore there may not be an easy way of doing this.
I see using stdin or file input or pipe input pretty self-explanatory. However, reading command line arguments is a different story. Here's a demo how I usually code it, but it looks kind of heavy-handed and hacked to me. Also, in more complicated scenarios with options, this could become a pretty messy piece of code. I'm also not sure how fail-safe or fool proof this is...
#define SIZ 1024
#include <stdio.h>
#include <stdlib.h>
extern void do_something_with_the_array(float *, int);
int main(int argc, const char * argv[])
{
float f[SIZ];
int k = 0;
if(argc > 2){
for(k = 0; k < argc - 1; k++)
f[k] = (float)atof(argv[k+1]);
}
else while ((scanf("%f", &f[k]) == 1)&&(k < SIZ))
k++;
do_something_with_the_array(f, k);
return 0;
}
Thanks in advance!
I do not know off-hand of a C library that will make the three specific cases you mentioned look the same (although someone who does, please answer because I'd like to know, too!). I think you're looking for something not unlike the diamond <> operator in Perl, but for individual arguments rather than files containing arguments.
I think #David Hoelzer has the right idea: handle the three cases separately. For example, when processing command-line or file arguments, don't generate "Enter a value" prompts that you might print for interactive input. For command-line processing, getopt is a good place to start.
Now, a challenge to you: Wrap those three operations in a library and make it open-source so the rest of us can benefit! :)
Quite a few programs do care if they're invoked with keyboard input vs. file input, including the shell itself.
Let us take /bin/sh as our first example. If you call it directly, it starts an interactive shell, but if you pipe something into it, it starts as a non-interactive reading shell. The main difference between the two is if it is not interactive, it doesn't display the $ prompt. However just in case it really is interactive, it can be started with the -i option to make it assume its interactive when it would normally decide otherwise.
The magic involved here is isatty(); see man 3 isatty.
In addition, some programs like to receive keyboard input while processing redirected standard input. There are two generally favored ways of doing this; either opening and reading from /dev/tty or reading standard error, depending on context. Most stuff in an interactively started pipeline doesn't have standard error redirected, so this tends to work well (reading a redirected standard error yields an error immediately as the handle isn't open for read). If you want to make it potentially fully automatable, you read standard error, otherwise you read /dev/tty.

C - Executing Bash Commands with Execvp

I want to write a program Shellcode.c that accepts in input a text file, which contains bash commands separeted by newline, and executes every commands in the text file: for example, the text file will contain:
echo Hello World
mkdir goofy
ls
I tried this one (just to begin practicing with one of the exec functions):
#include <stdio.h>
#include <unistd.h>
void main() {
char *name[3];
name[0] = "echo";
name[1] = "Hello World";
name[2] = NULL;
execvp("/bin/sh", name);
}
I get, in return,
echo: Can't open Hello World
I'm stuck with the execvp function, where did I go wrong?
You're doing it wrong.
The first array index is the name of the program, as explained in the docs:
The execv(), execvp(), and execvpe() functions provide an array of pointers to null-terminated strings that represent the argument list available to the new program. The first argument, by convention, should point to the filename associated with the file being executed. The array of pointers must be terminated by a NULL pointer.
Also, bash doesn't expect free-form argument like that, you need to tell it you're going to pass commands using the -c option:
So, you need:
name[0] = "sh";
name[1] = "-c";
name[2] = "echo hello world";
name[3] = NULL;
To pass a script to bash on the command line you must add the option '-c' and pass the whole script as a single string, i.e.
#include <stdio.h>
#include <unistd.h>
void main() {
char *name[] = {
"/bin/bash",
"-c",
"echo 'Hello World'",
NULL
};
execvp(name[0], name);
}
Many problems here: The exec() family of functions do not execute multiple programs - these functions execute a single program, and replace the currently running process in memory with the new program. The null-pointer-terminated array of strings you pass to execvp is supposed to contain the command-line arguments to the program executed by execvp.
If you want to execute multiple programs, you'll need to loop over each line and execute the programs one by one. But you can't use execvp because that immediately replaces the currently executing process (your C program) with the process executed via the shell, meaning that the rest of your C program will never be executed. You need to learn how to use fork() combined with execvp so you can execute child processes. You first call fork() to create a child process, and then from the child process you call execvp. Fork + Exec is a common strategy in UNIX environments to launch other processes from a parent process.

Transfer files in C

How do I transfer files from one folder to another, where both folders are present in oracle home directory?
int main(int argc, char *argv[]){
char *home, *tmp2;
home = getenv("ORACLE_HOME");
temp2 = getenv("ORACLE_HOME");
strcat (home,"A");
strcat (tmp2,"B");
//transfer files from home to tmp2
}
strcat doesn't seem to work. Here, I see tmp2 pointer doesn't get updated correctly.
Edit: OS is a UNIX based machine. Code edited.
I require a binary file which does this copying, with the intention that the real code cannot be viewed. Hence I didn't consider using shell script as an option. The files in A are encrypted and then copied to B, decrypted in B and run. As the files are in perl, I intend to use system command to run them in the same C code.
Using the system(3) command is probably a good idea since you get the convenience of a shell interpreter to expand filenames (via *) but avoids the hassle of computing the exact length of buffer needed to print the command by using a fixed length buffer and ensuring it cannot overflow:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#define BUFSZ 0xFFF
int main(void)
{
char * ohome = getenv("ORACLE_HOME"), cmd[BUFSZ];
char * fmt="/bin/mv %s/%s/* %s/%s";
int written = snprintf(cmd, BUFSZ, fmt, ohome, "A", ohome, "B"), ret;
if ((written < 0) || (written >= (BUFSZ-1))) {
/* ERROR: print error or ORACLE_HOME env var too long for BUFSZ. */
}
if ((ret = system(cmd)) == 0) {
/* OK, move succeeded. */
}
return 0;
}
As commenter Paul Kuliniewicz points out, unexpected results may ensue if your ORACLE_HOME contains spaces or other special characters which may be interpreted by the subshell in the "system" command. Using one of the execl or execv family will let you build the arguments without worrying about the shell interpreter doing it's own interpretation but at the expense of using wildcards.
First of all as pointed out before, this "security" of yours is completely useless. It is trivial to intercept the files being copied (there are plenty of tools to monitor file system changes and such), but that is another story.
This is how you could do it, for the first part. To do the actual copying, you'd have to either use system() or read the whole file and then write it again, which is kind of long for this kind of quick copy.
int main(int argc, char *argv[]){
char *home, *tmp2;
home = strdup(getenv("ORACLE_HOME"));
tmp2 = strdup(getenv("ORACLE_HOME"));
home = realloc(home, strlen(home)+strlen("A")+1);
tmp2 = realloc(tmp2, strlen(tmp2)+strlen("B")+1);
strcat (home,"A");
strcat (tmp2,"B");
}
By the way, if you could stand just moving the file, it would be much easier, you could just do:
rename(home,tmp2);
Not realted to what you are asking, but a comment on your code:
You probably won't be able to strcat to the results of a getenv, because getenv might (in some environments) return a pointer to read-only memory. Instead, make a new buffer and strcpy the results of the getenv into it, and then strcat the rest of the file name.
The quick-n-dirty way to do the transferring is to use the cp shell command to do the copying, but invoke it using the system command instead of using a shell script.
Or, have your C program create a shell script to do the copying, run the shell script, and then delete it.

Reading command line arguments after '<' in C

Let me start by saying this is associated with a homework assignment. However, this is a very small and relatively insignificant part of the assignment.
The C program receives input via command line arguments but it needs to be in the form:
$ ./program < input
How, would I go about receiving that input as a string? Each time I try to print out the 3rd argument from argv I receive this message:
input: No such file or directory.
< is a shell redirect - it is handled outside your program. What you'll see is the contents of the file name 'input' being send to your standard input stream. This is a common way for programs to operate, although they usually also handle being given a file name e.g. sed.
If I had to guess I would think the:
input: No such file or directory.
is coming from the shell, as it is unable to open the file specified: "input".
On the other hand, if you actually want the < input as arguments to your program, you can escape or quote them so the shell won't interpret them. (Escaping left as an exercise for the reader :-)).
The ./program < input syntax is a special shell syntax saying "Redirects everything in the file named input to the standard entry of the program".
To read the input, your program just have to use standard input reading functions, line fgets or scanf.
On *nix systems, there won't be a third element of argv. If you execute that command on almost any Unix-like shell, it will be similar to doing this:
cat input | ./program
So your ./program has only one element in argv, but it's stdin is the file input, so to read the file you would just read from stdin. Note that this is a perfectly valid way to design your program. Many Unix programs read from standard input if no files are given, so that you may pipe in input from other programs (or in this case, from files).
What comes after the < is not a command-line argument. The contents of the file will be piped into your program by the shell.
All you need to do is read from stdin and you'll get the contents of the file.
You need to escape the '<', otherwise shell will parse it, and program won't receive it in command-line.
If you're using bash, then:
./program '<' input
or
./program \< input
Other shells might do it differently (e.g. Windows' default, cmd.exe, uses ^ as escape character, not \).
This is a Unix shell thing. The form someprogram < somefile tells someprogram to run using somefile as its input. If you want to do something different involving the < symbol, you'll need to quote it.
The < means that the program will read it's standard input (stdin) from the named file (input). So just read from stdin (using fgets, fread, etc).
Leave off the '<'. You want command line arguments do this:
$ ./program -Dflag seven=ixnay FromDinger
In your application, try this:
int main( int argc, char **argv )
{
int i;
for( i = 0 ; i < argc ; ++i )
printf( "Arg %d = %s\n", i, argv[i] );
return 0;
}
You'll notice that the first argument is the name of the executable (at index 0), and your second argument (at index 1) will be "-Dflag"
Actually, this is a very common technique used in programming tournaments. The data your program needs is stored in a file, let's say data.txt , and then redirected to your application using the "<" on the shell, like this: ./program < data.txt
So, in your source code, what you need to do is something like this:
#include <iostream>
#include <string>
using namespace std;
int main(void)
{
string tmp;
string full_content;
while (cin >> tmp)
full_content += " "+tmp;
cout << full_content << endl;
}
.. and you'll get all the data from the file on a string (and separated by spaces).
That's one way to do it, I hope it helps.
[]'s
You can get it by reading stdin.

Resources