asp
access
blog
程序注入的研究與實現(下)
5. 無dll注入
在第三中方法中,我們啟動遠端執行緒時,執行緒函式是我們從kernel32.dll中取得的loadlibrary函式的位址為執行緒函式的位址,其實我們可以直接將執行緒函式體和函式引數寫入目標程序的位址空間,然後建立遠端執行緒。
使用這個方法時,需要注意以下幾個問題:
(1) 遠端執行緒函式體不得使用kernel32.dll,user32.dll以外的函式。因為這個兩個模組在各個程序的相對位址是一樣的,如果一定要使用其它函式,則必須將函式體寫入目標程序空間。
(2) 不能使用任何字串常量,因為字串常量是存放在pe檔案裡.data這個段裡面的,函式裡儲存的只是相對位址。
(3) 去掉編譯器的/gz編譯選項,這個選項是用來enable stack frame run-time error checking。當這個選項開啟時,編譯器會在每個函式中加入一些**,用來檢驗esp在函式體中是否被改變,但是這些檢驗函式的位址在不同pe檔案中有可能是不一樣的。
(4) 不得使用增量鏈結(incremental linking)。增量鏈結是編譯器為了減少鏈結時間做的處理,把函式體用乙個jmp指令代替,這樣就可以隨意改變函式的內容,而不用修改call指令。
(5) 不要在函式體內使用超過4kb的區域性變數。區域性變數是存放在棧中的,例如下面這個函式
void dummy(void)
在分配區域性變數空間時是這樣的
:00401000 push ebp
:00401001 mov ebp, esp
:00401003 sub esp, 00000100 ; change esp as storage for
; local variables is needed
:00401006 mov byte ptr [esp], 00 ; var[0] = 0;
:0040100a mov byte ptr [esp+01], 01 ; var[1] = 1;
:0040100f mov byte ptr [esp+ff], ff ; var[255] = 255;
:00401017 mov esp, ebp ; restore stack pointer
:00401019 pop ebp
:0040101a ret
但是當區域性變數的大小超過4kb時,棧指標並不直接改版,而是呼叫另乙個函式來分配記憶體,這個函式有可能在不同程序中的位址不一樣。
(6) 函式體內switch語句中的case不要超過3個,否則編譯器會在pe檔案中使用跳轉表,而這個跳轉表有可能在目標程序中並不存在。
下面是乙個無dll注入的例子:
//引數結構 ;
cpp**
typedef
struct _remotepararemotepara;
// 遠端執行緒執行體
dword __stdcall threadproc(remotepara *para)
dword threadsize=1024;
dword pid = 4688;
dword byte_write;
handle hremoteprocess,hthread;
remotepara myremotepara,*premotepara;
void *premotethread;
hinstance huser32 ;
hremoteprocess = openprocess(process_all_access,false,pid);
if(!hremoteprocess)return 0;
// 在遠端程序位址空間分配虛擬記憶體
premotethread = virtualallocex(hremoteprocess, 0, threadsize, mem_commit | mem_reserve,page_execute_readwrite);
if(!premotethread)return 0;
// 將執行緒執行體threadproc寫入遠端程序
if(!writeprocessmemory(hremoteprocess, premotethread, &threadproc, threadsize,0))return 0;
zeromemory(&myremotepara,sizeof(remotepara));
huser32 = loadlibrary(l"user32.dll");
myremotepara.dwmessagebox = (pvoid)getprocaddress(huser32, "messageboxw");
wcscat(myremotepara.strmessagebox,l"hello!"); //複製messagebox函式的引數
//寫進目標程序
premotepara =(remotepara *)virtualallocex (hremoteprocess ,0,sizeof(remotepara),mem_commit,page_readwrite);
if(!premotepara)return 0;
if(!writeprocessmemory (hremoteprocess ,premotepara,&myremotepara,sizeof myremotepara,0))return 0;
// 啟動執行緒
hthread = createremotethread(hremoteprocess ,0,0,(lpthread_start_routine)premotethread ,premotepara,0,&byte_write);
freelibrary(huser32);
closehandle(hremoteprocess);
參考文獻:
程序注入的研究與實現
程序注入的研究與實現 為了對記憶體中的某個程序進行操作,並且獲得該程序位址空間裡的資料,或者修改程序的私有資料結構,必須將自己的 放在目標程序的位址空間裡執行,這時就避免不了使用程序注入方法了。程序注入的方法分類如下 5.無dll注入 在第三中方法中,我們啟動遠端執行緒時,執行緒函式是我們從kern...
MockServer的測試思想與實現(下篇)
mockserver的技術實現 目前,筆者已經用python實現了乙個基於socket介面的mock server並在測試中進行了一定的應用,實現中利用了一些python的語言特性 一點rpc技術和一點dsl的技巧。乙個case 下面先看乙個實際的case,case加入了許額外的注釋,以解釋這段 的...
c 實現dll注入其它程序
dll注入技術才具有強大的功能和使用性,同時簡單易用,因為dll中可以實現複雜的功能和很多的技術。技術要點 1 宿主程序呼叫loadlibrary,就可以完成dll的遠端注入。可以通過createremotethread將loadlibrary作為宿主程序的乙個執行緒來啟動,就可以完成 控制目標程序...