Windows黑客編程基礎

俗話說:“萬事開頭難”,編程也不例外,初學者如何入門關鍵要有一份正確的理論作指
導,下面的這篇文章雖不能說是至理名言,但我相信通過作者細膩的分析、講解和引導,
定能給初學者起到啓蒙的作用。本文分上下兩部分,本期注重於講理論,更精彩的還在下
期,請讀者密切關注。

Windows黑客編程基礎(上)

文/勁風

上面的題目帶有“黑客”兩個字,請大家別誤會了,其實沒有多少是講黑客的,這完全是
一篇菜鳥級的編程雜談,如果您已是高手,就不必在此浪費時間了 。

前幾天在網上看了“病毒”兄寫的《WIN下編程須知》一文,覺得在編程方面要寫出一篇適
合初學者們看的入門級文章的確很重要,可惜病毒兄只在該文裏介紹了線程、消息、句柄
等幾個基本概念。很多初學者看了對編程還是感到很迷惑,一個從來沒有寫過程序的人如
何入門?如何在短時間內寫出自己的程序來?筆者帶着這些問題寫了這篇文章。這也是筆
者在學習編程的初期所遇到的困惑,在此根據筆者的個人理解將其整理成文,希望能引起
廣大菜鳥們的共鳴,對初學者們有所幫助。

從理論上說,任何一門語言都可以在任何一個系統上編程,只要找到該系統提供的“接口
”和對系統內部機制有深入的瞭解就可以了,至少我是這麼認爲的。正如c語言可以在win
dows下編程,也同樣可以在Linux上大放異彩一樣。

編程是一項很繁雜的工作,除了應用編程工具之外,瞭解系統本身內部工作機理非常重要
,這是你寫出穩定兼容的程序所必不可少的前提條件。你要在哪一種系統上編程就要對該
系統的機制進行研究,至少你應該知道一個程序在那個系統上是如何運行的。

一、瞭解Windows 內部機制

Windows 是一個“基於事件的,消息驅動的”操作系統。

在Windows下執行一個程序,只要用戶進行了影響窗口的動作(如改變窗口大小或移動、單
擊鼠標等)該動作就會觸發一個相應的“事件”。系統每次檢測到一個事件時,就會給程
序發送一個“消息”,從而使程序可以處理該事件。每個Windows 應用程序都是基於事件
和消息的,而且包含一個主事件循環,它不停地、反覆地檢測是否有用戶事件發生。每次
檢測到一個用戶事件,程序就對該事件做出響應,處理完再等待下一個事件的發生。

Windows 下的應用程序不斷地重複這一過程,直至用戶終止程序,用代碼來描述實際上也
就是一個消息處理過程的while循環語句。

下面便簡單介紹一下與 Windows 系統密切相關的幾個基本概念:

⒈窗口:這是我要說的第一個概念。似乎是地球人都知道的事兒了,窗口是Windows本身以
及Windows 環境下的應用程序的基本界面單位,但是很多人都誤以爲只有具有標題欄、狀
態欄、最大化、最小化按鈕這樣標準的方框才叫窗口。其實窗口的概念很廣,例如按鈕和
對話框等也是窗口哦,只不過是一種特殊的窗口罷了。

從用戶的角度看,窗口就是顯示在屏幕上的一個矩形區域,其外觀獨立於應用程序,事實
上它就是生成該窗口的應用程序與用戶間的直觀接口;從應用程序的角度看,窗口是受其
控制的一部分矩形屏幕區。應用程序生成並控制與窗口有關的一切內容,包括窗口的大小
、風格、位置以及窗口內顯示的內容等。用戶打開一個應用程序後,程序將創建一個窗口
,並在那裏默默地等待用戶的要求。每當用戶選擇窗口中的選項,程序即對此做出響應。

⒉程序:通常說的程序都是指一個能讓計算機識別的文件,接觸得最多的便是.exe型的可
執行文件,這個不難理解。

