9x環境中windows提供了想光的api函式用於隱藏系統程序。但是到了2000以上系統,已經無法真正的做到對於程序的隱藏,除非編寫底層驅動。但是我們可以通過一些變通的辦法來達到隱藏程序的目的,其中乙個就是遠端注入。簡單的說就是先編寫乙個api的dll,然後將這個dll庫注入到乙個系統程序中,作為它的乙個執行緒去執行。
要實現dll注入,首先需要開啟目標程序。
hremoteprocess = openprocess( process_create_thread | //允許遠端建立執行緒
process_vm_operation | //允許遠端vm操作
process_vm_write, //允許遠端vm寫
false, dwremoteprocessid )
由於我們後面需要寫入遠端程序的記憶體位址空間並建立遠端執行緒,所以需要申請足夠的許可權(process_create_thread、vm_operation、vm_write)。
如果程序打不開,以後的操作就別想了。程序開啟後,就可以建立遠執行緒了,不過別急,先想想這個遠執行緒的執行緒函式是什麼?我們的目的是注入乙個dll。而且我們知道用loadlibrary可以載入乙個dll到本程序的位址空間。於是,自然會想到如果可以在目標程序中呼叫loadlibrary,不就可以把dll載入到目標程序的位址空間了嗎?對!就是這樣。遠執行緒就在這兒用了一次,建立的遠執行緒的執行緒函式就是loadlibrary,而引數就是要注入的dll的檔名。(這裡需要自己想一想,注意到了嗎,執行緒函式threadproc和loadlibrary函式非常相似,返回值,引數個數都一樣) 還有乙個問題,loadlibrary這個函式的位址在哪兒?也許你會說,這個簡單,getprocaddress就可以得出。於是**就出來了。
char *pszlibfileremote="my.dll";
pthread_start_routine pfnstartaddr = (pthread_start_routine)getprocaddress(getmodulehandle("kernel32"), "loadlibrarya");
createremotethread( hremoteprocess, null, 0, pfnstartaddr, pszlibfileremote, 0, null);
但是不對!不要忘了,這是遠執行緒,不是在你的程序裡,而pszlibfileremote指向的是你的程序裡的資料,到了目標程序,這個指標都不知道指向哪兒去了,同樣pfnstartaddr這個位址上的**到了目標程序裡也不知道是什麼了,不知道是不是你想要的loadlibrarya了。但是,問題總是可以解決的,windows有些很強大的api函式,他們可以在目標程序裡分配記憶體,可以將你的程序中的資料拷貝到目標程序中。因此pszlibfileremote的問題可以解決了。
char *pszlibfilename="my.dll";//注意,這個一定要是全路徑檔名,除非它在系統目錄裡;原因大家自己想想。
//計算dll路徑名需要的記憶體空間
int cb = (1 + lstrlena(pszlibfilename)) * sizeof(char);
//使用virtualallocex函式在遠端程序的記憶體位址空間分配dll檔名緩衝區
pszlibfileremote = (char *) virtualallocex( hremoteprocess, null, cb, mem_commit, page_readwrite);
//使用writeproces**emory函式將dll的路徑名複製到遠端程序的記憶體空間
ireturncode = writeproces**emory(hremoteprocess, pszlibfileremote, (pvoid) pszlibfilename, cb, null);
ok,現在目標程序也認識pszlibfileremote了,但是pfnstartaddr好像不好辦,我怎麼可能知道loadlibrarya在目標程序中的位址呢?其實windows為我們解決了這個問題,loadlibrarya這個函式是在kernel32.dll這個核心dll裡的,而這個dll很特殊,不管對於哪個程序,windows總是把它載入到相同的位址上去。因此你的程序中loadlibrarya的位址和目標程序中loadlibrarya的位址是相同的(其實,這個dll裡的所有函式都是如此)。至此,dll注入結束了。
但是目前還有乙個問題,上面的方法是無法將dll注入到系統程序中去的,原因是程序級別不夠。那麼我們就要提公升注入程式的程序級別。使用下面的函式:
void enabledebugpriv( void )
tkp.privilegecount = 1;
tkp.privileges[0].luid = sedebugnamevalue;
tkp.privileges[0].attributes = se_privilege_enabled;
if ( ! adjusttokenprivileges( htoken, false, &tkp, sizeof tkp, null, null ) )
closehandle( htoken ); }
最後我們來做乙個簡單的例子:
首先編寫注入程式的**
// #include "stdafx.h"
#include "winnt.h"
void enabledebugpriv();
int apientry winmain(hinstance hinstance,
hinstance hprevinstance,
lpstr lpcmdline,
int ncmdshow)
//提公升許可權
void enabledebugpriv( void )
tkp.privilegecount = 1;
tkp.privileges[0].luid = sedebugnamevalue;
tkp.privileges[0].attributes = se_privilege_enabled;
if ( ! adjusttokenprivileges( htoken, false, &tkp, sizeof tkp, null, null ) )
closehandle( htoken ); }
然後編寫需要注入的dll的**
#include "stdafx.h"
#include "winnt.h"
#include
bool apientry dllmain( handle hmodule,
dword ul_reason_for_call,
lpvoid lpreserved )
default:
return true; }
}將編譯好的dll放到c盤根目錄下面執行注入程式。我們可以發現彈出了乙個標示了被注入程序id的對話方塊。
如上,只要我們再dll中編寫我們需要的**,就可以隱秘的在電腦裡執行我們需要的事情。
Windows下的程序通訊
剪貼簿 剪貼簿 clipped board 實質是win32 api中一組用來傳輸資料的函式和訊息,為windows應用程式之間進行資料共享提供了乙個 中介,windows已建立的剪下 複製 貼上的機制為不同應用程式之間共享不同格式資料提供了一條捷徑。當使用者在應用程式中執行剪下或複製操作時,應 用...
Windows下的程序 一
什麼是程序?程序就是乙個正在執行的程式的例項,由兩部分組成 核心物件。作業系統用核心物件對程序進行管理,核心物件是作業系統儲存程序統計資訊的地方。位址空間。其中包含所有可執行檔案或dll模組的 和資料,以及一些其他的資料,提供執行緒執行的環境。程序比較 懶惰 它不做任何事情,所有的事情都交給執行緒在...
windows下程序通訊
1 程序與程序通訊 2 程序通訊方法 2.1 檔案對映 win32 api中共享記憶體 shared memory 實際就是檔案對映的一種特殊情況。程序在建立檔案對映物件時用0xffffffff來代替檔案控制代碼 handle 就表示了對應的檔案對映物件是從作業系統頁面檔案訪問記憶體,其它程序開啟該...