I'm a second year cs student, still not nearly as proficient at programming as I would like to be. We're working with OS161 in C this year.
To the problem, I'm supposed to write a C program that can take command like arguments and echo them back. Ok, no problem. I've done this in other languages before. Here's the code I tried:
#include <stdio.h>
int main (int argc, char *argv[]) {
int i = 0;
printf("\ncmdline args count=%s", argc);
/* First argument is executable name only */
printf("\nexe name=%s", argv[0]);
for (i=1; i< argc; i++) {
printf("\narg%d=%s", i, argv[i]);
}
printf("\n");
return 0;
}
This compiles just fine with gcc, but when I run it, I get Segmentation Fault. I run it with gdb, and this is what I get:
Program received signal SIGSEGV, Segmentation fault.
0x00007ffff7abc493 in _IO_vfprintf_internal (s=0x7ffff7dd97a0, format=<value optimized out>,
ap=0x7fffffffe3f0) at vfprintf.c:1623
1623 vfprintf.c: No such file or directory.
in vfprintf.c
When I comment out the printf statements, it runs, but obviously then won't do what I need it to. As far as I can tell, it is the printf statements that are the problem, but why? I looked it up and I included the right header. It's hard for me to imagine that there is actually something wrong with vfprintf.c, since this all takes place on my school's VM that I ssh into. If anyone could throw me a bone, I'd really appreciate it. Thanks!
Edit, as you can see, I have the wrong conversion specifier. That was the whole problem.
argc is an integer, but you told printf to use the format %s.
printf("\ncmdline args count=%s", argc);
Because you used %s, printf treats the value of argc as a memory address from which it tries to fetch the characters in the string, which resulted in the segmentation fault.
Change the format to %d:
printf("\ncmdline args count=%d", argc);
Related
#include<stdio.h>
#include<ctype.h>
void main()
{
FILE *fp1,*fp2,*fp3;
char a[100],b;
int i=0,j=0;
fp1=fopen("names.txt","r");
fp2=fopen("names.txt","w");
i=0;
do
{
b=fgetc(fp1);
b=toupper(b);
a[i]=b;
i++;
} while(b!=EOF);
i=0;
do
{
fputc(a[i],fp2);
i++;
}while(a[i]!=EOF);
fclose(fp1);
fclose(fp2);
fclose(fp3);
}
am getting segmentation fault while compiling this code can u plzz help me spotting the error
the error is like"line 2:segmentation fault
"
You need to learn how to debug. Either learn how to use a debugger, or if you haven't got the patience, simply put some debug prints in the code to see how far it is getting. For example:
fprintf(stderr, "%d\n", i);
That will tell you something. You will find the error pretty quickly.
My guesses are:
Your file is bigger than 100 characters.
b should be an int and you should not store it in the array.
The second loop should not look for end-of-file, but should use the count of the number of characters you read.
You are closing fp3 but you haven't opened it.
But again, this is basic stuff. You need to learn to do basic debugging.
I don't know if I have to tell it again, but english is not my native language and I'm not a very good student, I've seen you are able to correct my message so it's fine but I'd like to apologize once again.
Here is the deal, I have a program, which convert a given graph passed in argument to Dimacs format that I'll store in a .cnf file. (We use it to solve it with a SAT-solver)
He's perfectly working when I use it by myself, so I'd like to have another program, graph_generator, that I'll pipe into myprogram to have random graphes.
I've made my graph_generator program, and he correctly prints graph at the format I want, so I've tried to do basically ./graph_generator | ./myprogram but I instantly get a segmentation fault, I can't see why, graph_generator returns exactly what it's expected, and when I want to use a debugger, I don't see how it's possible knowing that I pipe a result, when I copy paste the result of graph_generator myprogram correctly generates my .cnf file.
I don't know where the problem could come from, I have a theory but it's a bit lame, it's that the stdout of graph_generator, once piped myprogram considers the space as an argument and there is the problem. Anyone could help me please?
int main (int argc, char* argv[]){
graph* mygraph;
int taille, nbEdge;
int i;
FILE* resultat;
printf("mark 1");
taille = atoi(argv[1]);
nbEdge = atoi(argv[2]);
printf("mark 2");
mygraph = build_empty_graph(taille);
for(i = 3; i < argc; i+= 2)
add_edge(atoi(argv[i]), atoi(argv[i+1]), mygraph);
resultat = fopen("resultat.cnf", "w");
write_result_comments(resultat);
write_result_header(resultat, mygraph);
write_first_stack(resultat, mygraph);
write_second_stack(resultat, mygraph);
fclose(resultat);
return 0;
}
Here is the main of myprogram, when I use it with the pipe, the message "mark1" doesn't even appears
It is segfaulting because you don't check argc and are passing no values as arguments.
Please note that stdin is a separate stream from the arguments in argv.
Best way to fix this is to build up hierarchically:
tokenizer: read stdin in a loop with getchar until you get to whitespace (space, tab or newline).
parser: atoi is fine, since you only pass ints.
state machine: first two args to taille and nbEdge, rest in pairs (x, y) to call the program. Maybe use a switch statement and a state variable in a loop.
program: the rest of your program pretty much as is.
I'm attempting to create a simple C program to dump the raw command line to debug the output of programs that call other programs. Here is what I have so far:
#include <stdio.h>
int main (int argc, char **argv)
{
int i;
for (i = 0; i < argc; i++)
fprintf (stderr, "%s ", argv[i]);
fputs ("\n", stderr);
return (0);
}
There are several problems with this method. First of all, I have to insert a space manually after every argument. Secondly, the qouting on the original command like is lost, so with input like this:
./argvdump "'something'" """'"'""""other things""""'"'"""
I get output like this:
./argvdump something other things
which isn't very useful for debugging since I can't see what was actually on the command line.
Does anyone know how to get the actual raw command line?
The OS (or more specifically the shell) is the piece doing things like removing whitespace and quotes. There is no way to reconstruct the whole command line including all of those artifacts.
You could assume that if an argv member contains a space then originally it had quotes around it...
I have installed the linux distro named DVL (damn vulnerable linux), and I'm exercising with buffer overflow exploits.
I wrote two virtually identical programs which are vulnerable to bof:
//bof_n.c
#include <stdio.h>
void bof() {
printf("BOF");
}
void foo(char* argv) {
char buf[10];
strcpy(buf, argv);
prinf("foo");
}
int main(int argc, char* argv[]) {
if (argc >= 1) {
foo(argv[1]);
}
return 0;
}
and
//bof.c
#include <stdio.h>
void bof() {
printf("BOF!\n");//this is the only change
}
void foo(char* argv) {
char buf[10];
strcpy(buf, argv);
prinf("foo");
}
int main(int argc, char* argv[]) {
if (argc >= 1) {
foo(argv[1]);
}
return 0;
}
After that I compiled both of them, and I obtained the bof() function address in both cases (e.g., objdump -d bof.o | grep bof). Let's name such an address ADDR which is on 4 byte.
I also found that if I write 32 byte in the buf variable, the EIP register is completely overwritten (I cannot copy here the output of gdb since it is on a virtual machine).
Now, if I do:
./bof `perl -e 'print "\x90"x28 . "ADDR"'`
I get:
fooBOF!
Segmentation fault
Instead if I try the same approach but using bof_n, I only get the "Segmentation fault" message.
Therefore I tried to increment the number of time ADDR value is repeated, and I found that if it is being repeated for at least 350 times, I get the wanted result. But instead of having the output above exactly, I get a long list of "BOF" messages one after the other. I tried to obtain just one "BOF" message, but apparently I cannot do that (I got or zero, or a long list of them).
Why this is happening? Any idea?
I'm using DVL with gcc 3.4.6
What's your goal?
You should really be using a debugger for this, try the GDB Debugger or gdb. With it you can see the memory/registers/stack and disassembly of whats currently going on in the system.
I'd guess that in the first function, the string being only 3 characters in length, gets optimized to \x42\x4f\x46\x00, so the disassembly may be slightly different.
The C source is pretty much irrelevant, you'll need to either disassemble or fuzz both binaries to find appropriate size for both NOP sleds.
I found out the solution. The issue was about the printing of the message and not the buffer overflow exploit itself.
In fact the register eip was being correctly overwritten also in the bof_n example, and the program flow was being correctly redirected in the bof() function. The problem was that, apparently, the stdout were not flushed out before the Segmentation fault and hence no message was being shown.
Instead, using fprintf(stderr, "BOF");, I finally get the "BOF" message.
I have this program
I'd like to amend it to use getCommandLine()
Just, after the While loop, to print what getCommandLine() returns.
I don't know C, though I do know programming..
How can I use getCommandLine?
I know logically, getCommandLine is a Windows thing, and I have to import something, but can anybody answer with code that actually does it?
If it makes any difference, i'm compiling it with TCC(Tiny C Compiler)
#include <stdio.h>
int main(int argc, char *argv[]) {
int i = 0;
while (argv[i]) {
printf("argv[%d] = %s\n", i, argv[i]);
i++;
}
return 0;
}
As documented here:
http://msdn.microsoft.com/en-us/library/windows/desktop/ms683156(v=vs.85).aspx
You'll need to include <windows.h>. But I don't think it does what you think it does. It just gives you the full command line string, in the case that you don't have argv/argc.
Also you might find this post helpful:
Canonical way to parse the command line into arguments in plain C Windows API