⒊進程:說到進程,學過《操作系統》的人都很清楚,所謂進程就是應用程序的執行實例
(或稱一個執行程序)。需要注意的是:進程是程序動態的描述,而上面說到的程序是靜
態的描述,兩者有本質的區別。舉個例子,從網上Down了一個瑞星殺毒軟件到C盤但沒有運
行,那個.exe 可執行文件叫做程序,它是一個二進制碼的文件。一旦雙擊了exe文件圖標
運行程序,那個“正在運行着的瑞星殺毒”便稱爲進程,它在雙擊的那一刻被系統創建,
當你關機或者在任務欄的圖標上單擊鼠標右鍵選“退出”時,進程便消亡,徹底結束了生
命。進程經歷了由“創建”到“消亡”的生命期,而程序自始至終存在於你的硬盤上,不
管你的機器是否啓動。

⒋線程:線程是進程中的一個執行單元,同一個進程中的各個線程對應於一組CPU指令、一
組CPU寄存器以及一堆棧。進程本來就具有動態的含義,然而實質上是通過線程來執行體現
的,從這個意義上說,Windows 中進程的動態性意義已經不是很明顯了,只算是給程序所
佔的資源劃定一個範圍而已(個人觀點,純屬個人理解,不必引起爭議!),真正具有動
態性意義的是線程。以前在大二學習操作系統課的時候就有個同學跟筆者提起這點,筆者
還跟他駁得面紅耳赤呢!現在想想,覺得很有道理,不得不佩服那位同學對Windows內部機
制瞭解得如此清楚。

之所以在此花那麼多的篇幅說線程,是因爲下面將要介紹到多線程編程技巧,如果不理解
這點,那就很難應用到實踐上,希望大家明白。

⒌消息:我們幾乎做每一個動作都會產生一個消息,在用鼠標指點江山的今天,鼠標被移
動會產生WM_MOUSEMOVE消息,鼠標左鍵被按下會產生WM_LBUTTONDOWN的消息,鼠標右鍵按
下便產生WM_RBUTTONDOWN消息等等。所有的這些都可以通過GetMessage,SendMessage等函
數得到,以後的操作中我們會經常接觸到這些函數。

⒍事件:何謂事件?從它的字面意思我們就可以明白它的含義,如在程序運行的過程中改
變窗口的大小或者移動窗口等,都會觸發相應的“事件”。

⒎句柄:單單一個“柄”字便可以解釋它的意思了,我們天氣熱搖扇子的時候只要抓住扇
柄便可以控制整個扇子的運動了,在程序中也差不多是這個意思。通常一個句柄就可以傳
遞我們所要做的事情。有經驗的讀者肯定清楚,編寫程序總是要和各種句柄打交道的,句
柄是系統用來標識不同對象類型的工具,如窗口、菜單等,這些東西在系統中被視爲不同
類型的對象,用不同的句柄將他們區分開來。

看看C++ 教材中是如何給句柄下定義的:“在Win32裏,句柄是指向一個無值型對象(voi
d *)的指針,是一個4字節長的數據”。雖然我對它的本質是什麼還是很迷惑,但我知道
句柄並不是一個真正意義上的指針。從結構上看,句柄的確是一個指針,儘管它沒有指向
用於存儲某個對象的內存位置(很多書都這麼說,這正是我的迷惑所在),而實際上句柄
指向的是一個包含了對該對象進行的引用的位置。在編程時,只要抓住了對象的句柄就可
以對該對象進行操作了(我在《一個簡單木馬程序的編寫與僞裝策略》中說到的對QQ密碼
的截獲就是要找到QQ登陸窗口的句柄後纔開始截密行動的)。下面再舉個例子來說明句柄
的運用:編一個程序,使QQ登陸窗口的號碼框和密碼框均變黑,相關代碼及解釋:

void __fastcall TForm1::FormCreate(TObject *Sender)

{

HWND hCurWindow,HC,HE;//定義三個窗口句柄變量,hCurWindow用於存放QQ用戶登陸窗口
的句柄,HC、HE分別存放號碼框和密碼框的句柄。

if((hCurWindow= FindWindow(NULL,"QQ用戶登錄"))!=0||(hCurWindow=FindWindow(NULL
,"OICQ用戶登錄"))!=0)

{//很明顯,調用FindWindow()函數去獲得QQ登陸窗口的句柄

String str;

str.sprintf("0x%x",hCurWindow);

}

TCHAR wClassName[255];//類名變量

HC=GetWindow(hCurWindow, GW_CHILD);//得到號碼框的句柄

HE=GetWindow(HC, GW_HWNDNEXT);//接着得到密碼框的句柄

GetClassName(HE, wClassName, sizeof(wClassName));//得到類名

GetClassName(HC, wClassName, sizeof(wClassName));//得到類名

EnableWindow(HE,false);//使窗口失效

EnableWindow(HC,false);//使窗口失效

}

