Hook : SetThreadContext
目前windows下注入dll的技術大體上就是兩種
1:鉤子 SetWindowsHook
2:創建遠程線程 CreateRemoteThread
儘管都能實現遠程注入dll,但都難逃殺毒軟件的法眼,特別是 CreateRemoteThread
一般都被殺毒軟件監控的很牢,這裏提供一個巧妙的方法能夠利用目標進程(確切地說是線程)
自己主動調用LoadLibrary裝載dll.
我們想一想,windows下vc調試器可以調試正在運行的進程,功能很是強大,那可不可以
借鑑調試器的機理呢?完全可以,調試器的機理大致分爲以下幾步:
1:OpenProcess() 獲取目標進程句炳,擁有調試權限(我們這裏不需要用這個權限)
2:SuspendThread() 掛起目標進程的主線程
3:GetThreadContext(), SetThreadContext() 讀寫目標線程的當前CPU上下文信息。
4:ReadProcessMemory(), WriteProcessMemory() 讀寫目標進程內存數據。
好了,這裏面就給我們提供了很好的方法,是什麼?對了就是 GetThreadContext(), SetThreadContext()
這兩個API函數,它倆不但是哥們,也是我們最好的朋友(親一下)。
下面給出代碼:
1:我們自己的dll
BOOL APIENTRY DllMain( HANDLE hModule, DWORD ul_reason_for_call, LPVOID lpReserved
{
//很簡單,我們不搞破壞,緊緊彈個信息框。
::MessageBox(0,"嘿嘿嘿!!!",0,0);
return TRUE;
}
2:我們的主程序
typedef HMODULE (__stdcall *pLoadLibrary)(LPCSTR lpLibFileName);
void test()
{
//不能直接使用常量字符串,否則會引起目標進程讀取數據異常。
char dllname[] = {'c',':','//','d','l','l','t','e','s','t','.','d','l','l','/0'};
//必須用2088770939這個 LoadLibrary 函數的絕對地址(在我的xp下是這個地址,使用時應該在自己的windows下獲取)
pLoadLibrary pFunc = pLoadLibrary(2088770939);
//調用LoadLibrary,因爲LoadLibrary函數在windows下每個進程中絕對地址都是一樣的。
pFunc(dllname);
return;
}
//以下是控制注入的函數
#include <windows.h>
void Inject()
{
CONTEXT context;
memset(&context,0,sizeof(context));
context.ContextFlags = CONTEXT_CONTROL;
PROCESS_INFORMATION piProcInfo;
STARTUPINFO siStartInfo;
ZeroMemory( &piProcInfo, sizeof(PROCESS_INFORMATION) );
ZeroMemory( &siStartInfo, sizeof(STARTUPINFO));
siStartInfo.cb = sizeof(STARTUPINFO);
BOOL bOk = CreateProcess(NULL,
"C://WINDOWS//system32//notepad.exe", // command line
NULL, // process security attributes
NULL, // primary thread security attributes
FALSE, // handles are inherited
0, // creation flags
NULL, // use parent's environment
"C://WINDOWS//system32//",// use parent's current directory
&siStartInfo, // STARTUPINFO pointer
&piProcInfo); // receives PROCESS_INFORMATION
::WaitForInputIdle(piProcInfo.hProcess,-1);
//爲目標進程分配空間
LPVOID pRemote = ::VirtualAllocEx(piProcInfo.hProcess,0,4096,MEM_RESERVE|MEM_COMMIT,PAGE_EXECUTE_READWRITE);
DWORD dWriten = 0,id = 0;
//將test函數寫入目標進程
::WriteProcessMemory(piProcInfo.hProcess,pRemote,(LPVOID)test,1024,&dWriten);
//掛起目標進程的主線程
::SuspendThread(piProcInfo.hThread);
//獲取目標線程的CPU上下文信息
i = ::GetThreadContext(piProcInfo.hThread,&context);
//更改Eip指令爲我們拷貝好的test函數
context.Eip = (long)pRemote;
//設置目標線程的CPU上下文信息
i = ::SetThreadContext(piProcInfo.hThread,&context);
//喚醒目標線程,
::ResumeThread(piProcInfo.hThread);
//目標線程此時就會執行我們的test函數了,執行完後還會繼續沿着
//自己原先的代碼序列執行下去。
return 0;
}
1:鉤子 SetWindowsHook
2:創建遠程線程 CreateRemoteThread
儘管都能實現遠程注入dll,但都難逃殺毒軟件的法眼,特別是 CreateRemoteThread
一般都被殺毒軟件監控的很牢,這裏提供一個巧妙的方法能夠利用目標進程(確切地說是線程)
自己主動調用LoadLibrary裝載dll.
我們想一想,windows下vc調試器可以調試正在運行的進程,功能很是強大,那可不可以
借鑑調試器的機理呢?完全可以,調試器的機理大致分爲以下幾步:
1:OpenProcess() 獲取目標進程句炳,擁有調試權限(我們這裏不需要用這個權限)
2:SuspendThread() 掛起目標進程的主線程
3:GetThreadContext(), SetThreadContext() 讀寫目標線程的當前CPU上下文信息。
4:ReadProcessMemory(), WriteProcessMemory() 讀寫目標進程內存數據。
好了,這裏面就給我們提供了很好的方法,是什麼?對了就是 GetThreadContext(), SetThreadContext()
這兩個API函數,它倆不但是哥們,也是我們最好的朋友(親一下)。
下面給出代碼:
1:我們自己的dll
BOOL APIENTRY DllMain( HANDLE hModule, DWORD ul_reason_for_call, LPVOID lpReserved
{
//很簡單,我們不搞破壞,緊緊彈個信息框。
::MessageBox(0,"嘿嘿嘿!!!",0,0);
return TRUE;
}
2:我們的主程序
typedef HMODULE (__stdcall *pLoadLibrary)(LPCSTR lpLibFileName);
void test()
{
//不能直接使用常量字符串,否則會引起目標進程讀取數據異常。
char dllname[] = {'c',':','//','d','l','l','t','e','s','t','.','d','l','l','/0'};
//必須用2088770939這個 LoadLibrary 函數的絕對地址(在我的xp下是這個地址,使用時應該在自己的windows下獲取)
pLoadLibrary pFunc = pLoadLibrary(2088770939);
//調用LoadLibrary,因爲LoadLibrary函數在windows下每個進程中絕對地址都是一樣的。
pFunc(dllname);
return;
}
//以下是控制注入的函數
#include <windows.h>
void Inject()
{
CONTEXT context;
memset(&context,0,sizeof(context));
context.ContextFlags = CONTEXT_CONTROL;
PROCESS_INFORMATION piProcInfo;
STARTUPINFO siStartInfo;
ZeroMemory( &piProcInfo, sizeof(PROCESS_INFORMATION) );
ZeroMemory( &siStartInfo, sizeof(STARTUPINFO));
siStartInfo.cb = sizeof(STARTUPINFO);
BOOL bOk = CreateProcess(NULL,
"C://WINDOWS//system32//notepad.exe", // command line
NULL, // process security attributes
NULL, // primary thread security attributes
FALSE, // handles are inherited
0, // creation flags
NULL, // use parent's environment
"C://WINDOWS//system32//",// use parent's current directory
&siStartInfo, // STARTUPINFO pointer
&piProcInfo); // receives PROCESS_INFORMATION
::WaitForInputIdle(piProcInfo.hProcess,-1);
//爲目標進程分配空間
LPVOID pRemote = ::VirtualAllocEx(piProcInfo.hProcess,0,4096,MEM_RESERVE|MEM_COMMIT,PAGE_EXECUTE_READWRITE);
DWORD dWriten = 0,id = 0;
//將test函數寫入目標進程
::WriteProcessMemory(piProcInfo.hProcess,pRemote,(LPVOID)test,1024,&dWriten);
//掛起目標進程的主線程
::SuspendThread(piProcInfo.hThread);
//獲取目標線程的CPU上下文信息
i = ::GetThreadContext(piProcInfo.hThread,&context);
//更改Eip指令爲我們拷貝好的test函數
context.Eip = (long)pRemote;
//設置目標線程的CPU上下文信息
i = ::SetThreadContext(piProcInfo.hThread,&context);
//喚醒目標線程,
::ResumeThread(piProcInfo.hThread);
//目標線程此時就會執行我們的test函數了,執行完後還會繼續沿着
//自己原先的代碼序列執行下去。
return 0;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.