A question about allocating memory : C [UBUNTU] - c

I'm currently doing an exercise where I have to create a program that takes all the code that is written inside it, and outputs it to the screen when the program is executed.
The exercise suggests that we may find it appropriate to change the file names of the program in the future - and assuming that the renaming is done in a coordinated manner, i.e. the source file and the execution file are given the same new name (except for the extension), the program should work correctly, without the need for any changes to the source code, and without the need to recompile.
The C program itself is called 'prnt.c'-
I wrote the following code:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define ENDFILEC ".c" /* extension */
int main(int argc, char *argv[])
{
FILE *filePointer;
int character;
char *fileNameToOpen;
fileNameToOpen = (char *)malloc(strlen(argv[0]) + 3); /* allocating memory for string + 3 for the extension - '.c' and \0 */
strcpy(fileNameToOpen, argv[0]);
strcat(fileNameToOpen , ENDFILEC); /* ending '.c' in the end */
filePointer = fopen(fileNameToOpen, "r");
while(!feof(filePointer))
{
character = fgetc(filePointer);
printf("%c" , character);
}
fclose(filePointer);
return 0;
}
I made a 'makefile' to compile the program and I made it so that the executable would be called 'prnt1'.
basically, like the following:
prnt1 : prnt.c
gcc -ansi -Wall -pedantic prnt.c -o prnt1
The compilation worked, but whenever I run the program itself, it gives me a runtime error, saying: "Segmentation fault (core dumped)". When I look at the code itself, I don't seem to reach a memory that doesn't belong to me, so what could be an explanation for that problem and what can be done about it? Thank you in advance for your help.

Since you said that the executable is named "prnt1" and the source file (which you want to read the code from) is named "prnt", argv[0] has the name of the executable (i.e. "prnt1") and, when ".c" is appended to argv[0], it becomes "prnt1.c" – which is definitely not the file you are trying to read from; athen, since this file doesn't exist, you're getting a segmentation fault.
So, as Tom Karzes said, always check the return value of fopen().

Related

Using the system function to run another .cpp file [duplicate]

This question already has an answer here:
Compiling a source file using system(), 'main referenced from implicit entry/start for main executable [closed]
(1 answer)
Closed 6 years ago.
This program is a'grader' program, where I simply request the user to enter the name of a txt file and a .cpp source file which processes the txt file and gets its info. I then compile the source file along with the txt file, which outputs another text file. This new textile is then compared to the output expected(which I have been given as well.).
The system function allows users to run UNIX commands from a C program. When I am trying to compile the source file the user provides
I am getting an error saying that
"_main", referenced from: implicit entry/start for main executable.
clang: error: linker command failed with exit code 1 (use -v to see invocation)
sh: ./myProg: No such file or directory
The source file that I am compiling provided by my professor has one function which looks like this :
#include <stdio.h>
#include <stdlib.h>
#define MAX_VALUES 3
#define OUTPUT_LINES 5
int notmain(int argc, char **argv)
{
/*
* argv is just the file name
*/
//printf(argv[1]);
int values[MAX_VALUES];
int i, j;
FILE *inputFile;
char name [20]="input.txt"; // I have included this piece of code to see if there is a correct output from the source file provided by the user.
if ( (inputFile = fopen(name, "r") ) == NULL) {
printf("Error opening input file.\n\n");
exit(1);
}
for(i = 0; i < MAX_VALUES; i++)
fscanf(inputFile, "%d", &values[i]);
for(i = 0; i < OUTPUT_LINES; i++){
for (j=0; j < MAX_VALUES; j++)
printf("%d ", values[j]*(i+1) + j);
printf("\n");
}
return 0;
}
The code that I have written can be seen below: This code takes the information from the user and then compiles it.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define NUM_LINES 5
int main(){
char srcfile[200];
char inpfile[200];
char resultfile[200];
printf("Please enter the name of the source file: \n");
scanf("%s",srcfile);
printf("Please enter the name of the input file: \n");
scanf("%s",inpfile);
printf("Please enter the name of the expected result file: \n");
scanf("%s",resultfile);
char test1 [100]="gcc -o myProg ";
char test2 [100]="./myProg ";
strcat(test2,inpfile);
strcat(test2," > ");
strcat(test2,resultfile);
strcat(test1,srcfile);
printf("%s\n",test1); //these are just tests
printf("%s",test2); //these are just tests
if (system(test1)) {
printf("There is an error compiling the program ");
}
if (system(test2)!= 0) {
printf("There is an error running the executable");
}
return 0;
}
If you are looking for the solution I have posted it in the answers
The file you're trying to compile doesn't have a main function, which is the entry point for C programs. This means that it's actually not possible to build that file alone into an executable.
If the name of the function is supposed to be notmain then you'll have to write another source file that has a main function and calls notmain. This second main would belong to the executable your program is compiling, not to your program. You would have three source files:
Your grader program, which handles compilation.
A sort of wrapper file that effectively does:
int main(int argc, char *argv[]) {
notmain(argc, argv);
}
And finally the program to be graded.
You'll also either need to extern the notmain function or provide a header to share it. Your grader program would then compile the wrapper main and the source file to be graded together.
The question: Can you run two c programs with 2 main functions? The answer: Yes . In order to do this you have to use the terminal to compile the program with the two main functions separately. However if they interact with one another Im afraid I don't have a solution to that Now in this specific case here is how I did it. I went to the terminal and wrote. In this case I run one program which runs another program using the system function
gcc -c main.c (this compiles the main function).
Then after that i wrote gcc -o Myprogram main.o
This will create an executable named Myprogram which you can run by writing
./Myprogram
In this case my main method is compiling another source file so I don't need to compile that program as well in the terminal. When i compiled this program it created an output.txt file in the same directory the executable and the source files are in.

