Python %字符串格式中字符的含义(printf样式格式)

Python %字符串格式中字符的含义(printf样式格式),python,format-string,Python,Format String,我目前正在处理一个格式化字符串漏洞()并遇到了这种奇怪的语法(作为用于pwn的python脚本的一部分): 我知道作者打算用上述值(2493)覆盖内存地址。我可以使用以下语法实现相同的目标: payload += "%2493x%17$hn".rjust(16) 因此,我确实知道第二部分中$和hn的含义 我主要被上面第一个版本中的多个“%”和出现在连字符之外的“%2493”弄糊涂了。 我试着用谷歌搜索,但这只会导致标准格式的字符串解释 有人可以解释上面的第一个版本,或者可能有一个链接来解释它。

我目前正在处理一个格式化字符串漏洞()并遇到了这种奇怪的语法(作为用于pwn的python脚本的一部分):

我知道作者打算用上述值(2493)覆盖内存地址。我可以使用以下语法实现相同的目标:

payload += "%2493x%17$hn".rjust(16)
因此,我确实知道第二部分中$和hn的含义

我主要被上面第一个版本中的多个“%”和出现在连字符之外的“%2493”弄糊涂了。 我试着用谷歌搜索,但这只会导致标准格式的字符串解释


有人可以解释上面的第一个版本,或者可能有一个链接来解释它。

$
hm
没有什么特别的意思,它们只是字符串中的字符。只需运行字符串格式代码,您将看到:

>>> "%%%du|%%17$hn|" % 2493
'%2493u|%17$hn|'
在上面的字符串中,
%d
被您的号码替换为
2493
%%
用于显示字符串中的
%%
,因为单个
%%
在字符串格式中具有特殊含义。其余为普通字符串

%-格式化(也称为)是Python字符串格式化的一种旧样式,现在通常使用函数进行格式化。建议使用新的高级字符串格式替换
%
运算符

可在以下网站上对两者进行非常好的比较:


从中,它允许以下转换类型:

Conversion   Meaning
'd'          Signed integer decimal.     
'i'          Signed integer decimal.     
'o'          Signed octal value.
'u'          Obsolete type – it is identical to 'd'.    
'x'          Signed hexadecimal (lowercase).    
'X'          Signed hexadecimal (uppercase).    
'e'          Floating point exponential format (lowercase).
'E'          Floating point exponential format (uppercase).
'f'          Floating point decimal format.
'F'          Floating point decimal format. 
'g'          Floating point format. Uses lowercase exponential format if exponent is less than -4 or not less than precision, decimal format otherwise.
'G'          Floating point format. Uses uppercase exponential format if exponent is less than -4 or not less than precision, decimal format otherwise.
'c'          Single character (accepts integer or single character string).  
'r'          String (converts any Python object using repr()).  
's'          String (converts any Python object using str()).   
'a'          String (converts any Python object using ascii()). 
'%'          No argument is converted, results in a '%' character in the result.
并且具有转换标志字符,如下所示:

+------+--------------------------------------------------------------------------------------------------------------+
| Flag | Meaning                                                                                                      |
+------+--------------------------------------------------------------------------------------------------------------+
| '#'  | The value conversion will use the “alternate form” (where defined below).                                    |
+------+--------------------------------------------------------------------------------------------------------------+
| '0'  | The conversion will be zero padded for numeric values.                                                       |
+------+--------------------------------------------------------------------------------------------------------------+
| '-'  | The converted value is left adjusted (overrides the '0' conversion if both are given).                       |
+------+--------------------------------------------------------------------------------------------------------------+
| ' '  | (a space) A blank should be left before a positive number (or empty string) produced by a signed conversion. |
+------+--------------------------------------------------------------------------------------------------------------+
| '+'  | A sign character ('+' or '-') will precede the conversion (overrides a “space” flag).                        |
+------+--------------------------------------------------------------------------------------------------------------+

您在引号外看到的
%
是一个运算符(取模数表示数字的同一个运算符)。当其左参数是字符串时,它会执行“旧式”字符串格式设置。在Python2.6引入
str.format
之前,这一直是字符串格式的主要类型,因此您会在较旧的代码中看到很多。
%
操作符使用的格式化语言非常接近于C的
printf
,因此一些更习惯C的程序员可能也更喜欢它,而不是更新的、可能更“Pythonic”的格式化方法

在您的示例中,格式字符串最相关的部分是
%d
,它将参数格式化为整数
%
是用于在格式字符串中引入替换的字符,这就是为什么在其他两个位置的格式字符串中有另一个有趣的功能。如果要在输出中使用一个百分号,则需要在格式字符串中输入两个:
%%
。您有两次,一次在
%d
之前,一次在之后


最后得到的字符串,
“%2493x%17$hn”
对Python没有任何特殊意义,但可能在其他语言或特定上下文中。它将不再作为格式字符串使用,因为
%17$
不是有效的格式说明符(
%2493x
是有效的,尽管可能只是巧合)。

可能代码的作者(我不打算阅读这篇长篇文章)希望以后像这样使用
有效负载
实际有效负载=有效负载%(val1,val2,val3,…)
。我不确定这一点,因为
%17$hn
将导致
不支持的格式字符“$”(0x24).
异常。不管怎么说,从您发布的代码片段来看,它们毫无意义。大家好,我刚刚意识到,这可能实际上是一个我不知道的python格式问题,因为我通常使用python3和.format()语法,而不是旧的python2%语法。因此“%d”%5将用值5替换%d,%%将放置单个%。谜团解开了。谢谢大家的支持。
+------+--------------------------------------------------------------------------------------------------------------+
| Flag | Meaning                                                                                                      |
+------+--------------------------------------------------------------------------------------------------------------+
| '#'  | The value conversion will use the “alternate form” (where defined below).                                    |
+------+--------------------------------------------------------------------------------------------------------------+
| '0'  | The conversion will be zero padded for numeric values.                                                       |
+------+--------------------------------------------------------------------------------------------------------------+
| '-'  | The converted value is left adjusted (overrides the '0' conversion if both are given).                       |
+------+--------------------------------------------------------------------------------------------------------------+
| ' '  | (a space) A blank should be left before a positive number (or empty string) produced by a signed conversion. |
+------+--------------------------------------------------------------------------------------------------------------+
| '+'  | A sign character ('+' or '-') will precede the conversion (overrides a “space” flag).                        |
+------+--------------------------------------------------------------------------------------------------------------+