最美情侣中文字幕电影,在线麻豆精品传媒,在线网站高清黄,久久黄色视频

歡迎光臨散文網(wǎng) 會員登陸 & 注冊

淺談內(nèi)存搜索

2023-01-04 16:50 作者:拾柒-光羽  | 我要投稿

? ? ???????????????????????????????????????????????????????????

先來細(xì)談原理


????對系統(tǒng)進(jìn)程遍歷 打印 獲取進(jìn)程?PID?句柄?????????

?????????

以下簡單的控制臺應(yīng)用程序獲取正在運(yùn)行的進(jìn)程列表。 首先,該 GetProcessList 函數(shù)使用 CreateToolhelp32Snapshot 拍攝系統(tǒng)中當(dāng)前正在執(zhí)行的進(jìn)程快照,然后使用 Process32First 和 Process32Next 遍歷快照中記錄的列表。 對于每個進(jìn)程,GetProcessList依次調(diào)用ListProcessModules遍歷模塊列表中所述的函數(shù),以及ListProcessThreads遍歷線程列表中所述的函數(shù)。

一個簡單的錯誤報告函數(shù) printError顯示任何失敗的原因,這通常源于安全限制。 例如, OpenProcess 對于 Idle 和 CSRSS 進(jìn)程失敗,因?yàn)樗鼈兊脑L問限制會阻止用戶級代碼打開它們。

#include <windows.h>

#include <tlhelp32.h>

#include <tchar.h>



// ?Forward declarations:

BOOL GetProcessList( );

BOOL ListProcessModules( DWORD dwPID );

BOOL ListProcessThreads( DWORD dwOwnerPID );

void printError( TCHAR* msg );



int main( void )

{

 ?GetProcessList( );

 ?return 0;

}



BOOL GetProcessList( )

{

 ?HANDLE hProcessSnap;

 ?HANDLE hProcess;

 ?PROCESSENTRY32 pe32;

 ?DWORD dwPriorityClass;



 ?// Take a snapshot of all processes in the system.

 ?hProcessSnap = CreateToolhelp32Snapshot( TH32CS_SNAPPROCESS, 0 );

 ?if( hProcessSnap == INVALID_HANDLE_VALUE )

 ?{

 ? ?printError( TEXT("CreateToolhelp32Snapshot (of processes)") );

 ? ?return( FALSE );

 ?}



 ?// Set the size of the structure before using it.

 ?pe32.dwSize = sizeof( PROCESSENTRY32 );



 ?// Retrieve information about the first process,

 ?// and exit if unsuccessful

 ?if( !Process32First( hProcessSnap, &pe32 ) )

 ?{

 ? ?printError( TEXT("Process32First") ); // show cause of failure

 ? ?CloseHandle( hProcessSnap ); ? ? ? ? ?// clean the snapshot object

 ? ?return( FALSE );

 ?}



 ?// Now walk the snapshot of processes, and

 ?// display information about each process in turn

 ?do

 ?{

 ? ?_tprintf( TEXT("\n\n=====================================================" ));

 ? ?_tprintf( TEXT("\nPROCESS NAME: ?%s"), pe32.szExeFile );

 ? ?_tprintf( TEXT("\n-------------------------------------------------------" ));



 ? ?// Retrieve the priority class.

 ? ?dwPriorityClass = 0;

 ? ?hProcess = OpenProcess( PROCESS_ALL_ACCESS, FALSE, pe32.th32ProcessID );

 ? ?if( hProcess == NULL )

 ? ? ?printError( TEXT("OpenProcess") );

 ? ?else

 ? ?{

 ? ? ?dwPriorityClass = GetPriorityClass( hProcess );

 ? ? ?if( !dwPriorityClass )

 ? ? ? ?printError( TEXT("GetPriorityClass") );

 ? ? ?CloseHandle( hProcess );

 ? ?}



 ? ?_tprintf( TEXT("\n ?Process ID ? ? ? ?= 0x%08X"), pe32.th32ProcessID );

 ? ?_tprintf( TEXT("\n ?Thread count ? ? ?= %d"), ? pe32.cntThreads );

 ? ?_tprintf( TEXT("\n ?Parent process ID = 0x%08X"), pe32.th32ParentProcessID );

 ? ?_tprintf( TEXT("\n ?Priority base ? ? = %d"), pe32.pcPriClassBase );

 ? ?if( dwPriorityClass )

 ? ? ?_tprintf( TEXT("\n ?Priority class ? ?= %d"), dwPriorityClass );



 ? ?// List the modules and threads associated with this process

 ? ?ListProcessModules( pe32.th32ProcessID );

 ? ?ListProcessThreads( pe32.th32ProcessID );



 ?} while( Process32Next( hProcessSnap, &pe32 ) );



 ?CloseHandle( hProcessSnap );

 ?return( TRUE );

}





