关于在Linux的堆栈段执行代码的实践和思考
2015-09-16 17:29
555 查看
在内核态是可以执行的,具体代码如下:
具体平台信息为:
Linux ubuntu 2.6.32-38-generic #85-Ubuntu SMP Wed Jan 25 13:59:45 UTC 2012 i686 GNU/Linux
编译加载模块并运行,得到结果如下:
![](https://oscdn.geek-share.com/Uploads/Images/Content/201908/31/692c2d37a0d6ac49f1e6f2c43b307da1)
可以看到,hello函数确实运行了(因为len的值确实被改变了)。
在用户态测试运行,代码如下:
编译运行结果如下:
![](https://oscdn.geek-share.com/Uploads/Images/Content/201908/31/1d1f49543a92c81b2a9e8e0746970e5f)
可见发生了段错误,查看一下内核log,可知发生了一般性保护异常(包含用来限制用户态的程序不能在堆栈运行代码的保护机制):
具体平台信息为:
Linux ubuntu 2.6.32-38-generic #85-Ubuntu SMP Wed Jan 25 13:59:45 UTC 2012 i686 GNU/Linux
#include <linux/init.h> #include <linux/kernel.h> #include <linux/module.h> #include <linux/miscdevice.h> #include <linux/mutex.h> #include <linux/compiler.h> #include <linux/fs.h> #include <linux/sched.h> #include <linux/uaccess.h> #include <linux/gfp.h> MODULE_LICENSE("GPL"); MODULE_AUTHOR("Linmiaohe"); MODULE_DESCRIPTION("try to run func in privata kmalloc area"); typedef int (*func)(unsigned int); int hello(unsigned int start) { return 0x61; } static int __init func_init(void) { unsigned int len = 0; unsigned char *q = NULL; unsigned char *p = NULL; int i = 0; func qq = NULL; p = (unsigned char *)hello; q = kmalloc(0x64,GFP_KERNEL); /*0xc3 -->i686平台的ret指令的机器码*/ for(i = 0;p[i]!=0xc3;i++){ q[i] = p[i]; //printk(KERN_INFO "hello:%p:\t%02x\t",p+i,p[i]); //printk(KERN_INFO "q:%p:\t%02x\t",q+i,q[i]); } q[i] = p[i]; //printk(KERN_INFO "hello:%p:\t%02x\t",p+i,p[i]); //printk(KERN_INFO "q:%p:\t%02x\t",q+i,q[i]); printk(KERN_INFO "len = 0x%x before hack\n",len); //printk(KERN_INFO "i = %d\n",i); qq = (func)q; len = qq(0); printk(KERN_INFO "len = 0x%x after hack\n",len); printk(KERN_INFO "***********func module has been registered*************\n"); return 0; } static void __exit func_exit(void) { printk(KERN_INFO "***********func module has been unregistered*************\n"); } module_init(func_init); module_exit(func_exit);
编译加载模块并运行,得到结果如下:
可以看到,hello函数确实运行了(因为len的值确实被改变了)。
在用户态测试运行,代码如下:
#include<stdio.h> #include<stdlib.h> #include<string.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; hello(0); p = (unsigned char *)hello; q = malloc(0x64); 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); //printf( "i = %d\n",i); qq = (func)q; len = qq(0); printf( "len = 0x%x after hack\n",len); return 0; }
编译运行结果如下:
可见发生了段错误,查看一下内核log,可知发生了一般性保护异常(包含用来限制用户态的程序不能在堆栈运行代码的保护机制):
相关文章推荐
- Linux命令大全
- Linux最基础(第一篇)——用户权限
- Linux系统平均负载3个数字的含义
- CentOS NTP服务器
- linux sort 命令详解
- maven 安装配置
- VMware Workstation 7.x 安装CentOS 5.6
- Centos中压缩(zip)和解压(unzip)命令
- linux线程6(CSDN论坛上很火的一个讨论贴)
- 利用ConfigParser读取配置文件
- 【转】Linux逻辑卷管理
- 学习Linux第三天
- centos 文本搜索
- Linux 下重新挂载分区方法
- linux c 及 c++打印调用者函数caller function的方法,包括arm c平台
- CentOS里上传下载查看命令
- Linux Ubuntu 上快速安装 Ruby 2.2
- Linux下破解密码
- centos 普通用户添加sudo 权限
- linux命令——scp远程复制文件或目录