用戶態進程在堆棧執行代碼時,因爲內核在加載該進程的時候,取消了在堆棧上執行代碼的權限,因此如果在其上執行代碼的話,進程會直接死掉。
接下來是在堆棧執行代碼的測試例子,主要思路是給物理內存加上可執行代碼的權限。代碼如下:
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<unistd.h>
#include<sys/mman.h>
#include<sys/types.h>
#include<sys/stat.h>
#include<fcntl.h>
typedef int (*func)(unsigned int);
int hello(unsigned int start)
{
return 0x61;
}
int main(void)
{
unsigned int len = 0;
unsigned char *q = NULL;
unsigned char *p = NULL;
int i = 0;
func qq = NULL;
FILE *f;
int n, fd;
fd = open("/dev/mem", O_RDWR|O_EXCL|O_SYNC);
if(fd == -1){
printf("open /dev/mem failed!\n");
return -1;
}
/*通過mmap設置其用可執行權限(PROT_EXEC)*/
q = mmap(NULL, 0xff, PROT_READ|PROT_WRITE|PROT_EXEC, MAP_SHARED, fd, 0x20000);
if(q == 0){
printf("mmap failed!\n");
}
p = (unsigned char *)hello;
/*拷貝代碼*/
for(i = 0;p[i]!=0xc3;i++){
q[i] = p[i];
printf( "hello:%p:\t%02x\t\n",p+i,p[i]);
printf( "q :%p:\t%02x\t\n",q+i,q[i]);
}
q[i] = p[i];
printf( "hello:%p:\t%02x\t\n",p+i,p[i]);
printf( "q :%p:\t%02x\t\n",q+i,q[i]);
printf( "len = 0x%x before hack\n",len);
qq = (func)q;
/*執行*/
len = qq(0);
printf( "len = 0x%x after hack\n",len);
close(fd);
munmap(q, 0xff);
return 0;
}
結果如下:
可見,成功執行了該代碼。