分開後,下次見面不知道是多久之後的事情
今晚在台北街頭的不是世界級駭客跟世界級書匠
只是兩個二十幾歲的年輕小夥子.
無話不聊,無話不聊
謝謝你,從你身上學到很多.
加油,相信你會發展的很好. :)
分開後,下次見面不知道是多久之後的事情
今晚在台北街頭的不是世界級駭客跟世界級書匠
只是兩個二十幾歲的年輕小夥子.
無話不聊,無話不聊
謝謝你,從你身上學到很多.
加油,相信你會發展的很好. :)
這個禮拜被派去匈牙利首都布達佩斯參加會議,第一次一個人跑到地球的另外一邊,出發前心情有點忐忑。台北沒有直達布達佩斯的班機,所以必須先飛香港、轉機到德國、再轉小飛機到布達佩斯。
在慕尼黑的時候小緊張了一下,被海關當做偷渡客 ,不過因為匈牙利簽證天衣無縫(廢話本來就是真的) 也有回程機票,就讓我走了。哈哈!
![]()
Budapest給我的感覺有點介於台南與花蓮市之間 ,建築挺漂亮,但是現代化的程度還ok而已。物
價在歐洲應該算偏低,比台北略高吧!一份麥當勞大約快兩百台幣。想要用少少的經費體驗歐洲風情,這裡算是自助不錯的選擇。
抵達之後,立刻到information center換福林以及買Budapest card。
我買的Budapest card是三日票,可以免費達乘大眾交通工具,多處景點也有折扣。
不過如果只需要免費坐捷運跟公車,推薦更划算的One-day travel card,每人1500福林。
如果算的更精一點,捷運及公車的單程票是290福林,制定好計畫是有可能把一天的車費降的更低一些。建議至少第一天買張One-day travel card,來回坐公車捷運熟悉一下街道以及方向。
隨後做200E公車前往捷運站Kobanya-Kispest,路上遇到馬來西亞華僑,閒聊了一下.。
到捷運站之後,坐了12站抵達旅館附近的站點Nyugati pu。
說是捷運,其實只不過是我們的台鐵普通車在地底下跑,挺有歷史的。
出了捷運站找了一下路,最後順利抵達旅館check-in。
發了報平安的訊息之後,衣服也沒換澡也沒洗,立刻出門找market買水。
Budapest沒有看到國際連鎖知名的超商,為了找買水的地方,第一天就破了自助旅行的大忌,一個人在小巷子裡子來走去。最後眼尖看見一間店鋪有賣水,買了水之後出門想認 一下標誌,原來布達佩斯的超商外面掛的牌子是可口可樂的標誌,還會有一個0-24的牌子。
回旅館休息,洗了澡小憩片刻,安排了幾個景點之後又出門了。
第一站坐捷運來到Opera,這座Opera有超過百年的歷史,本來想買張票,但是5/1剛好公休。只好前往下一站位於Kossuth ter站的國會大廈。之前就聽說布達佩斯的國會大廈是歐洲最美,哈,就來見識一下有多美。
結果一出站,映入眼簾的國會大廈果然美的讓我停止呼吸... 不過!!5/1似乎也沒有開放內部導覽,扼腕阿!! 好吧,那只好去國會對面的博物館繞繞,這間博物館應該是以前王宮貴族的家改造的。內部雖然只有三層,卻大到讓我迷路。不過展出的東西實在是沒什麼,有騙錢的嫌疑。(門票600福林)
參觀完以後,坐上國會門口的2路電車,沿著多瑙河欣賞一下風光.當電車開到Erzsebet橋
附近時,決定上橋走走.這一走就開啟了兩小時的走路旅程...
倒也不是橋太長走不完,而是走到另外一端時發現許多觀光客朝一個小丘的階梯拾級而上.
我也就跟上瞧瞧有什麼好玩的. 爬到一半竟然看到St.Gellert的雕像!
這是原本想要來的景點,但因為沒有大眾交通工具直達而放棄.想不到竟然莫名其妙的就到了...XDXD
繼續向上爬,爬到飢腸轆轆氣喘如牛,但是沿途卻賞了不少配斯以及多瑙河的好風景.最後終於到了丘頂,看到了Liberation Monument,趕快買了支雪糕補充體力.XD
註:後來才知道在M2的Astoria站搭乘47,49路面電車過多瑙河在蓋雷特酒店前下車,那站是蓋雷特山比較正統的登高起點.還可以洗溫泉喔!山上看夜景也是很美的!
下了小丘又沿著橋走回配斯,途中順著人群到達一個戶外演唱會的地點,人很多很high,可惜聽不懂.看地圖決定去著名的Vaci大街瞧瞧.這條街是以餐館跟紀念品聞名,相當漂亮的歐洲大街.話說歐洲人好像很喜歡在戶外吃,就連漢堡王也要在店外面圍一圈讓客人坐. Vaci street的另外一端是Central Marcket,最大的傳統市場.但是今天竟然休市! 這時候我才發覺這城市怎麼了,沿街的商店幾乎都是休市,遊客似乎比居民還多XD 可能5/1是什麼重大節日吧.那只後之後有緣再來拜訪了.
走了一下午腳也酸了.乾脆坐上49路電車,來來回回的欣賞布達佩斯的城市風光.最後時差發作,竟然在電車上睡著了哈哈.買了麥當勞跟水之後就回飯店休息了.
(Day 2)
今天早上出門,特地先去參觀了旅館附近的火車站.整體感覺挺有歷史的,沒有剪票口,要上車是滿容易的,哈哈。 出了火車站搭上四路公車,前往Moszcva廣場.途中經過Margit橋,可以到達號稱多瑙河綠寶石的Margit island,如果星期日有時間的話再來參觀.(六路也可以到)
到了Moszcva廣場滿滿的都是人,這裡不只是布達城捷運與公車的交會點。也是前往城堡山的搭車起點.上坡之後搭上16路公車,行駛一小段之後我就後悔了.因為城堡山其實算個小丘.不陡路途也不長,其實讓公車開一站進入城堡山之後,就可以下車步行.當機立斷,馬上在城堡山城門口下車,開始了一整天的暴走 XDXD
城門口附近是數間博物館,有的展覽兵器,也有的是歷史文物.布達佩斯身為一個遊客比居民多的城市,廣設博物館是很聰明的事情.整個城市博物館總數應該有五十座,不知道要逛哪邊的話,就逛逛博物館吧! 第二聰明的事情就是公共廁所要收錢.博物館沒興趣,廁所總是要上的吧XD 在門口收錢的可不是凶神惡煞的地頭蛇,是文質彬彬的政府公職,旁邊還擺一台收銀機可以找錢XD.
扯遠了,入了城堡山門口之後變開始步行,印入眼簾的是漂亮的建築物以及壯觀的教堂.參觀了漁夫堡,馬提亞斯教堂,最令我印象深刻的還是Royal Palace.匈牙利皇室似乎喜歡以威猛的雄獅為誌,到處可見栩栩如生的獅像.
城堡山的景色實在是很美,不論是建築物的壯觀,或是向山下眺望多瑙河,都讓人流連忘返.
中午在皇宮附近用餐之後,在附近看好了一條下山小徑,沿著小徑行走,不一會兒就抵達百年歷史的Szechenyi chain bridge.
過了橋之後買了支雪糕在公園裝悠閒,這裡剛好位於 M1捷運的起點Vorosmarty,那就去昨天無緣的Oprea吧! 今天果然有開張!晚上歌劇最便宜有500福林的座位,不過要聽到九點半. 一個小時的參訪要價3000福林...好詭異的比例,讓我考慮一下吧...
買了一些紀念品之後,繼續沿著歐洲最古老的地鐵M1 前往Szechenyi furdo站.這一站可以去泡溫泉,聽說容易遇到同性戀 XDXD
一出站就是中央公園,許多匈牙利人在這裡遊玩,很熱鬧. 往Andrassy大道的方向走(可以感受到地鐵在腳下震動@"@),不一會兒就到達英雄廣場.這座廣場是百年前為了紀念匈牙利建國一千年而造,有許多匈牙利英雄的雕像,非常漂亮,還遇到新人來這裡拍婚紗,實在是很幸福呢 ^^Y
出了英雄廣場之後,又沿著Andrassy這條很舒服的大道走了一站,Bajza u.我遇到了11路公車的極限,一整天的行走讓我左腳膝關節不舒服.只好去超市買了水,牛奶跟麵包。然後回到旅館休息.
傍晚六點半,躺在床上還在想晚餐要吃什麼,疲倦感襲來,就這樣睡了11個小時. XDXD
1.“Windows via C/C++”, “The old new thing”
2.“Windows NT 2000 Native API Reference”
3. “Windows Internals ”, “Memory management algorithm and implementation in c/c++ ”
4.“Windows Internals ”
5.“Programming the Windows Driver Model””Windows Internals ”, OSR Nt Insider 6.Winddk\src\filesys\filter\sfilter,filespy ,OSR
7.Winddk\src\filesys\filter\miniFilter\passThrough, minispy, ctx , MS file system , OSR
8.Winddk\src\filesys\fastfat,“ Windows NT File System Internals ”, OSR
9.“天書夜讀”“Undocumented Windows 2000 Secrets”, Sysinternals forum
10.“Intel® 64 and IA-32 Architectures Software Developer’s Manual”,”自己動手寫作業系統”
Debugging and trouble shooting
1.”軟件調適”
2. ”Advanced Windows Debugging”
3. “Memory Dump Analysis Anthology”
4. Windbg
註:這是一份Windows系統的學習地圖。所記錄的是Win32 API以及更底層的系統相關資料。不包含硬體及網路相關。學海無涯,僅取最具代表性之參考資料。
有人古典音樂可以百聽不膩,可惜我沒有那個福氣與慧根,不論如何用心欣賞都會想睡。爵士樂就好多了,尤其是Bill Evans與Thelonious Monk這兩位大師的曲子,可以一邊聽一邊思考問題、撰寫程式。
腦海中的爵士樂手的名字非常之少,能說出名字的只有這兩位。(Thelonious Monk的first name還不會念,常常以專輯名稱Solo Monk來稱呼之。)介紹這兩位大師的音樂給我的正是恩師,路德維希先生。
明天是老師重要的日子,這裡以一曲輕快的I hadn't anyone till you,預祝老師一切順利![]()
相關知識:Windows kernel driver,x86 knowledge, Windbg command
原文連結
在開發Windows Kernel Driver的時候,最常使用的記憶體配置的函式之一是ExAllocatePoolWithTag。此函式可以指定一個四個字的標籤(Tag),而配置出來的記憶體便會"貼上"這個標籤。在記憶體洩漏(memory leak)的情況,此標籤就成為解決問題的重要工具!
不過在使用記憶體標籤功能之前,如果系統的不是Windows 2003、Vista或是更新的版本,那我們需要調整一下系統設定。下載Windbg並且安裝完成之後,此時會發現同一包裡面除了Windbg還有另一個小工具:GFlags。這個小工具讓我們可以藉由UI對系統的各項設定進行調整,好處就是不用去死記這些設定對應的Registry。繼續偵錯之前,先讓我們把"Enable Pool Tagging"打開:
題外話,我覺得周大師這篇"Live Debugging環境設定"寫的很棒。
回到本文,現在我們覺得有Memory leak發生,想中斷在ExAllocatePoolWithTag偵錯。除了前一篇所提利用IAT位置來中斷,也可以使用條件中斷,檢查ExAllocatePoolWithTag的第三個參數,如果是我們的標籤就中斷,其餘放行。
假設標籤是"BaPd",轉成ACSII碼 B = 42、a = 61、P = 50、d = 64。因為Intel-CPU處理資料的時候遵守Little endian(小頭派)的運作原則,所以開頭的資料會放在記憶體的低位(B在記憶體的地址比a少一個位元組,a又比P少一個位元組),但是在Windbg顯示32bits的時候是由高位(也就是d)到低位(最低的是開頭的B)顯示,所以會看到d(64)、P(50)、a(61)、B(42),串起來就是64506142。依照本系列第一篇所提及的條件中斷語法:
1: bp nt!ExAllocatePoolWithTag ".if(poi(@esp+0xC) == 64506142){da @esp+0xC L4;k}.else{g}"
這樣就會在每次(呼叫ExAllocatePoolWithTag) + (Tag = "BaPd")的時候,列印出標籤、堆疊的內容並且中斷。但缺點是條件中斷會讓系統效能明顯的降低X10。由於標籤實在是太重要了,Windows提供了另外一種方法:用Windbg以ed(enter value)指令把想要中斷的標籤輸入到nt!poolhittag,如此一來每當屬於該標籤的記憶體被配置,系統會中斷。記得Intel的小頭政策,輸入標籤時要反向輸入CPU才看的懂。
下面這個例子我們先清掉原來的條件中斷點,然後輸入'dPaB'到nt!poolhittag,待中斷發生時檢查堆疊與標籤內容是否是我們想要的:
1: kd> bl
2: 0 e 82734b10 0001 (0001) nt!ExAllocatePoolWithTag ".if(poi(@esp+0xC) == 64506142){da @esp+0xC l4;kvn}.else{g}"
3: kd> bc 0
4: kd> ed nt!PoolHitTag 'dPaB'
5: d> g
6: Break instruction exception - code 80000003 (first chance)
7: nt!DbgBreakPoint:
8: 8269ef0c cc int 3
9: kd> kvn
10: # ChildEBP RetAddr Args to Child
11: 00 8273ca88 82735401 80809f70 83d816f8 80829ae0 nt!DbgBreakPoint (FPO: [0,0,0])
12: 01 8273cadc 829a66c6 00000000 00000038 64506142 nt!ExAllocatePoolWithTag+0x8eb
13: 02 8273cafc 829acc8f 80831cb8 82743100 00000000 nt!BootApplicationPersistentDataInitialize+0x50
14: 03 8273cca0 8292ab03 8080a648 39332b42 83540c00 nt!InitBootProcessor+0x412
15: 04 8273cd0c 82733804 827433c0 82743100 8273d000 nt!KiInitializeKernel+0x770
16: 05 00000000 00000000 00000000 00000000 00000000 nt!KiSystemStartup+0x32c
17: kd> da 8273cadc+0x10 L4
18: 8273caec "BaPd"
分析dump的時候,如果遇到沒有symbol的module,又恰巧它用了Frame pointer omission的最佳化,在函式的開頭跟結尾省去了對ebp的操作,那麼stack的分析很可能就落的沒有結果,譬如下面的這個例子,Windbg分析堆疊最後斷在savrt,無法得知堆疊更早的資訊,對於偵錯幫助有限:
1: bd74e438 8045163d nt!IopParseDevice+0xa04
2: bd74e4ac 804a4e8a nt!ObpLookupObjectName+0x4d5
3: bd74e5bc 80496b85 nt!ObOpenObjectByName+0xc5
4: bd74e690 be7728c6 nt!IoCreateFile+0x3ec
5: bd74e6e0 be77382b savrt+0x458c6
6: bd74e6ec be7752a5 savrt+0x4682b
7: bd74e768 be744773 savrt+0x482a5
8: bd74e77c be742e4b savrt+0x17773
9: bd74e7a4 be745e75 savrt+0x15e4b
10: 00000000 00000000 savrt+0x18e75
怎棒?幸好k指令(Display stack backtrace)可以指定參數,讓Windbg重新分析堆疊,進而逼近原始的真實資料。
k = ebp esp eip
大致流程是這樣的,當發生先前所舉的那個情況,偵錯者便印出堆疊上的所有資訊,然後依照x86堆疊運作規則,以及邏輯推理,判斷"斷掉的"堆疊所記錄的ebp、esp以及eip(我覺得,應該看成ReturnAddress),然後餵給k指令。其實Call stack的整個追蹤就是靠這三個資訊,Windbg也是使用這三個訊息,反推出整個Call Stack的"長相"。Nt Insider:Stacking the deck是一篇很不錯的參考。
怎麼起頭呢?我們先在堆疊上找一個"可能是正確"的ebp。ebp會有什麼特徵?ebp會存放前一個stack frame的ebp之位置,而ebp+4則是存放了return address。首先注意到的是第21行:
1: kd> dps bd74e7a4
2: bd74e7a4 00000000
3: bd74e7a8 be745e75 savrt+0x18e75
4: bd74e7ac e5d590b0
5: bd74e7b0 e369d7a8
6: bd74e7b4 be74355a savrt+0x1655a
7: bd74e7b8 bd74e7c8
8: bd74e7bc e369d7a8
9: bd74e7c0 e369d7a8
10: bd74e7c4 be741b0f savrt+0x14b0f
11: bd74e7c8 00000000
12: bd74e7cc e5da1e68
13: bd74e7d0 e5da1e70
14: bd74e7d4 be741c26 savrt+0x14c26
15: bd74e7d8 00000000
16: bd74e7dc e5da1e70
17: bd74e7e0 e1bffb48
18: bd74e7e4 be8329bc SYMEVENT+0xd9bc
19: bd74e7e8 00000000
20: bd74e7ec e5da1e70
21: bd74e7f0 bd74e810
22: bd74e7f4 be834e74 SYMEVENT+0xfe74
23: bd74e7f8 e5da1e70
24: bd74e7fc e1374c28
25: bd74e800 e5da1e68
26: bd74e804 bd74e870
27: bd74e808 e1374c30
28: bd74e80c e1374c28
29: bd74e810 bd74e824
30: bd74e814 be835023 SYMEVENT+0x10023
31: bd74e818 e5da1e68
32: bd74e81c bd74e870
33: bd74e820 e1374c48
34: bd74e824 bd74e838
35: bd74e828 be82b07f SYMEVENT+0x607f
36: bd74e82c bd74e870
1: kd> k = bd74e810 bd74e810-8 be834e74
2: ChildEBP RetAddr
3: WARNING: Stack unwind information not available. Following frames may be wrong.
4: bd74e810 be835023 SYMEVENT+0xfe74
5: bd74e824 be82b07f SYMEVENT+0x10023
6: bd74e838 be833d28 SYMEVENT+0x607f
7: bd74e854 be82c7b9 SYMEVENT+0xed28
8: bd74e894 bfd7fd2a SYMEVENT+0x77b9
9: bd74e8fc 8041fb8b <EDIT - removed module name>+0xcd2a
10: bd74e910 8049c945 nt!IopfCallDriver+0x35
11: bd74ea98 8045163d nt!IopParseDevice+0xa04
12: bd74eb0c 804a4e8a nt!ObpLookupObjectName+0x4d5
13: bd74ec1c 80496b85 nt!ObOpenObjectByName+0xc5
14: bd74ecf0 80497f27 nt!IoCreateFile+0x3ec
15: bd74ed30 80465691 nt!NtCreateFile+0x2e
16: bd74ed30 77f8f9c5 nt!KiSystemService+0xc4
17: 0006e808 00000000 ntdll!NtCreateFile+0xb