久久国产成人av_抖音国产毛片_a片网站免费观看_A片无码播放手机在线观看,色五月在线观看,亚洲精品m在线观看,女人自慰的免费网址,悠悠在线观看精品视频,一级日本片免费的,亚洲精品久,国产精品成人久久久久久久

分享

VC知識庫文章

 JP_Morgen 2014-05-18

一、 前言:

遠(yuǎn)程線程技術(shù)指的是通過在其他進(jìn)程中創(chuàng)建新線程的方法進(jìn)入該進(jìn)程的內(nèi)存地址空間,,從而獲得對該進(jìn)程的控制權(quán)的方法,。
在進(jìn)程中可以通過CreateThread函數(shù)創(chuàng)建線程,被創(chuàng)建的新線程與主線程共享地址空間以及其他的資源,。同樣,,通過CreateRemoteThread函數(shù)可以在其他進(jìn)程內(nèi)創(chuàng)建新線程,新創(chuàng)建的的遠(yuǎn)程線程可以共享遠(yuǎn)程進(jìn)程的地址空間,。

所以通過在遠(yuǎn)程進(jìn)程中創(chuàng)建新的方法,,就可以進(jìn)入到遠(yuǎn)程進(jìn)程的內(nèi)存地址空間,也就擁有了和那個遠(yuǎn)程進(jìn)程相當(dāng)?shù)臋?quán)限,,可以在遠(yuǎn)程進(jìn)程中執(zhí)行代碼,,從而達(dá)到遠(yuǎn)程進(jìn)程控制、進(jìn)程隱藏的目的,。

二 ,、基本原理:

2.1. A P I 函數(shù)

其中VirtualAllocEx和CreateRemoteThread兩個API函數(shù)只能NT內(nèi)核下用。實現(xiàn)的基本過程如下:

(1)通過OpenProcess函數(shù)打開進(jìn)程PID為ProcessID的遠(yuǎn)程進(jìn)程:

hProcess = OpenProcess(PROCESS_ALL_ACCESS, false, ProcessId),;

(2)通過VirtualAllocEx函數(shù)在剛打開的進(jìn)程中申請IMageSize個字節(jié)的內(nèi)存:

InjectPoint = (LPBYTE)VirtualAllocEx(hProcess, 0, ImageSize, MEM_COMMIT, PAGE_EXECUTE_READWRITE) ,;

(3)通過WriteProcessMemory函數(shù)將NewModule開始的IMageSize個字節(jié)的代碼寫入已經(jīng)申請的內(nèi)存中:

WriteProcessMemory(hProcess, InjectPoint, NewModule, ImageSize, NULL) ;

(4)通過CreateRemoteThread函數(shù)啟動剛寫入的代碼:

CreateRemoteThread(hProcess, NULL, 0, RemoteEntryPoint, Param, 0, NULL);

2.2. 重定位和函數(shù)導(dǎo)入的問題

在遠(yuǎn)程進(jìn)程執(zhí)行的代碼中最重要的是要解決代碼的重定位和API函數(shù)導(dǎo)入的問題,,對于參考文獻(xiàn)1的方法是通過在遠(yuǎn)程進(jìn)程中執(zhí)行LoadLibrary函數(shù)將DLL文件載入,,所以系統(tǒng)會自動完成代碼的重定位和API函數(shù)導(dǎo)入工作:而參考文獻(xiàn)2中提到的方法是通過匯編語言進(jìn)行編程來解決,相對來講會使編程難度增大,但隱藏性是最好的,。在這里,,探討一種新的方法既能使用高級語言進(jìn)行編程又有完美的隱藏效果的方法。

首先要解決的是重定位問題,,這就要用到pE文件中的重定位表,,利用重定位表將即將寫入遠(yuǎn)程進(jìn)程的代碼按照在遠(yuǎn)程進(jìn)程申請到的內(nèi)存地址通過RelocCode函數(shù)進(jìn)行重定位,然后將重定位好的代碼寫入遠(yuǎn)程進(jìn)程的內(nèi)存空間,。這些寫入的代碼必然要用到API函數(shù),,所以在遠(yuǎn)程線程代碼調(diào)用第一個API之前,要替系統(tǒng)來完成裝入API函數(shù)對應(yīng)的DLL文件,,ing填好相關(guān)API函數(shù)入口地址的工作,,這就要用到PE文件的輸入表提供的信息,輸入表記錄了一個win32程序需要加載的所有DLL文件名及從中引入的API函數(shù)名,,這就可以用LoadLIbrary函數(shù)注入需要用的DLL文件,,在通過GETProcAddress函數(shù)獲得相應(yīng)的API函數(shù)地址,,這里是通過LoadAPI函數(shù)來完成這些工作,。下面程序中的LoadAPI函數(shù)作為遠(yuǎn)程線程的入口,其用到的API函數(shù)LoadLibrary和 GETProcAddress的入口地址有時如何確定的呢,?事實上幾乎所有的Windows進(jìn)程都會裝入“kernel32.dll”,,而這兩個函數(shù)就定位于“kernel32.dll”中,而且所有裝入“kernel32.dll”的進(jìn)程都會把它裝入到同一個虛擬內(nèi)存地址,,即在本地進(jìn)程中使用到“kernel32.dll”中的API函數(shù)和遠(yuǎn)程進(jìn)程中對應(yīng)的API函數(shù)地址是一樣的,,所以在遠(yuǎn)程進(jìn)程代碼中可以想本地進(jìn)程一樣調(diào)用LoadLibrary加載DLL文件,然后用GETProcAddress獲得輸入函數(shù)的入口地址并寫入響應(yīng)的數(shù)據(jù)結(jié)構(gòu)中,,完成API函數(shù)的導(dǎo)入,。