BOOL ListProcessModules( DWORD dwPID )

{

 ?HANDLE hModuleSnap = INVALID_HANDLE_VALUE;

 ?MODULEENTRY32 me32;



 ?// Take a snapshot of all modules in the specified process.

 ?hModuleSnap = CreateToolhelp32Snapshot( TH32CS_SNAPMODULE, dwPID );

 ?if( hModuleSnap == INVALID_HANDLE_VALUE )

 ?{

 ? ?printError( TEXT("CreateToolhelp32Snapshot (of modules)") );

 ? ?return( FALSE );

 ?}



 ?// Set the size of the structure before using it.

 ?me32.dwSize = sizeof( MODULEENTRY32 );



 ?// Retrieve information about the first module,

 ?// and exit if unsuccessful

 ?if( !Module32First( hModuleSnap, &me32 ) )

 ?{

 ? ?printError( TEXT("Module32First") ); ?// show cause of failure

 ? ?CloseHandle( hModuleSnap ); ? ? ? ? ? // clean the snapshot object

 ? ?return( FALSE );

 ?}



 ?// Now walk the module list of the process,

 ?// and display information about each module

 ?do

 ?{

 ? ?_tprintf( TEXT("\n\n ? ? MODULE NAME: ? ? %s"), ? me32.szModule );

 ? ?_tprintf( TEXT("\n ? ? Executable ? ? = %s"), ? ? me32.szExePath );

 ? ?_tprintf( TEXT("\n ? ? Process ID ? ? = 0x%08X"), ? ? ? ? me32.th32ProcessID );

 ? ?_tprintf( TEXT("\n ? ? Ref count (g) ?= 0x%04X"), ? ? me32.GlblcntUsage );

 ? ?_tprintf( TEXT("\n ? ? Ref count (p) ?= 0x%04X"), ? ? me32.ProccntUsage );

 ? ?_tprintf( TEXT("\n ? ? Base address ? = 0x%08X"), (DWORD) me32.modBaseAddr );

 ? ?_tprintf( TEXT("\n ? ? Base size ? ? ?= %d"), ? ? ? ? ? ? me32.modBaseSize );



 ?} while( Module32Next( hModuleSnap, &me32 ) );



 ?CloseHandle( hModuleSnap );

 ?return( TRUE );

}



BOOL ListProcessThreads( DWORD dwOwnerPID ) 

{ 

 ?HANDLE hThreadSnap = INVALID_HANDLE_VALUE; 

 ?THREADENTRY32 te32; 

 

 ?// Take a snapshot of all running threads ?

 ?hThreadSnap = CreateToolhelp32Snapshot( TH32CS_SNAPTHREAD, 0 ); 

 ?if( hThreadSnap == INVALID_HANDLE_VALUE ) 

 ? ?return( FALSE ); 

 

 ?// Fill in the size of the structure before using it. 

 ?te32.dwSize = sizeof(THREADENTRY32); 

 

 ?// Retrieve information about the first thread,

 ?// and exit if unsuccessful

 ?if( !Thread32First( hThreadSnap, &te32 ) ) 

 ?{

 ? ?printError( TEXT("Thread32First") ); // show cause of failure

 ? ?CloseHandle( hThreadSnap ); ? ? ? ? ?// clean the snapshot object

 ? ?return( FALSE );

 ?}



 ?// Now walk the thread list of the system,

 ?// and display information about each thread

 ?// associated with the specified process

 ?do 

 ?{ 

 ? ?if( te32.th32OwnerProcessID == dwOwnerPID )

 ? ?{

 ? ? ?_tprintf( TEXT("\n\n ? ? THREAD ID ? ? ?= 0x%08X"), te32.th32ThreadID ); 

 ? ? ?_tprintf( TEXT("\n ? ? Base priority ?= %d"), te32.tpBasePri ); 

 ? ? ?_tprintf( TEXT("\n ? ? Delta priority = %d"), te32.tpDeltaPri ); 

 ? ? ?_tprintf( TEXT("\n"));

 ? ?}

 ?} while( Thread32Next(hThreadSnap, &te32 ) ); 



 ?CloseHandle( hThreadSnap );

 ?return( TRUE );

}



