will be skipped in the future. */
l->l_init_running = 0;
l->l_init_called = 1;
continue;
}
if (l->l_info[DT_INIT]
&& (l->l_name[0] != '' || l->l_type != lt_executable))
{
/* Run this object's initializer. */
l->l_init_running = 1;
/* Print a debug message if wanted. */
if (_dl_debug_impcalls)
_dl_debug_message (1, "\ncalling init: ",
l->l_name[0] ? l->l_name : _dl_argv[0],
"\n\n", NULL);
/*共享库的基地址 init在基地址中的偏移量*/
return l->l_addr l->l_info[DT_INIT]->d_un.d_ptr;
}
/* No initializer for this object.
Mark it so we will skip it in the future. */
l->l_init_called = 1;
}
/* Notify the debugger all new objects are now ready to go. */
_r_debug.r_state = RT_CONSISTENT;
_dl_debug_state ();
return 0;
}
在main()之前的程式流程看试有点简单,但正在运行的时候还是比较复杂的
(自己用GBD跟踪下就知道了),因为一般的程式都需要涉及到PLT,GOT标号的
重定位。弄清楚这个对ELF由为重要,以后有机会再补上一篇吧。
★ 手动确定程式和动态连接器的入口
[alert7@redhat62 alert7]$ cat helo.c
#include
int main(int argc,char **argv)
{
printf("hello\n");
return 0;
}
[alert7@redhat62 alert7]$ gcc -o helo helo.c
[alert7@redhat62 alert7]$ readelf -h helo
ELF Header:
Magic: 7f 45 4c 46 01 01 01 00 00 00 00 00 00 00 00 00
Class: ELF32
Data: 2's complement, little endian
Version: 1 (current)
OS/ABI: UNIX - System V
ABI Version: 0
Type: EXEC (Executable file)
Machine: Intel 80386
Version: 0x1
Entry point address: 0x8048320
Start of program headers: 52 (bytes into file)
Start of section headers: 8848 (bytes into file)
Flags: 0x0
Size of this header: 52 (bytes)
Size of program headers: 32 (bytes)
Number of program headers: 6
Size of section headers: 40 (bytes)
Number of section headers: 29
Section header string table index: 26
在这里我们看到程式的入口为0x8048320,能够看看是否为main函数。
[alert7@redhat62 alert7]$ gdb -q helo
(gdb) disass 0x8048320
Dump of assembler code for function _start:
0x8048320 <_start>: xor 雙,雙
0x8048322 <_start 2>: pop %esi
0x8048323 <_start 3>: mov %esp,靫
0x8048325 <_start 5>: and xfffffff8,%esp
0x8048328 <_start 8>: push 陎
0x8048329 <_start 9>: push %esp
0x804832a <_start 10>: push 韝
0x804832b <_start 11>: push x804841c
0x8048330 <_start 16>: push x8048298
0x8048335 <_start 21>: push 靫
0x8048336 <_start 22>: push %esi
0x8048337 <_start 23>: push x80483d0
0x804833c <_start 28>: call 0x80482f8 <__libc_start_main>
0x8048341 <_start 33>: hlt
0x8048342 <_start 34>: nop
End of assembler dump.
呵呵,不是main吧,程式的入口是个_start例程。
再来看动态连接器的入口是多少
[alert7@redhat62 alert7]$ ldd helo
libc.so.6 => /lib/libc.so.6 (0x40018000)
/lib/ld-linux.so.2 => /lib/ld-linux.so.2 (0x40000000)
动态连接器ld-linux.so.2加载到进程地址空间0x40000000。
[alert7@redhat62 alert7]$ readelf -h /lib/ld-linux.so.2
ELF Header:
Magic: 7f 45 4c 46 01 01 01 00 00 00 00 00 00 00 00 00
Class: ELF32
Data: 2's complement, little endian
Version: 1 (current)
OS/ABI: UNIX - System V
ABI Version: 0
Type: DYN (Shared object file)
Machine: Intel 80386
Version: 0x1
Entry point address: 0x1990
Start of program headers: 52 (bytes into file)
Start of section headers: 328916 (bytes into file)
Flags: 0x0
Size of this header: 52 (bytes)
Size of program headers: 32 (bytes)
Number of program headers: 3
Size of section headers: 40 (bytes)
Number of section headers: 23
Section header string table index: 20
共享object入口地址为0x1990。加上整个ld-linux.so.2被加载到进程地址空间0x40000000。
文章整理:西部数码--专业提供域名注册、虚拟主机服务
http://www.west263.com
以上信息与文章正文是不可分割的一部分,如果您要转载本文章,请保留以上信息,谢谢!