以上代碼在C++ Builder下編譯通過,只要運行次程序,QQ登陸窗口的號碼框和密碼框馬上
變黑色,如圖1所示,無非是EnableWindow()函數所起的作用。

圖1

你還可以添加一個Timer控件,將上面的代碼copy到void __fastcall TForm1::Timer1Tim
er(TObject *Sender)函數中,並在後邊加上這一句代碼:

SendMessage(hCurWindow,WM_CLOSE,0,0); 使QQ一啓動就關閉,讓別人永遠也用不了QQ,
挺有趣兒的哦,(請參考光盤內的程序一)

⒏API與SDK:API是英文 Application Programming Interface 的簡稱,意爲“應用程序
接口”,泛指系統爲應用程序提供的一系列接口函數。其實質是程序內的一套函數調用,
在編程的時候可以直接調用,而不必知道其內部實現的過程,只知道它的原型和返回值就
可以了,此外,手頭經常放着一本“Windows API大全”之類的書也是必不可少的,不然你
根本不知道哪些API是幹什麼用的,瞎編也編不出什麼東西來。在後面我們會介紹調用API
編程的例子,調用API編程工作雖然煩瑣,但由於API函數都被封裝在dll庫裏,程序只有在
運行的時候才調用的,因此程序的體積小而且運行效率高。

SDK是英文 Software Development Kit 的縮寫,指“軟件開發工具包”,在防火牆的設計
中就經常涉及到SDK。

有關基本的概念就談這些,那些C/C++的基本語法、什麼是面向對象等知識請大家查閱相關
的書籍,此類書籍各大書店已汗牛充棟,不再多敘。下面直接談談語種和編程工具的選擇
問題,這也是初學者們最迷惑的問題。

二、編程語言以及工具的選擇:

從上面的介紹我們對Windows 有了進一步的瞭解,現在就該開始行動了,選擇要學的語言
和工具是第一步,而且是非常重要的一步工作,筆者建議一切以簡單、易接受爲原則,不
然你會自信心大減的,何必偏要跟自己過不去自討苦吃呢?

在開始的時候很多人都感到迷惑,目前的編程語言那麼多,有c、c++、c#、java、彙編、
html等等,究竟學哪些好呢?最開始我該學什麼呢?甚至有人將vc、c++ builder也列爲兩
種不同的語言!這些都是對編程語言缺乏瞭解造成的。筆者開始的時候也犯過同樣的錯誤
,曾經給自己寫過一份計劃書:先學c語言,接着學c++、c#、java、彙編、vb、vc、c++
builder……,哪一種語言用多少時間去專攻等等,現在回想起來覺得多麼的可笑!只要學
得精,一門就夠了。從實用的角度來講,C++ 是最好的選擇(個人意見,其實每一種語言
都很好),而VC和C++ Builder是其相應開發工具的兩大主流,筆者極力推薦初學者使用C
++ Builder,因爲很容易上手,如果一下子就用VC的話,也許會打擊你的自信心:)。


三、談談促進編程能力提高的兩個途徑

如果你是一個黑客技術的狂熱者的話,到雅虎去搜索黑客教程的時候就會發現,很多的中
文教程在談到如何進行黑客編程時,十有八九都會介紹以下兩大最佳途徑:一、讀程序;
二、寫程序,並且都提出了教程作者的看法,下面我想談談這方面的個人觀點。

⒈讀程序:我將讀程序放在前面是有原因的。在你沒有閱讀過一份完整的源代碼之前,你
別指望能寫出有多好的程序來!這是對每一位初學者的忠告也是警告,而且必須具備一定
的語言基礎知識,這裏的基礎知識主要是指語法知識,最起碼要能讀懂別人的程序的每一
行意思。有沒有程序的設計思想,在這個時期並不重要,只要具備一定的語法基礎就可以
了,思想可以通過閱讀完別人的源程序後分析得來。