void printError( TCHAR* msg )

{

 ?DWORD eNum;

 ?TCHAR sysMsg[256];

 ?TCHAR* p;



 ?eNum = GetLastError( );

 ?FormatMessage( FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,

 ? ? ? ? NULL, eNum,

 ? ? ? ? MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language

 ? ? ? ? sysMsg, 256, NULL );



 ?// Trim the end of the line and terminate it with a null

 ?p = sysMsg;

 ?while( ( *p > 31 ) || ( *p == 9 ) )

 ? ?++p;

 ?do { *p-- = 0; } while( ( p >= sysMsg ) &&

 ? ? ? ? ? ? ? ? ? ? ? ? ?( ( *p == '.' ) || ( *p < 33 ) ) );



 ?// Display the message

 ?_tprintf( TEXT("\n ?WARNING: %s failed with error %d (%s)"), msg, eNum, sysMsg );

}

-----選自微軟開發(fā)文檔? ? ??

????使用window的api 對目標(biāo)進(jìn)程讀取?

ULONG ReadMemory(

 ?ULONG offset,

 ?PVOID lpBuffer,

 ?ULONG cb,

 ?PULONG lpcbBytesRead

);

-----選自微軟開發(fā)文檔? ?記得加windows.h

????????搜索算法? KMP

? ? ? ? ? ? ? ? ?具體的算法原理 介紹 再此暫不涉及?KMP算法的介紹

?????????????????????KMP是字符串匹配算法 他的作用是用來匹配字節(jié)在內(nèi)存中的位置

????????????????????字節(jié)的類型?

unsigned char

KMP算法的簡單實(shí)現(xiàn) 寫的不規(guī)范請見諒?

		set<UINT_PTR> address_list;
		


		void KMP(unsigned char* zichuan, unsigned char* muchuan,UINT_PTR len_zi,UINT_PTR len_mu,UINT_PTR fujia=0) {
			if (len_zi <= len_mu) {
				

				int* next = (int*)init_ptr(len_mu * 4);
				int prefix_len = 0;//當(dāng)前的共同前后綴長度

				for (int i = 1; i <= len_mu - 1;) {

					if (muchuan[prefix_len] == muchuan[i]) {
						prefix_len += 1;
						next[i] = prefix_len;
						i += 1;
					}//相同的時候很簡單 如上
					else {
						//接下來分為倆種 如果當(dāng)前前后綴的相同長度為0 直接可以跳過賦0
						if (prefix_len == 0) {
							next[i] = 0;
							i += 1;
						}
						else {
							prefix_len = next[prefix_len - 1];//將當(dāng)前長度設(shè)置為前綴中相同位置的前一個 然后進(jìn)入下一次循環(huán) i不變
						}

					}
				}



				//printf("\n開始執(zhí)行KMP算法\n\n");

				/*上面是計(jì)算 next
				這里開始 查找*/	int i = 0/*指向母串的指針*/, j = 0/*指向子串的指針*/;
				while (i <= len_mu - 1) {
					/*printf("第%d個 匹配中 : ?", i);*/
					/*if (j >= 子串長度) {
						i = i - j + 2;
						j = 0;
						j = 0;
					}*/
					if (zichuan[j] == muchuan[i]) {
						i += 1;
						j += 1;
						/*printf("相等\n");*/

					}
					else if (j > 0) {
						j = next[j - 1];//通過next數(shù)組回退
						/*printf("回退\n");*/
					}
					else {
						/*printf("i進(jìn)一位 不用回退\n");*/
						i += 1;//子串第一個就匹配失敗 也就不用回退了
					}
					/*printf(" ? ? 當(dāng)前j值%d ? ? ?\n", j);*/
					if (j == len_zi) {

						address_list.insert(i - j + fujia);


						/*Sleep(1000000);*/
						i = i - j + 2;
						j = 0;
						/*printf("\n找到 在 %d 位\n\n", i-j);*/
					};//匹配成功 插入set 注意是i-j
				}
				free(next);
			}
		}


