2006年,我工作時的座位坐在wowocock旁邊。wowocock寫代碼的時候代碼風格一團糟。滿篇都是混亂型的命名、超級跨全工程的全局變量,詭異的跳轉。而且屢教不改。但是調(diào)程序卻很牛,開著WinDbg,基本上不用看源碼,也知道發(fā)生了什么。
因為不用看源碼,所以看Windows內(nèi)核原有的代碼和看自己的代碼基本沒有太大的區(qū)別,只要別跟太遠。這樣就獲得了遠遠超出一般只能看懂C語言的程序員的能力。許多問題沒有前人的指點也可以自己解決。而且能做出很多別人做不出來的事來。
有時候碰到一些問題,比如說在WindowsXP有,但是Windows2000下沒有的調(diào)用。一般人也就直接放棄了。但是他卻會自己去跟蹤了XP下調(diào)用的實現(xiàn),然后在2000下寫一個替代品出來。其實在安全軟件領域,反匯編、自己patch、和crack早已經(jīng)大行其道。無論你站在邪惡破壞的一方,還是站在正義安全的一方,都不得不這樣做。因為應用層病毒的時代早就過去了,rootkit的時代到來了。
這里涉及的到其實是一個理解調(diào)試器里的匯編語言的能力的問題。你可以覺得那些rootkit牛人的技術有多強,他們知道很多對你來說聞所未聞的東西。但是實際上他們也可以對你說這其實很簡單。因為答案就在調(diào)試器窗口里的那堆匯編里。
雖然我大學畢業(yè)的時候已經(jīng)是2002年,但是大學里的匯編語言教材卻還停留在8086階段。無法理喻這種落后性。從實模式編程到保護模式編程是一個飛躍,這個過程在從DOS進化到Windows9X的時候就已經(jīng)發(fā)生。然而我在大學期間里卻只學到了實模式的編程,以簡單的觀念看待X86的CPU,甚至不知道Ring0和Ring3的切換,本質(zhì)也就是不知道應用與內(nèi)核的區(qū)別。
實際上大部分程序員都是如此。很可能一生都不會再次去接觸那一堆匯編語言。當程序崩潰調(diào)試器崩出來一堆非C語言的東西,那些只是天書而已。當場關閉然后回頭去猜測問題可能出現(xiàn)在哪里。如果猜不出來,那么就可以放棄了。其實原因并不是因為我們懶惰,而是因為我們所學的東西沒有實際用途。一件好東西如果沒有用,就像是屠龍寶刀,如果沒有龍可以屠,那就只是廢鐵一塊。顯然很少有人再去寫實模式下的程序了(更何況是匯編)。而我們急需要做的事情,又不是我們所學能解決得了的。
很多朋友很想學習內(nèi)核編程。因為這聽起來更酷。是真的。這很有趣,而且又可以好好的復習一下匯編語言,讓廢鐵重新變成寶刀,那何樂而不為呢。內(nèi)核編程和應用編程的區(qū)別在于,內(nèi)核總是運行在復雜的條件下。一個應用程序只要在自己的進程空間內(nèi)放心大膽的跑就行了。就算出一點問題,程序崩潰了,問題當然是在這個進程之中了。讓我們甕中捉鱉吧。內(nèi)核則不同。內(nèi)核的代碼可能運行在系統(tǒng)中所有的進程和線程環(huán)境下。而且是同時的。內(nèi)核模塊之間互相調(diào)用,和硬件交互。等待中斷,發(fā)出指令讓CPU進行種種“熱身”。當問題發(fā)生,操作系統(tǒng)將會崩潰。WinDbg將會向您展示真正的天書,記載著Windows在最后崩潰瞬間的狀況。OK,我們不是MS的程序員,不可能看到秒鐘在停止前指向某一行C語言代碼。唯一值得慶幸的是:它們曾今是C語言代碼,只是經(jīng)過編譯了。
學習了wowowock多年的調(diào)試經(jīng)驗,我和他合寫了那本在網(wǎng)上流傳的《天書夜讀》。我個人感覺匯編在應用程序的編程中作用不大。因為應用編程環(huán)境相對簡單,而且代碼規(guī)模宏大得多。而內(nèi)核往往是小巧而精致的。期望只懂C語言就搞定自己編寫的內(nèi)核模塊中的BUG顯得不太現(xiàn)實。當然我不排除有這樣的可能。但是當我們寶刀在手,Windows內(nèi)核的天書直接向我們放開閱讀時,還有什么能難得住我們的呢?我非常感謝博文視點的朋友,最終將《天書夜讀:從匯編語言到Windows內(nèi)核編程》正式出版。相信更多的程序員同行和愛好者,會因此打開全新視野的大門。
上述文字由《天書夜讀:從匯編語言到Windows內(nèi)核編程》作者譚文提供