#include "stdafx.h"
#include #include using std::cin;
dword dwoldeip = 0;
dword funremote = 0;
byte shellcode[25] = ;
bool threadcontexttest(dword dwprocessid, dword dwmemsize)
; if (!getthreadcontext(hthread, &stccontext))
return false;
hmodule hmodule = loadlibrary(l"user32.dll");
funremote = (dword)getprocaddress(hmodule, "messageboxa");
// 獲取原始eip
dwoldeip = stccontext.eip;
printf("stccontext.eip:%p\n", stccontext.eip);
// 申請記憶體
lpvoid lpaddr = virtualallocex(hprocess, null, dwmemsize, mem_commit, page_execute_readwrite);
if (!lpaddr)
return false;
printf("lpaddr:%p\n", lpaddr);
// 構造shellcode
memcpy(&shellcode[16], &funremote, 4);
memcpy(&shellcode[1], &dwoldeip, 4);
// 寫入記憶體
bool bret = writeprocessmemory(hprocess, lpaddr, shellcode, dwmemsize, null);
if (!bret)
return false;
// 設定eip
stccontext.eip = (dword)lpaddr;
setthreadcontext(hthread, &stccontext);
//system("pause");
dword dwresumecount = resumethread(hthread);
printf("恢復執行緒,dwresumecount:%d\n", dwresumecount);
return true;
}int _tmain(int argc, _tchar* argv)
我把執行的**寫成了shellcode,就是彈乙個 messagebox,但是前面一句和最後一句是重點,第一句是把當前eip 壓棧,最後的ret就是
返回到正確eip 這個是必須有的,在這裡ret指令的內部操作是:棧頂字單元出棧,其值賦給ip暫存器。即實現了乙個程式的轉移,將棧頂字單元儲存
的偏移位址作為下一條指令的偏移位址。
當然也可以把你自己的執行**寫成函式,遇到的問題就是計算函式的大小,一般方法就是搜尋特徵碼ret(高老溼說滴),然後特徵碼位址減
去,函式位址,就是大小~~
由於eip必須在執行的時候才能得到,所以我把獲得的eip直接memcopy到相應shellcode位置。
執行結果:
主線程呼叫(通過修改執行緒上下文實現)
思路 將主線程掛起後獲取到主線程的eip,然後將eip修改為shellcode的位址恢復執行緒執行,當shellcode執行完成後跳轉到舊eip處繼續執行。1 typedef void stdcall pfn call const void pvin,void pvout 23 bool callf...
程序上下文與執行緒上下文
6.1.2 執行緒上下文 作業系統管理很多程序的執行。有些程序是來自各種程式 系統和應用程式的單獨程序,而某些程序來自被分解為很多程序的應用或程式。當乙個程序從核心中移出,另乙個程序成為活動的,這些程序之間便發生了上下文切換。作業系統必須記錄重啟程序和啟動新程序使之活動所需要的所有資訊。這些資訊被稱...
R3多執行緒
ncreatethread 是windows的api函式 sdk函式的標準形式,直截了當的建立方式,任何場合都可以使用 提供作業系統級別的建立執行緒的操作,且僅限於工作者執行緒。不呼叫mfc和rtl的函式時,可以用createthread,其它情況不要使用。因為 qcruntime中需要對多執行緒進...