从elf文件中的地址执行函数

时间:2014-10-30 07:39:36

标签: linux elf

我有一个简单的c文件,它在main中打印一条消息而不执行任何其他操作 使用gcc编译它来生成.out文件。使用elf解析器获取entry_address 启动函数和使用此addressas函数指针我试图执行c文件中的main函数,但它给出了seg错误。

e.g

test.c
void main()
{
  print("something");
}

通过gcc生成的test.out elf文件

我通过nm test.out

得到以下内容
0000000000601020 A _edata
0000000000601030 A _end
00000000004005e8 T _fini
00000000004003c8 T _init
0000000000400410 T _start
000000000040043c t call_gmon_start
0000000000601020 b completed.6531
0000000000601010 W data_start
0000000000601028 b dtor_idx.6533
00000000004004d0 t frame_dummy
00000000004004f4 T main

起始地址为0x0400410 T _start。 现在我写下面的另一个c代码来执行test.c中的main函数。

execute.c
void main()
{

   typedef int func(void); 
   f = (func*)0x00400410;
   f();
 }

gcc execute.c -o execute.out编译excute.c会在调用f()时给出分段错误。

所需的输出是打印something

是否可以从地址执行elf文件功能,我错了。

1 个答案:

答案 0 :(得分:1)

您的问题表明了一些基本的错误理解。让我们一个接一个。

首先,正如hcs指出的那样,test.outexecute.out彼此之间没有没有。当一个正在运行时,另一个加载到您的进程空间。你期望能够从test.out execute.out调用一个函数与我右前裤口袋中的钱数(就像你在那里找到一个25c硬币)一样,然后伸入你自己的右前裤口袋里,并希望在那里找到相同的25c硬币。

与此相关,你也期望甚至拥有合适的裤子口袋,因为我有一个(希望在_start 0x00400410找到execute.out仅因为_start }在test.out)的那个地址。实际上,您可能会在同一地址找到_start,或者您可能找不到。也许你今天穿着短裙,而且根本没有前右裤袋。

最后,考虑一下程序的执行情况。谁叫你main例程? (那是对的,_start确实如此)。现在,您已安排main再次致电_start。你有什么期望呢?它会再次调用main。这将再次呼叫_start。这称为无限递归,并且会导致二进制文件因堆栈耗尽而崩溃。

注意:崩溃的实际原因是不同的,并且与_start在同一进程中不期望被调用两次的事实有关。