三、編程實現(xiàn):

001.//為了簡化代碼,,下面程序中去掉了對出錯處理的代碼,,實際應(yīng)用中應(yīng)該考慮程序運(yùn)行時可能的出錯:
002.#include "stdafx.h"
003.static PIMAGE_NT_HEADERS    nt_header;
004.#define IMAGESIZE   (nt_header->OptionalHeader.SizeOfImage)
005.#define EXPORT_TABEL   (nt_header->OptionalHeader.DataDirectory[0].VirtualAddress)
006.#define RELOC_TABEL    (nt_header->OptionalHeader.DataDirectory[5].VirtualAddress)
007.static void RelocCode (PBYTE  Image, LPBYTE   InjectBase) // 完成代碼的重定位
008.{   
009.DWORD  Rva = 0, RvaCount = 0, RelocOffset=0;
010.WORD  *Offset = NULL;
011.LPBYTE RelocTable = Image + RELOC_TABEL; //重定位表位置
012.PIMAGE_BASE_RELOCATION  basereloc= (PIMAGE_BASE_RELOCATION) RelocTable;
013.RelocOffset= (DWORD)InjectBase -  nt_header ->OptionalHeader.ImageBase; //重定位表偏移
014.while(basereloc ->VirtualAddress != NULL)// 遍歷重定位表,修正需要重定位的代碼
015.
016.Offset = (WORD*)(RelocTable + sizeof(IMAGE_BASE_RELOCATION));
017.RvaCount = (basereloc ->SizeOfBlock - sizeof(IMAGE_BASE_RELOCATION)) / 2;
018.for(DWORD i=0; iVirtualAddress + (DWORD)Image;
019.*(DWORD*)Rva += RelocOffset;//RVA加上修正量進(jìn)行修正
020.}
021.RelocTable += basereloc ->SizeOfBlock;//指向下一頁重定位信息處
022.basereloc  = (PIMAGE_BASE_RELOCATION) RelocTable;
023.}
024.}
025.int LoadAPI(LPBYTE InjectBase)// 用于完成API函數(shù)的導(dǎo)入,,參數(shù)為要插入代碼處地址
026.
027.PIMAGE_DOS_HEADER dos_h = (PIMAGE_DOS_HEADER) InjectBase;
028.PIMAGE_NT_HEADERS nt_h = (PIMAGE_NT_HEADERS)(InjectBase + dos_h->e_lfanew);
029.PIMAGE_IMPORT_DESCRIPTOR import_d = (PIMAGE_IMPORT_DESCRIPTOR)
030.(InjectBase + nt_h->OptionalHeader.DataDirectory[1].VirtualAddress);
031.for(  ; import_d->OriginalFirstThunk != 0; import_d++)//遍歷導(dǎo)入表
032.{  
033.HMODULE hDll = LoadLibrary((LPCSTR)(InjectBase + import_d->Name));
034.//上面能直接引用LoadLibrary是由于本地和遠(yuǎn)程進(jìn)程中該函數(shù)地址都是相同的
035.if(hDll == NULL) 
036.return 0;
037.PIMAGE_THUNK_DATA Origin = (PIMAGE_THUNK_DATA)(InjectBase +import_d->OriginalFirstThunk);
038.PIMAGE_THUNK_DATA First = (PIMAGE_THUNK_DATA)(InjectBase + import_d->FirstThunk);
039.LPCSTR Name = NULL;
040.PIMAGE_IMPORT_BY_NAME Import_name = NULL;
041.for(; Origin->u1.Ordinal != 0; Origin++, First++)
042.{  
043.if(Origin->u1.Ordinal & IMAGE_ORDINAL_FLAG)
044.Name = (LPCSTR)IMAGE_ORDINAL(Origin->u1.Ordinal);
045.else
046.{  
047.Import_name = (PIMAGE_IMPORT_BY_NAME)(InjectBase + (DWORD)( Origin->u1.AddressOfData));
048.Name = (LPCSTR)Import_name->Name;
049.}
050.First->u1.Function = (DWORD * )GetProcAddress(hDll, Name);
051.//上面能直接引用GetProcAddress是由于本地和遠(yuǎn)程進(jìn)程中該函數(shù)地址都是相同的
052.if(First->u1.Function == NULL) 
053.return 0;
054.}
055.}
056.return 1;
057.}
058.DWORD RemoteThread_Main(HINSTANCE hInstance) //遠(yuǎn)程要執(zhí)行的代碼,,在這里只演示MessageBox
059.
060.::MessageBox (0,"遠(yuǎn)程線程插入成功!","遠(yuǎn)程線程",0);
061.return 1;
062.}
063.DWORD  ThreadEntry(LPBYTE  ImageBase) /***   遠(yuǎn)程線程入口  ***/
064.{   
065.if(LoadAPI(ImageBase))//先完成API函數(shù)的導(dǎo)入工作
066.RemoteThread_Main ((HINSTANCE)ImageBase);  //執(zhí)行函數(shù)RemoteThread_Main中的代碼
067.return 1;
068.}
069.static DWORD GetTargetProcessId() //獲取遠(yuǎn)程進(jìn)程 PID
070.
071.DWORD ProcessId = 0;
072.HWND hWnd = FindWindow("Progman", "Program Manager");//獲取資源管理器進(jìn)程PID
073.if(hWnd != NULL)
074.GetWindowThreadProcessId(hWnd, &ProcessId);
075.return ProcessId;
076.}
077.int APIENTRY WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,LPSTR lpCmdLine, int nCmdShow)
078.{  
079.LPBYTE  InjectPoint = NULL, Module = NULL, NewModule = NULL,Param =NULL;
080.HANDLE hProcess = NULL, hThread = NULL;
081.DWORD ProcessId = 0, ImageSize = 0;
082.LPTHREAD_START_ROUTINE    RemoteEntryPoint = NULL;
083.Module = (unsigned char *)GetModuleHandle(NULL);//獲取自身句柄
084.nt_header = (PIMAGE_NT_HEADERS)(Module + ((PIMAGE_DOS_HEADER)Module)->e_lfanew);
085.ImageSize = IMAGESIZE ; //得到內(nèi)存映象大小
086.//通過VirtualAllocEx申請存放自身代碼的內(nèi)存空間
087.NewModule =( LPBYTE )VirtualAlloc(NULL, ImageSize, MEM_COMMIT | MEM_RESERVE,
088.PAGE_EXECUTE_READWRITE);
089.memcpy(NewModule, Module, ImageSize) ; //將自身復(fù)制到NewModule處
090.nt_header = (PIMAGE_NT_HEADERS)(NewModule + ((PIMAGE_DOS_HEADER)NewModule)->e_lfanew);
091.if( ProcessId = GetTargetProcessId() ) //獲取遠(yuǎn)程進(jìn)程 PID
092.if( hProcess = OpenProcess(PROCESS_ALL_ACCESS, false, ProcessId)) //打開進(jìn)程
093.//通過VirtualAllocEx在打開的遠(yuǎn)程進(jìn)程中申請內(nèi)存空間
094.if( InjectPoint = (LPBYTE)VirtualAllocEx(hProcess, 0, ImageSize, MEM_COMMIT, PAGE_EXECUTE_READWRITE) )
095.{  
096.RelocCode (NewModule, InjectPoint); //重定位NewModule處的代碼
097.RemoteEntryPoint = (LPTHREAD_START_ROUTINE)( InjectPoint +(DWORD) &ThreadEntry - Module );//得到ThreadEntry在遠(yuǎn)程進(jìn)程中的地址
098.Param  = InjectPoint; //將插入點(diǎn)地址作為參數(shù)傳遞給線程函數(shù)
099.//將重定位好的代碼通過WriteProcessMemory寫入遠(yuǎn)程進(jìn)程的內(nèi)存空間中
100.if(WriteProcessMemory(hProcess, InjectPoint, NewModule, ImageSize, NULL))
101.//通過CreateRemoteThread啟動剛寫入的代碼,,參數(shù)為Param
102.CreateRemoteThread(hProcess, NULL, 0, RemoteEntryPoint, Param, 0, NULL);
103.}
104.return 0;
105.}

四 ,、總結(jié)

代碼可以把它當(dāng)做一個模板,只要是在RemoteThread_Main函數(shù)中加入實現(xiàn)各種功能的代碼即可把它隱藏到其他進(jìn)程中去運(yùn)行,。遠(yuǎn)程線程技術(shù)除了隱藏進(jìn)程外,,還有其他一些用途,如用于殺毒軟件進(jìn)行內(nèi)存殺毒等。

以上代碼均在WindowsXP專業(yè)版和Windows2000下正常運(yùn)行,,注意在編譯程序時候應(yīng)保留重定位表的信息,,即在“Project”菜單中選“SETting”,然后選Link選項卡,,將Link incrementally選上在進(jìn)行編譯,,否則會出錯。 

    本站是提供個人知識管理的網(wǎng)絡(luò)存儲空間,,所有內(nèi)容均由用戶發(fā)布,,不代表本站觀點(diǎn)。請注意甄別內(nèi)容中的聯(lián)系方式,、誘導(dǎo)購買等信息,,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,,請點(diǎn)擊一鍵舉報,。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評論

    發(fā)表

    請遵守用戶 評論公約

    類似文章 更多