記得在大一學習C語言的時候,我們都很重視語法的學習,整天都看教材、做練習,而且趕
在老師的講課前預習,課後又複習鞏固,將一些語法點記得滾瓜爛熟,可後來一到做課程
設計的時候,坐在電腦面前簡直是老鼠拖雞蛋—無從下手了,而且不斷的問自己:“我平
時的努力哪去了?語法都會了呀,怎麼還是做不出程序來?”相信很多人都像筆者以前那
樣,錯誤地以爲學會了語法就等於掌握了編程。

編程的能力包括經驗、技巧、耐心等幾個因素,而並非想象中的那樣簡單,更不要以爲編
程就是簡簡單單的寫程序!

其實學一門語言並不需要刻意去記那些條條框框的語法,在看代碼的時候,遇到了不明白
的地方再去查相關的資料,一點一點補充基礎知識再配合源程序的思路,這時的理解纔是
最深刻的,我可以肯定地說,這個時候對語法的接受程度絕對比你剛開始時的死記要強!
 

讀程序也不能單純地讀,要真正做到“俯而讀,昂而思”。好的代碼是百讀不厭的,比如
Shotgun的那道構造洪水Ping攻擊的代碼,我至少讀了20遍。筆者喜歡將從網上搜集來的代
碼打印到紙上(儘管學校的打印費貴得要命,打一份代碼就得花去十幾塊甚至幾十塊大洋
~~~),然後邊看邊做好眉批,遇到一個新函數記下它的功能,一些忘記了的知識在旁邊標
出來,還可以寫上對程序的看法等等。特別是遇到了一些新的API函數,最好標出來,對你
以後編程的時候也許會用得着,最後別忘了分析一下程序的思路,這樣對你以後編寫類似
的程序很有幫助的。

⒉寫程序:問題可談到點子上了,學那麼多語言,讀那麼多程序最終還不是爲了寫程序,
做出適合需要的軟件來?“君子性非異也,善加於物也”,筆者認爲一切從借鑑開始,先
是修改別人的程序,等到有了一定的程度再寫出屬於自己的程序。

剛開始寫程序,不要奢望一下子寫出很出色的程序來,“萬丈高樓平底起”,編程貴在動
手,只要你動手去寫了,就算只有一句“printf(“Hello!”);”也是一次進步!此外,還
要依照自身的能力循序漸進地寫,開始的時候寫一點功能簡單的、篇幅短小的代碼,力求
簡潔、完整,“麻雀雖小,但五臟俱全”,然後在此基礎上進行擴充,一點一點添加功能
,下面筆者摘錄一位國內一流編程高手、“豪傑超級解霸”的作者樑肇新的編程心得,請
大家看看一個成功的程序員是如何寫程序的,希望對廣大菜鳥有所啓發:

寫程序的方法:在Win98的環境中,先寫主幹,用最少的代碼實現最基本的功能。然後一點
點添加功能,每加一點都要調試。儘量少用動態分配、全局變量。充分利用操作系統直接
提供的API。在Win98下調試通過之後,再在Win95下調試通過,然後是Win97,WindowsME,
WinNT4.0。這樣才能寫出穩定、快速的程序。

給程序員的建議:1、不要急於求成,這樣往往欲速不達。2、不要什麼東西都想學,什麼
都沒掌握。3、每天都要自我總結,分析自己的錯誤率和廢碼率,不斷加強自我管理。4、
代碼格式很重要。代碼要規範、嚴謹,效率要高。5、不要盲從簡單的開發工具(這點筆者
不是很同意,最起碼要有一定的功底的人才敢這麼說)。6、有了成果要公開,不要捨不得
,不然很快會過時的(以上兩段摘自《程序員》增值合訂本2001.上冊P18,請讀者前往參
考)。

參考書籍:《Windows C 程序設計》,清華大學出版社

《超級解霸樑肇新》,《程序員》合訂本

聲明:本文爲勁風原創文章,發表在《黑客防線》增刊上,在“青山在線”論壇首帖,本
文非 For 高手,只面向廣大的初學者。

Windows黑客編程基礎(下)

文/勁風

四、黑客編程的幾個基本技巧

