if(find_task_by_vpid(pid))
{
myProcess = kmalloc(sizeof(find_task_by_vpid(pid)), GFP_KERNEL);
myProcess = find_task_by_vpid(pid);
}
I've included sched.h where this method is declared, but am getting the following errors:
(on the first line) warning: implicit declaration of function 'find_task_by_vpid'
(on the last line) warning:assignment makes pointer from integer without a cast
Presumably the issues are related, but I can't figure out what the matter is.
Running Ubuntu (6.06.2) linux kernel version 2.6.15.51-server.
I believe you're including the wrong sched.h. My system has several sched headers but only /usr/src/linux-headers-3.5.0-18/include/linux/sched.h contains the declaration of find_task_by-vpid(). I recommend you check your include paths.
Related
I am trying to compile some WinAPI code using gcc compiler.
However whenever I call functions like CreateSemaphoreEx, CreateMutexEx (and some other Ex functions) I get
"undefined reference to 'CreateSemaphoreEx'" link error.
It works with CreateSemaphore or CreateMutex but not the Ex versions of these functions.
First I compiled with mwindows flag as such (gcc main.c -mwindows)
Then I tried linking to the library manually (gcc -lkernel32 main.c)
I have also tried using CreateSemaphoreExA
I also tried uninstalling and reinstalling mingw-w64 and even tried switching to TDM-GCC
I know if I change it to CreateSemaphore call it works, however I want to use the Ex version.
#include <windows.h>
int main(int argc, char** argv)
{
int initial_count = 0;
int maximum_count = 5;
HANDLE semaphore = CreateSemaphoreEx(0, initial_count, maximum_count, NULL, 0, SYNCHRONIZE | SEMAPHORE_MODIFY_STATE);
}
How can I get access to these WinAPI functions using gcc compiler on Windows (if it is at all possible).
-------- Complete Compiler Output ---------
main.c: In function 'main':
main.c:8:21: warning: implicit declaration of function 'CreateSemaphoreEx'; did you mean 'CreateSemaphoreA'? [-Wimplicit-function-declaration]
HANDLE semaphore = CreateSemaphoreEx(0, initial_count, maximum_count, NULL, 0, SYNCHRONIZE | SEMAPHORE_MODIFY_STATE);
^~~~~~~~~~~~~~~~~
CreateSemaphoreA
main.c:8:21: warning: initialization of 'HANDLE' {aka 'void *'} from 'int' makes pointer from integer without a cast [-Wint-conversion]
C:\Users\Nexwave\AppData\Local\Temp\cc3ncRYX.o:main.c:(.text+0x49): undefined reference to `CreateSemaphoreEx'
collect2.exe: error: ld returned 1 exit status
Edit 1:
I know about linking.
My question is whether the kernel32 library used by mingw-w64 different than one used by Microsoft's linker.
And if it is different then why is there no definition for CreateSemaphoreEx (and some other Ex functions) that are available in the actual Kernel32.lib
The problem indicated by the first diagnostic:
implicit declaration of function 'CreateSemaphoreEx'
The other errors are cascading from that. In general you should always fix the first compiler diagnostic before worrying too much about the others.
Note, I would recommend using standard compiler switches so that it says "error" instead of "warning" for this error condition, and breaks compilation. Some people see the word "warning" and think "oh it's just a warning and not important, I'll ignore it" but that would be a mistake in this case.
The error message above means that your system headers do not define CreateSemaphoreEx. Why is this? Here are the main possibilities:
You're on an old version of Windows; the function was added in Windows Vista and will not be accessible if you're on XP for example. (The Windows headers don't define the prototype and macro if the system is detected as being pre-Vista).
You're using an old version of mingw-w64 that doesn't have this function.
In Debian 8's source code /source/procps-3.3.9/lib/fileutils.c line 38 is:
char const *write_error = _("write error");
I am confused about the _("write error") part. Google showed that result on variable naming convention or library reserved names, but nothing about when _ was on the right side of = and before a () quoted string.
I also put this line into a simplest test program as only useful line then had compilation failed saying:
test.c:5:20: warning: implicit declaration of function ‘_’ [-Wimplicit-function-declaration]
char const *str = _("test string");
^
test.c:5:20: warning: initialization makes pointer from integer without a cast [-Wint-conversion]
/tmp/cczQpqTh.o: In function `main':
test.c:(.text+0x15): undefined reference to `_'
collect2: error: ld returned 1 exit status
Does anyone know what _(" ") format means?
This is the standard way to mark up strings for translation using GNU gettext, a free software translation tool.
The _() macro is found by an external tool which extracts the text to make it translatable, as well as (at run-time) do look-ups to replace the literal with the necessary translation.
There is nothing special about the name _, it's just a very short but perfectly valid C identifier. Perhaps it's a bit iffy to begin a public symbol with an underscore, I'm not sure right now.
The error you're getting is because your test program very likely fails to include the <libintl.h> header (part of gettext, of course) which declares this macro. Thus you get the normal "undefined reference" error, as expected.
For some bizarre reason, when I try to use the function get_current_dir_name with MinGW GCC compiler,
I get this result on linkage:
undefined reference to `get_current_dir_name'
collect2.exe: error: ld returned 1 exit status
But, I get this only when using the function like this
printf("%i", get_current_dir_name());
or this
printf("%s", get_current_dir_name());
When I try to do
printf(get_current_dir_name());
I get this, which makes no sense, because the function returns a char *, according to docs:
tester.c: In function 'main':
tester.c:16:2: warning: passing argument 1 of 'printf' makes pointer from integer without a cast [enabled by default]
printf(get_current_dir_name());
^
In file included from tester.c:1:0:
c:\mingw\include\stdio.h:294:37: note: expected 'const char *' but argument is of type 'int'
_CRTIMP int __cdecl __MINGW_NOTHROW printf (const char*, ...);
Google seem to really dislike talking about C, because I can find how to get the workdir on almost any existing language, except C. The only thing that pops up are some docs, which describe 3 functions: getcwd, getwd, and get_current_dir_name. I really want to use the get_current_dir_name one because of it's cleanness.
How do I deal with this? Is this a minGW bug? Or am I missing something?
You apparently failed to include any header that contains a declaration of get_current_dir_name(). Thus, the compiler will assume a return value of int, which is not a valid first argument for printf() (you should increase the warning levels so you'll get an error instead of just a warning).
Furthermore, linking fails, so you also do not link against a library that implements the function, which is expected: get_current_dir_name() is a GNU extension and not part of the C standard library.
On Windows, you need to use the equivalent functionality provided by the Windows API, ie GetCurrentDirectory(), declared in windows.h.
I am a little puzzled. I have project that I compile with
CFLAGS=-g -O2 -Wall -Wextra -Isrc/main -pthread -rdynamic -DNDEBUG $(OPTFLAGS) -D_FILE_OFFSET_BITS=64 -D_XOPEN_SOURCE=700
Now I want to use mkdtemp and therefor include unistd.h
char *path = mkdtemp(strdup("/tmp/test-XXXXXX"));
On MacOSX the compilation gives some warnings
warning: implicit declaration of function ‘mkdtemp’
warning: initialization makes pointer from integer without a cast
but compiles through. While mkdtemp does return a non-NULL path accessing it results in a EXC_BAD_ACCESS.
Question 1: The template is strdup()ed and the result is non-NULL. How on earth can this result in an EXC_BAD_ACCESS?
Now further down the rabbit hole. Let's get rid of the warnings. Checking unistd.h I find the declaration hidden by the pre processor.
#if !defined(_POSIX_C_SOURCE) || defined(_DARWIN_C_SOURCE)
...
char *mkdtemp(char *);
...
#endif
Adding -D_DARWIN_C_SOURCE to the build makes all the problems go away but leaves me with a platform specific build. The 10.6 man page just says
Standard C Library (libc, -lc)
#include <unistd.h>
Removing the _XOPEN_SOURCE from the build makes is work on OSX but then it fails to compile under Linux with
warning: ‘struct FTW’ declared inside parameter list
warning: its scope is only this definition or declaration, which is probably not what you want
In function ‘tmp_remove’:
warning: implicit declaration of function ‘nftw’
error: ‘FTW_DEPTH’ undeclared (first use in this function)
error: (Each undeclared identifier is reported only once
error: for each function it appears in.)
error: ‘FTW_PHYS’ undeclared (first use in this function)
Question 2: So how would you fix this?
The only fix I have found is to #undef _POSIX_C_SOURCE right before the unistd.h include ...but that feels like an ugly hack.
You've asked two questions here, and I'm just going to answer the first:
Question 1: The template is strdup()ed and the result is non-NULL. How on earth can this result in an EXC_BAD_ACCESS?
As the warnings above tell you:
warning: implicit declaration of function ‘mkdtemp’
This means it couldn't find the declaration for mkdtemp. By C rules, that's allowed, but it's assuming the function returns an int.
warning: initialization makes pointer from integer without a cast
You've told the compiler "I've got a function that returns int, and I want to store the value in a char*". It's warning you that this is a bad idea. You can still do it, and therefore it compiles.
But think about what happens at runtime. The actual code you link to returns a 64-bit char*. Then your code treats that as a 32-bit int that it has to cast to a 64-bit char*. How likely is that to work?
This is why you don't ignore warnings.
And now for the second question:
Question 2: So how would you fix this?
Your problem is that you're explicitly passing -D_XOPEN_SOURCE=700, but you're using a function, mkdtemp, that isn't defined in the standard you're demanding. That means your code shouldn't work. The fact that it does work on linux doesn't mean your code is correct or portable, just that you happened to get lucky on one platform.
So, there are two rather obvious ways to fix this:
If you want to use _XOPEN_SOURCE=700, rewrite your code to only use functions that are in that standard.
If you've only added _XOPEN_SOURCE=700 as a hack that you don't really understand because it seemed to fix some other problem on linux, find the right way to fix that problem on linux.
It may turn out that there's a bug on one platform or another so there just is no right way to fix it. Or, more likely, you're using a combination of non-standard functions that can be squeezed in on different platforms with a different set of flags on each. In that case, your Makefile (or whatever drives the build) will have to pass different flags to the compiler on different platforms. This is pretty typical for cross-platform projects; just be glad you only have one flag to worry about, and aren't building 3000 lines worth of autoconf.
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.