字符串字面您有:
"\b3\bc\77\7\de\ed\44\93\75\ce\c0\9\19\59\c8\f\be\c6\30\6"
將根據C89產生不確定的行爲(不知道是否爲C89源是可以信任的,但我的下面點仍持有),並定義執行,行爲根據C11標準。具體而言,\d
,\e
,\9
,\c
是未在標準中定義的轉義序列。 gcc
不會抱怨\e
,因爲它是代表ESC的GNU擴展。
由於存在實現定義的行爲,因此我們有必要了解您使用的編譯器,結果可能會有所不同。
另一件事是,你沒有顯示明確,你知道編譯後的字符串的內容。 (更清晰的顯示方式應該包括字符串在內存中的內容的十六進制轉儲,並顯示如何識別轉義序列)。
這是看起來如何樣十六進制字符串是由編譯器識別:拐彎抹角
String: \b 3 \b c \77 \7 \d e \e d \44 \9 3 \75 \c e \c 0 \9 \1 9 \5 9 \c 8 \f \b e \c 6 \20 \6
Char: \b 3 \b c \77 \7 d e \e d \44 \9 3 \75 c e c 0 9 \1 9 \5 9 c 8 \f \b e c 6 \20 \6
Hex: 08 33 08 63 3f 07 64 65 1b 64 24 39 33 3d 63 65 63 30 39 01 39 05 39 63 38 0c 08 65 63 36 18 06 00
夠了跳動。假設您正在使用gcc
編譯代碼(忽略警告)。當代碼運行時,使用fwrite
將整個char[]
寫入文件。我還假設在源代碼中只使用小寫字符。
您應該將所有可能的轉義序列\xy
映射爲2位十六進制數字到1或2個字節的序列。有沒有那麼多的人,你可以寫一個程序來模擬編譯器的行爲:
- 如果
x
是任何的a
,b
,f
(如\n
其他轉義序列不是十六進制數字)和e
(由於GNU擴展)。它映射到特殊字符。
- (如果你在源代碼中使用大寫字母,也注意
\E
映射到ESC)
- 如果
xy
形成一個有效的八進制序列。它被映射到具有相應值的字符。
- 如果
x
形成有效的八進制序列。它被映射到具有相應值的字符。
- 否則,
x
保持不變。
- 如果沒有消耗
y
,則y
保持不變。
請注意,實際的char
可能來自兩種不同的方式。例如,\f
和\14
將映射到相同的char
。在這種情況下,可能無法取回源中的字符串。你能做的最多的是猜測源代碼中的字符串是什麼。
以您的字符串爲例,開頭的08
和33
可以來自\b3
,但它也可以來自\10\63
。
使用map生成,有些情況下映射清晰:大於3f
的十六進制不能來自八進制轉義序列,並且必須來自原始字符串中字符的直接解釋。從這裏,你知道如果遇到e
,它必須是第二個字符看起來像十六進制序列。
您可以使用地圖作爲指導,並將模擬作爲一種方法來檢查地圖是否會產生回ASCII碼。在不瞭解源代碼中聲明的字符串的任何信息的情況下,可以派生的最多是源代碼中原始(已損壞)字符串的候選列表。如果您至少知道源代碼中字符串的長度,則可以縮小候選列表的大小。
當然 - 爲什麼不呢?什麼具體問題阻止你這樣做? –
它們不像您期望的那樣被保存爲十六進制值。這是肯定的一件事。 – nhahtdh
你的問題是什麼? – Arpit