unable to execute execl() with MinGW on windows 8 - c

I have a file hello.exe file path is D:\test\hello.exewhich is a simple hello world program (tested ok).
I have another program proc.c file path is D:\test\proc.c with code as follows:
#include<stdio.h>
#include<stdlib.h>
#include<windows.h>
#include<process.h>
#include<errno.h>
#include<string.h>
main(int argc,char *argv[])
{
int ret;
ret=execl("D:\\test\\hello.exe","D:\\test\\hello.exe");
if(ret==-1)
printf("%d:\t%s",ret,errno);
}
The program hangs (windows dialog says The program has stopped working)!!!
I even tried D:/test/hello.exe as param to execl(), but the same...
Where am I going wrong???
Please someone provide me the right syntax? Please prvide me example codes using various functions of process.h with MinGW under windows. Web tutorial links are acceptable as well.
Thanks a lt !!!

You have to include a library,
#include<unistd.h>
Because it is defined in this library So if you don't include this you will get AN error.
and correct your code because you have written "exec" not execl.
int main()
{
execl("D:/test/hello","D:/test/hello",0);
return 0;
}

If you compiled with warnings, you'd notice that errno is an int, but you're trying to use it with printf as a string, which means it is being used as a pointer. Memory address 0xFFFFFFF2 (or whatever the hexadecimal value of errno is) probably isn't valid.
Aside from that, you need to end your execl invocation with a NULL pointer. Otherwise the function will keep thinking it has more command line arguments, all of which are strings, until the first NULL it finds in memory or until the first invalid memory access, whichever comes first. Because copying the strings involves dereferencing a pointer, it will read the address made up of unknown bytes and attempt to dereference the pointer at that address repeatedly. If the pointer cannot be dereferenced, meaning accessing the address for reading data from it cannot be done, it will crash your program.
In the future, please compile with -Wall.

Related

Undefined behaviour while calling a function from dll

Though the title reads dll, the actual library loaded is an exe. Suppose I have an exe file testlib.exe. I need to call a function from it, let it be func(). What I am doing is:
#include <windows.h>
#include <stdio.h>
typedef char* (__stdcall *f_func)();
int main()
{
HINSTANCE hGetProcIDDLL = LoadLibrary("testlib.exe");
f_func func = (f_func)GetProcAddress(hGetProcIDDLL, "func");
printf(func());
return 0;
}
Now most of the times I run the program it gives the correct output, but in some cases (1 out of 8 for example) it gives either garbage text or values of some other variables in testlib.exe. I identify it's due to wrong memory reference but can neither explain nor solve it.
My os is windows and I'm using mingw gcc. I do not use MSVS as it does not fit well in code portability.
PS: The testlib.exe is well built and I cannot change it. It is unlikely to have any problem. I tried different versions and also it's running in other build systems well. Also it is a release build, so less hope in debugging.
UPDATE:
I've seen this question, it says that it is possible by patching the IAT table. My point is completly different. I am using a function that is neither initialised by main nor by dllmain.
Actually what I found that GetProcAddress gives right function pointer everytime. What gets messed is the return object. For example if the function in exe library is:
const char* func() {
return "Sometext";
}
then sometimes the reference to "sometext is sometimes wrong. I do suspect randomised loading but I'm not sure. I renamed the exe as dll but no change observed.

How to check if environment variable is set from C program