以下將要談到的幾個基本技巧很重要,雖然對於編程高手來說這是在玩小孩子把戲,但對 於一位初學者,掌握以下幾個技巧將爲你的編程掃清道路,而且很容易編寫出有趣的程序 ,培養你對編程的興趣。

技巧⒈學會修改註冊表。

相信大家都知道當瀏覽了一些網頁惡意代碼,IE標題、默認主頁等被改得面目全非,這就 是通過改動註冊表來更改系統設置的例子。Windows中的註冊表是個好東東,它是windows 系統的靈魂,是許多軟件記錄數據的地方(當然也包括windows本身)。windows通過它記 錄大量的數據,然後在下一次啓動時再讀取相應的數據來設置系統。通過控制註冊表就可 以控制整個系統,所以很多的黑客程序都在註冊表上動手腳(尤其是木馬程序和作惡劇程 序),學會修改註冊表可以實現一些有趣而強大的功能。我們完全可以通過編程來操作注 冊表,達到與手動更改註冊表編輯器產生一樣的效果。“超級兔子”中的大部分功能就是 通過修改註冊表來完成的。操作註冊表有專門的API函數,大家可以參考有關資料,下面筆 者以C++ Builder爲例說明如何在程序中操作註冊表:

程序二:編程修改IE標題內容

新建一個工程,在Unit1.h文件中包含Registry單元:

#include <Registry.hpp>

然後就可以在.cpp文件操作註冊表了,接着來!在窗體的OnCreate()里加入以下代碼(你 可以在try{}裏面加入任何操作註冊表的代碼):

TRegistry* Registry;

Registry = new TRegistry();創建一個TRegistry類型的對象Registry,用於修改註冊表 。

try{

Registry->RootKey = HKEY_CURRENT_USER;//設置主鍵,這是必不可少的,設置好主鍵後 ,就可以操作這個主鍵下所有的鍵值了。

if( Registry->OpenKey("Software//Microsoft//Internet Explorer//Main",FALSE))// 調用OpenKey()打開括號裏所指的鍵

{

Registry->WriteString("Window Title",”臺灣是中國的一部分,世界上只有一箇中國! ”);//調用WriteString()往註冊表裏寫入IE標題

Registry->CloseKey();//關閉該鍵

}

else

{//如果打開失敗的話

Registry->CreateKey("Software//Microsoft//Internet Explorer//Main");//就調用Cr eateKey()新建上述鍵

Registry->WriteString("Window Title","臺灣是中國的一部分,世界上只有一箇中國! ");//再寫入IE標題內容

Registry->CloseKey();//最後關閉該鍵,這個也不能忽視,它跟上面的OpenKey成對使用 的

}//End of try

__finally

{//要是出錯,跳到這裏處理

Registry->CloseKey();//關閉所要打開的鍵

delete Registry;//銷燬Registry對象,釋放資源。

}

編譯運行上面的代碼就可以將IE的標題改爲“臺灣是中國的一部分,世界上只有一箇中國 !”了。筆者寫了個小程序,可以測出當前的IE標題和默認主頁是什麼,並可隨意修改他 們,還可以禁止別人修改你的默認主頁和註冊表編輯器,運行界面如圖2所示(詳細的代碼 請參考黑防的光盤)。

 

技巧⒉調用API編程

其實這是最簡單的,API是系統在DLL裏爲我們提供的程序接口,可以直接調用的。只要我 們有一本《Windows API大全》之類的書就足夠了,下面舉個簡單的例子:

程序三:調用API函數隱藏Windows的任務欄:

HWND WndHandle;//定義句柄類型變量

WndHandle=FindWindow("Shell_TrayWnd",NULL);//調用API函數FindWindow()獲得任務 欄的句柄

ShowWindow(WndHandle,SW_HIDE);//再調用API函數ShowWindow()隱藏任務欄

大家看到,在上面調用API函數FindWindow()和ShowWindow()的過程中,只要我們知道 函數的名字和括號裏的參數是什麼就行了,至於實現的過程不必理會,也輪不到我們這些 菜鳥去理會:)學會調用API,你可以寫出功能強大的程序來,這一技巧對於初學者來說是 必須掌握的(代碼請參考黑防光盤)。

技巧⒊多線程編程技術