Segmentation fault on file write

When I am trying to print to a file it gives a segmentation fault. How can I print date and time to file?
#include <time.h>
#include <stdio.h>
main()
{
FILE *fp;
time_t mytime;
mytime=time(NULL);
fp=("sys.txt","w+");
fprintf(fp,"%s",ctime(&mytime));
fclose(fp);
return 0;
}
You forgot to (a) call fopen() and (b) pay attention to your compiler's warnings. If you didn't get compiler warnings, turn them on or get a better compiler.
A segmentation fault usually occurs when your program tries to access memory that it doesn't own or have access permission to.
This problem occurs in your program because you have incorrectly tried to open a file. You have to use the fopen() call to open a file:
FILE *fopen(const char *path, const char *mode);
In its present state, the program tries to write a string to a file described by a file descriptor containing some random value. That is, it tries to write to a random file that might not exist and that it definitely does not have write access to.
If you compiled your code with gcc, you would see this notifying you of a potential problem:
warning: assignment from incompatible pointer type
Replace fp=("sys.txt","w+"); with fp=fopen("sys.txt","w+");
And read about File Operations in C

How can a C program determine and print the location of its own executable?

I want to write a a C program that prints its location.
For example if i put the program exe file to D:\myfolder\myc_prog, it should print the same location D:\myfolder\myc_prog and if I put that exe file to the location E:\mynewfold\ , it should print the updated location E:\mynewfold.
Actually, I have no idea how to do it that's why I'm not able to provide much details for this question.
Since you're using Windows, GetModuleFileName should do the trick. Just pass NULL for the hModule parameter. Be sure to read the documentation carefully if you want to handle long file names (and you typically do). You'll also have to strip the name of the executable to get the directory path. A quick-and-dirty way to do so is to remove everything after the last \.
#include <Windows.h>
#include <stdio.h>
int main(int argc, char *argv[]){
char buff[256];
if(GetCurrentDirectory(256, buff)){//get current directory
printf("%s\n", buff);
}
return 0;
}

unix command result to a variable - char*

