前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >二进制基础

二进制基础

作者头像
HauHau
发布2022-01-12 09:09:41
3500
发布2022-01-12 09:09:41
举报
文章被收录于专栏:叹世界叹世界

做 pwn 或者 reverse 的一些基础

程序的编译与链接

编译:由 C 语言代码生成汇编代码

汇编:由汇编代码生成机器码

链接:将多个机器码的目标文件链接成一个可执行文件

Linux 下的可执行文件格式 ELF

可执行文件:.out

动态链接库:.so

静态链接库:.a

Windows 下的可执行文件格式 PE

可执行文件:.exe

动态链接库:.dll

静态链接库:.lib

ELF 文件结构

节视图 (磁盘中划分程序)、段视图 (内存中)

32 位系统虚拟内存大小为 4GB (2 的 32 次方)

并且内核空间 (kernal) 共享,下面的用户空间为 3GB,上面的内核空间为 1GB

操作系统 (arch 为例):1. linux 内核 (不同发行版都一样)。 2. 软件是由 GUN 开发的 (ls, cd 等) 3. arch 提供软件源 4. 桌面环境也是一个用户态程序 (也是一个软件)

内核是用于管理硬件的,所以内核只要在内存中装载一份,复用的思想

glic 动态链接库在内存中也只有一份

64 位操作系统 256TB, 内核 128TB, 用户 128TB

内存从低位向高位写

进程虚拟地址空间

代码语言:javascript
复制
用户空间中分为(从上往下地址由高到低)
    内核空间
    栈空间(Stack):动态存储区, 控制程序流
    Memory Mapping Region:映射一个虚拟空间(glic)
    堆空间(heap):动态存储区, 满足用户动态内存申请(malloc)
    data段:静态存储区
    code段:静态存储区
    
堆空间从低地址向高地址增长
栈空间从高地址向低地址增长


段和节:

·代码段包含了代码和只读数据
    .test节(用户的代码实现)
    .rodata节
    .hash节
    .dynsym节
    .dynstr节
    .plt节
    .rel.got节
    ......
·数据段包含了可读可写数据
    .data节(一般性数据)
    .dynamic节(动态链接所需要的结构)
    .got节
    .got.plt节
    .bss节(全局偏移量的地址)
    ......
·栈段

·一个段包含多个节(意思是从磁盘到内存,一个段会变为多个节)
·段视图用于进程的内存区域的rwx权限划分
·节视图用于ELF文件 编译链接时 与 在磁盘上存储时 的文件结构的组织

程序的装载与进程的执行

磁盘上的可执行文件要先到内存,才能被 CPU 执行

从程序变为虚拟内存中

代码语言:javascript
复制
int glb;
char* str = "Hello world";

int sum(int x, int y)
{
    int t = x + y;
}

int main
{
    sum(1, 2); (调用函数消耗的内存空间在栈中)
    void* ptr = malloc(0x100);
    read(0, ptr, 0x100);    // input "deadbeef"
    return 0;
}

编译链接执行 载入内存

代码语言:javascript
复制
Kernel: 
Stack: t、ptr (程序进程执行栈)
Shared libraries: 
Heap: "deadbeef" (存放堆分配的空间)
Bss: glb (存放未初始化的全局变量)(不占用磁盘空间但是占用内存空间)
Data: str (保存只读、不可写、不可执行的数据)
Text: main、sum、"Hello world!" (以机器码的形式存放函数)
Unused: 

型参x、y的:
    amd64: CPU寄存器中
    x86: Stack中
代码语言:javascript
复制
大端序和小端序

小端序(LSB):
    ·低地址存放数据低位、高地址存放数据高位(高"ABC"低, 内存中低到高: CBA)
    ·主要关注
大端序(MSB):
    ·低地址存放数据高位、高地址存放数据低位(高"ABC"低, 内存中低到高: ABC)
代码语言:javascript
复制
amd64寄存器结构
    rax: 8Bytes (rax表示64bits(8Bytes)长的寄存器) 64位
    eax: 4Bytes (eax表示32bits(4Bytes)长的寄存器, 取rax的低四字节来操作)    32位
    ax: 2Bytes  (rx的低二字节)   16位
    ah: 1Bytes  (ax中的高一位字节)
    al: 1Bytes  (ax中的第一位字节)

部分寄存器的功能
    RIP: PC, 存放下一条指令的偏移地址
    RSP: 存放当前栈帧的栈顶偏移地址
    RBP: 存放当前栈帧的栈底偏移地址
    RAX: 通用寄存器或存放函数返回值
