zoukankan      html  css  js  c++  java
  • 格式化字符串

    格式化字符串:

    格式化字符串函数可以接受可变数量的参数,并将第一个字符串作为格式化字符串,然后去解析之后的参数。常见的格式化字符串函数有:

    • scanf
    • printf,输出到stdout
    • fprintf,输出到指定的FILE流
    • vprintf,根据参数列表格式化输出到 stdout
    • vfpirntf,根据参数列表格式化输出到指定 FILE 流
    • sprintf,输出到字符串
    • snprintf,输出指定字节数到字符串
    • vsprintf,根据参数列表格式化输出到字符串
    • vsnprintf,根据参数列表格式化输出指定字节到字符串
    • setproctitle,设置argv
    • syslog,输出日志

     常利用的格式化字符串有:

    • %x,以十六进制输出内存内容
    • %p,以带前缀0x的十六进制输入内存内容
    • %s,泄露指定地址空间的内容
    • %n,向指定地址空间写入以输出的字节数
    • %hn,向指定地址空间写入两个字节的数据,写入的数值是已输出的字节数
    • %hhn,向指定地址空间写入一个字节的数据,写入的数值是已输出的字节数

    下面逐个讲解。先看一个例程:

    #include <stdio.h>
    int main()
    {
        char s[100];
        int a=1, b=0x22222222, c=-1;
        scanf("%s", s);
        printf("%04x.%04x.%08x.%s
    ", a, b, c, s);
        printf(s);
        return 0;
    }

    运行后的结果如下:

    countfatcode@ubuntu:~/Code $ ./formatstring 
    yuan
    0001.22222222.ffffffff.yuan

    接下来调试观察是如何泄露内存的:

    gdb-peda$ stack 20
    0000| 0xffffd3b0 --> 0x80485d3 ("%04x.%04x.%08x.%s
    ")
    0004| 0xffffd3b4 --> 0x1 
    0008| 0xffffd3b8 ("""""37737737737735032337737735032337737730331377367377265", <incomplete sequence 360>)
    0012| 0xffffd3bc --> 0xffffffff 
    0016| 0xffffd3c0 --> 0xffffd3e8 ("yuan")
    0020| 0xffffd3c4 --> 0xffffd3e8 ("yuan")
    0024| 0xffffd3c8 --> 0xf7ffd918 --> 0x0 
    0028| 0xffffd3cc --> 0xf0b5ff 
    0032| 0xffffd3d0 --> 0xffffd40e --> 0xffff0000 --> 0x0 
    0036| 0xffffd3d4 --> 0x1 
    0040| 0xffffd3d8 --> 0xc2 
    0044| 0xffffd3dc --> 0x1 
    0048| 0xffffd3e0 ("""""377377377377yuan")
    0052| 0xffffd3e4 --> 0xffffffff 
    0056| 0xffffd3e8 ("yuan")
    0060| 0xffffd3ec --> 0x0 
    0064| 0xffffd3f0 --> 0xf7ffd000 --> 0x23f40 
    0068| 0xffffd3f4 --> 0xf7ffd918 --> 0x0 
    0072| 0xffffd3f8 --> 0xffffd410 --> 0xffffffff 
    0076| 0xffffd3fc --> 0x804827d ("__libc_start_main")
    gdb-peda$ ni
    0001.22222222.ffffffff.yuan

    观察上图栈结构可知程序把printf函数的第一个参数的首地址压入栈中,然后根据格式化字符串依次解析栈中除栈顶中的内容。

  • 相关阅读:
    autocad.net 利用linq获取矩形框内的块参照
    autocad.net 只在图纸空间遍历块的方法
    autocad.net中判断当前被激活的空间
    计划搞一个程序来应对客户的修改标记问题
    条件编译解决AutoCAD多版本问题
    初学者往往不知道怎么获得断点,请看下面的链接应该可以解决你的问题!
    2014年3月9日正式入住博客园
    学习:SpringCloud(一)
    简单使用:SpringBoot整合Redis
    Redis 使用过程中遇到的具体问题
  • 原文地址:https://www.cnblogs.com/countfatcode/p/11796479.html
Copyright © 2011-2022 走看看