F
I'm using Graphviz to render .dot file as graphs, and typically I would write in my terminal :
dot -Tpng yourFile.dot -o yourOutput.png to produce a .png image representing my graph. (I'm using a Unix environment btw)
Now let's say I have the following C function:
#include <stdlib.h>
#include <string.h>
#define MAXSIZE 255
typedef struct placeholder mystruct;
struct placeholder {
...
}
void outputGraph(mystruct str, char* outputName) {
char command[MAXSIZE];
char* tmpFile = "temp.dot";
char imageFile[MAXSIZE];
snprintf(imageFile, MAXSIZE, "%s.png", outputName);
FILE* file = fopen(tmpFile, "w");
writeStructToFile(str, file);
snprintf(command, MAXSIZE, "dot -Tpng %s -o %s", tmpFile, imageFile);
system(command);
snprintf(command, MAXSIZE, "rm %s", tmpFile);
system(command);
}
(my function WriteStructToFile is another one that I made and is working properly so the problem is somewhere else)
From what I understood about the system() function, it should produce the image output just the same as when I execute the same command myself.
Well, it does execute without any errors, but there is no image in the directory where I'm working.
At first, I thought, it's easy, system() doesn't start a new shell in the same working directory, so I tried to see the output of system(pwd); and it was my current working directory. So back to the starting point.
I also tried to check the value system(command) by doing int status = system(command); and then printf("status : %d\n", status); and, well, it printed 0.
Now I'm kinda clueless, I really don't see why it doesn't produce the image output.
I'd be very interested in any ideas or even solutions you have.
This is not the most elegant code, but it works & may help you debug your problem. It calls dot in three different ways. All three work as expected.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main () {
char command[50];
int rc;
strcpy(command, "dot -Tdot this.gv" );
rc=system(command);
printf("\n\n+++ call #1 returned %d\n", rc);
strcpy(command, "dot -Tdot this.gv -oout1.dot" );
rc=system(command);
printf("\n\n+++ call #2 returned %d\n", rc);
strcpy(command, "dot -Tdot this.gv -o out2.dot" );
rc=system(command);
printf("\n\n+++ call #3 returned %d\n", rc);
return(0);
}
snprintf(command, MAXSIZE, "touch %s", tmpFile);
system(command);
Why do you code that?
You certainly don't need to use system(3) then touch(1). You could use appropriate syscalls(2) (open(2) and close(2) here) or at least fopen(3) followed by fclose(3).
You might in some cases consider using popen(3) with pclose(3)
Of course, after
snprintf(command, MAXSIZE, "dot -Tpng %s -o %s", tmpFile, imageFile);
int bad = system(command);
You need to first check that bad is 0 and you probably want to use stat(2) or access(2) to check that imageFile exists.
There could be many reasons why system with a dot command fails. For example, a bad $PATH variable. I suggest using popen(3) with pclose(3) and probably /usr/bin/dot in the command.
Compile your C code using GCC as gcc -Wall -Wextra -g and use GDB to debug your executable. Both strace(1) and ltrace(1) could help you understand the behavior of your program.
Consider reading Advanced Linux Programming and studying for inspiration the source code of some simple open source Linux shells, such as sash or (more complex) GNU bash.
Be aware that Graphviz could be used as a library.
I wasn't closing the temp.dot file in which I was writing. My mistake.
I shall now remember to always close files that I open!
A big thank you to everyone who helped on here.
(Whether it was for the problem or on how to use properly SO)
Related
I have a bunch of C files that try to read and write CSV and other random data to and from disk using stdio functions like fread(), fwrite(), fseek(). (If it matters, it's for a university assignment where we are to experiment with IO performance using different block sizes, and various structures to track data on disk files and so on.)
What I wanted to do was compile these source files (there are dozens of them)
without the definitions for fopen(), fread(), fwrite() that come from <stdio.h>. I want to supply my own fopen(), fread(), fwrite() where I track some information, like which process tried to read which file, and how many blocks/pages where read and things like that, and then call the normal stdio functions.
I don't want to have to go through every line of every file and change fopen() to my_fopen() .... is there better way to do this at compile time?
I am half way working on a Python program that scans the source files and changes these calls with my functions but it's getting a bit messy and I am kind of lost. I thought maybe there is a better way to do this; if you could point me in the right direction, like what to search for that would be great.
Also I don't want to use some Linux profiling stuff that reports which syscalls where made and what not; I just want to execute some code before calling these functions.
An alternative to the LD_PRELOAD trick (which requires you to write a separate library and works only on Linux) you can use the --wrap option of the GNU linker. See here for an example of this technique.
Main differences with LD_PRELOAD:
no external library needed - it's all in the executable;
no runtime options needed;
works on any platform as long as you are using the GNU toolchain;
works only for the calls that are resolved at link time - dynamic libraries will still use the original functions
No but yes but no. The best way I know of is to LD_PRELOAD a library that provides your own versions of those functions. You can get at the originals by dlopening libc.so (the dlopen NULL trick to get at libc functions isn't applicable here because your library will have already been loaded).
One way of doing it is by redefining all the stdio functions you need. fopen becomes my_fopen, fread becomes my_fread, then have your my_fopen call fopen. This can be done in a header file that you include in the files where you want to replace the calls to fopen. See example below.
main.c:
#include <stdio.h>
#include "my_stdio.h"
int main(void)
{
FILE *f;
char buf[256];
f = fopen("test.cvs", "r");
if(f == NULL)
{
printf("Couldn't open file\n");
return 1;
}
fread(buf, sizeof(char), sizeof(buf), f);
fclose(f);
return 0;
}
my_stdio.c:
#include <stdio.h>
FILE *my_fopen(const char *path, const char *mode)
{
FILE *fp;
printf("%s before fopen\n", __FUNCTION__);
fp = fopen(path,mode);
printf("%s after fopen\n", __FUNCTION__);
return fp;
}
int my_fclose(FILE *fp)
{
int rv;
printf("%s before fclose\n", __FUNCTION__);
rv = fclose(fp);
printf("%s after fclose\n", __FUNCTION__);
return rv;
}
size_t my_fread(void *ptr, size_t size, size_t nmemb, FILE *stream)
{
size_t s;
printf("%s before fread\n", __FUNCTION__);
s = fread(ptr,size,nmemb,stream);
printf("%s after fread\n", __FUNCTION__);
return s;
}
size_t my_fwrite(const void *ptr, size_t size, size_t nmemb, FILE *stream)
{
size_t s;
printf("%s before fwrite\n", __FUNCTION__);
s = fwrite(ptr,size,nmemb,stream);
printf("%s after fwrite\n", __FUNCTION__);
return s;
}
my_stdio.h:
#ifndef _MY_STDIO_H_
#define _MY_STDIO_H_
#define fopen my_fopen
#define fclose my_fclose
#define fread my_fread
#define fwrite my_fwrite
#endif /* _MY_STDIO_H_ */
Makefile:
main: main.o my_stdio.o
$(CC) -g -o $# main.o my_stdio.o
main.o: main.c
$(CC) -g -c -o $# $<
my_stdio.o: my_stdio.c my_stdio.h
$(CC) -g -c -o $# $<
Another way: Add -Dfread=my_fread to the Makefile CFLAGS for any .o files you wish to "spy" on. Add in my_fread.o that defines my_fread [which has no -D tricks].
Repeat the above for any functions you wish to intercept. About the same as the LD_PRELOAD [in terms of effectiveness and probably easier to implement]. I've done both.
Or create a my_func.h that does the defines and insert a #include "my_func.h" in each file. Dealer's choice
UPDATE
Forgot about another way. Compile normally. Mangle the symbol names in the target .o's [symbol table] (via a custom program or ELF/hex editor): Change fread into something with the same length that doesn't conflict with anything [you can control this]. Target name: qread or frea_ or whatever.
Add your intercept .o's using the new names.
This might seem "dirty", but what we're doing here is a "dirty" job. This is an "old school" [sigh :-)] method that I've used for .o's for which I didn't have the source and before LD_PRELOAD existed.
I'm using this code from here: Read and Execute Shellcode from a .txt File
#include <stdio.h>
#include <sys/mman.h>
#include <sys/stat.h>
#include <stdlib.h>
int main(void)
{
FILE *file = fopen("text.txt", "r");
unsigned char *buf;
int length = 0;
struct stat st;
int v;
// get file size and allocate. We're going to convert to bytes
// from text, so this allocation will be safely large enough
fstat(fileno(file), &st);
buf = valloc(st.st_size);
while (fscanf(file, "\\x%02x", &v) == 1)
{
buf[length++] = v;
}
fclose(file);
mprotect(buf, length, PROT_EXEC);
int (*ret)() = (int (*)())buf;
ret();
return 0;
}
And I'm compiling with: gcc -fno-stack-protector -z execstack testshell.c -o testshell
It runs just fine but the shellcode it executes writes to the terminal, but I would like to somehow redirect that to a file.
I tried:
./testshell > output.txt
but couldn't seem to get that to capture the results of the shellcode either.
How can I capture the output of any shellcode it runs, and if possible redirect that to a file?
Update: The shellcode I am using, and it outputs with a sys_write syscall output to a file descriptor (It does a calculation and prints to the screen) -
\xeb\x4d\x5e\x66\x83\xec\x0c\x48\x89\xe0\x48\x31\xc9\x68\x33\x09\x00\x7c\x48\x89\xcf\x80\xc1\x0c\x40\x8a\x3e\x40\xf6\xd7\x40\x88\x38\x48\xff\xc6\x68\x16\x96\xd0\xd9\x48\xff\xc0\xe2\xea\x2c\x0c\x48\x89\xc6\x68\xf2\xf5\x44\x48\x48\x31\xc0\x48\x89\xc7\x04\x01\x48\x89\xc2\x80\xc2\x0b\x0f\x05\x48\x31\xc0\x04\x3c\x0f\x05\xe8\xae\xff\xff\xff\x85\xa7\xaa\xc7\x9e\x87\xa5\xa5\x8e\xb7\x87\xba\x31\x80\xe0\x55\xef\xa1\x93\x0c\x4e\x1c\xdc\x34\x53\xb3\x8b\x43\x48\x68\x30\x1d\x4b\x65\x5b\x52\x41\x4e\x44\x53\x54\x52\x32\x5d
Transferring comments into an answer, giving credit where credit's due.
Deanie said:
This should work if the shellcode is writing to stdout and not stderr. Try:
./testshell > output.txt 1>&2
To which user2059300, the OP, responded:
No dice on the 1>&2, the output still occurs in the terminal and not in output.txt
And David C. Rankin said:
I think he meant ./testshell > output.txt 2>&1 to redirect both stdout & stderr to output.txt.
But user2059300 stated:
Still a no-go on that, … I provided the shellcode I'm testing.
Then I asked:
How does the shell code do the writing? What is it doing? I'm not going to dissect it for you; shell code tends to be very platform specific, and you've not identified which system you're using. Granted, it is reasonably easy to guess that you're using Linux on an Intel machine, but it might be 32-bit or 64-bit Linux, and what the shell code does still needs to be understood to know how to redirect its output. If it opens the terminal and writes to it, you'll be hard put to avoid the output appearing on the terminal, for example.
And user2059300 stated:
It's a sys_write syscall output to a file descriptor.
prompting me to ask:
Which file descriptor? 0, 1, 2, or another?
David C. Rankin noted:
That's still up in the air. Dumping to assembly shows a call to fprintf, but redirecting both stderr and stdout does nothing. It's almost like a kernel printf is being used.
And I countered with:
That's why I listed 0 as a candidate file descriptor. File descriptor 0 is usually a dup of file descriptors 1 and 2, so you can both write to 0 (standard input) and read from 1 and 2 (standard output and standard error). Of course, doing so is totally unsupported and non-portable (and you can't do it via the file streams stdin, stdout, stderr), but then shell code in general is non-portable.
And that seems to have been the key. David C. Rankin confirmed:
Hah! You nailed it. ./testshell > output.txt 0>&1 worked just fine. Learning has occurred… Thanks. That is the first, and hopefully the last time, I'll run across that. I'm too old to be learning those tricks.
and so did user2059300:
Thank you guys so much. Learning has indeed occurred. ./testshell > output.txt 0>&1
Obviously, I didn't know that was going to be the solution, but when the I/O redirection of standard output and standard error failed, it became a possibility. That behaviour has a very long history (7th Edition Unix, probably before that, too), though seldom if ever explicitly documented.
How do I get the absolute path to the directory of the currently executing command in C? I'm looking for something similar to the command dirname "$(readlink -f "$0")" in a shell script. For instance, if the C binary is /home/august/foo/bar and it's executed as foo/bar I want to get the result /home/august/foo.
Maybe try POSIX realpath() with argv[0]; something like the following (works on my machine):
#include <limits.h> /* PATH_MAX */
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char **argv) {
char buf[PATH_MAX];
char *res = realpath(argv[0], buf);
(void)argc; /* make compiler happy */
if (res) {
printf("Binary is at %s.\n", buf);
} else {
perror("realpath");
exit(EXIT_FAILURE);
}
return 0;
}
One alternative to argv[0] and realpath(3) on Linux is to use /proc/self/exe, which is a symbolic link pointing to the executable. You can use readlink(2) to get the pathname from it. See proc(5) for more information.
argv[0] is allowed to be NULL by the way (though this usually wouldn't happen in practice). It is also not guaranteed to contain the path used to run the command, though it will when starting programs from the shell.
I have come to the conclusion that there is no portable way for a commpiled executable to get the path to its directory. The obvious alternative is to pass an environment variable to the executable telling it where it is located.
Well, I am learning programming in C, and I got an assignment to get 3 characters from an input text file into 3 variables and then print their ASCII values.
I wrote this code:
#include <stdio.h>
int main()
{
char a,b,c;
printf("Insert 3 characters:\n");
a=getch();
b=getch();
c=getch();
printf("%d, %d, %d",(int)a,(int)b,(int)c);
}
I opened a text file (input.txt) and wrote there: "abc".
I managed to compile the code with the MinGW compiler, and on the CMD window that I opened in the folder of the .exe file, I wrote: "Task.exe <input.txt".
The program ran normally. I mean, it waited for me to input 3 characters.
What have I done wrong in my work?
help me please :)
You are asked to read from an input text file.
Why don't you use fopen to open a file handle, and fgetc to read from it?
You could perhaps use fscanf. Don't forget to use the resulting count.
And of course, you should call fclose. Using perror is useful to handle error cases.
So start your code with something that checks that your program has an argument, then fopen it:
int main(int argc, char**argv) {
if (argc<2) { fprintf(stderr, "missing program argument\n");
exit(EXIT_FAILURE); };
FILE* fil = fopen(argv[1], "r");
if (!fil) { perror(argv[1]); exit(EXIT_FAILURE); };
Then run Task.exe input.txt in your console (no redirection needed!).
You should take the habit of reading the documentation of every function you are using, of testing failure cases, of compiling with all warnings & debug info (gcc -Wall -Wextra -std=c99 -g), and of using the debugger (gdb).
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);