通過上一篇的介紹 ,大家都很清楚線程的概念了,它是進程內部的一個執行單元(如一個 函數等),上期說了那麼多理論,現在該派上用場了。編寫多線程應用程序是指使程序在 運行時創建多個線程併發地運行於同一個進程中。今年6月份橫空出世的“中國黑客”病毒 不是採用了全球獨創的“三線程技術”嗎?雖然筆者沒機會分析它的樣本代碼,但此種病 毒的工作效率如此之高是與它的多線程技術分不開的。

使用多線程技術編程有如下優點:

①提高CPU的利用率。由於多線程併發運行,可以使用戶在做一件事情的時候還可以做另外 一件事。特別是在多個CPU的情況下,更可以充分地利用硬件資源的優勢:將一個大任務分 成幾個小任務,由不同的CPU來合作完成。

②採用多線程技術,可以設置每個線程的優先級,調整工作的進度。

清楚了使用多線程技術的優勢之後,下面便來談談如何在C++ Builder環境下開發多線程的 應用程序,在C++ Builder 環境中,通過 TThread 類就可以很方便地編寫多線程應用程序 (但不能直接使用,因此要派生新類),具體流程如下:

從TThread 類派生出一個新的線程類->創建線程對象->設置線程對象的屬性項->掛起或喚 醒線程(根據具體情況操作)->結束線程。

要說明一點的是:在應用程序中要合理地設置線程的優先級。不要因爲某些線程的優先級 很高而使其他一些線程因爲等不到CPU的處理時間而被“餓死”,也不要因爲線程的級別都 差不多而導致的頻繁切換花費大量的CPU時間。(本段引自《C++ Builder 5 編程實例與技 巧》P284)。

技巧⒋讓程序實現後臺監控

這是一個很基本的技巧。如果你是一個木馬程序的愛好者,當你閱讀衆多的木馬源程序的 時候,就會發現100%的木馬程序都很注意自身的後臺監控本領,也就是隱身技術,面對不 同的系統要施展不同的對策才能實現。很多殺毒程序就採用了這種後臺監控技術,使程序 隨着系統的啓動而運行,然後在後臺悄悄地監視系統的一舉一動,一發現有不對路的程序 就把它“揪”出來示衆。實現程序的後臺監控技術有如下幾個關鍵:

①正常運行時,不顯示程序的窗體;

②系統每次啓動都自動運行程序一次;

③程序圖標不顯示在任務欄上;

④不顯示在按Ctrl+Alt+Del 調出的任務列表中;

⑤通過熱鍵可以調出隱藏的窗體

實現方法:對於①,要不顯示窗體,我們可以編輯WinMain函數,設置ShowMainForm值爲F alse就可以隱藏程序的窗體了。參考代碼:Application->ShowMainForm = false ;對於 ②,可以利用技巧1所介紹的方法修改註冊表,鍵值如下:HKEY_LOCAL_MACHINE/SOFTWARE /Microsoft/Windows/CurrentVersion/Run ,使用的是WriteString()方法。這是冰河等 多種舊木馬慣用的啓動手段之一(當然還有文件關聯、注入dll等方法);對於③,要使程 序圖標不顯示在任務欄上,也很簡單,調用API函數SetWindowLong 可以讓程序運行後不出 現在任務欄裏,不過要放在窗體的OnCreate()裏面。代碼如下:

SetWindowLong(Application->Handle,GWL_EXSTYLE,WS_EX_TOOLWINDOW);

對於④,調用RegisterServiceProcess API 函數將程序註冊成爲一個服務模式程序,讓它 運行在較高的優先級下,就不會出現在程序列表中(對Win9X有效,WinNT/2000/XP下無效) 。具體的代碼請參考筆者的《一個簡單木馬程序的編寫與僞裝策略》一文,不在此重敘( 請參考《黑客防線》2002年第6期)。對於⑤,要先定義捕獲Windows消息WM_HOTKEY的鉤子 函數,然後向Windows加入一個全局原子,並保留其句柄,最後向Windows登記熱鍵,這個 可以調用API函數RegisterHotKey來實現。

技巧⒌使用定時觸發器

