好久沒弄這個玩意了,感覺有些過時了,但是這兩天突然想到了這個,突然發現有些疑問要解決,所以回過頭來看看這個。
#include<stdio.h><br />#include"windows.h"<br />typedef struct{<br />DWORD address;<br />char a[10];<br />}info;<br />typedef int (_stdcall *msgbox)(HWND, LPCTSTR, LPCTSTR, UINT);<br />DWORD WINAPI t(LPVOID p){<br />info *p1=(info*)p;<br />msgbox m=(msgbox)p1->address;<br />m(0,p1->a,p1->a,0);<br />//MessageBoxA(0,p1->a,p1->a,0);<br />while(1);<br />return 0;<br />}<br />main()<br />{<br />HANDLE ph=::OpenProcess(PROCESS_ALL_ACCESS,false,1956);<br />void *s;<br />s=::VirtualAllocEx(ph,0,1024*4,MEM_COMMIT,PAGE_EXECUTE_READWRITE);<br />::WriteProcessMemory(ph,s,t,1024*4,0);<br />info i;<br />ZeroMemory(&i,sizeof(i));<br />::strcpy(i.a,"a");<br />HINSTANCE m=::LoadLibrary("user32.dll");<br />i.address=(DWORD)::GetProcAddress(m,"MessageBoxA");<br />long m1=(long)(PROC)MessageBoxA;<br />info *s1;<br />s1=(info *)::VirtualAllocEx(ph,0,sizeof(info),MEM_COMMIT,PAGE_READWRITE);<br />::WriteProcessMemory(ph,s1,&i,sizeof(info),0);<br />HANDLE hrt=::CreateRemoteThread(ph,0,0,(LPTHREAD_START_ROUTINE)s,s1,0,0);<br />}</p><p>
這個就是無dll的遠程線程注入代碼,在注入函數裡我把messageboxA這個函數注釋掉了,因為按我原來的理解,messageboxA在這裡被編譯成了函數的地址,既然user32。dll在每個進程裡函數的映射地址都是一樣的,那麼應該沒問題啊,但是事實是把那個注釋去掉後運行就無情的報錯了。
沒辦法,看下彙編代碼吧。
long m1=(long)(PROC)MessageBoxA;
00401170 mov eax,[__imp__MessageBoxA@16 (004242b4)]
00401175 mov dword ptr [ebp-20h],eax
這段彙編的代碼是取messageboxA的地址,對應的彙編代碼是取004242b4這個地址中的值到eax裡,發現問題所在了,在004242b4這個地址上。我們知道,每個模組對應一個pe檔案,檔案裡有IAT這個函數匯入表,當我們的程式需要調用某個庫裡的函數時,系統便去IAT裡去這個函數符號的地址,地址中的值便是該函數在記憶體中映射的真真實位址,去掉注釋之所以報錯是004242b4這個地址在本地線程裡,而不是在遠程線程裡。進程間都是獨立的,你拿著本地的地址在遠程進程調用當然會報錯了。
好了,疑問解決了,本文有不足之處,還望大家多多指正。