這是一個隱藏很深的bug因電腦升級而暴露出來的例子。
Protel99se是2000年前後推出的電子設計軟件,包含畫原理圖、畫PCB、CAM、電路仿真等功能。它用法簡明,能滿足大多數情況下PCB設計的需求,而且在低效能電腦上也能流暢執行。至今仍有大量老一輩工程師在使用,因此PCB工廠也必須相容這種陳舊的檔格式。
2008年左右大家漸漸開始發現,在保存工程時,有時會彈出這樣的錯誤框
熟悉C語言的你肯定知道,這是printf這類函數的格式化字串參數寫錯了。但搞電子設計的前輩工程師們並不懂得這麽深入。
終於有一天,一位EE與IT雙修的年輕大佬用OllyDbg探查,揭開了謎底。
原來,軟件中有這樣一個函數,每次呼叫生成一個隨機檔名,用於臨時檔。核心邏輯寫成偽代碼是這樣的
def
get_random_file_name
():
隨機數
=
GetTickCount
()
#1
檔名
=
'
%s
\
%s%x
.tmp'
%
(
**
,
**
,
隨機數
)
while
True
:
if
檔名不存在
:
break
隨機數
=
GetTickCount
()
檔名
=
'
%s
\s
%x
%.tmp'
%
(
**
,
**
,
隨機數
)
#2
return
檔名
如果硬碟很快,迅速保存好了前一個檔,就會導致下次呼叫的間隔太短,1處會返回同一個值,於是執行到2處。而2處的格式字串寫錯了。所以,高效能電腦就會觸發這個bug。
字串位於文字池裏,是明文儲存的,所以只要搜尋這串文字並改正就好了,可以直接給exe檔打修補程式。這位大佬同時釋出了這個二進制修補程式。
參考資料
[原創]關於出現 Protel 99 SE 'Format '%x' invalid or incompatible with argument' 的分析
針對評論區補充一下。
偽代碼只是展示程式邏輯,我用python當皮套只因它精練。
據大佬分析,源程式是delphi寫的,並不是C艹。上述偽代碼展現的業務邏輯是先用ida外掛程式從組譯反推C再簡化而來的,萬惡之源的delphi源碼是怎麽寫的已經不得而知了。