在C++ Builder 環境下,定時觸發器即Timer控件,有時候我們希望程序隔一段時間重複執 行相同的動作,比如對QQ密碼截獲的時候,就要隔一段間隔尋找一次QQ登錄窗口。在C++ Builder 中,只要將執行這些動作的代碼放到一個Timer中去就OK了。

聽說“中國黑客”病毒運行幾分鐘後就自動創建一個新的線程,用於尋找OICQ的“發送消 息”窗口,在10分鐘內一直在找,一旦找到就將“去******”等帶有政治色彩的言論發送 給受害者QQ上的好友,10分鐘後自動結束該線程。我想在查找“發送消息”窗口的10分鐘 內就運用了定時器,該病毒是用匯編開發的。可是在C++ Builder中是如何運用的呢?其實 控件的出現使得編程變得很簡單,添加一個Timer控件,設置幾下控件的屬性,雙擊Timer 控件,將代碼放到裏面去就行了。程序執行的時候,相隔指定的時間就重複執行裏面的代 碼了。實際上筆者在上一期的“程序一”中尋找QQ登錄窗口時,就運用了定時器,請讀者 參考光盤中的源程序。

有關編程技巧的介紹到此爲止,請讀者參考另類書籍,掌握更多的黑客編程技巧,編寫出 受歡迎的黑客程序來。

五、Socket 編程與網絡通信基礎

由於本文的主題是“黑客編程基礎”,而黑客是互連網上“來無影,去無蹤”的黑衣人, 如冰河、網絡神偷等黑客程序都是基於互連網的,談黑客編程離開網絡編程就會大失其味 。所以,下面接着談談網絡編程,大凡基於網絡應用的程序都離不開Socket。

Socket 爲套接字之意,是作爲計算機與計算機之間通信的接口。有關Socket的概念在第6 期《黑客防線》的《Socket 編程的基礎和基本過程》一文中有詳細的描述,請大家參考, 不在此多敘。需要指出的是:Winsock是訪問衆多的基層網絡協議的一種接口,在每個Win 32平臺上,它都以不同的形式存在着,Winsock 是網絡編程的接口,不是協議,這是容易 弄錯的地方。

現在來談談Winsock 編程的過程,大凡在Win32平臺上的Winsock編程都要經過下列的基本 步驟:定義變量->獲得Winsock版本->加載Winsock庫->初始化->創建套接字->設置套接字 選項->關閉套接字->卸載Winsock庫,釋放所有資源。

下面以一道極其簡單的程序來說明如何進行Winsock編程。程序四:編一個程序來獲取本地 機器的IP地址。

使用Winsock提供的API函數是最基本的網絡技術,爲了給初學者看個清楚,筆者打算在Vi sual C++ 和C++ Builder下各寫一個,便於大家區分這兩種不同的編程工具的特性(對於 本程序來說,他們都差不多,而對於某些通信程序,他們實現起來就相差很遠了,但本質 是差不多的)。先來看Visual C++ 下的源程序,實現步驟:打開Visual C++ ,從“File ”菜單中的“New”新建一個工程,選中“Win 32 Console Application”,意思是說生成 的是Win32的控制檯程序。另外,初學者要注意一點:只要程序中用到了 Winsock API 函 數,都要在工程設置的 Link 中增加 Ws2_32.lib 文件,不然程序將不能通過編譯,方法 是:點擊“Project”菜單,選擇“Settings... ALT+F7” ,在彈出的“Project Settin gs”對話框右側選“Link”標籤,再在“Project Options”下方的編輯框中增加Ws2_32. lib文件,點“OK”就可以了。

加載好文件之後,就可以在CheckIP.cpp文件里加入以下代碼了:

//-------Begin from ------------

//包含需要使用的頭文件

#include "stdafx.h"

#include "windows.h"

#include <winsock.h>

#include "stdio.h"

#include "stdlib.h"

#include "string.h"

void CheckIP(void) //定義CheckIP()函數,用於獲取本機IP地址

