在windows的平台上,dll是系統的基礎,那麼我們首先就利用dll來完成我們的遠端
執行緒。在dll中,有乙個入口點函式:dllmain,其原形如下:
bool apientry dllmain( handle hmodule,
dword ul_reason_for_call,
lpvoid lpreserved)
;return true;
}下面我們來說說它的引數ul_reason_for_call,這個引數就是告訴dll,系統為什麼呼叫這個函式:
dll_process_attach: 當系統第一次裝載dll到程序空間時,就發出這個通知;如果以後在該程序中
繼續呼叫loadlibrary或loadlibraryex函式,系統將不再發出這個通知,只是
給dll的引用計數加1
dll_process_detach: 當dll從程序空間中解除安裝時,系統將呼叫dllmain函式,傳遞dll_process_detach
給ul_reason_for_call
這個函式的返回值表示dll是否初始化成功(如果ul_reason_for_call不是dll_process_attach,系統將
忽略這個返回值)。
現在就可以使用dll_process_attach這個訊息來完成我們想要做的事。
我們如果能讓目標程序呼叫我們自己的的dll,那麼,我們就可以在遠端程序中做一些其它的事了。。
:pok,讓我們繼續:
在win2k中,我們可以使用createremoththread實現成我們的想法。
createremoththread的說明:
原型:handle winapi createremotethread(handle hprocess,
lpsecurity_attributes lpthreadattributes,
dword dwstacksize,
lpthread_start_routine lpstartaddress,
lpvoid lpparameter,
dword dwcreationflags,
lpdword lpthreadid);
執行成功,返回目標程序中的執行緒handle。
hprocess 目標程序的process handle
lpthreadattributes 遠端執行緒的安全屬性。如果為null,則繼承父程序的安全屬性
dwstacksize 遠端執行緒的堆疊大小。如果為0則為1m(系統預設為1m)
lpstartaddress 遠端執行緒**的起始位址。
lpparameter 遠端執行緒的引數
dwcreationflags 遠端執行緒的的選項
lpthreadid 傳出的引數,遠端執行緒的thread id
好,有了這些東東,我們就可以在目標程序中執行loadlibrary了,目標程序就可呼叫我們的dll了。 :p
相關的資料我們在上面已經了解過了,下面我們來看看具體是怎麼實現的;
1. 開啟目標程序:
//開啟遠端程序
hremoteprocess = openprocess(process_create_thread | //允許建立執行緒
process_vm_operation | //允許vm操作
process_vm_write, //允許vm寫
false, dwremoteprocessid );
2. 因為win2k的字串使用unicode來表示的,所以呢?我們要把ascii表示的字串轉換成unicode的形式:
//將dll檔案全路徑的ansi碼轉換成unicode碼
ireturncode = multibytetowidechar(cp_acp,
mb_err_invalid_chars,
lpdllfullpathname,
strlen(lpdllfullpathname),
pszuncodedllname, max_path);
3. 因為是要在遠端程序中執行的,那麼所有的字串、資源都要轉換成目標程序的位址空間,怎麼轉換呢?
沒辦法!!
那怎麼辦呢?用writeproces**emory把這些東西寫到目標程序中不就行了 :p
//計算dll路徑名需要的記憶體空間
int cb = (1 + lstrlenw(pszuncodedllname)) * sizeof(wchar); //注意,這兒用的是是unicode碼
//在目標程序中分記憶體
pszremotedllpath = (pwstr) virtualallocex( hremoteprocess, null, cb,
mem_commit, page_readwrite);
//將dll的路徑名複製到遠端程序的記憶體空間
ireturncode = writeproces**emory(hremoteprocess,
pszremotedllpath, (pvoid) pszuncodedllname, cb, null);
4. 得到loadlibrary函式在目標程序中的位址
pthread_start_routine pfnstartaddr = (pthread_start_routine)
getprocaddress(getmodulehandle(text("kernel32")), "loadlibraryw");
5. 使用createremotethread函式建立遠端執行緒
//啟動遠端執行緒,通過遠端執行緒呼叫使用者的dll檔案
//就相當於在目標程序中執行loadlibrary("我們的dll")
//如果到這還不明白為什麼呼叫loadlibrary,大夥,板磚上呀!!! :)
hremotethread = createremotethread( hremoteprocess, null, 0,
pfnstartaddr, pszremotedllpath, 0, null);
6. ok,到現在為止,我們已經在目標程序中執行了我們的**了,目標實現了,別急著走,還有些工作要做的:
//等待遠端執行緒退出
waitforsingleobject(hremotethread, infinite);
//清場處理
if (pszremotedllpath != null)
virtualfreeex(hremoteprocess, pszremotedllpath, 0, mem_release);
if (hremotethread != null) closehandle(hremotethread );
if (hremoteprocess!= null) closehandle(hremoteprocess);
最後,還有一些需要注意的地方:
你在目標程序中的程式不能出現執行時錯誤,出現了會怎麼辦呢?如果出現,windows就會告訴你
xx程序(這可是目標程序呀!)出現了非法操作......
如果你想使用這麼方式來殺掉目標程序(嘿嘿,有些程序windows的任務管理器殺不掉,這種方式就可以
搞定!!),ok,你就可以go home了。不想出現這種情況了嘛,也go home,回家檢查**去。我也要
zzzzzz了。。
哎,別急,,98下怎麼辦?
98下嘛,沒有createremotethread這上函式,不過呢。有乙個未公布的的函式createkernelthread,這個
函式藏在kernel32.dll裡面,用getprocaddress就可以找它出來了:
fcreatekernelthread = getprocaddress(getmodulehandle("kernel32.dll"), "createkernelthread");
說明如下:
handle createkernelthread(lpsecurity_attributes, size_t, lpthread_start_routine, lpvoid, dword, lpdword);
這是呼叫的例子:
hthread=fcreatekernelthread(null, 0, (pthread_start_routine) prun, prunparam, 0, &threadid);
其它的步驟嘛,和win2k下的沒有什麼區別。。。。
遠端執行緒嵌入技術
遠端執行緒嵌入技術 遠端執行緒技術指的是通過在另乙個程序中建立遠端執行緒的方法進入那個程序的記憶體位址空間。我們知道,在程序中,可以通過createthread函式建立執行緒,被建立的新執行緒與主線程 就是程序啟動時被同時自動建立的那個執行緒 共享位址空間以及其他的資源。但是很少有人知道,通過cre...
遠端執行緒嵌入技術
遠端執行緒技術指的是通過在另乙個程序中建立遠端執行緒的方法進入那個程序的記憶體位址空間。我們知道,在程序中,可以通過createthread函式建立執行緒,被建立的新執行緒與主線程 就是程序啟動時被同時自動建立的那個執行緒 共享位址空間以及其他的資源。但是很少有人知道,通過createremotet...
遠端執行緒嵌入技術
遠端執行緒嵌入技術 遠端執行緒技術指的是通過在另乙個程序中建立遠端執行緒的方法進入那個程序的記憶體位址空間。我們知道,在程序中,可以通過createthread函式建立執行緒,被建立的新執行緒與主線程 就是程序啟動時被同時自動建立的那個執行緒 共享位址空間以及其他的資源。但是很少有人知道,通過 cr...