Void pointer and attributer constructor in a vulnerable code - c

I am supposed to find the vulnerability in the code and i feel its hidden either in the __attribute__((constructor)) or the pointer .Here i can make out that it's a void pointer but i have never encountered a pointer with () (wasnt able to find out either) so what type of a pointer is this and is the (void(*)()) in (void(*)())&name for type casting or something else?Also is does the attribute constructor here play any role it feels like an empty default constructor
#include <stdio.h>
#include <string.h>
//Ignore this thing
__attribute__((constructor))
void setup(){
setvbuf(stdout,NULL,2,0);
setvbuf(stderr,NULL,2,0);
setvbuf(stdin,NULL,2,0);
}
int main()
{
printf("What's you name?\n");
char name[100];
fgets(name,100,stdin);
void(*Kekpointer)() = (void(*)())&name;
Kekpointer();
return 0;
}
i tried analyzing these functions so i came to the conclusion that pointer , the fgets function or the attribute constructor but i am not able to proceed further . i also got this hint " for challenge , your goal is to get a shell. Flag is stored on the remote server. Read the source code carefully and try to find out the vulnerability. This is a beginner level challenge !". but it didnt guide me anywhere. I am expecting more info on the pointer expecially

On any modern hosted system this code is 100% safe. Memory allocated for name will not have executable attributes and any attempt to execute code from there will end in an exception.
You need to make this memory executable:
int main()
{
char name[100];
size_t pagesize = getpagesize();
mprotect(name, pagesize,PROT_EXEC);
printf("What's you name?\n");
fgets(name,100,stdin);
void(*Kekpointer)() = (void(*)())&name;
Kekpointer();
return 0;
}

