1
12
在我看来,你似乎正在加载一个精灵图像,然后试图直接跳入精灵头部? http://en.wikipedia.org/wiki/Executable_and_Linkable_Format 如果您试图执行另一个二进制文件,为什么不为您使用的任何平台使用流程创建函数呢? |
2
30
您需要具有写执行权限的页面。如果您使用的是unix,请参阅mmap(2)和mprotect(2)。你不应该使用malloc。 另外,请阅读其他人所说的,您只能使用加载程序运行原始机器代码。如果你试图运行一个ELF头,它可能仍然会出错。 关于回复和downmods的内容: 1-OP说他试图运行机器代码,所以我回答说,而不是执行一个可执行文件。
它在Linux x86_64上正好显示了这种行为,其他实现中肯定会出现其他丑陋的行为。 |
3
13
使用malloc很好。 好的,这是我的最终答案,请注意我使用了原始海报的代码。 我正在从磁盘加载此代码的编译版本到堆分配区域“bin”,就像原始代码一样(名称不使用argv固定,值0x674来自;
这可以在运行时使用BFD(二进制文件描述符库)或其他工具查找,您可以调用其他二进制文件(不仅仅是您自己),只要它们静态链接到同一组库。
你可以用 UPX 另外,很抱歉之前断开的链接:| |
4
4
第一种方法意味着您通常不能期望文件的字节0是可执行的;在intead中,标题中的信息描述了如何在内存中加载文件的其余部分以及从何处开始执行它。
第二种方法是,当您找到入口点时,您不能期望将其视为一个接受参数的C函数
在一个给定的操作系统下手工操作会深入到我无法理解的深度;但我相信有一种更好的方式来做你想做的事。您是试图将外部文件作为开关操作执行,还是加载外部二进制文件并将其功能作为程序的一部分?Unix中的C库可以满足这两种需求。 |
5
3
更有可能是调用通过函数指针跳转到的代码导致了segfault,而不是调用本身。您发布的代码无法确定加载到bin中的代码是否有效。最好的方法是使用调试器,切换到汇编程序视图,中断返回语句,然后 踏入 函数调用,以确定您希望运行的代码确实正在运行,并且它是有效的。 还要注意的是,为了运行在所有的代码将需要 位置独立 此外,如果您的处理器/操作系统启用了数据执行预防,那么这种尝试很可能是注定要失败的。在任何情况下,这充其量都是不明智的,加载代码是操作系统的目的。 |
6
2
你试图做的事情与口译员的工作类似。除此之外,解释器读取用Python等解释语言编写的程序,动态编译代码,将可执行代码放入内存,然后执行它。 您可能还想阅读更多有关即时编译的内容:
Just in time compilation
有一些库可用于JIT代码生成,例如 GNU lightning 和 libJIT
为了执行代码,您必须使用一些技术,例如使用mmap()将可执行代码映射到进程的地址空间,将该页标记为可执行并跳转到该内存段。这比这更复杂,但为了理解Python、Ruby等脚本语言的解释器下面发生的事情,这是一个很好的开始。 这个 online version “本书的主题” Linkers and Loaders “将为您提供有关对象文件格式、执行程序时幕后发生的情况、链接器和加载器的角色等更多信息。这本书读得很好。 |
7
1
您可以dlopen()打开一个文件,查找符号“main”,并通过转换为pointer-to-function-returning-int-taking-0,1,2或3 char使用0、1、2或3个参数(所有类型均为char*)调用它* |
8
1
在unix上 exec 电话可以做到这一点。 您的问题片段可以重写:
|
9
0
可执行文件不仅仅包含代码。头、代码、数据、更多数据,这些内容由操作系统及其库分离并加载到内存的不同区域。您不能将程序文件加载到单个内存块中,并期望跳转到它的第一个字节。
|
Jiji · 将简单对象强制转换为简单的通用接口 6 年前 |
tobeypeters · 反射铸造 6 年前 |
Alex · 是否改为存储字符串的整数的通用ArrayList? 6 年前 |
Kai · 如何在C#中转换会话中存储的词典? 6 年前 |
Ján ЯabÄan · 布尔值到双精度的快速转换方法 6 年前 |