How can I assign "pwd" (or any other command in that case) result (present working dir) to a variable which is char*?
command can be anything. Not bounded to just "pwd".
Thanks.
Start with popen. That will let you run a command with its standard output directed to a FILE * that your parent can read. From there it's just a matter of reading its output like you would any normal file (e.g., with fgets, getchar, etc.)
Generally, however, you'd prefer to avoid running an external program for that -- you should have getcwd available, which will give the same result much more directly.
Why not just call getcwd()? It's not part of C's standard library, but it is POSIX, and it's very widely supported.
Anyway, if pwd was just an example, have a look at popen(). That will run an external command and give you a FILE* with which to read its output.
There is a POSIX function, getcwd() for this - I'd use that.
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
int main(int argc, char* argv[]) {
char *dir;
dir = getcwd(NULL, 0);
printf("Current directory is: %s\n", dir);
free(dir);
return 0;
}
I'm lazy, and like the NULL, 0 parameters, which is a GNU extension to allocate as large a buffer as necessary to hold the full pathname. (It can probably still fail, if you're buried a few hundred thousand characters deep.)
Because it is allocated for you, you need to free(3) it when you're done. I'm done with it quickly, so I free(3) it quickly, but that might not be how you need to use it.
You can fork and use one of the execv* functions to call pwd from your C program, but getting the result of that would be messy at best.
The proper way to get the current working directory in a C program is to call char* getcwd(char* name, size_t size);

Executing machine code in memory