Re: what type of a pointer is this and is the "(void()())" in "(void()())&name" for type casting or something else?```:
The left-hand side:
void(*Kekpointer)()
----> kekpointer is a pointer to a function taking no parameters and returning void (returning nothing).
The right-hand side:
(void(*)())&name
----> the & is the address-of operator. The typecast stands for a pointer to a function taking no parameters and returning void. So the address-of name has been type-casted to a pointer to a function taking no parameters and returning void (returning nothing), which matches the left-hand side.
The expression type-casts the name buffer to a function pointer, and then initialises the left-hand side with its address.

Related

Typecasting void double pointer to void, why? [duplicate]

This question already has answers here:
What does casting to `void` really do? [duplicate]
(4 answers)
Closed 3 years ago.
The code I'm working on has a function which has a double pointer of type void, in the function pointer the double pointer is typecasted to void, and the pointer is not used anywhere else. I cant find any where why this is done. someone please shed some light.
static void kbd_callback(const char *name, int name_len,
const char *instruction, int instruction_len,
int num_prompts,
const LIBSSH2_USERAUTH_KBDINT_PROMPT *prompts,
LIBSSH2_USERAUTH_KBDINT_RESPONSE *responses,
void **abstract /* <-- This */)
{
int i;
size_t n;
char buf[1024];
(void)abstract; // <---- and this
...
}
The type of the callback is probably part of the API of a LIBSSH2 library. The library passes every parameter to the callback that it expects the callback will need. Whatever that parameter is, this particular callback doesn't need it. The programmer has four choices:
He can leave out the name of the parameter in the prototype, replacing void **abstract with void **. This makes it so that someone trying to understand his code has to look at the LIBSSH2 API to understand what the last parameter is.
He can just not use the parameter. But this will get him a warning from his compiler.
He can use the parameter in a way that has no consequence to hide the warning.
He could comment out the parameter name, like this: void ** /*abstract*/.
This programmer choose option 3.
Personally, I tend to prefer option 4 for this case. I'd also prefer to see something like this:
#define OK_UNUSED(a) if (false && (a)); else (void) 0
...
OK_UNUSED(abstract);
This makes it very clear that it's okay that the parameter is unused.
It's a double pointer meaning it is a pointer to a pointer. Being of type void it can hold any type. So i'm assuming it will be used to hold a pointer, in this case i'm assuming the developer does not know what type of pointer it will be passed or it holds different types already declared and initialized in the program.

Confused on "pass by reference" in C and when to use an & or *

I'm not as knowledgeable in C as I thought I was, but can anyone explain to me what I'm doing wrong here ? I am writing a program for an embedded system using a Texas Instruments microcontroller using UARTS (an asynchronous receiver transmitter on the microcontroller). UART libraries are usually included when I'm building a project.
Anyway, here is my issue: I have 4 functions that just prints a string to the console and my code compiles, but it gives me warnings and not compilation errors.
void foward(unsigned char *command) {
UARTPutString(UART_BASE, &command);
}
void reverse(unsigned char *command) {
UARTPutString(UART_BASE, &command);
}
void left(unsigned char *command) {
UARTPutString(UART_BASE, &command);
}
void right(unsigned char *command) {
UARTPutString(UART_BASE, &command);
}
My issue mainly lines with when to use a pointer in the simplest sense. The reason why I used a pointer for char* command is because the imported library was written like that, but I have no idea why we have to use a char pointer. And what do you put as the second argument in:
UARTPutString(UART_BASE, &command);
When do I use &, or * ? I know pointers point to the memory address of something, but it's not clicking to me on when I need to use *, &, and so forth when using it as parameters for a function.
This warning is mentioned 21 times for some reason:
Description Resource Path Location Type
#169-D argument of type "unsigned char **" is incompatible with parameter of type "unsigned char *" uartconsole.c /Command_Line_Interface line 82 C/C++ Problem
Thank for the help !
The 2nd argument to UARTPutString() is supposed to be a string, which is a char * value -- a string is a pointer to a sequence of characters.
command is declared to be char *, so you should just pass that directly. Adding & creates a pointer to a pointer, which is char **, and incompatible with char *.
UARTPutString(UART_BASE, command);
You use & before a variable when you need to pass the variable by reference. This is usually done if the function needs to modify the variable's value. It may also be used for large structure variables, to avoid making a copy of the variable when passing it to the function.
You need to write:
UARTPutString(UART_BASE, command);
Your command is a pointer (i.e., a variable holding an address) to a character array.
When writing &command you take the address of command. The type of the &command expression is therefore the address of a pointer unsigned char **, which is what the compiler is complaining about.
So that warning is telling you the compiler is expecting just unsigned char * as the second argument of UARTPutString(), which is the type of command.
What is confusing about * in C is that its 'meaning' depends on the place where it's used. In a variable declaration it says that the variable is a pointer. While used in an expression, for example if you would write *command = 0;, it dereferences the pointer; the opposite of when * is used in a declaration.
There's a lot more to say about this and I suggest you read relevant sections of the C-FAQ.
Good luck. C is a very nice language and worth putting the effort in.

Why function call only pass the first argument

I'm trying to call a function (on line 15) just via a cast but only the first argument is getting passed, how could I fix it?
I tried to change the float value "2" to 2.0f to declare it's a float and not an int but it's still not working.
!Note that the code is horrible because it's a code golf, the line 15 has to be in a dll form later, this code here is just a test program to avoid launching the target process multiples times. Here's my actual code with a score of 58 chars
DllMain(a,b,c){((int(*)(int,float))927309216)(‭7903472‬,2);}
#include <Windows.h>
#include <stdio.h>
char * sSkelModelStencil = "SkelModelStencil"; //here I reproduce the char like it is in the memory
void SetConsoleFloat(const char *sKey, float fVal) //this is the reproduction of SetConsoleFloat in CShell.dll
{
printf("arg1: %s arg2: %f\n", sKey, fVal); //printing the arguments getting passed into the function
return;
}
int main()
{
while (1) {
SetConsoleFloat("SkelModelStencil", 2); //calling the reproduction function
((int(*)())SetConsoleFloat)(sSkelModelStencil,2); //calling the reproduction function via a cast & using SetConsoleFloat addr
system("PAUSE");
}
}
In some architectures, the way arguments are passed depends on the way they're declared. For instance, special registers may be used for float parameters. It's the declaration of the function type that matters, not the declaration of the argument expression.
The parameter signature () is different from (const char *sKey, float fVal), and as a result the fVal argument is being passed differently from the way the function expects to receive it.
First of all - this is atrocious code, don't do that.
Secondly - compile your code with compiler warnings on, so the compiler can tell you where you might be going wrong. Of course, you need a proper C compiler (which MSVC is not, in case you were using that). gcc will tell you:
a.c:15:10: warning: function called through a non-compatible type
But, to answer your question: You're casting into the wrong type of function: You're using the function type void (); but you need void (const char*, float). So, try:
((void(*)(const char*, float))SetConsoleFloat)(sSkelModelStencil,2);
instead of your existing line 15. It's also a good idea to separate casts from type definitions of functions - for clarity - so you would have:
typedef void (*scf_function_t)(const char*, float);
earlier, and then:
((scf_function_t) SetConsoleFloat)(sSkelModelStencil,2);
but again - there's really no good reason to do any of this in the first place.

How to declare function return type `int (*)[3]`?

int (*)[3] foo (); doesn't work.
How to declare function return pointer to array of 3?
It might not be useful, but I want to know if it's possible.
First, I agree with the other answers that you probably need a typedef or a struct in there to clarify.
If you want to know how to declare the return type, it's
int (*foo(void))[3] {
In the "declaration reflects use" pattern, you can build this up by considering the usage, i.e. how to get from foo's type to the plain type int:
take foo
call it (with no arguments): foo()
dereference the return value: *foo()
add an array index: (*foo())[i]; the parentheses are needed because the postfix syntax would otherwise take precedence over prefix one.
the result is of plain type int
Declaration reflects it:
take foo
call it: foo(void), inserting void to say it's specifically a 0-param function rather than one with an unspecified set of parameters
dereference the function return value: *foo(void)
add an array index: (*foo(void))[3], making the "index" be the size of the array
we got down to the plain type, so declare that the thing you built has that type: int (*foo(void))[3]
Example code:
#include <stdio.h>
int arr[3];
int (*foo(void))[3] {
return &arr;
}
int main (void) {
arr[0] = 413;
arr[1] = 612;
arr[2] = 1025;
printf("%d %d %d\n", (*(foo()))[0], (*(foo()))[1], (*(foo()))[2]);
return 0;
}
Side note: be sure that the array you are returning a pointer to will continue to exist after the function returns.
I'd advise against doing this.
It's often done as a poor workaround for the apparent limitation that C has of not being able to have an array as a return value.
Too often, a dangling pointer will be returned since the programmer will return a pointer to an array in the function that has automatic storage duration. Then this gets hacked to a static which ruins the threading model and breaks all previous returned pointers!
Only slightly better is returning a pointer given to you by a malloc call internal to the function. But then, that burdens (asymmetrically) the caller with having to call free at some point. Eventually your function winds up in some kind of precompiled library which uses a different C runtime to a client. Your malloc and their free no longer match, and you end up with a truck load of undefined behaviour!
Instead of all this, do consider passing the array by pointer on the function parameter list, preferably pre-allocating the memory.
One way is:
typedef int Int_array_3[3];
Int_array_3 * foo(void);
As a rule of thumb, avoid functions passing/returning raw array pointers or function pointers, because such code is a nightmare both to program and read. In this case it would have been
int (*func()) [3]
which is completely unreadable. Just forget about writing such code. Instead, use a typedef to define an array type:
typedef int iarr3_t [3];
And then write a function returning a pointer to such an array:
iarr3_t* func (void);
However, as indicated by other comments and answers, returning an array pointer is usually quite questionable practice to begin with. The need to do so could be an indication of poor program design.

void type variables in c storage

What are void type variable in C?
I have rough idea but not sure how i can use them for below scenario.
server/ client program
I have a struct array which contains hostname, address in server. I want to send it to the client over the socket. How i can achieve it?
struct ipinfo{
char hostname[64];
char address[64];
}
struct ipinfo allip[5];
I read some where that i can copy into specific memory location as void type variable and them send the variable? Can any one please explain this concept? I really appreciate it.
In C the only time void can be used as a variable type is if it's a pointer. They are handy for when you aren't sure what type of data you have coming.
void * somePointer;
This can be used for various things.
Referencing an object without knowing the type.
Handling plain memory without a type. Malloc (and I believe new in C++) returns a void pointer as at the moment the memory is without a type.
Try not to use void pointers though, they are generally a good idea to stay away from. Likely to cause errors and headaches. You can often times find a better solution.
The void keyword can also be used in front a function.
void printHello(void)
{
printf("Hello");
}
In this function we use void because it's not returning anything. Void functions can simply do whatever task we assign them without returning anything. We also don't need to pass any data into the function, so we specify void in the parameters.
Note: If you're ever learning C++, there's something you really need to keep in mind about function parameters.
void printHello() // <- This is bad in C, it will take any number of anything practically
{
printf("Hello");
}
Always put void in the parameters if you want no arguments passed in for C.
void printHello() // <- Good in C++, it won't allow any arguments on a call
{
std::cout << "Hello";
}
You cannot however use void as a variable type as in
void a = 0;
void b = 's';
void c = 5.5
// You can't use void to store anything
I don't think void means what you hope it means. void is used in C-like languages to indicate an unknown type, or no type. For example, void* is a void pointer. It's a memory address that has some data at it, but the format of the data (and even its size) is not specified. In order to use that data you need to assign some type to it, usually through an assignment or and explicit or implicit cast.
Here's an example:
void * memory = malloc(16);
memory[0] = 0; // this won't compile!
int * int_array = memory;
int_array[0] = 0; // this is ok because we know the type
void is also used to indicate that a function doesn't have a return value.
Here's an example:
void exit(int status);
void can also be used as an indication that you're intentionally discarding the return value of a function call. This can improve the readability of your program, or suppress some compiler diagnostics.
Here's an example:
(void)memset(memory, 0, 16); // why does memset have a return value??
Another use of void is to indicate an empty parameter list. In C, a function declared like main() has an unspecified parameter list, not an empty list.
Here's an example:
int main(void) {
...
}
I'm afraid that none of these application are likely to help you solve your socket problem.
void pointers are mainly used in function argument when you expect that argument to be of any type because you can cast any type to void then back to any type without loss of data , the only thing you can't do with a void pointer is to dereference it.

Resources