I'm currently working on a program, and I would like to print special output if an environment variable is set.
For example, suppose I want environment variable "DEBUG".
In my bash command prompt, I set DEBUG by typing the command:
DEBUG=
Then in my C program, I can verify this environment variable is set by printing out all the content of char **environ. DEBUG does show up in this environment printout.
However, I don't know how to retrieve this environment variable for conditional checking. I've tried using the function getenv like so:
getenv("DEBUG")
If I were to try to print out this output like below I get a seg fault:
printf("get env: %s\n", getenv("DEBUG"));
I even tried this on a known environment variable like "HOME":
printf("get env: %s\n", getenv("HOME"));
which still produces a seg fault.
Does any one have any experience checking if an environment variable is set from a C program? I'm having issues even pulling a single environment variable which is preventing me from doing so.
getenv returns NULL when the environment variable for which it is asked is not set. Your check could thus simply be
if(getenv("DEBUG")) {
// DEBUG is set
} else {
// DEBUG is not set
}
Note that there is a difference between shell and environment variables; if you want a variable to show up in the environment of a shell's subprocess, you have to export it in the shell:
export DEBUG=some_value
or
DEBUG=some_value
export DEBUG
It is not enough to just say DEBUG=some_value.
It's because you are not including stdlib.h and the compiler is assuming getenv() returns int.
You have two options, you can declare getenv() like
char *getenv(const char *);
or include stdlib.h, and the same applies for printf() but in that case the header is stdio.h.
You should enable compiler warning, on linux gcc and clang both support -Wall -Wextra -Werror, the most important one, -Werror will prevent compilation in this case.
You need to make sure that getenv (and printf) are correctly declared.
For getenv, you need:
#include <stdlib.h>
If you don't declare it, segfaults are likely when you call it. If you were to get that far, trying to use the value it returns would probably also segfault.
Undeclared functions are handled as though they were declared to accept either integer or double arguments (depending on what is provided) and as though they return integers. If int is the same size as a pointer, that might work, but in the common case where pointers are 64 bits but ints are only 32, passing a pointer as though it were an integer will result in half of its bits being dropped on the floor, making it pretty much unusable as a pointer.
Always specify -Wall when you compile your code, and make sure you pay attention to the warnings. They are important.
code snippet :
if(NULL == getenv("TIME_ELAPSED"))
{
putenv("TIME_ELAPSED=1");
}
we have to take care of error handling for putenv also .Sometimes it returns
ENOMEM Insufficient space to allocate new environment.

Valgrind reports silly arg to malloc, how do I find out where?

I get a warning when running my program under valgrind:
==24214== Warning: silly arg (-1) to malloc()
How can I determine what call to malloc() is faulty? Is there a way I can do this without recompiling?
The program is compiled with -g (debug) and without -s (strip).
After a modicum of experimentation on a relatively antique RedHat Linux with Valgrind version 3.2.1, it appears that it does not produce a more precise warning. Further, even Valgrind 3.7.0 on Mac OS X 10.7.3 doesn't do a better job of identifying the erroneous call.
Test code:
#include <stdlib.h>
#include <stdint.h>
int main(void)
{
int l = -1;
char *x = malloc(l);
return (uintptr_t)x & 1;
}
So, since valgrind does not help, you are probably reduced to using the debugger on the program, breaking on calls to malloc() — perhaps conditionally breaking when the argument is equal to (size_t)-1.
Indeed, it appears that valgrind refuses to print a stack trace for this situation, even with --verbose. Please write to the mailing list; there should be an option for this otherwise the diagnostic isn't that helpful.
Note that the argument of malloc is an unsigned type, size_t, which does not have -1 in its range. What this situation means is actually that the largest possible value of size_t was passed to malloc.
Strictly speaking, that is not an erroneous API call, but it does probably indicate that something is wrong. (Your program does not need multi-gigabyte arrays, right?)
you can do a break point on malloc and make it conditional, for example that the arg is <0
You might find where that text "silly arg" gets called inside valgrind. Bring up your debugger and break on that spot. Run your program and when it brings you back to the debugger prompt go up until you're at the line that called the malloc.
I ended up inserting printf's and finding if it came before or after the valgrind printf. Less fancy than what you guys reccomended, but it worked faster than trying to implement the other solutions.

How to write a quine program without main()

I went through all sorts of quine problems, but my task was to get a quine problem without main(), and loops are also forbidden.
Without loop, it is easy, but I can't figure out how to write one without main(). Can anyone help me or provide me with a link?
You cannot create a (non-freestanding) C program without a main() function. Thus, creating a quine in C without a main() is impossible in the usual sense.
That said, depending on how you define a quine, you might be able to construct a source file which fails to compile, but for which the compile error (on a certain specific compiler) is the contents of the source file.
First thing its impossible to write program without main function because compiler always starts execution from main() function, without main function linker will not be aware of start of data segment.
Yeah but playing with some tricks with preprocessor you can do it, but this is not a good method to do that.
http://www.gohacking.com/2008/03/c-program-without-main-function.html
This might help you.
Take a look here too:
Is a main() required for a C program?
#include <stdio.h>
int
foo(void) {
printf("pong!\n");
return 0;
}
int main() __attribute__((weak, alias("foo")));
There is main() declaration, but not definition.

