2014年10月21日 星期二

Windows server 2008 R2 SP1 kernel socket leak

最近發現在 server 2008 上面跑的 service 出現 connection error,
經過測試, 確定網路是通的
後來自己寫了小程式去做 socket connect 測試, 發現只要同時開多個 socket, 一定會出現 exception

an operation on a socket could not be performed because the system lacked sufficient buffer space

上網查了資料, 這個錯誤常常是因為 windows 有 socket port range 限制, 但是 application 頻繁的打開跟關閉 socket 所已 port number 達到 windows 規定上限

http://blog.zhaojie.me/2010/08/lack-of-dynamic-ports-when-frequently-open-and-close-socket.html

http://blog.miniasp.com/post/2010/11/17/How-to-deal-with-TIME_WAIT-problem-under-Windows.aspx

這種情況通常等個一會讓 windows 把關掉的 socket port number 再重用, 就可以避開
但是我遇到的情況是不管等多久這個 exception 都會出現

繼續查資料發現 windows 還有一個 known issue, kernel socket leak

http://support.microsoft.com/kb/2577795

當這個 issue 發生時, 因為是 kernel 沒有把 socket 正確關閉, 所以除了重開機不然沒救
這個 KB 描述的現象跟我遇到的非常相似, 而且我使用的 server 剛好就是該 KB 有提到的
server 2008 R2 SP1.

可惜的是沒有一個方法可以確定是不是真的發生了 kernel socket leak, 只能先裝上 hotfix
再看看之後會不會發生

2014年10月13日 星期一

在 blog 中程式碼上色的解決方案: Google Javascript code prettifier

想在 blog 中貼上程式碼上色, Google 出了一個很簡單使用的解決方案

Javascript code prettifier

只要在 blog 的 template 加上一個連結
<script src="https://google-code-prettify.googlecode.com/svn/loader/run_prettify.js"></script>

再把程式碼區塊用特定的 html 元素包起來, 就可以幫程式碼上色了

reference:
https://google-code-prettify.googlecode.com/svn/trunk/README.html

用 parameterized queries 防止 SQL Injection

當用程式做資料庫操作時, 不建議把 SQL command 直接寫在 code 裡面, 因為這樣常會有背 SQL injection 的風險, 比較好的方式是使用 parameterized queries.

例如:

string stmt = "INSERT INTO dbo.Test(id, name) VALUES(@ID, @Name)";

SqlCommand cmd = new SqlCommand(smt, _connection);
cmd.Parameters.Add("@ID", SqlDbType.Int);
cmd.Parameters.Add("@Name", SqlDbType.VarChar, 100);

for (int i = 0; i < 10000; i++)
{
    cmd.Parameters["@ID"].Value = i;
    cmd.Parameters["@Name"].Value = i.ToString();

    cmd.ExecuteNonQuery();
}

reference:
http://stackoverflow.com/questions/60174/how-can-i-prevent-sql-injection-in-php
http://stackoverflow.com/questions/8218867/c-sharp-sql-insert-command

2014年7月7日 星期一

Anti debugger tricks

Windows 有 IsDebuggerPresent API 可以讓程式知道自己是不是正在被 debug.
其實這個 API 就是去 PEB 裡面讀取 BeingDebugged 欄位.

程式也可以自己取得 PEB 位址, 然後讀取 BeingDebugged 欄位, 而不呼叫 API.
免得很容易就被人 bypass.

除了 BeingDebugged 欄位外, PEB 還有 NtGlobalFlag 欄位可以檢查是否被 debug.

GetStartupInfo API 也可以用來 anti debug, 因為被 Ollydbg lunch 的程式
StartupInfo 裡面的 dwFlags 會跟被 explorer lunch 起來的不一樣.

Reference:
http://www.codeproject.com/Articles/29469/Introduction-Into-Windows-Anti-Debugging

2014年6月25日 星期三

Debug 程式好用的指令 EB FE

0xEBFE 是一個短跳指令, 作用是跳到這個指令原本的位址
可以看做是單一指令的 infinite loop

有時候想 attach debugger 到某個程式時可以先把 EP 改成 EBFE
等程式在這邊 loop 時再 attach 上去就好了

2014年6月16日 星期一

Debug custom exception filter set by SetUnhandledExceptionFilter

SetUnhandledExceptionFilter 可以讓程式設定自定義的頂層 exception filter
用來處理程式中未被處理的 exception

之前想要 debug 這種 custom exception filter, 但用 debugger 開啟程式後卻怎麼也跑不到
查了後才發現這是 MS 的設計

MSDN 上的描述:

A pointer to a top-level exception filter function that will be called whenever the UnhandledExceptionFilter function gets control, and the process is not being debugged. A value of NULL for this parameter specifies default handling within UnhandledExceptionFilter

不過為什麼要有這麼奇怪的設計? 真的讓人猜不透
如果只有執行檔沒有 source code 時要怎麼 debug?

幸好網路上早有了怎麼 bypass 的方法,
UnhandledExceptionFilter 是呼叫 NtQueryInformationProcess 檢查程式是否正在被 debug 的
所以只要改掉 NtQueryInformationProcess 回傳的值就好了