{

WORD wVersionRequested;// WORD類型變量,用於存放Winsock版本的正確值

WSADATA wsaData;

char name[255];//定義用於存放獲得的主機名的變量

CString ip;//定義IP地址變量

PHOSTENT hostinfo;

wVersionRequested = MAKEWORD( 2, 0 );

//調用MAKEWORD()獲得Winsock版本的正確值,用於下面的加載Winsock庫

if ( WSAStartup( wVersionRequested, &wsaData ) == 0 ) {

//現在是加載Winsock庫,如果WSAStartup()函數返回值爲0,說明加載成功,程序可以 繼續往下執行

if( gethostname ( name, sizeof(name)) == 0) {

//如果成功地將本地主機名存放入由name參數指定的緩衝區中

if((hostinfo = gethostbyname(name)) != NULL) {

//這是獲取主機名,如果獲得主機名成功的話,將返回一個指針,指向hostinfo,hostin fo爲PHOSTENT型的變量,下面即將用到這個結構體

LPCSTR ip = inet_ntoa (*(struct in_addr *)*hostinfo->h_addr_list);

//調用inet_ntoa()函數,將hostinfo結構變量中的h_addr_list轉化爲標準的點分表示 的IP地址(如192.168.0.1)

printf("%s/n",ip);//輸出IP地址 } }

WSACleanup( );//卸載Winsock庫,並釋放所有資源 } }

int main(int argc, char* argv[])//主函數,程序的入口

{

CheckIP();//調用CheckIP()函數獲得、輸出IP地址

return 0;//由於main()定義爲int型,所以應帶回一個int型的數值

}

 

下面接着來看看在C++ Builder 下如何實現,其實兩者的思想是一樣的,只是在C++ Buil der下實現的界面友好點而已,實現方法:打開C++ Builder 5,默認情況下已經新建一個 工程,保存這個工程文件就可以了,構造如下面圖4所示的界面,在相應之處添入下面的代 碼即可。

程序代碼:

//包含頭文件

#include <vcl.h>

#include <WINSOCK2.H>

#pragma hdrstop

#include "Unit1.h"

#pragma package(smart_init)

#pragma resource "*.dfm"

TForm1 *Form1;

__fastcall TForm1::TForm1(TComponent* Owner)

: TForm(Owner)

{ }

void TForm1::GetHostIpAddress()

{// GetHostIpAddress()獲得本機IP地址

struct hostent *thisHost;

struct in_addr in;

char MyName[80];

char *ptr;

WORD wVersionRequested;

WSADATA wsaData;

int err;

wVersionRequested = MAKEWORD( 2, 0 );

err = WSAStartup( wVersionRequested, &wsaData );

if( err != 0 )

return;

if(LOBYTE( wsaData.wVersion ) != 2 ||

HIBYTE( wsaData.wVersion ) != 0 )

{ WSACleanup( );

return; }

if(gethostname(MyName,80)==SOCKET_ERROR)

return;

if(!(thisHost=gethostbyname(MyName)))

return;

memset((void *)&in,sizeof(in),0);

in.s_addr=*((unsigned long *)thisHost->h_addr_list[0]);

if(!(ptr=inet_ntoa(in)))

return;

WSACleanup( );

Edit1->Text=AnsiString(ptr);}

void __fastcall TForm1::FormCreate(TObject *Sender)

{ GetHostIpAddress();}

void __fastcall TForm1::Button1Click(TObject *Sender)

{Close();//添加一個“確定”按鈕,點擊即關閉程序。}

程序在 C++ Builder 5 下編譯通過,運行界面如圖4所示。通過比較你會發現他們是大同 小異的,對於同一程序,兩者工具各有秋千,至於選擇哪種由你決定,最好是兩者相得益 彰。

 

“臨淵羨魚,不如退而結網”,雖說“通往電腦的路不止一條”,然而對於編程,道路卻 只有一條,就是:動手去做,親身實踐。

兄弟,願你成爲一個出色的舵手,用代碼去駑駕電腦的世界,用編程去填充七彩的人生!  

參考書籍:《C++ Builder 5 編程實例與技巧》,機械工業出版社

《WIN 編程須知》,病毒兄的作品,再次感謝病毒兄。

聲明:本文爲勁風原創文章,發表在《黑客防線》增刊上,在“青山在線”論壇首帖,本 文非 For 高手,只面向廣大的初學者。

全文完,歡迎大家談談您的看法,以督促本人的學習。

轉載自:http://blog.csdn.net/zerray/article/details/390392

發佈了2 篇原創文章 · 獲贊 2 · 訪問量 5萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章