Why cast "extern puts" to a function pointer "(void(*)(char*))&puts"?

I'm looking at example abo3.c from Insecure Programming and I'm not grokking the casting in the example below. Could someone enlighten me?
int main(int argv,char **argc)
{
extern system,puts;
void (*fn)(char*)=(void(*)(char*))&system;
char buf[256];
fn=(void(*)(char*))&puts;
strcpy(buf,argc[1]);
fn(argc[2]);
exit(1);
}
So - what's with the casting for system and puts? They both return an int so why cast it to void?
I'd really appreciate an explanation of the whole program to put it in perspective.
[EDIT]
Thank you both for your input!
Jonathan Leffler, there is actually a reason for the code to be 'bad'. It's supposed to be exploitable, overflowing buffers and function pointers etc. mishou.org has a blog post on how to exploit the above code. A lot of it is still above my head.
bta, I gather from the above blog post that casting system would somehow prevent the linker from removing it.
One thing that is not immediately clear is that the system and puts addresses are both written to the same location, I think that might be what gera is talking about “so the linker doesn’t remove it”.
While we are on the subject of function pointers, I'd like to ask a follow-up question now that the syntax is clearer. I was looking at some more advanced examples using function pointers and stumbled upon this abomination, taken from a site hosting shellcode.
#include <stdio.h>
char shellcode[] = "some shellcode";
int main(void)
{
fprintf(stdout,"Length: %d\n",strlen(shellcode));
(*(void(*)()) shellcode)();
}
So the array is getting cast to a function returning void, referenced and called? That just looks nasty - so what's the purpose of the above code?
[/EDIT]
Original question
User bta has given a correct explanation of the cast - and commented on the infelicity of casting system.
I'm going to add:
The extern line is at best weird. It is erroneous under strict C99 because there is no type, which makes it invalid; under C89, the type will be assumed to be int. The line says 'there is an externally defined integer called system, and another called puts', which is not correct - there are a pair of functions with those names. The code may actually 'work' because the linker might associate the functions with the supposed integers. But it is not safe for a 64-bit machine where pointers are not the same size as int. Of course, the code should include the correct headers (<stdio.h> for puts() and <stdlib.h> for system() and exit(), and <string.h> for strcpy()).
The exit(1); is bad on two separate counts.
It indicates failure - unconditionally. You exit with 0 or EXIT_SUCCESS to indicate success.
In my view, it is better to use return at the end of main() than exit(). Not everyone necessarily agrees with me, but I do not like to see exit() as the last line of main(). About the only excuse for it is to avoid problems from other bad practices, such as functions registered with atexit() that depend on the continued existence of local variables defined in main().
/usr/bin/gcc -g -std=c99 -Wall -Wextra -Wmissing-prototypes -Wstrict-prototypes -Wold-style-definition -c nasty.c
nasty.c: In function ‘main’:
nasty.c:3: warning: type defaults to ‘int’ in declaration of ‘system’
nasty.c:3: warning: type defaults to ‘int’ in declaration of ‘puts’
nasty.c:3: warning: built-in function ‘puts’ declared as non-function
nasty.c:8: warning: implicit declaration of function ‘strcpy’
nasty.c:8: warning: incompatible implicit declaration of built-in function ‘strcpy’
nasty.c:10: warning: implicit declaration of function ‘exit’
nasty.c:10: warning: incompatible implicit declaration of built-in function ‘exit’
nasty.c: At top level:
nasty.c:1: warning: unused parameter ‘argv’
Not good code! I worry about a source of information that contains such code and doesn't explain all the awfulness (because the only excuse for showing such messy code is to dissect it and correct it).
There's another weirdness in the code:
int main(int argv,char **argc)
That is 'correct' (it will work) but 100% aconventional. The normal declaration is:
int main(int argc, char **argv)
The names are short for 'argument count' and 'argument vector', and using argc as the name for the vector (array) of strings is abnormal and downright confusing.
Having visited the site referenced, you can see that it is going through a set of graduated examples. I'm not sure whether the author simply has a blind spot on the argc/argv issue or is deliberately messing around ('abo1' suggests that he is playing, but it is not helpful in my view). The examples are supposed to feed your mind, but there isn't much explanation of what they do. I don't think I could recommend the site.
Extension question
What's the cast in this code doing?
#include <stdio.h>
char shellcode[] = "some shellcode";
int main(void)
{
fprintf(stdout,"Length: %d\n",strlen(shellcode));
(*(void(*)()) shellcode)();
}
This takes the address of the string 'shellcode' and treats it as a pointer to a function that takes an indeterminate set of arguments and returns no values and executes it with no arguments. The string contains the binary assembler code for some exploit - usually running the shell - and the objective of the intruder is to get a root-privileged program to execute their shellcode and give them a command prompt, with root privileges. From there, the system is theirs to own. For practicing, the first step is to get a non-root program to execute the shellcode, of course.
Reviewing the analysis
The analysis at Mishou's web site is not as authoritative as I'd like:
One, this code uses the extern keyword in the C language to make the system and puts functions available. What this does (I think) is basically references directly the location of a function defined in the (implied) header files…I get the impression that GDB is auto-magically including the header files stdlib.h for system and stdio.h for puts. One thing that is not immediately clear is that the system and puts addresses are both written to the same location, I think that might be what gera is talking about “so the linker doesn’t remove it”.
Dissecting the commentary:
The first sentence isn't very accurate; it tells the compiler that the symbols system and puts are defined (as integers) somewhere else. When the code is linked, the address of puts()-the-function is known; the code will treat it as an integer variable, but the address of the integer variable is, in fact, the address of the function - so the cast forces the compiler to treat it as a function pointer after all.
The second sentence is not fully accurate; the linker resolves the addresses of the external 'variables' via the function symbols system() and puts() in the C library.
GDB has nothing whatsoever to do the compilation or linking process.
The last sentence does not make any sense at all. The addresses only get written to the same location because you have an initialization and an assignment to the same variable.
This didn't motivate me to read the whole article, it must be said. Due diligence forces me onwards; the explanation afterwards is better, though still not as clear as I think it could be. But the operation of overflowing the buffer with an overlong but carefully crafted argument string is the core of the operation. The code mentions both puts() and system() so that when run in non-exploit mode, the puts() function is a known symbol (otherwise, you'd have to use dlopen() to find its address), and so that when run in exploit mode, the code has the symbol system() available for direct use. Unused external references are not made available in the executable - a good thing when you realize how many symbols there are in a typical system header compared with the number used by a program that includes the header.
There are some neat tricks shown - though the implementation of those tricks is not shown on the specific page; I assume (without having verified it) that the information for getenvaddr program is available.
The abo3.c code can be written as:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(int argc, char **argv)
{
void (*fn)(char*) = (void(*)(char*))system;
char buf[256];
fn = (void(*)(char*))puts;
strcpy(buf, argv[1]);
fn(argv[2]);
exit(1);
}
Now it compiles with only one warning with the fussy compilation options I originally used - and that's the accurate warning that 'argc' is not used. It is just as exploitable as the original; it is 'better' code though because it compiles cleanly. The indirections were unnecessary mystique, not a crucial part of making the code exploitable.
Both system and puts normally return int. The code is casting them to a pointer that returns void, presumably because they want to ignore whatever value is returned. This should be equivalent to using (void)fn(argc[2]); as the penultimate line if the cast didn't change the return type. Casting away the return type is sometimes done for callback functions, and this code snippet seems to be a simplistic example of a callback.
Why the cast for system if it is never used is beyond me. I'm assuming that there's more code that isn't shown here.

Resources