接下來就是如何組裝他們了

首先 遍歷進(jìn)程獲取到權(quán)限句柄

HANDLE handle

然后 讀取目標(biāo)進(jìn)程的內(nèi)存

這里我們可以優(yōu)化為一次讀取一塊內(nèi)存 然后對內(nèi)存塊使用KMP算法 加上內(nèi)存塊的首地址 便是我們想要得到的地址了 沒有考慮內(nèi)存對齊的情況 大佬在寫的時候可以修改



void search(HANDLE hprocess,unsigned char* zijieji,UINT_PTR len,UINT_PTR startaddress=0,UINT_PTR finaladdress= 0x7fffffffffff)
		{
			
			unsigned char arBytes[BLOCKMAXSIZE];					// 409600的數(shù)據(jù)緩沖區(qū),用來存放一個內(nèi)存頁

			int i = 0;

			address_list.clear();
			/*int weishu = len;*/
			unsigned long long BlockSize;
			MEMORY_BASIC_INFORMATION mbi;
			UINT_PTR address_now = startaddress;
			/*VirtualQueryEx(hprocess, (LPCVOID)(address_now), &mbi, sizeof(mbi));*/
			while (address_now<finaladdress && VirtualQueryEx(hprocess, (LPCVOID)(address_now), &mbi, sizeof(mbi))!=0)
			{
				
				//獲取可讀可寫和可讀可寫可執(zhí)行的內(nèi)存塊
				if (mbi.Protect == PAGE_READWRITE || mbi.Protect == PAGE_EXECUTE_READWRITE)
				{
					i = 0;
					BlockSize = mbi.RegionSize;
					//搜索這塊內(nèi)存
					if (BlockSize < 0) {
						break;
				}
					while (BlockSize >= BLOCKMAXSIZE)
					{
						



						if (ReadProcessMemory(hprocess, (LPCVOID)(address_now + (BLOCKMAXSIZE * i)), arBytes, BLOCKMAXSIZE, NULL)) {

							KMP(zijieji, arBytes, len, BLOCKMAXSIZE, address_now + (BLOCKMAXSIZE * i));


						}


						BlockSize -= BLOCKMAXSIZE;
						i++;
					}


					if (ReadProcessMemory(hprocess, (LPCVOID)(address_now + (BLOCKMAXSIZE * i)), arBytes, BlockSize, NULL)) {

						KMP(zijieji, arBytes, len, BlockSize, address_now + (BLOCKMAXSIZE * i));


					}


				}
				address_now += mbi.RegionSize;


			}





		}


將讀取到的內(nèi)存塊進(jìn)行匹配 最后對容器打印輸出便完成啦

不過不如ce快 應(yīng)該是沒進(jìn)行內(nèi)存對齊的問題()可以多開兩個線程加快速度

附上搜索截圖


搜索Caculator.exe中字節(jié)碼為0的內(nèi)存


淺談內(nèi)存搜索的評論 (共 條)

分享到微博請遵守國家法律
义乌市| 安塞县| 承德县| 铜梁县| 共和县| 会东县| 胶南市| 法库县| 岐山县| 嘉鱼县| 三明市| 江城| 盐边县| 济宁市| 灵丘县| 敦煌市| 茶陵县| 东光县| 花垣县| 永济市| 广东省| 綦江县| 炉霍县| 保德县| 河南省| 雅安市| 遵化市| 厦门市| 元阳县| 佛教| 龙游县| 儋州市| 靖边县| 朔州市| 和政县| 兴隆县| 商南县| 邯郸市| 普兰店市| 古田县| 台山市|