zoukankan      html  css  js  c++  java
  • 通过pwndbg看看c中局部变量是如何在stack上放置的 此外 printf %n的作用终于弄明白了

    先上一个例子:

    #include<stdio.h>
    
    int main()
    
    {
    
        int n,num;
    
        char*m2="Decimal";
    
        char*m3="Octal";
    
        char*m4="Hexadecimal";
    
        num = printf("%s%s%s%n",m2,m3,m4,&n);
    
        printf("
    
    %d
    ",n); 
    
     printf("
    
    %d
    ",num);
    
     
    
        return 0;
    
    }
    

    ────────────────────────────────────────────────────────[ SOURCE (CODE) ]─────────────────────────────────────────────────────────
    In file: /data/test_n.c
       10
       11     char*m3="Octal";
       12
       13     char*m4="Hexadecimal";
       14
     ► 15     num = printf("%s%s%s%n",m2,m3,m4,&n);
       16
       17     printf(" %d ",n);
       18
       19  printf(" %d ",num);
       20
    ────────────────────────────────────────────────────────────[ STACK ]─────────────────────────────────────────────────────────────
    00:0000│ rsp  0x7fffffffec30 —▸ 0x5555555551c0 (__libc_csu_init) ◂— push   r15
    01:0008│      0x7fffffffec38 —▸ 0x555555556012 ◂— 'Hexadecimal'  看下局部变量是如何放在stack里的
    02:0010│      0x7fffffffec40 —▸ 0x55555555600c ◂— 0x6548006c6174634f /* 'Octal' */
    03:0018│      0x7fffffffec48 —▸ 0x555555556004 ◂— 0x6c616d69636544 /* 'Decimal' */
    04:0020│ rbp  0x7fffffffec50 —▸ 0x5555555551c0 (__libc_csu_init) ◂— push   r15
    05:0028│      0x7fffffffec58 —▸ 0x7ffff7e27cca (__libc_start_main+234) ◂— mov    edi, eax
    06:0030│      0x7fffffffec60 —▸ 0x7fffffffed48 —▸ 0x7fffffffef1a ◂— '/data/a.out'
    07:0038│      0x7fffffffec68 ◂— 0x100000000
    ──────────────────────────────────────────────────────────[ BACKTRACE ]───────────────────────────────────────────────────────────
     ► f 0     55555555515e main+41
       f 1     7ffff7e27cca __libc_start_main+234
    ──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
    pwndbg> p m2
    $1 = 0x555555556004 "Decimal"
    pwndbg> p m3
    $2 = 0x55555555600c "Octal"
    pwndbg> p m4
    $3 = 0x555555556012 "Hexadecimal"

    接下来单步运行分析程序的作用:

    ────────────────────────────────────────────────────────[ SOURCE (CODE) ]─────────────────────────────────────────────────────────
    In file: /data/test_n.c
        4
        5 {
        6
        7     int n,num;
        8
     ►  9     char*m2="Decimal";
       10
       11     char*m3="Octal";
       12
       13     char*m4="Hexadecimal";
       14
    ────────────────────────────────────────────────────────────[ STACK ]─────────────────────────────────────────────────────────────
    00:0000│ rsp  0x7fffffffec30 —▸ 0x5555555551c0 (__libc_csu_init) ◂— push   r15
    01:0008│      0x7fffffffec38 —▸ 0x555555555050 (_start) ◂— xor    ebp, ebp
    02:0010│      0x7fffffffec40 —▸ 0x7fffffffed40 ◂— 0x1
    03:0018│      0x7fffffffec48 ◂— 0x0
    04:0020│ rbp  0x7fffffffec50 —▸ 0x5555555551c0 (__libc_csu_init) ◂— push   r15
    05:0028│      0x7fffffffec58 —▸ 0x7ffff7e27cca (__libc_start_main+234) ◂— mov    edi, eax
    06:0030│      0x7fffffffec60 —▸ 0x7fffffffed48 —▸ 0x7fffffffef1a ◂— '/data/a.out'
    07:0038│      0x7fffffffec68 ◂— 0x100000000
    ──────────────────────────────────────────────────────────[ BACKTRACE ]───────────────────────────────────────────────────────────
     ► f 0     55555555513d main+8
       f 1     7ffff7e27cca __libc_start_main+234
    ──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
    pwndbg> p &n
    $8 = (int *) 0x7fffffffec30
    pwndbg> p n
    $9 = 1431654848

    运行到printf处stack的状态请注意:

    ────────────────────────────────────────────────────────[ SOURCE (CODE) ]─────────────────────────────────────────────────────────
    In file: /data/test_n.c
       10
       11     char*m3="Octal";
       12
       13     char*m4="Hexadecimal";
       14
     ► 15     num = printf("%s%s%s%n",m2,m3,m4,&n);
       16
       17     printf(" %d ",n);
       18
       19  printf(" %d ",num);
       20
    ────────────────────────────────────────────────────────────[ STACK ]─────────────────────────────────────────────────────────────
    00:0000│ rsp  0x7fffffffec30 —▸ 0x5555555551c0 (__libc_csu_init) ◂— push   r15  # 这个地址就是存放局部变量n
    01:0008│      0x7fffffffec38 —▸ 0x555555556012 ◂— 'Hexadecimal'
    02:0010│      0x7fffffffec40 —▸ 0x55555555600c ◂— 0x6548006c6174634f /* 'Octal' */
    03:0018│      0x7fffffffec48 —▸ 0x555555556004 ◂— 0x6c616d69636544 /* 'Decimal' */
    04:0020│ rbp  0x7fffffffec50 —▸ 0x5555555551c0 (__libc_csu_init) ◂— push   r15
    05:0028│      0x7fffffffec58 —▸ 0x7ffff7e27cca (__libc_start_main+234) ◂— mov    edi, eax
    06:0030│      0x7fffffffec60 —▸ 0x7fffffffed48 —▸ 0x7fffffffef1a ◂— '/data/a.out'
    07:0038│      0x7fffffffec68 ◂— 0x100000000

    然后继续运行,

    ────────────────────────────────────────────────────────[ SOURCE (CODE) ]─────────────────────────────────────────────────────────
    In file: /data/test_n.c
       12
       13     char*m4="Hexadecimal";
       14
       15     num = printf("%s%s%s%n",m2,m3,m4,&n);
       16
     ► 17     printf(" %d ",n);
       18
       19  printf(" %d ",num);
       20
       21  
       22
    ────────────────────────────────────────────────────────────[ STACK ]─────────────────────────────────────────────────────────────
    00:0000│ rsp  0x7fffffffec30 ◂— 0x1700000017
    01:0008│      0x7fffffffec38 —▸ 0x555555556012 ◂— 'Hexadecimal'
    02:0010│      0x7fffffffec40 —▸ 0x55555555600c ◂— 0x6548006c6174634f /* 'Octal' */
    03:0018│      0x7fffffffec48 —▸ 0x555555556004 ◂— 0x6c616d69636544 /* 'Decimal' */
    04:0020│ rbp  0x7fffffffec50 —▸ 0x5555555551c0 (__libc_csu_init) ◂— push   r15
    05:0028│      0x7fffffffec58 —▸ 0x7ffff7e27cca (__libc_start_main+234) ◂— mov    edi, eax
    06:0030│      0x7fffffffec60 —▸ 0x7fffffffed48 —▸ 0x7fffffffef1a ◂— '/data/a.out'
    07:0038│      0x7fffffffec68 ◂— 0x100000000

    神奇的事情发生了,stack上0x7fffffffec30地址处的值修改了,变成了 0x1700000017。最终程序输出n和num都是23。

    为啥是23,

    >>> len("Decimal")
    7
    >>> len("Octal")
    5
    >>> len("Hexadecimal")
    11

    因为打印的字符总数是23.

    但是%n的作用,终于在一篇英文中看到了。

    What is use of %n in printf() ?

    Last Updated: 09-10-2019

    In C printf(), %n is a special format specifier which instead of printing something causes printf() to load the variable pointed by the corresponding argument with a value equal to the number of characters that have been printed by printf() before the occurrence of %n.

    filter_none

    edit

    play_arrow

    brightness_4

    #include<stdio.h>
      
    int main()
    {
      int c;
      printf("geeks for %ngeeks ", &c);
      printf("%d", c);
      getchar();
      return 0;
    }

    The above program prints “geeks for geeks 10”. The first printf() prints “geeks for geeks”. The second printf() prints 10 as there are 10 characters printed (the 10 characters are “geeks for “) before %n in first printf() and c is set to 10 by first printf().

  • 相关阅读:
    springMVC上传文件简单案例
    java监听器、定时器的使用
    javaweb的web.xml配置说明,初始化过程
    Linux下解决高并发socket最大连接数限制,tcp默认1024个连接
    tsung压力测试——Tsung测试统计报告说明【转】
    tsung压力测试——tcp测试tsung.xml配置模版说明
    tsung压力测试——安装
    Java同步锁——lock与synchronized 的区别【转】
    Java集合——HashMap,HashTable,ConcurrentHashMap区别
    SpringMVC源码情操陶冶-FreeMarker之web配置
  • 原文地址:https://www.cnblogs.com/bonelee/p/13775831.html
Copyright © 2011-2022 走看看