先上一个例子:
#include
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("nn%dn",n);
printf("nn%dn",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(“nn%dn”,n);
18
19 printf(“nn%dn”,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(“nn%dn”,n);
18
19 printf(“nn%dn”,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(“nn%dn”,n);
18
19 printf(“nn%dn”,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
filter_none
edit
play_arrow
brightness_4
#include
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().
服务器托管,北京服务器托管,服务器租用 http://www.fwqtg.net
机房租用,北京机房租用,IDC机房托管, http://www.fwqtg.net
相关推荐: Kubernetes(k8s)包管理工具Helm:Helm包管理
目录 一.系统环境 二.前言 三.包管理工具Helm简介 四.安装部署helm 五.配置helm以及helm常用命令 六.使用helm安装应用 七.搭建helm私有仓库 八.总结 一.系统环境 本文主要基于Kubernetes1.21.9和Linux操作系统C…