Reference:
http://evilcodecave.wordpress.com/2008/07/24/setunhandledexception-filter-anti-debug-trick/

2014年6月3日 星期二

Program crash without WER dialog

在 XP 上很容易發生 process silent death,
因為在 XP 上做 error reporting 的機制是由 crashed process 負責,
所以只要將 stack 搞爛, 就可以讓 WER dialog 不顯示
甚至註冊的 unhandled exception handler 也不會被執行

但是在 Vista 之後, 實作 error reporting 的機制移到另外的 process 中, 所以在 XP 上
讓 process silent death 的方式在 Vista 之後就不行了
不過如果搞爛 stack, 雖然有 WER dialog,
但是 unhandled exception handler 不會被執行
猜測是因為 unhandled exception handler 的執行也需要 stack,
但是既然 stack 爛掉了, 自然也就無法執行

Reference:
http://stackoverflow.com/questions/14195327/how-to-crash-a-process-on-windows-7-without-getting-the-wer-dialog

2014年5月19日 星期一

CreateToolhelp32Snapshot enumrate process 的順序

使用 CreateToolhelp32Snapshot 來枚舉 process 的順序是 pid 從小到大
並且循著 process tree 來枚舉

例如下面的 process tree



枚舉的 process pid 順序就會是
4, 580, 736, 4148, 832, 7212, 10444, 10452, 840,936

2014年5月18日 星期日

使用 private/public key 的加密用途

private/public key 是加密技術中的一種, private key 只有自己持有, public key 人人可以持有
private/public key 總是成對的

使用 public key 加密後的資料也只有相對應的 private key 可以解開
使用 private key 加密的後的資料只有用相對應的 public key 可以解開

使用 public key 加密的應用方式通常是保護資料隱密性
像是用在網路上傳輸的私密訊息
因為只有持有 private key 的人才可以解開資料

使用 private key 加密的應用方式通常是確保資料完整性與來源
例如應用程式的數位簽章
一個應用程式的開發者跟 CA 機構申請憑證後得到數位憑證和 private/public key pair
然後用 private key 將 digtital sign 加密後跟 public key 一起寫入應用程式
使用者用 public key 解密後即可得到開發者的簽名證明這個應用程式是該開發者所發行

CA 機構保證申請者的唯一性, 不用怕惡意使用者偽造開發者身分
而且簽入數位簽章時也會將 checksum 之類的資料寫入
因此不怕應用程式被竄改過

2014年5月4日 星期日

透過 samba 讓 android 裝置存取其他 android 系統的檔案 (不需要 root)

iphone 有 air play 可以將手機畫面鏡像投影到 appile tv 上
android 最近出了 miracast 也可以讓 android 手機鏡像投影到另外的 android 裝置
如果家裡有智慧電視或電視盒的人可以方便的將手機裡的多媒體檔案放到大螢幕上欣賞

但是 miracast 是最近才出來的產品, 如果電視盒或是手機有一方不支援, 就不能使用
若是要為了這個功能要去買新的產品又覺得不太划算

其實, 如果只是想要在電視上看手機上的影片, 圖片, 不需要 miracast, 也不需要 DLNA
(DLNA 是個雞肋的功能, 放影片不能載入額外字幕檔)
 只需要裝以下幾個 APP 就夠了

ES 檔案瀏覽器
MX player
BS player
samba server

samba server 可以讓 android 手機用跟 windows 網路芳鄰一樣的方式分享檔案
裝完後啟動設定一下 server, 記得 samba server 強制要求一定要設定 name directory



之後可以用 info tab 來看本機 ip 位址



如果想瀏覽檔案的話, 打開 ES 檔案瀏覽器, 進入局域網選新建
然後加入伺服器位址


假如手機有 root 的話, 
服務器位址那邊填入手機 ip + name directory
ex: 192.168.1.101/sdcard
就可以瀏覽手機內檔案, 想要放照片或影片都沒有問題

 如果手機沒有 root 的話, 需要在 url 上多加 port number
samba protocol 預設是使用 445 port,
但是因為安全性的關係 android 不讓 app 使用這個 port
所以沒 root 的手機會看到 samba server 使用的是 7777 port
所有必須使用以下的 url 形式
192.168.1.101:7777/sdcard

沒有 root 的手機用 ES 檔案瀏覽器可以播放照片沒有問題
但是播放影音檔時就不行了, 猜測是 ES 瀏覽器的 bug

不過 bs player 有支援瀏覽區網, 所以可以用 bs player 連進手機
在 bs player 的瀏覽區網模式用以下 url
 192.168.1.101:7777/sdcard
就可以瀏覽手機內的檔案並撥放

要用 mx player 的話

可以利用 ES 瀏覽器的 http streaming server
首先不要退出 ES 瀏覽器, 讓 ES保持連進手機的狀態
然後打開網路瀏覽器, 在網址列輸入下列 url

http://127.0.0.1:59777/smb/手機ip@手機ip:7777/name directory/file path

ex:
http://127.0.0.1:59777/smb/192.168.1.101@192.168.1.101:7777/sdcard/xxx/yyy.mkv

此時會跳出提示選擇 app 來播放影片, 再選 mx player 就可以了