问题
I am working on this c program. I am compiling it with gcc on a 64 bits x64 linux:
#include <stdio.h>
char buffer[]={0x90,0x90,0xC3};
int main(int argc, char *argv[])
{
void (*fct)();
fct=buffer;
fct();
return 0;
}
0x90 opcode is NOP
0xC3 opcode is RET
I want to know what i should do in order to run this program. I get a segfault when running it...
Thanks
回答1:
TL;DR Compile with -z execstack
to enable Linux's read-implies-exec feature for your executable. Despite the name, it applies to all pages, not just the stack.
The program is faulting because the buffer
symbol goes into the .data
section that in turns goes, along with other sections, into an ELF segment mapped Read-write but not executable.
To make the buffer
executable the best course of action would be to make a new ELF segment with flags RWE and assign it a new section, then tell GCC to put buffer
in this new section.
This could be done, in principle with the following linker script:
PHDRS
{
MYSEG PT_LOAD FLAGS (7);
}
SECTIONS
{
MYSECT : { *(MYSECT) } : MYSEG
}
, changing the source:
#include <stdio.h>
char buffer[] __attribute__ ((section ("MYSECT"))) ={0x90,0x90,0xC3};
int main(int argc, char *argv[])
{
void (*fct)();
fct=buffer;
fct();
return 0;
}
and the compiling passing the -T
switch to GCC.
But this won't work.
GCC uses a default linker script based on the command line and the -T
switch replace it entirely.
It's possible to get the script used by GCC with -Wl,-verbose
and update it.
If we split the compilation and the linking by first invoking GCC with -c
and then LD, we'd get only one segment because that's what we put in the linker script - thereby defeating all our efforts to make only buffer
the only executable data.
With -z execstack
we actually only tell GCC to use a linker script that sets the GNU_STACK
ELF segment RWE.
This is a marker segment (size and lma are zero) used by the loader to setup the correct permissions for the stack pages.
But in truth it is used as a compatibility switch - when the stack is set as executable the loader will set all the writable pages as executable.
If you are playing with shellcodes -z execstack
will make it easy, however it exposes your application to a boatload of attacks, but I guess this is what you needed in the first place.
来源:https://stackoverflow.com/questions/52342991/running-data-shellcode-in-c-executable