Air9

And it's turtles all the way down...

⇝

Air9

And it's turtles all the way down...

Linux x86 elf 程序启动过程

2017-03-16

Kali rolling x86-64 环境,默认动态链接
参考 32 位: http://dbp-consulting.com/tutorials/debugging/linuxProgramStartup.html

流程图如下:

流程图

64 位草图

最简单的 main

int main()
{
}

gcc -ggdb -o prog1 prog1.c

execve

运行程序时,shell 或者 gui 调用 execve() 函数触发系统调用:

  • 系统会分配栈区并将 argc, argv, envp 压栈
  • 按照 shell 设定 FD
  • 装载器负责重定位和调用preinitializers(图中preinitarray1..n)
  • 从程序代码段中 _start 位置开始执行程序

_start

_start 是程序执行的初始位置,通过objdump -d prog1查看汇编

00000000004003b0 <_start>:
4003b0: 31 ed xor %ebp,%ebp
4003b2: 49 89 d1 mov %rdx,%r9 # argv
4003b5: 5e pop %rsi # argc
4003b6: 48 89 e2 mov %rsp,%rdx # linker destructor
4003b9: 48 83 e4 f0 and $0xfffffffffffffff0,%rsp
4003bd: 50 push %rax
4003be: 54 push %rsp
4003bf: 49 c7 c0 30 05 40 00 mov $0x400530,%r8 # <__libc_csu_fini>
4003c6: 48 c7 c1 c0 04 40 00 mov $0x4004c0,%rcx # <__libc_csu_init>
4003cd: 48 c7 c7 a6 04 40 00 mov $0x4004a6,%rdi # <main>
4003d4: ff 15 16 0c 20 00 callq *0x200c16(%rip) # 600ff0 <__libc_start_main@GLIBC_2.2.5>
4003da: f4 hlt
4003db: 0f 1f 44 00 00 nopl 0x0(%rax,%rax,1)

_start的作用就是配置__libc_start_main的参数并进行调用:

  • xor %ebp, %ebp用于将 %ebp 清零,同时作为最外层标记

  • 对 %rdi, %rsi, %rdx, %rcx, %r8, %r9 的操作均为传参,因为共 7 个参数,还用到了栈来传递第一个参数

    1. main地址, 由__libc_start_main调用, 另外在程序终止后main的返回值会由__libc_start_main传递给exit
    2. argc
    3. argv
    4. __libc_csu_init
    5. __libc_csu_fini
    6. Destructor of dynamic linker. Registered by libc_start_main with cxat_exit()
      to call the FINI for dynamic libraries that got loaded before us.
    7. 栈 - 函数调用前的%rsp
  • 为了提升访存效率,编译器通常采用 16B 对齐。为了保证函数调用时的新栈帧是 16B 对齐的,使用and指令将 %esp 对齐。

  • 同时,为了将 %esp 保存在 16B 对齐的位置,使用push %rax提前填充 8B

_start调用__libc_start_main前的状态:

before __libc_start_main

__libc_start_main

__libc_start_main定义如下:

int __libc_start_main(
int (*main) (int, char * *, char * *),
int argc,
char * * ubp_av,
void (*init) (void),
void (*fini) (void),
void (*rtld_fini) (void),
void (* stack_end)
);

main的完整参数调用应该是int main(int argc, char** argv, char** envp), 但是__libc_start_main中却并不包含 envp, 因为envp可以由argc和argv计算得到

ELF auxiliary vector

使用 gdb 调试 prog1, 在_start处下断点, 运行初始状态如下:
_start
可以看到从栈顶向栈底依次放置的是: argc, argv, 0x0, 环境变量等, 即ELF 辅助向量.

__libc_start_main 的主要功能

  • setuid, setgid

  • 启动线程

  • 寄存fini和rtld_fini的参数, 等待at_exit调用

  • 调用__libc_csu_init

  • 调用main

  • 调用exit

    ​

__libc_csu_init

调用__libc_csu_init之前

