最近買了Flex與Visual Studio For C#兩本書來看,不知道為什麼,我對把程式碼內砍在HTML上的東西總是會感冒,尤其是又得加上JavaScript, CSS等等的,儘管DreamWeaver已經儘量讓這些不同的程式看起來不是那麼難以處理,但終究是沒辦法像Delphi寫Win32那麼的方便,尤其是除錯時更牽涉到了瀏覽器的支援性,想到此,對PHP, ASP等網路應用開發總是興趣缺缺。
我想這些大公司大概也意識到,一個開發員要兼顧所有技術,幾乎是不可能的任務,但WebBase的應用程式又是大勢所趨,本來我是寄望Delphi在Windows上的成就能夠轉移到Web應用上,但看來這不是一獗可至,雖然Delphi也有解決方案,但卻不比目前主流的技術方便到哪裡去。
以前曾用Flash搭配PHP寫過很小型的資料庫應用,那時我就覺得Flash若能把前後端整合起來,變成一個獨立的開發環境,那麼AS的開發員就不用自己去寫什麼接收、輸出XML之類的東西,果然後來Flex就冒出來了,目前僅玩過一遍他的IDE環境,雖然與Delphi, VC那種怪物仍有一大段差距,但就Web應用來說,已經非常足夠了。
至於VC的WPF我也小看了一下,對於C#,稍微翻過大概就知道怎麼寫了,每種物件導向語言其實都差不多,對有C++/Java/Pascal的人來說不難上手,但微軟似乎怎麼也放不開,主力仍舊放在MsSQL, ASP.NET上,相對於Flex後端的自由度來說,讓我有點翻不下去。
兩種開發環境都有自己的優勢,C#秉持著主流語言的模式,吸引其他開發員加入,但在後端的自由度不夠,似乎總是要用微軟的解決方案才能使用。
Adob的AS在物件導向上太過模糊,AS的初學者很容易寫成義大利麵程式,不管是Flash或Flex,他的IDE環境也都沒有VC或Delphi來的強大。
最後比較起來,我還是偏好使用Flex,畢竟在視覺上還是Adobe具有絕對的優勢,只要Adobe的Flash Player夠爭氣,我相信是有拿來做大專案的本錢的。
2009年1月4日 星期日
2008年10月13日 星期一
愛情最後的手段
輸家,永遠是痛苦的一方,無論是自己還是周遭的朋友,在必要的時後,都必須用科學的態度,客觀的審視狀況,縮短傷痛的深度與時間,通常男女的搭配都是一強一弱,弱的一方,往往就是愛情裡的輸家,何謂弱的一方呢,舉例來說,男人在外留連夜店不歸,女人在家苦守電話難眠,狀況非常明顯,男人覺得光陰似箭,女人覺得分秒難挨,除非女人在心靈學上有深厚的修養,否則會一直扮演輸家的角色直到最後,但心靈修養高的女人,卻也不屑與這樣的男人深交,那麼這時就必須有破釜沈舟的決心逆轉已成的敗局,雖然這其中帶有報復色彩,但實際上對雙方來說還是具有正面意義的。
失去,是愛情的終點站,當其中一方對"失去"並不在意時,愛情就已經不再存在,所謂最後的手段,就是把失去的角色對調,也就是俗稱的,在對方甩了你之前,先甩了他。
雖然聽起來有點老套,但重點在於這個"甩"字,要用得高明,就必須有勇氣與心機。
雙方只要仍有愛情(尚未出軌),就會對"失去"產生過敏,這也是反敗為勝的最後機會,比對方更變本加厲,更加明顯的透露著第三者.....That's All.....很簡單吧...
不過大部分人都不敢這麼做(尤其是女人),這一篇有點無聊,剛好聽到個酒鬼聽她的女朋友在訴苦,兩個人苦來苦去的,卻不想想反敗為勝的方法.......好....打完收工...
失去,是愛情的終點站,當其中一方對"失去"並不在意時,愛情就已經不再存在,所謂最後的手段,就是把失去的角色對調,也就是俗稱的,在對方甩了你之前,先甩了他。
雖然聽起來有點老套,但重點在於這個"甩"字,要用得高明,就必須有勇氣與心機。
雙方只要仍有愛情(尚未出軌),就會對"失去"產生過敏,這也是反敗為勝的最後機會,比對方更變本加厲,更加明顯的透露著第三者.....That's All.....很簡單吧...
不過大部分人都不敢這麼做(尤其是女人),這一篇有點無聊,剛好聽到個酒鬼聽她的女朋友在訴苦,兩個人苦來苦去的,卻不想想反敗為勝的方法.......好....打完收工...
2008年9月28日 星期日
軟體防駭小招數
辛苦寫的程式一下被破解了,那種感覺真的是很XXX....
目前有很多加殼程式,但只要遇到低階語言高手,還是會被破解,只是多花點時間而已,所以我花了幾天,設法在高階語言上造成破解障礙。
一般來說破解者常用的方是就是修改程式內的日期,讓程式以為還沒到期,或是用跳躍的方式,讓程式跳過驗證序號或是日期的那一段函數,所以不管設多少關卡,只要破解者有耐心一一跳過,還是可以破解成功的,況且設太多關卡,對撰寫者來說也是一種困擾。
程式的執行是具有連續性的,某個動作後發生某個事件,這也讓破解人只要依著順序去找出關鍵位置就能輕易跳過,所以這個位置就是雙方鬥智的關鍵。
我想到的方法必須依賴到網路伺服器做驗證,一旦驗證端是在程式內,無論如何都會被跳過,所以改由伺服器來做驗證,以日期來說,程式先送軟體過期日給伺服器,這時第一個問題來了,破解者可以輕易的變造這個日期,所以日期在傳送之前必須先經過加密,例如
myDate:= 'alsdkfjsks233+==';
SendmyDate(myDate); ////傳送到伺服器
伺服器收到後做解密的動作然後進行驗證,關鍵就在此處,如果伺服器驗證後傳回布林值或是其他帶碼,程式收到後勢必還需要再做判斷,例如
if serverBack = true then 驗證過關 else 驗證失敗
像這樣判斷,一下子就被破解了,破解者只要直接跳到驗證成功,程式就會正常的執行下去,所以在程式中不可出現像這樣的判斷,我的作法是伺服器直接傳回Event名稱。
舉例來說,假設程式是寫在一個Timer的onTimer上,那麼這個Timer的EventName就由伺服器回傳,也就是說必須在程式中有兩個onTimer事件,一個是驗證過關 onGoodTimer ,一個是驗證失敗 onBadTimer ,而Timer在初始狀態下是不賦予任何事件的(也可以先賦予失敗事件),當伺服器驗證失敗後,直接傳 "onBadTimer" 回來,然後直接將這個字串所代表的事件賦予Timer,注意,千萬不要寫成
if serverBack = 'onBadTimer' then xxx (這跟前面沒兩樣)
必須直接賦予,代碼如下
procedure TmainForm.ExecMethod(OnObject: TObject; MethodName: string) ;
var
Routine: TMethod;
begin
//事件所在位置是mainForm,所以OnObject指定為mainForm
myTimer.OnTimer:= nil;
Routine.Data := Pointer(OnObject);
Routine.Code := OnObject.MethodAddress(MethodName) ; //由mainForm調出事件的指標位置
myTimer.OnTimer:= TNotifyEvent(Routine);
end;
執行:
ExecMethod(mainForm, ServerBack);
這樣一來,即使破解者跳過驗證這一段,Timer也無法得到正確的Event而變成沒有作用,即使破解者知道這個作法,也必須從你的程式碼中找出正確的事件來,這會讓他們很頭痛,況且他不一定會朝這方面去想,更增加了破解難度,如果再加上CodeVisual或Themida這種難纏的殼,軟體被破解的機率就比較小了。
由於Pascal跟C++是屬於編譯型程式,所以無法把ASC碼當作機械碼用,如果是直譯型程式(如Flash, JavaScript),用這方式就更方便了,甚至可以將整個Function放在Server,回傳時只要調用Eval函數轉換即可。
目前有很多加殼程式,但只要遇到低階語言高手,還是會被破解,只是多花點時間而已,所以我花了幾天,設法在高階語言上造成破解障礙。
一般來說破解者常用的方是就是修改程式內的日期,讓程式以為還沒到期,或是用跳躍的方式,讓程式跳過驗證序號或是日期的那一段函數,所以不管設多少關卡,只要破解者有耐心一一跳過,還是可以破解成功的,況且設太多關卡,對撰寫者來說也是一種困擾。
程式的執行是具有連續性的,某個動作後發生某個事件,這也讓破解人只要依著順序去找出關鍵位置就能輕易跳過,所以這個位置就是雙方鬥智的關鍵。
我想到的方法必須依賴到網路伺服器做驗證,一旦驗證端是在程式內,無論如何都會被跳過,所以改由伺服器來做驗證,以日期來說,程式先送軟體過期日給伺服器,這時第一個問題來了,破解者可以輕易的變造這個日期,所以日期在傳送之前必須先經過加密,例如
myDate:= 'alsdkfjsks233+==';
SendmyDate(myDate); ////傳送到伺服器
伺服器收到後做解密的動作然後進行驗證,關鍵就在此處,如果伺服器驗證後傳回布林值或是其他帶碼,程式收到後勢必還需要再做判斷,例如
if serverBack = true then 驗證過關 else 驗證失敗
像這樣判斷,一下子就被破解了,破解者只要直接跳到驗證成功,程式就會正常的執行下去,所以在程式中不可出現像這樣的判斷,我的作法是伺服器直接傳回Event名稱。
舉例來說,假設程式是寫在一個Timer的onTimer上,那麼這個Timer的EventName就由伺服器回傳,也就是說必須在程式中有兩個onTimer事件,一個是驗證過關 onGoodTimer ,一個是驗證失敗 onBadTimer ,而Timer在初始狀態下是不賦予任何事件的(也可以先賦予失敗事件),當伺服器驗證失敗後,直接傳 "onBadTimer" 回來,然後直接將這個字串所代表的事件賦予Timer,注意,千萬不要寫成
if serverBack = 'onBadTimer' then xxx (這跟前面沒兩樣)
必須直接賦予,代碼如下
procedure TmainForm.ExecMethod(OnObject: TObject; MethodName: string) ;
var
Routine: TMethod;
begin
//事件所在位置是mainForm,所以OnObject指定為mainForm
myTimer.OnTimer:= nil;
Routine.Data := Pointer(OnObject);
Routine.Code := OnObject.MethodAddress(MethodName) ; //由mainForm調出事件的指標位置
myTimer.OnTimer:= TNotifyEvent(Routine);
end;
執行:
ExecMethod(mainForm, ServerBack);
這樣一來,即使破解者跳過驗證這一段,Timer也無法得到正確的Event而變成沒有作用,即使破解者知道這個作法,也必須從你的程式碼中找出正確的事件來,這會讓他們很頭痛,況且他不一定會朝這方面去想,更增加了破解難度,如果再加上CodeVisual或Themida這種難纏的殼,軟體被破解的機率就比較小了。
由於Pascal跟C++是屬於編譯型程式,所以無法把ASC碼當作機械碼用,如果是直譯型程式(如Flash, JavaScript),用這方式就更方便了,甚至可以將整個Function放在Server,回傳時只要調用Eval函數轉換即可。
訂閱:
文章 (Atom)