格式化字串介紹

2022-09-22 05:00:08 字數 1683 閱讀 3484

格式化字串(format string),是一些程式語言在格式化輸出api函式中用於指定輸出引數的格式與相應位置的字串引數,例如c、c++等程式語言的print類函式,其中的轉換說明(conversion specification)用於把隨後對應的0個或多個函式引數轉換為相應的格式輸出;格式化字串中轉換說明以外的其他字元原樣輸出。

通俗的來說,格式化字串函式就是將計算機記憶體中表示的資料轉換為我們人類可讀的字串格式。

print函式執行的大致流程如下:

格式化字串的在進入print函式後,函式首先會獲得第乙個引數,也就是格式化字串,依次讀取格式化字串中的每乙個字元,如果該字元是%,則繼續讀取下乙個非空字元,獲取對應的引數解析並輸出;如果該字元不為%,則直接輸出到標準輸出。

例子:printf("my name is %s,i'm %d years old.","tom",20)

c語言printf函式代表的一類格式化字串的基本格式如下:

%[parameter][flags][field width][.precision][length]type

parameter可以忽略,或者是n$,用來獲取格式化字串中的指定引數,比如

int a=0x1111,b=0x2222,c=0x3333;

printf("%3$p",a,b,c)

輸出為0x3333

flags可以為乙個或者多個,可以是這些字元:+,空格,-,#,0

field width給出顯示數值的最小寬度

precision常指明輸出的最大長度

length指出浮點型引數或整型引數的長度,可以是以下字元

hh:輸出1byte h:輸出2byte

l:輸出4byte ll:輸出8byte

在格式化字串漏洞利用中我們通常使用hh和h,也就是一次性寫1位元組和一次性寫2位元組

type,也稱轉換說明,可以是如下字元

d/i:有符號整型,intu:無符號整型,unsigned int

x/x:16進製制unsigned int,x使用小寫字母輸出,x使用大寫字母輸出

s:輸出null結尾字串直到精度規定的上限;如果沒有指定精度,則輸出所有位元組

c:把int引數轉為unsigned char型別輸出,格式化漏洞利用中通常使用其輸出大量字元

p:void*型別,輸出對應變數的值

n:不輸出字元,但是把已經成功輸出的字元個數寫入對應的整型指標引數所指的變數。

通過格式化字串洩露出棧中相關位址的資訊

棧上有flag那就–洩露棧記憶體

利用 %x 來獲取對應棧的記憶體,但建議使用 %p,可以不用考慮位數的區別。利用 %s 來獲取變數所對應位址的內容,只不過有零截斷。利用 %order$x 來獲取指定引數的值。同樣把x改為s來獲取指定引數對應位址的內容。

附:常見的格式化字串函式

輸入:scanf、sscanf

輸出:printf、fprintf、sprintf、snprintf、vsprintf、vsnprintf、vfprintf、vprintf

字串格式化

sprintf snprintf snprintf std stringstream std strstream boost lexical cast boost format cstring format 1 sprintf 使用 sprintf 不安全,輕則破壞資料的準確性,重則程式崩潰。請看下...

格式化字串

通常在使用字串的時候,會對字串進行格式化,然後輸出或呼叫 一般我們使用替換標記對字串進行格式化 string str1 string.format add is 1,2,3 而且在c 中的替換標記可以以任意順序和次數出現在格式化字串中,但替換值是按順序排的,而且替換標記不能超出索引範圍 string...

字串格式化

例如 string s hello map.put target world string res format s,map 有什麼用呢?比如在some.properties中配置模板字串,但是如果用 這種方式,在配置了spring讀取properties注入變數的時候,這個變數就找不到會報錯。這個...