热门标签 | HotTags
当前位置:  开发笔记 > 前端 > 正文

如何在C中将内存段标记为可执行文件?

如何解决《如何在C中将内存段标记为可执行文件?》经验,为你挑选了1个好方法。

我最近正在研究一些JIT编译器。据我所知,JIT是一种将一些脚本语言代码即时编译为本地代码的技术(在执行之前)。正如我想象的那样,这种编译器的内部结构使我发现,必须在生成的本机代码所在的位置上放置一段动态分配的缓冲区。但是然后我们需要一种方法来从保存数据的缓冲区内开始运行代码。我的意思是,char[]由于安全隐患,操作系统不能阻止您这样做,因此您不能只是将一些代码放入a 然后跳入执行。必须有某种方法将缓冲区标记为可执行文件。考虑以下天真的方法:

#include 

void *jit_some_native_code(void) {
  void *code_segment = malloc(1024);
  /*
   * bla bla bla...
   * Generate code into this code_segment.
   */

  return code_segment;
}

int main(void) {
  void *code = jit_some_native_code();
  /*
   * How can I start executing instruction in code?
   */

  typedef void (*func_ptr_t)(void);

  /*
   * This won't work. OS bans you doing so.
   */
  ((func_ptr_t)code)();

}

在Ubuntu上,该代码将运行,但会以状态代码26退出。鉴于C的类型不安全特性,该代码可以编译,但对于C ++,编译器只会使您停止。这是否意味着JIT必须绕过编译器以及设置可执行标志?

编辑:此外mprotect,如果使用mmap,还可以指定页面映射权限:

   PROT_EXEC  Pages may be executed.
   PROT_READ  Pages may be read.
   PROT_WRITE Pages may be written.
   PROT_NONE  Pages may not be accessed.

这样,页面将具有可执行权限。



1> Nina..:

如果要使堆中的区域成为可执行文件,则可以使用mprotect。

int main() {
  typedef void (*func_t)(void);
  void *code = &some_jit_func;
  int pagesize = getpagesize();
  mprotect(code, pagesize,PROT_EXEC);
  ((func_t)code)();
}

您还可以使用PROT_READ / PROT_WRITE对标志进行OR


@ryyker号。正如其[手册](https://pubs.opengroup.org/onlinepubs/9699919799/functions/mprotect.html)中明确提到的那样,`mprotect` _changes_一页内存的访问权限。除此之外,大多数操作系统将拒绝执行可执行和可写的页面。
推荐阅读
  • TortoiseSVN与VisualSVN Server的安装及基本操作指南
    本文详细介绍了如何安装VisualSVN Server以及TortoiseSVN客户端,并提供了基本的操作步骤,包括配置仓库、用户管理及权限设置等关键环节。 ... [详细]
  • Barbican 是 OpenStack 社区的核心项目之一,旨在为各种环境下的云服务提供全面的密钥管理解决方案。 ... [详细]
  • 在Windows Server 2008 R2上配置IIS FTP服务
    本文详细介绍了如何在Windows Server 2008 R2操作系统上通过IIS配置FTP服务的过程,包括服务器角色的选择与安装、FTP站点的创建以及必要的服务和防火墙设置检查。 ... [详细]
  • 微信小程序中实现位置获取的全面指南
    本文详细介绍了如何在微信小程序中实现地理位置的获取,包括通过微信官方API和腾讯地图API两种方式。文中不仅涵盖了必要的准备工作,如申请开发者密钥、下载并配置SDK等,还提供了处理用户授权及位置信息获取的具体代码示例。 ... [详细]
  • 本文探讨了Web开发与游戏开发之间的主要区别,旨在帮助开发者更好地理解两种开发领域的特性和需求。文章基于作者的实际经验和网络资料整理而成。 ... [详细]
  • 在安装Ubuntu 12.10并尝试安装VMware Tools时,遇到了一个常见的错误提示:指定的路径不是有效的3.5.0-17-generic内核头文件路径。本文将提供解决这一问题的具体步骤。 ... [详细]
  • 如何从python读取sql[mysql基础教程]
    从python读取sql的方法:1、利用python内置的open函数读入sql文件;2、利用第三方库pymysql中的connect函数连接mysql服务器;3、利用第三方库pa ... [详细]
  • 深入解析:OpenShift Origin环境下的Kubernetes Spark Operator
    本文探讨了如何在OpenShift Origin平台上利用Kubernetes Spark Operator来管理和部署Apache Spark集群与应用。作为Radanalytics.io项目的一部分,这一开源工具为大数据处理提供了强大的支持。 ... [详细]
  • ML学习笔记20210824分类算法模型选择与调优
    3.模型选择和调优3.1交叉验证定义目的为了让模型得精度更加可信3.2超参数搜索GridSearch对K值进行选择。k[1,2,3,4,5,6]循环遍历搜索。API参数1& ... [详细]
  • 理解文档对象模型(DOM)
    本文介绍了文档对象模型(DOM)的基本概念,包括其作为HTML文档的节点树结构,以及如何通过JavaScript操作DOM来实现网页的动态交互。 ... [详细]
  • 本文详细介绍了JSP(Java Server Pages)的九大内置对象及其功能,探讨了JSP与Servlet之间的关系及差异,并提供了实际编码示例。此外,还讨论了网页开发中常见的编码转换问题以及JSP的两种页面跳转方式。 ... [详细]
  • 深入解析8086 CPU的转移指令
    本文详细介绍了8086 CPU中的转移指令,包括无条件转移、条件转移、循环指令及过程调用等,同时探讨了offset操作符的功能及其应用实例。 ... [详细]
  • 前端开发中的代码注释实践与规范
    本文探讨了前端开发过程中代码注释的重要性,不仅有助于个人清晰地回顾自己的编程思路,还能促进团队成员之间的有效沟通。文章将详细介绍HTML、CSS及JavaScript中的注释使用方法,并提出一套实用的注释规范。 ... [详细]
  • iTOP4412开发板QtE5.7源码编译指南
    本文详细介绍了如何在iTOP4412开发板上编译QtE5.7源码,包括所需文件的位置、编译器设置、触摸库编译以及QtE5.7的完整编译流程。 ... [详细]
  • 在树莓派Ubuntu(ARM64)上安装Node.js
    本文详细介绍了如何在树莓派Ubuntu系统(ARM64架构)上安装Node.js,包括下载、解压、移动文件以及创建软链接等步骤。 ... [详细]
author-avatar
杨斜2602934873
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有