代码语言:javascript
复制
静态链接的程序的执行过程

user mode
    $ ./binary
    frok()
    execve("./binary", *argv[], *envp[])
    
kernel mode
    -----------------------------------
    sys_execve()
    do_execve()
    search_binary_handler()
    load_elf_binary()
    -----------------------------------
    
user mode
    _start
    main()
    
代码语言:javascript
复制
动态链接的程序的执行过程

user mode
    $ ./binary
    frok()
    execve("./binary", *argv[], *envp[])
    
kernel mode
    -----------------------------------
    sys_execve()
    do_execve()
    search_binary_handler()
    load_elf_binary()
    -----------------------------------
    
user mode
    ld.so   //库函数偏移地址
    _start
    __libc_start_main()
    _init
    main()
    

x86&amd64 汇编基础简述

函数状态涉及到: esp, ebp, eip esp 存储函数调用栈的栈顶地址 ebp 存储当前函数状态的基地址 eip 存储下一条执行的指令的地址

指令格式 | Base | Index | Scale | | ——————— | —– | —– | | 0 | 2 | 4 | | 偏移地址: 0+2*4 = 8 | | |

假设位移为: 0x10

则地址为: 0+2*4+0x10 = 24

代码语言:javascript
复制
·MOV: 
    MOV DEST SRC 把源操作数传给目标(源操作数和被操作数不能同时是内存)
    
·LEA: 把源操作数的有效地址送给指定的寄存器
    LEA EBX ASC: 取ASC的地址存放至EBX寄存器中
    
·ADD/SUB: 目的操作数 +/- 源操作数 -> 目的操作数地址

·PUSH: 将一个寄存器中的数据入栈,然后RSP减一个字节
    例如:   push $2
    分解为: sub 长度 %rsp
            mov $2 (%rsp)
            
·POP: 出栈用一个寄存器接受数据, 然后RSP减一个字节
    例如:   pop 目的地址
    分解为: mov (%rsp) 目的地址
            add 长度 %rsp
            
·CMP
    目的操作数减去源操作数
    
·JMP
    
·J[Condition]:
    
·CALL: 将目标地址压栈, 然后JMP
    例如:   call    reg
    分解为: push    RIP
            JMP     reg
            
·LEAVE: 函数返回时, 回复父函数栈帧的指令
    MOV ESP, EBP
    POP EBP
    
·RET: 在函数返回时, 控制程序执行流返回父函数的指令
    POP RIP(实际不存在的)

两种汇编格式

intel

AT&T

mov eax, 8

movl $8, %eax

mov ebx, 0ffffh

movl $0xffff, %ebx

int 80h

int $0x80

mov eax, [ecx]

movl (%ecx), %eax

[ ]: 取目的地址中的数值

intel

操作符重载

intel 汇编格式

代码语言:javascript
复制
[base+index*scale]Disp

byte ptr
mov qword ptr [rsp], 0xfffff
代码语言:javascript
复制
sum: 
    push ebp
    mov ebp, esp
    mov eax, [ebp+12]
    add eax, [ebp+8]
    pop ebp
    retn

AT&T

在操作符后面会加上操作数的大小描述

AT&T 汇编格式

代码语言:javascript
复制
Disp(base, index, scale)

movq $0xffff, (%rsp)

C 语言

数据类型

汇编代码后缀

char

字节

b byte

short

w word

int

双字

l

long int

双字

l

long long int

char*

双字

l

float

单精度

s

double

双精度

l

long double

扩展精度

t

代码语言:javascript
复制
sum:
    pushl %ebp
    movl %esp, %ebp
    movl 12(%ebp), %eax
    addl 8(%ebp), %eax
    popl %ebp
    ret
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2021-09-13,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 程序的编译与链接
  • Linux 下的可执行文件格式 ELF
  • Windows 下的可执行文件格式 PE
  • ELF 文件结构
  • 进程虚拟地址空间
  • 程序的装载与进程的执行
  • x86&amd64 汇编基础简述
    • intel
      • AT&T
      相关产品与服务
      轻量应用服务器
      轻量应用服务器(TencentCloud Lighthouse)是新一代开箱即用、面向轻量应用场景的云服务器产品,助力中小企业和开发者便捷高效的在云端构建网站、Web应用、小程序/小游戏、游戏服、电商应用、云盘/图床和开发测试环境,相比普通云服务器更加简单易用且更贴近应用,以套餐形式整体售卖云资源并提供高带宽流量包,将热门软件打包实现一键构建应用,提供极简上云体验。
      领券
      问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档