论坛首页 安全工具分享区 阅读主题

[原创]从GDB中观察x86-64函数控制流

91 浏览 0 回复
#1 楼主 2026-06-01 21:08:47
测试代码#include <stdio.h>

int test_if(int x) {
    if (x > 10) {
        return 1;
    } else {
        return 0;

int test_for(int n) {
    int sum = 0;
    for (int i = 0; i < n; i++) {
        sum += i;
    return sum;

int test_while(int x) {
    while (x > 0) {
        x--;
    return x;

int test_switch(int x) {
    switch (x) {
        case 0: return 100;
        case 1: return 200;
        case 2: return 300;
        default: return -1;

int main() {
    printf("%d\n", test_if(15));
    printf("%d\n", test_for(10));
    printf("%d\n", test_while(5));
    printf("%d\n", test_switch(1));
    return 0;
}运行环境:
    Ubuntu 20.04.6 LTS编译指令:
    gcc -g -O0 -o main main.cgcc版本    gcc version 9.4.0调试工具:    GDB
gdb ./main启动调试:进入main函数内部       (gdb) x/10i $rip       0x5555555551f7 <main>: endbr64        0x5555555551fb <main+4>: push   %rbp       0x5555555551fc <main+5>: mov    %rsp,%rbp       0x5555555551ff <main+8>: mov    $0xf,%edi       0x555555555204 <main+13>: callq  0x555555555149 <test_if>    
       发现在调用test_if时,传递了一个参数,参数为0xf
单步调试进入test_if函数:
   0x555555555149 <test_if>:    endbr64     0x55555555514d <test_if+4>: push   %rbp    0x55555555514e <test_if+5>: mov    %rsp,%rbp    0x555555555151 <test_if+8>: mov    %edi,-0x4(%rbp)    0x555555555154 <test_if+11>: cmpl   $0xa,-0x4(%rbp)    0x555555555158 <test_if+15>: jle    0x555555555161 <test_if+24>    0x55555555515a <test_if+17>: mov    $0x1,%eax    0x55555555515f <test_if+22>: jmp    0x555555555166 <test_if+29>    0x555555555161 <test_if+24>: mov    $0x0,%eax    0x555555555166 <test_if+29>: pop    %rbp    0x555555555167 <test_if+30>: retq  
   发现cmpl 指令,对比了 0xa,与参数0xf    jle 指令,判断0xf 是否小于等于 0xa 通过jle指令可以看出是有符号比较    0xa = 10, 0xf = 15    如果小于等于则跳转0x555555555161,将0赋值给eax,后返回函数,则函数返回值为0    如果大于0xa则继续向下执行    将eax赋值为1跳转到0x555555555166,函数返回。    即:    if (a <= b){       retrun 0;    }else{       return 1;    }    该函数返回值为1
   0x555555555209 <main+18>: mov    %eax,%esi   0x55555555520b <main+20>: lea    0xdf2(%rip),%rdi        # 0x555555556004   0x555555555212 <main+27>: mov    $0x0,%eax   0x555555555217 <main+32>: callq  0x555555555050 <printf@plt>   0x55555555521c <main+37>: mov    $0xa,%edi
   执行printf函数输出1
继续执行   0x55555555521c <main+37>: mov    $0xa,%edi   0x555555555221 <main+42>: callq  0x555555555168 <test_for>   传递了一个参数0xa   进入test_for:                0x555555555168 <test_for>: endbr64  0x55555555516c <test_for+4>: push   %rbp 0x55555555516d <test_for+5>: mov    %rsp,%rbp 0x555555555170 <test_for+8>: mov    %edi,-0x14(%rbp) 0x555555555173 <test_for+11>: movl   $0x0,-0x8(%rbp) 0x55555555517a <test_for+18>: movl   $0x0,-0x4(%rbp) 0x555555555181 <test_for+25>: jmp    0x55555555518d <test_for+37> 0x555555555183 <test_for+27>: mov    -0x4(%rbp),%eax 0x555555555186 <test_for+30>: add    %eax,-0x8(%rbp) 0x555555555189 <test_for+33>: addl   $0x1,-0x4(%rbp) 0x55555555518d <test_for+37>: mov    -0x4(%rbp),%eax 0x555555555

...(已截断)

---
来源: 看雪论坛
原文链接: https://bbs.kanxue.com/thread-291286.htm

暂无回复,快来抢沙发吧!

请登录后参与讨论

立即登录 注册账号