I'm trying to figure out how to execute machine code stored in memory.
I have the following code:
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char* argv[])
{
FILE* f = fopen(argv[1], "rb");
fseek(f, 0, SEEK_END);
unsigned int len = ftell(f);
fseek(f, 0, SEEK_SET);
char* bin = (char*)malloc(len);
fread(bin, 1, len, f);
fclose(f);
return ((int (*)(int, char *)) bin)(argc-1, argv[1]);
}
The code above compiles fine in GCC, but when I try and execute the program from the command line like this:
./my_prog /bin/echo hello
The program segfaults. I've figured out the problem is on the last line, as commenting it out stops the segfault.
I don't think I'm doing it quite right, as I'm still getting my head around function pointers.
Is the problem a faulty cast, or something else?
You need a page with write execute permissions. See mmap(2) and mprotect(2) if you are under unix. You shouldn't do it using malloc.
Also, read what the others said, you can only run raw machine code using your loader. If you try to run an ELF header it will probably segfault all the same.
Regarding the content of replies and downmods:
1- OP said he was trying to run machine code, so I replied on that rather than executing an executable file.
2- See why you don't mix malloc and mman functions:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <sys/mman.h>
int main()
{
char *a=malloc(10);
char *b=malloc(10);
char *c=malloc(10);
memset (a,'a',4095);
memset (b,'b',4095);
memset (c,'c',4095);
puts (a);
memset (c,0xc3,10); /* return */
/* c is not alligned to page boundary so this is NOOP.
Many implementations include a header to malloc'ed data so it's always NOOP. */
mprotect(c,10,PROT_READ|PROT_EXEC);
b[0]='H'; /* oops it is still writeable. If you provided an alligned
address it would segfault */
char *d=mmap(0,4096,PROT_READ|PROT_WRITE|PROT_EXEC,MAP_PRIVATE|MAP_ANON,-1,0);
memset (d,0xc3,4096);
((void(*)(void))d)();
((void(*)(void))c)(); /* oops it isn't executable */
return 0;
}
It displays exactly this behavior on Linux x86_64 other ugly behavior sure to arise on other implementations.
Using malloc works fine.
OK this is my final answer, please note I used the orignal poster's code.
I'm loading from disk, the compiled version of this code to a heap allocated area "bin", just as the orignal code did (the name is fixed not using argv, and the value 0x674 is from;
objdump -F -D foo|grep -i hoho
08048674 <hohoho> (File Offset: 0x674):
This can be looked up at run time with the BFD (Binary File Descriptor library) or something else, you can call other binaries (not just yourself) so long as they are statically linked to the same set of lib's.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/mman.h>
unsigned char *charp;
unsigned char *bin;
void hohoho()
{
printf("merry mas\n");
fflush(stdout);
}
int main(int argc, char **argv)
{
int what;
charp = malloc(10101);
memset(charp, 0xc3, 10101);
mprotect(charp, 10101, PROT_EXEC | PROT_READ | PROT_WRITE);
__asm__("leal charp, %eax");
__asm__("call (%eax)" );
printf("am I alive?\n");
char *more = strdup("more heap operations");
printf("%s\n", more);
FILE* f = fopen("foo", "rb");
fseek(f, 0, SEEK_END);
unsigned int len = ftell(f);
fseek(f, 0, SEEK_SET);
bin = (char*)malloc(len);
printf("read in %d\n", fread(bin, 1, len, f));
printf("%p\n", bin);
fclose(f);
mprotect(&bin, 10101, PROT_EXEC | PROT_READ | PROT_WRITE);
asm volatile ("movl %0, %%eax"::"g"(bin));
__asm__("addl $0x674, %eax");
__asm__("call %eax" );
fflush(stdout);
return 0;
}
running...
co tmp # ./foo
am I alive?
more heap operations
read in 30180
0x804d910
merry mas
You can use UPX to manage the load/modify/exec of a file.
P.S. sorry for the previous broken link :|
It seems to me you're loading an ELF image and then trying to jump straight into the ELF header? http://en.wikipedia.org/wiki/Executable_and_Linkable_Format
If you're trying to execute another binary, why don't you use the process creation functions for whichever platform you're using?
An typical executable file has:
a header
entry code that is called before main(int, char **)
The first means that you can't generally expect byte 0 of the file to be executable; intead, the information in the header describes how to load the rest of the file in memory and where to start executing it.
The second means that when you have found the entry point, you can't expect to treat it like a C function taking arguments (int, char **). It may, perhaps, be usable as a function taking no paramters (and hence requiring nothing to be pushed prior to calling it). But you do need to populate the environment that will in turn be used by the entry code to construct the command line strings passed to main.
Doing this by hand under a given OS would go into some depth which is beyond me; but I'm sure there is a much nicer way of doing what you're trying to do. Are you trying to execute an external file as a on-off operation, or load an external binary and treat its functions as part of your program? Both are catered for by the C libraries in Unix.
It is more likely that that it is the code that is jumped to by the call through function-pointer that is causing the segfault rather than the call itself. There is no way from the code you have posted to determine that that code loaded into bin is valid. Your best bet is to use a debugger, switch to assembler view, break on the return statement and step into the function call to determine that the code you expect to run is indeed running, and that it is valid.
Note also that in order to run at all the code will need to be position independent and fully resolved.
Moreover if your processor/OS enables data execution prevention, then the attempt is probably doomed. It is at best ill-advised in any case, loading code is what the OS is for.
What you are trying to do is something akin to what interpreters do. Except that an interpreter reads a program written in an interpreted language like Python, compiles that code on the fly, puts executable code in memory and then executes it.
You may want to read more about just-in-time compilation too:
Just in time compilation
Java HotSpot JIT runtime
There are libraries available for JIT code generation such as the GNU lightning and libJIT, if you are interested. You'd have to do a lot more than just reading from file and trying to execute code, though. An example usage scenario will be:
Read a program written in a scripting-language (maybe
your own).
Parse and compile the source into an
intermediate language understood by
the JIT library.
Use the JIT library to generate code
for this intermediate
representation, for your target platform's CPU.
Execute the JIT generated code.
And for executing the code you'd have to use techniques such as using mmap() to map the executable code into the process's address space, marking that page executable and jumping to that piece of memory. It's more complicated than this, but its a good start in order to understand what's going on beneath all those interpreters of scripting languages such as Python, Ruby etc.
The online version of the book "Linkers and Loaders" will give you more information about object file formats, what goes on behind the scenes when you execute a program, the roles of the linkers and loaders and so on. It's a very good read.
You can dlopen() a file, look up the symbol "main" and call it with 0, 1, 2 or 3 arguments (all of type char*) via a cast to pointer-to-function-returning-int-taking-0,1,2,or3-char*
Use the operating system for loading and executing programs.
On unix, the exec calls can do this.
Your snippet in the question could be rewritten:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
int main(int argc, char* argv[])
{
return execv(argv[1],argv+2);
}
Executable files contain much more than just code. Header, code, data, more data, this stuff is separated and loaded into different areas of memory by the OS and its libraries. You can't load a program file into a single chunk of memory and expect to jump to it's first byte.
If you are trying to execute your own arbitrary code, you need to look into dynamic libraries because that is exactly what they're for.

Resources