void __libc_csu_init (int argc, char **argv, char **envp)
{
_init ();
const size_t size = __init_array_end - __init_array_start;
for (size_t i = 0; i < size; i++)
(*__init_array_start [i]) (argc, argv, envp);
}
00000000004004c0 <__libc_csu_init>:
4004c0: 41 57 push %r15
4004c2: 41 56 push %r14
4004c4: 41 89 ff mov %edi,%r15d
4004c7: 41 55 push %r13
4004c9: 41 54 push %r12
4004cb: 4c 8d 25 76 09 20 00 lea 0x200976(%rip),%r12 # 600e48 <__frame_dummy_init_array_entry>
4004d2: 55 push %rbp
4004d3: 48 8d 2d 76 09 20 00 lea 0x200976(%rip),%rbp # 600e50 <__init_array_end>
4004da: 53 push %rbx
4004db: 49 89 f6 mov %rsi,%r14
4004de: 49 89 d5 mov %rdx,%r13
4004e1: 4c 29 e5 sub %r12,%rbp
4004e4: 48 83 ec 08 sub $0x8,%rsp
4004e8: 48 c1 fd 03 sar $0x3,%rbp
4004ec: e8 9f fe ff ff callq 400390 <_init>
4004f1: 48 85 ed test %rbp,%rbp
4004f4: 74 20 je 400516 <__libc_csu_init+0x56>
4004f6: 31 db xor %ebx,%ebx
4004f8: 0f 1f 84 00 00 00 00 nopl 0x0(%rax,%rax,1)
4004ff: 00
400500: 4c 89 ea mov %r13,%rdx
400503: 4c 89 f6 mov %r14,%rsi
400506: 44 89 ff mov %r15d,%edi
400509: 41 ff 14 dc callq *(%r12,%rbx,8)
40050d: 48 83 c3 01 add $0x1,%rbx
400511: 48 39 dd cmp %rbx,%rbp
400514: 75 ea jne 400500 <__libc_csu_init+0x40>
400516: 48 83 c4 08 add $0x8,%rsp
40051a: 5b pop %rbx
40051b: 5d pop %rbp
40051c: 41 5c pop %r12
40051e: 41 5d pop %r13
400520: 41 5e pop %r14
400522: 41 5f pop %r15
400524: c3 retq
400525: 90 nop
400526: 66 2e 0f 1f 84 00 00 nopw %cs:0x0(%rax,%rax,1)
40052d: 00 00 00
0000000000400390 <_init>:
400390: 48 83 ec 08 sub $0x8,%rsp
400394: 48 8b 05 5d 0c 20 00 mov 0x200c5d(%rip),%rax # 600ff8 <__gmon_start__>
40039b: 48 85 c0 test %rax,%rax
40039e: 74 02 je 4003a2 <_init+0x12>
4003a0: ff d0 callq *%rax
4003a2: 48 83 c4 08 add $0x8,%rsp
4003a6: c3 retq

__libc_csu_init返回__libc_start_main前:

  • Linux
  • x86
  • elf
  • main
  • libc
  • start
  • init
  • gdb
  • Linux

扫一扫,分享到微信

微信分享二维码
polipo+ss实现 iTerm2 终端科学上网
keystone
© 2018 Air9
Hexo Theme Yilia by Litten
  • ⇝

