Well, I try to play a bit with stack overflow and security cookies,
But its seem that most of the tutorial programs that people with POC tutorial with them are not compile with security cookies.
So i decide to create a program that take input from file and create a buffer overflow.
This is what I come out with:
#include <stdio.h>
#include <string.h>
void manipulate(char *buffer)
{
char newbuffer[80];
strcpy(newbuffer, buffer);
}
int main()
{
char ch, buffer[4096];
char filename[] = "exploit.txt";
int i = 0;
FILE *inFile;
inFile = fopen(filename, "rb");
if (inFile == NULL)
{
fprintf(stderr, "Can't open input file !\n");
getchar();
return 1 ;
}
while (buffer[i] != EOF)
{
buffer[i++] = fgetc(inFile);
manipulate(buffer);
printf("The value of i is : %d\n", i);
getchar();
return 0;
}
}
My problem is that I am always get Can't open input file !\n. even when i created "exploit.txt" in the same location and put some "aaaa" in it.
The basics of opening a file are correct. You can improve your program by using errno and strerror to inform the user of why the attempt to open the file failed.
#include <errno.h>
fprintf(stderr, "Error opening \"%s\": %s\n", filename, strerror(errno));
I was able to successfully run your example program (ignoring the stack overflow portion) with no changes.
The issue is with the value of the current or present working directory which is used as the basis for the completing file path used to open any file.
You can check the program's working directory using either getcwd() from <unixstd.h> for Linux, BSD, and POSIX systems or _getcwd() from <direct.h> for some other type.
Nitpicking: The "txt" file extension is misleading when compared with the fopen opening in binary mode, as specificed by rb.
Related
I want to read a name from a file (for example config_file.txt with only one entry like run)
and then create filenames with that, like run0.txt, run1.txt and so on.
But I get something like run..0.txt with two black dots.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAXCHAR 1000
void generate(char const *fileName);
int main(int argc, char** argv) {
generate("config_file.txt");
}
void generate(char const *fileName) {
char id[MAXCHAR];
FILE *fp;
char str[MAXCHAR];
fp = fopen(fileName, "r");
if (fp == NULL) {
printf("Could not open file %s", fileName);
return 1;
}
while (fgets(str, MAXCHAR, fp) != NULL) {
strcpy(id, str);
}
fclose(fp);
FILE *filePtr;
char filename[100];
for(int i = 0;i < 8;i++){
sprintf(filename, "%s%d.txt", id,i);
filePtr = fopen(filename, "w");
}
fclose(filePtr);
}
As I noted in the comments, your code does not zap the newline that fgets() normally preserves as it reads lines before trying to add the extension to it.
The simple and reliable method for zapping the newline is:
str[stcspn(str, "\n")] = '\0';
There are alternatives that might be more efficient (though efficiency is probably a red herring here — creating files takes a lot longer than reading through a short line of characters), but you have to get a variety of conditions right (empty buffer, buffer with no newline, etc).
You also have:
if (fp == NULL) {
printf("Could not open file %s", fileName);
return 1;
}
You should report errors on stderr instead of stdout.
You might consider including the error number and/or error message.
You should finish the message with a newline.
You can't write return 1; in a function returning void — the compiler must complain about that.
C11 §6.8.6.4 The return statement:
¶1 A return statement with an expression shall not appear in a function whose return type is void. A return statement without an expression shall only appear in a function whose return type is void.
Hence, you should consider writing:
if (fp == NULL)
{
fprintf(stderr, "Could not open file %s for reading: %s\n", fileName, strerror(errno));
return;
}
I normally use a set of error reporting functions that I wrote, one of which tells the library the name of the program (err_setarg0(argv[0]); in main()) and the others of which produce error messages as desired. This code is available in my SOQ (Stack Overflow Questions) repository on GitHub as files stderr.c and stderr.h in the src/libsoq sub-directory.
I'd write:
if (fp == NULL)
err_syserr("failed to open file '%s' for reading: ", fileName);
The function doesn't return. If I wanted to return, I'd use err_sysrem() ('remark') and arrange a return. The sys part of the name means that the error number and message are automatically reported too. I prefer these to perror() because perror() doesn't make it easy to get the program name etc into the error message.
There are analogous libraries available on some systems — err(3) on macOS, and also available on Linux (err(3), does roughly the same job.
It's my first exercise about Files and I have to write some code so that if I write a word in the console, it gets printed in the file. The program ends if I input the word "fine" (it's Italian for end). It seems like the file is opened and closed correctly, the program reads the inserted chars, but nonetheless, the file remains blank.
I tried opening the file in various modes, I tried printing how many chars were read, I even tried deleting the file (but it actually does't exit even if I added exit(1).
#define _CRT_SECURE_NO_DEPRECATE
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
int main() {
FILE * fp;
char s[64];
if ((fp = fopen("prova.txt", "r+")) == NULL) {
printf("Error.\n");
exit(1);
}
do {
scanf("%s", s);
if (strcmp("fine", s) != 0) {
fprintf(fp, "%s ", s);
}
} while (strcmp("fine", s) != 0);
fclose (fp);
return 0;
}
It should save all the words in a text file, but it remains blank.
Your program looks OK. Most likely, you are checking the wrong file.
An educated guess: you are using some IDE. If this is the case, the file is created, but is created somewhere else. To be sure, print the working directory (man getcwd) somewhere in the beginning of your program, and look for the file there.
you have to use "w" to open a new file with write priviledges
change
if ((fp = fopen("prova.txt", "r+")) == NULL) {
with
if ((fp = fopen("prova.txt", "w+")) == NULL) {
EDIT: Maybe i didn't explained myself, r+ will fail if the file doesn't exist, changing it works for me
I'm testing out the basic functions to operate files with.
I try to first open/close a file to create it, and then open/close it again to append to it. Lastly, I print out what is in the file.
My code currently looks like the following:
#include <stdio.h>
#include <stdlib.h>
int main()
{
FILE * file;
char mark;
/* WRITING: */
file= fopen("goodbye.c","w");
if(!file)
{ printf("Couldn't open file.\n");
exit(EXIT_FAILURE); }
printf("Enter data to write to .c file:");
while((mark= getchar())!=EOF)
{
putc(mark,file);
}
fclose(file);
/* APPENDING: */
file= fopen("goodbye.c","a");
if(!file)
{ printf("Couldn't open file.\n");
exit(EXIT_FAILURE); }
char add;
scanf("%c",add);
putc(add,file);
fclose(file);
/* READING: */
file= fopen("goodbye.c","r");
if(!file)
{ printf("Couldn't open file.\n");
exit(EXIT_FAILURE); }
while((mark= getc(file))!= EOF)
{
printf("%c",mark);
}
fclose(file);
}
With this, I'm not able to append to the file. When using getchar(), I type ctrl+d once finished writing in the first place. After this it goes on to printing out what I just wrote, not giving me the chance to append to the file. Does ctrl+d somehow interrupt with scanf?
And how to get the result that I was looking for?
Your code only allows you to append a single character to the file, which is a little stingy. It can also (at least in theory) lead to problems on some systems if the last line of the text file does not end with a newline, which it won't if you add something other than a newline. Maybe you need a loop to read multiple characters?
Also, since you don't stop the initial input until EOF, you need to clear the 'error' on stdin with clearerr(stdin) to allow further input to occur. This works correctly on Mac OS X 10.10.1 Yosemite; it should work the same on other Unix systems. I can't answer confidently for Windows-based code unless it is using something like Cygwin to simulate Unix, but I expect it would work in much the same way there, too, even with MSVC.
Incidentally, my compiler complains about a missing & in the call to scanf() at:
char add;
scanf("%c",add);
If your compiler doesn't complain, either turn up the warning level or get a better compiler.
This code works as I'd expect:
#include <stdio.h>
#include <stdlib.h>
int main(void)
{
FILE *file;
char mark;
/* WRITING: */
file = fopen("goodbye.c", "w");
if (!file)
{
printf("Couldn't open file.\n");
exit(EXIT_FAILURE);
}
printf("Enter data to write to .c file:");
while ((mark = getchar()) != EOF)
{
putc(mark, file);
}
fclose(file);
printf("EOF 1\n");
/* APPENDING: */
file = fopen("goodbye.c", "a");
if (!file)
{
printf("Couldn't open file.\n");
exit(EXIT_FAILURE);
}
clearerr(stdin);
char add;
while (scanf("%c", &add) == 1)
putc(add, file);
fclose(file);
printf("EOF 2\n");
/* READING: */
file = fopen("goodbye.c", "r");
if (!file)
{
printf("Couldn't open file.\n");
exit(EXIT_FAILURE);
}
while ((mark = getc(file)) != EOF)
{
printf("%c", mark);
}
fclose(file);
return 0;
}
The only substantive changes are adding a loop around the scanf() — though frankly it would be better to use getchar() again, like in the first input loop — fixing the call to scanf(), adding the two printf() statements that report when EOF is detected, and including clearerr(stdin); to allow input to continue.
Sample output
Code without clearerr(stdin):
Enter data to write to .c file:Happiness is a bug-free program.
Happiness is seldom attained.
EOF 1
EOF 2
Happiness is a bug-free program.
Happiness is seldom attained.
Code with clearerr(stdin):
Enter data to write to .c file:Happiness is a bug-free program.
Happiness is seldom attained.
EOF 1
But it helps when you add the clearerr(stdin) to this one.
EOF 2
Happiness is a bug-free program.
Happiness is seldom attained.
But it helps when you add the clearerr(stdin) to this one.
I was going through an example from Maurice Bach's Unix Book. He writes a simple copy program like mentioned below. However it fails when the inputfile is a directory file. I did stumble upon opendir and few other such API's - should I use that?
If a binary file can work with this, why is directory file considered different? In Unix, isn't everything abstracted as a file regardless of the way it is interpreted by the program.
Also how can I extend this program to support directory file and then create a mknod of that? I want to test this, suppose I am in /home/user1 and do a $./copy /home/user user-home-clone and mknod it to see how that directory will be different from home. I guess that the user-home-clone might not have a reference to itself, but all the other files in /home/user [ even though it would a file called user-home-clone would be there in /home/user ] since it was not there when we did the copy command?
#include <stdlib.h>
#include <stdio.h>
#include <fcntl.h>
#include <unistd.h>
char buffer[2048];
int copy(FILE *source, FILE *destination)
{
int count;
while ((count = fread(buffer, 1, sizeof buffer , source)) > 0)
{
fwrite(buffer, 1, count, destination);
}
return 0;
}
int main(int argc, char* argv[])
{
int status;
FILE *source;
FILE *destination;
if (argc != 3)
{
printf("%s takes exactly 3 arguments\n", argv[0]);
exit(1);
}
source = fopen(argv[1], "r");
if (source == NULL)
{
printf("%s can't be opened for reading\n", argv[1]);
exit(1);
}
destination = fopen(argv[2], "wb");
if (destination == NULL)
{
printf("%s can't be opened for writing\n", argv[2]);
exit(1);
}
if (copy(source, destination) == 0)
{
status = 0;
}
else
{
status = 1;
}
fclose(source);
fclose(destination);
exit(status);
}
I use Centos 6.5 Linux Ext4 Filesystem
In early versions of Unix, directory files could be read as binary files. However, when network and other types of virtual filesystems were added, this ability was removed, because different filesystems implement directories differently. While it would be technically possible for the driver to emulate a byte stream structure for these directories, it wasn't seen as a useful feature. Directories should be treated as opaque, abstract collections, and accessed using the directory-specific functions.
I'm trying to make a program to open a file, called "write.txt".
#include <stdio.h>
main() {
FILE *fp;
fp = fopen("write.txt", "w");
return 0;
}
Should this work? Because it returns nothing.
Other than an old variant of main, there's not really much wrong with that code. It should, barring errors, create the file.
However, since you're not checking the return value from fopen, you may get an error of some sort and not know about it.
I'd start with:
#include <stdio.h>
#include <errno.h>
int main (void) {
FILE *fp;
fp = fopen ("write.txt","w");
if (fp == NULL) {
printf ("File not created okay, errno = %d\n", errno);
return 1;
}
//fprintf (fp, "Hello, there.\n"); // if you want something in the file.
fclose (fp);
printf ("File created okay\n");
return 0;
}
If you're adamant that the file isn't being created but the above code says it is, then you may be a victim of the dreaded "IDE is working in a different directory from what you think" syndrome :-)
Some IDEs (such as Visual Studio) will actually run your code while they're in a directory like <solution-name>\bin or <solution-name>\debug. You can find out by putting:
system ("cd"); // for Windows
system ("pwd") // for UNIXy systems
in to your code to see where it's running. That's where a file will be created if you specify a relative path line "write.txt". Otherwise, you can specify an absolute path to ensure it tries to create it at a specific point in the file system.
What did you expect it to 'return' - it opens a file, on most platforms creating one if it doesn't exist.
You should probably fclose(fp) the file at the end.
I think you want to print the contents of file write.txt. (Assume it contains characters).
#include <stdio.h>
int main()
{
FILE *fp,char ch;
fp=fopen("write.txt","r");
if(fp==NULL)
{
printf("Some problem in opening the file");
exit(0);
}
else
{
while((ch=fgetc(fp))!=EOF)
{
printf("%c",ch);
}
}
fclose(fp);
return 0;
}
I think you should study some more fundamentals in C before you start attempting to work with files. A return means some data is passed back to the calling code from the called function.In this case you return 0 at the end of your program. You did not do anything with your FILE pointer except cause a new file to be created...