程式者的胡言亂語

pageicon 星期五 五月 18, 2007

乖,葛格幫你打個針

說實話,我對Windows作業系統實在是外行(啊,其實對每個作業系統都外行),不過,前一陣子在玩API hooking時,看到WindowsDLL injection的技巧,還是不免覺得很妙。前幾天又在重溫API hooking的相關東西,又看到DLL injectioncode,所以覺得下這個標題不錯,就想說來給它記錄一下。


DLL injection就是把你的DLL注射到另一個process定址空間裡。在現代作業系統裡頭個別的process都是在各自獨立的定址空間裡,要像DOS那樣,所有的process共用同一個定址空間(如果連TSR也算的話,是可以有process啦),已經不多見了。所以,作業系統的基本責任之一,就是保護各個process彼此之間互不侵犯,所以因為有獨立的定址空間,同一個位址值,對不同的process可能具有不同的意義。這意謂著,你不能隨便的去寫甚至是讀取別的processmemory內容。


API hooking有很多實現的技巧,無論如何,你都需要進入你想要hook它的process,以便做一些事情。但這在有Windows作業系統維持各process之領域範圍的情況下,要怎麼去達到了。這就是我當初看到打針技巧時,覺得很妙的地方。


怎麼做DLL injection呢?隨便在Googlesearch一下,應該可以找到一堆。不過你可以參考


它的主要精神,大概是兩個重點,第一個是先利用GetProcAddress()取得kernal32.dll裡的LoadLibraryALoadLibraryW這兩個函式的位址,接著呢,用一個叫做CreateRemoteThread()API指定你想要注射的process,去執行LoadLibrary()這個函式。LoadLibrary是用來載入某個DLL的,這時候要載入那個DLL呢?當然就是你想注射的DLL。所以當CreateRemoteThread()做完後,你的DLL就會被你的對象process給載入,也就是說,它會成為該process定址空間的一部份,它就被注射進去了。


好啦,注射進去後,已經成為該process的一部份,和該process一整個融為一體。但這還不夠,因為被注射進去後,你通常還會想要做一些事情(例如去把人家API的函式位址換成自己提供的)。所以,要怎麼讓這「一些事情」被執行呢?如果你寫的是C++,你可以宣告一個globalobject,此時為了要初始化這個object,這個objectconstructor就會被執行,所以想做什麼就統統丟到它的constructor去吧。如果寫的是C,那也沒關係,寫到DllMain()裡,當process attach上這個DLL時,就做你想做的事吧。這時候你的DLL已經在別人的process裡了,所以想改什麼就改什麼啊。


當初想到用CreateRemoteThread()叫別的processLoadLibrary()的人,還真是厲害又有創意啊。

迴響:

不過 CreateRemoteThread+LoadLibrary 不能保證"dll一定會在整個程式執行前載入", 很多事情你不會想程式已經開始執行後動作的, 而且如果要做 API Hooking 的話, 最好是用 SuspendThread 把其它的 thread 停下來, 要不然一不小心就嘿嘿嘿... :p

用下面這個方法至少可以在整個"主程式"執行前開始跑, 不過要在一開始就執行的話, 大概得去修改 dll 的 loading 順序才能做到吧
http://www.deez.info/sengelha/code/win32-ldpreload/

由...發表 maniac on 五月 21, 2007 at 12:13 上午 CST #

啊啊, 這樣更狠 XD
受教了

由...發表 Qing on 五月 21, 2007 at 08:14 下午 CST #

發表迴響:
  • HTML 語法: 關閉
把對母乳媽媽的感謝與支持傳出去

« 九月 2010
星期日星期一星期二星期三星期四星期五星期六
   
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
  
       
今日

Search this blog

Links

Weblog menu

Today's referrers

Feeds