tag:

  • Privoxy
  • Shadowsocks
  • gfw
  • Coursera
  • JavaScript
  • AngularJS
  • ngResource
  • Python
  • Flask-SQLAlchemy
  • Alembic
  • Flask-Migrate
  • Flask
  • relationship
  • backref
  • Linux
  • x86
  • elf
  • main
  • libc
  • start
  • init
  • gdb
  • sorted
  • key
  • Closure
  • Decorator
  • func_defaults
  • Q
  • asm
  • align
  • capstone
  • ida
  • Spider
  • ThreadPool
  • logging
  • argparse
  • sqlite
  • requests
  • doctest
  • SublimeREPL
  • ExpandRegion
  • Anaconda
  • MarkdownEditing
  • Archlinux
  • pip
  • vmtools
  • bootstrap
  • keyboard
  • tagIndex
  • Brackets
  • gulp
  • browser-sync
  • python
  • ropgadget
  • Refactoring
  • git
  • github
  • ssh
  • hexo
  • rss
  • sitemap
  • idapython
  • idc
  • ionic
  • rop
  • keystone
  • unicorn
  • Mac
  • mongodb
  • MySQL
  • UTF-8
  • markdown
  • evernote
  • sublime
  • vscode
  • proxy
  • iTerm
  • polipo
  • Charles
  • 科学上网
  • Powerline
  • cookbook
  • closure
  • factory
  • string
  • python-magic
  • mime
  • apt-get
  • raspi
  • ANSI
  • termcolor
  • colorama
  • redis
  • brew
  • tmux
  • 字符集
  • 编码
  • ASCII
  • Unicode

    缺失模块。
    1、请确保node版本大于6.2
    2、在博客根目录(注意不是yilia根目录)执行以下命令:
    npm i hexo-generator-json-content --save

    3、在根目录_config.yml里添加配置:

      jsonContent:
        meta: false
        pages: false
        posts:
          title: true
          date: true
          path: true
          text: false
          raw: false
          content: false
          slug: false
          updated: false
          comments: false
          link: false
          permalink: false
          excerpt: false
          categories: false
          tags: true
    

  • 树莓派初体验

    2018-05-19

    #raspi

  • Markdown 同步 Evernote

    2017-06-01

    #markdown#evernote#sublime#vscode

  • polipo+ss实现 iTerm2 终端科学上网

    2017-04-03

    #Shadowsocks#proxy#iTerm#polipo#Charles#科学上网

  • Linux x86 elf 程序启动过程

    2017-03-16

    #Linux#x86#elf#main#libc#start#init#gdb

  • keystone

    2016-11-30

    #capstone#python#rop#keystone#unicorn

  • Python 控制终端输出颜色 & ANSI 控制码

    2016-10-12

    #Python#ANSI#termcolor#colorama

  • python-magic has no attribute 'from_file'

    2016-10-11

    #Python#pip#python-magic#mime#apt-get

  • idapython-elf-gadget

    2016-10-08

    #ida#python#idapython

  • ionic 使用 popover 时的一点小问题

    2016-09-27

    #JavaScript#AngularJS#ngResource#ionic

  • Code Smell

    2016-09-25

    #Refactoring

  • Mac 安装 mongodb

    2016-09-22

    #Mac#mongodb

  • 命令行调用 idapython 脚本

    2016-09-20

    #ida#python#idapython#idc

  • Mac 下使用 homebrew 安装 redis

    2016-09-12

    #Mac#redis#brew

  • Q 判断 Gadget 时遇到 align 伪指令的问题

    2016-08-23

    #Q#asm#align#capstone#ida

  • Flask-SQLAlchemy 中的 relationship & backref

    2016-08-16

    #Flask-SQLAlchemy#Flask#relationship#backref

  • hexo-rss-sitemap

    2016-07-28

    #hexo#rss#sitemap

  • Python 中的闭包与装饰器

    2016-07-25

    #Python#Closure#Decorator#func_defaults

  • 字符集与编码

    2016-07-06

    #Python#UTF-8#ANSI#字符集#编码#ASCII#Unicode

  • AngularJS-ngResource-save

    2016-07-06

    #Coursera#JavaScript#AngularJS#ngResource

  • brackets-live-preview-gulp

    2016-07-05

    #Coursera#JavaScript#AngularJS#Brackets#gulp#browser-sync

  • bootstrap-keyboard-tagIndex

    2016-06-28

    #Coursera#JavaScript#bootstrap#keyboard#tagIndex

  • Permission denied (publickey)

    2016-06-16

    #git#github#ssh

  • Python-Cookbook-1.09 简化 translate 方法

    2016-05-25

    #Python#cookbook#closure#factory#string

  • Python-sorted函数中key的用法

    2016-05-19

    #Python#sorted#key

  • Flask 数据库更新问题

    2016-05-16

    #Python#Flask-SQLAlchemy#Alembic#Flask-Migrate

  • Spider-07-doctest

    2016-04-08

    #Python#Spider#doctest

  • Mac 安装 MySQL 并设置 utf-8

    2016-04-07

    #MySQL#UTF-8

  • Spider-06-requests

    2016-04-07

    #Python#Spider#requests

  • Spider-05-Spider

    2016-04-06

    #Python#Spider

  • Sublime Preferences

    2016-04-05

    #SublimeREPL#ExpandRegion#Anaconda#MarkdownEditing

  • Spider-04-sqlite3

    2016-04-05

    #Python#Spider#sqlite

  • Spider-03-argparse

    2016-04-04

    #Python#Spider#argparse

  • Spider-02-logging

    2016-04-03

    #Python#Spider#logging

  • Spider-01-MyThreadPool

    2016-04-02

    #Python#Spider#ThreadPool

  • ropgadget capstone

    2016-03-10

    #capstone#python#ropgadget

  • hexo github

    2016-03-09

    #git#github#hexo

  • 10.11 privoxy [Errno 61] Connection refused

    2016-03-09

    #Privoxy#Shadowsocks#gfw

  • arch vmtools

    2016-03-09

    #Archlinux#vmtools

  • arch gdb pip ropgadget

    2016-03-09

    #gdb#Archlinux#pip

  • tmux copy2clipboard

    2016-03-09

    #Archlinux#tmux

  • iTerm下配置Powerline

    2016-03-09

    #iTerm#Powerline