__libc_start_main @ plt如何工作? [英] how __libc_start_main@plt works?

查看:108
本文介绍了__libc_start_main @ plt如何工作?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

要研究目标文件如何在linux中加载和运行,我制作了最简单的c代码,文件名为simple.c.

To study how the object file loaded and run in linux, I made the simplest c code, file name simple.c.

int main(){}

接下来,我制作目标文件并将目标文件另存为文本文件.

Next, I make object file and save object file as text file.

$gcc ./simple.c 
$objdump -xD ./a.out > simple.text

从许多互联网文章中,我可以发现gcc动态加载了诸如_start,_init,__ libc_start_main @ plt等启动函数.因此,在 http://dbp-consulting.com/的帮助下,我开始阅读我的汇编代码. tutorials/debugging/linuxProgramStartup.html .

From many internet articles, I could catch that gcc dynamically load initiating functions like _start, _init, __libc_start_main@plt, and so on. So I started to read my assembly code, helped by http://dbp-consulting.com/tutorials/debugging/linuxProgramStartup.html .

这是汇编代码的一部分.

Here is the some part of assembly code.

080482e0 <__libc_start_main@plt>:
 80482e0:       ff 25 10 a0 04 08       jmp    *0x804a010
 80482e6:       68 08 00 00 00          push   $0x8
 80482eb:       e9 d0 ff ff ff          jmp    80482c0 <_init+0x2c>

Disassembly of section .text:

080482f0 <_start>:
 80482f0:       31 ed                   xor    %ebp,%ebp
 80482f2:       5e                      pop    %esi
 80482f3:       89 e1                   mov    %esp,%ecx
 80482f5:       83 e4 f0                and    $0xfffffff0,%esp
 80482f8:       50                      push   %eax
 80482f9:       54                      push   %esp
 80482fa:       52                      push   %edx
 80482fb:       68 70 84 04 08          push   $0x8048470
 8048300:       68 00 84 04 08          push   $0x8048400
 8048305:       51                      push   %ecx
 8048306:       56                      push   %esi
 8048307:       68 ed 83 04 08          push   $0x80483ed
 804830c:       e8 cf ff ff ff          call   80482e0 <__libc_start_main@plt>
 8048311:       f4                      hlt
 8048312:       66 90                   xchg   %ax,%ax
 8048314:       66 90                   xchg   %ax,%ax
 8048316:       66 90                   xchg   %ax,%ax
 8048318:       66 90                   xchg   %ax,%ax
 804831a:       66 90                   xchg   %ax,%ax
 804831c:       66 90                   xchg   %ax,%ax
 804831e:       66 90                   xchg   %ax,%ax

080483ed <main>:
 80483ed:       55                      push   %ebp
 80483ee:       89 e5                   mov    %esp,%ebp
 80483f0:       b8 00 00 00 00          mov    $0x0,%eax
 80483f5:       5d                      pop    %ebp
 80483f6:       c3                      ret
 80483f7:       66 90                   xchg   %ax,%ax
 80483f9:       66 90                   xchg   %ax,%ax
 80483fb:       66 90                   xchg   %ax,%ax
 80483fd:       66 90                   xchg   %ax,%ax
 80483ff:       90                      nop



 ...

Disassembly of section .got:

08049ffc <.got>:
 8049ffc:       00 00                   add    %al,(%eax)
        ...

Disassembly of section .got.plt:

0804a000 <_GLOBAL_OFFSET_TABLE_>:
 804a000:       14 9f                   adc    $0x9f,%al
 804a002:       04 08                   add    $0x8,%al
        ...
 804a00c:       d6                      (bad)
 804a00d:       82                      (bad)
 804a00e:       04 08                   add    $0x8,%al
 804a010:       e6 82                   out    %al,$0x82
 804a012:       04 08                   add    $0x8,%al

我的问题是

在0x804830c中,称为0x80482e0(我已经理解了前面的指令.).

In 0x804830c, 0x80482e0 is called (I've already apprehended the previous instructions.).

在0x80482e0中,进程跳至0x804a010.

In 0x80482e0, the process jump to 0x804a010.

在0x804a010中,指令为< out%al,$ 0x82>

In 0x804a010, the instruction is < out %al,$0x82 >

...等等.刚出去? %al中有什么,0x82在哪里?我陷入了这一行.

...wait. just out? What was in the %al and where is 0x82?? I got stuck in this line.

请帮助....

* p.s.我是Linux和操作系统的初学者.我正在按学校班级学习操作系统概念,但仍然找不到如何学习正确的Linux汇编语言的方法.我已经下载了英特尔处理器手册,但是它太大了,无法阅读.谁能告诉我关于我的好材料?谢谢.

*p.s. I'm beginner to linux and operating system. I'm studying operating system concepts by school class, but still can not find how to study proper linux assembly language. I've already downloaded intel processor manual but it is too huge to read. Can anyone inform me good material for me? Thanks.

推荐答案

80482e0:       ff 25 10 a0 04 08       jmp    *0x804a010

这意味着检索存储在0x804a010的4字节地址并跳转到该地址."

This means "retrieve the 4-byte address stored at 0x804a010 and jump to it."

804a010:       e6 82                   out    %al,$0x82
804a012:       04 08                   add    $0x8,%al

这4个字节将被视为地址0x80482e6,而不是指令.

Those 4 bytes will be treated as an address, 0x80482e6, not as instructions.

80482e0:       ff 25 10 a0 04 08       jmp    *0x804a010
80482e6:       68 08 00 00 00          push   $0x8
80482eb:       e9 d0 ff ff ff          jmp    80482c0 <_init+0x2c>

因此,我们刚刚执行了一条指令,将我们恰好向前移动了一条指令.此时,您可能想知道是否有充分的理由.

So we've just executed an instruction that has moved us exactly one instruction forward. At this point, you're probably wondering if there's a good reason for this.

有.这是典型的PLT/GOT实现.包括图表在内的更多详细信息,请参见

There is. This is a typical PLT/GOT implementation. Much more detail, including a diagram, is at Position Independent Code in shared libraries: The Procedure Linkage Table.

__libc_start_main的实际代码在共享库glibc中.编译器和编译时链接程序不知道代码在运行时的位置,因此它们在您的编译程序中放置了一个简短的__libc_start_main函数,该函数仅包含三个指令:

The real code for __libc_start_main is in a shared library, glibc. The compiler and compile-time linker don't know where the code will be at run-time, so they place in your compiled program a short __libc_start_main function which contains just three instructions:

  • 跳转到GOT中第4个(或第5个,取决于您是从0还是1开始计数)指定的位置
  • 将$ 8压入堆栈
  • 跳转到解析器例程

第一次调用__libc_start_main时,解析器代码将运行.它将在共享库中找到__libc_start_main的实际位置,并将GOT的第4个条目修补为该地址.如果您的程序再次调用__libc_start_main,则jmp *0x804a010指令会将程序直接带到共享库中的代码.

The first time you call __libc_start_main, the resolver code will run. It will find the actual location of __libc_start_main in a shared library and will patch the 4th entry of the GOT to be that address. If your program calls __libc_start_main again, the jmp *0x804a010 instruction will take the program directly to the code in the shared library.

有人可以告诉我对我有用的材料吗?

Can anyone inform me good material for me?

Wikibooks上的 x86汇编书可能是一个起点.

The x86 Assembly book at Wikibooks might be one place to start.

这篇关于__libc_start_main @ plt如何工作?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