VC++枚举进程与模块

//http://www.myexception.cn/cpp/913576.html
#pragma once
#define _WIN32_WINNT 0x0500 
#include"windows.h"
#include"tlhelp32.h"
#include"stdio.h"
#include"NativeApi.h"
#include"wchar.h"
#include"psapi.h"//SDK6.0
#pragma comment(lib,"psapi.lib")SDK6.0,不知道为什么vc6好像没有自带这个头文件??

int GetUserPath(WCHAR* szModPath);
BOOL GetProcessModule(DWORD dwPID)
{
    BOOL bRet    =    FALSE;
    BOOL bFound    =    FALSE;
    HANDLE hModuleSnap = NULL;
    MODULEENTRY32 me32 ={0};
	
    hModuleSnap = ::CreateToolhelp32Snapshot(TH32CS_SNAPMODULE,dwPID);//创建进程快照
    if(hModuleSnap == INVALID_HANDLE_VALUE)
	{   
		printf("获取模块失败!\n");
		return FALSE;
	}
	
    me32.dwSize = sizeof(MODULEENTRY32);
    if(::Module32First(hModuleSnap,&me32))//获得第一个模块
	{
		do{
			printf("方法1列模块名:%s\n",me32.szExePath);
		}while(::Module32Next(hModuleSnap,&me32));
	}//递归枚举模块
	
	CloseHandle(hModuleSnap);
	return bFound;
}

bool ForceLookUpModule(DWORD dwPID)
{
	typedef DWORD( WINAPI *FunLookModule)(
		HANDLE ProcessHandle,
		DWORD BaseAddress,
		DWORD MemoryInformationClass,
		DWORD MemoryInformation,
		DWORD MemoryInformationLength,
		DWORD ReturnLength );
	HMODULE hModule = GetModuleHandle ("ntdll.dll" ) ;
	if(hModule==NULL)
	{ 
		return FALSE;
	}
    FunLookModule ZwQueryVirtualMemory=(FunLookModule)GetProcAddress(hModule,"ZwQueryVirtualMemory");
	if(ZwQueryVirtualMemory==NULL)
	{
		return FALSE;
	}
	HANDLE hProcess=OpenProcess(PROCESS_QUERY_INFORMATION,1,dwPID);
	if(hProcess==NULL)
		return FALSE;
	PMEMORY_SECTION_NAME Out_Data=(PMEMORY_SECTION_NAME)	malloc(0x200u);
	DWORD retLength;
	WCHAR Path[256]={0};
	wchar_t wstr[256]={0};
	
	for(unsigned int i=0;i<0x7fffffff;i=i+0x10000)
	{ 
		if( ZwQueryVirtualMemory(hProcess,(DWORD)i,2,(DWORD)Out_Data,512,(DWORD)&retLength)>0)
		{ 
			if(!IsBadReadPtr((BYTE*)Out_Data->SectionFileName.Buffer,1))
			{
				if(((BYTE*)Out_Data->SectionFileName.Buffer)[0]==0x5c)
				{
					if(wcscmp(wstr, Out_Data->SectionFileName.Buffer))			
					{   
						_wsetlocale(0,L"chs"); 				
						GetUserPath(Out_Data->SectionFileName.Buffer);
						wprintf(L"方法2列模块%s\n",Out_Data->SectionFileName.Buffer);
					}
					wcscpy(wstr,   Out_Data->SectionFileName.Buffer);
				}	
			}
		}
	}
	CloseHandle(hProcess);
	return TRUE;
	
}
int GetUserPath(WCHAR* szModPath)
{    //\Device\HarddiskVolume1, 
	WCHAR Path[256]={0};
	WCHAR* Temp3=new WCHAR[3];	
	Temp3[2]='\0';	
	Temp3[1]=':';
	THead* phead=new THead;
	phead->Next=NULL;
	phead->Num=szModPath[22];
	for(int i='C';i<='Z';i++)
	{Temp3[0]=i;
	if(QueryDosDeviceW(Temp3,Path,30))
		if(phead->Num==Path[22])
		{  
			phead->Disk=(WCHAR)i;
			break;
		}
	}
	   
   szModPath[0]=phead->Disk;
   szModPath[1]=':';
   szModPath[2]='\0';
   wcscpy(Path,szModPath+23);
   wcscat(szModPath,Path);
   
   delete phead;
   delete Temp3; 
   
   return 0;
}
BOOL EnableDebugPrivilege(BOOL fEnable)//这个用于提权的
{  
	BOOL fOk = FALSE;   
	HANDLE hToken;
	
	if (OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES,&hToken))
	{   
		TOKEN_PRIVILEGES tp;
		tp.PrivilegeCount = 1;
		LookupPrivilegeValue(NULL, SE_DEBUG_NAME, &tp.Privileges[0].Luid);
		tp.Privileges[0].Attributes = fEnable ? SE_PRIVILEGE_ENABLED : 0;
		AdjustTokenPrivileges(hToken, FALSE, &tp, sizeof(tp), NULL, NULL);
		fOk = (GetLastError() == ERROR_SUCCESS);
		CloseHandle(hToken);
	}
	else
	{
		return 0;
	}
	return(fOk);
}

void EnumModlueAll(DWORD dwPID)
{   
	HANDLE hProcess=OpenProcess(PROCESS_ALL_ACCESS,false,dwPID);
	if(hProcess==INVALID_HANDLE_VALUE)
	{ printf(" open process failed!\n");
	return;
	}
	DWORD size=0,ret=0;
	EnumProcessModules(hProcess,NULL,size,&ret);
	HMODULE *parry=(HMODULE*)malloc(ret+4);
	memset(parry,0,ret+4);
	if(EnumProcessModules(hProcess,parry,ret+4,&ret))
	{
		char* path=new char[MAX_PATH];
		memset(path,0,MAX_PATH);
		UINT i=0;
		
		while(GetModuleFileNameEx(hProcess,parry[i],path,MAX_PATH))
		{
			printf("方法3模块:%s\n",path);
			memset(path,0,MAX_PATH);
			i++;
		}
		delete path;
		
	}
	free(parry);
	
	CloseHandle(hProcess);
}

void EnumModuleEx(DWORD dwPID)
{   
	DWORD status;
	HMODULE hMod=GetModuleHandle("ntdll.dll");
	RTLCREATEQUERYDEBUGBUFFER RtlCreateQueryDebugBuffer=(RTLCREATEQUERYDEBUGBUFFER )GetProcAddress(hMod,"RtlCreateQueryDebugBuffer");
	RTLQUERYPROCESSDEBUGINFORMATION RtlQueryProcessDebugInformation=(RTLQUERYPROCESSDEBUGINFORMATION)GetProcAddress(hMod,"RtlQueryProcessDebugInformation");
	RTLDESTROYDEBUGBUFFER RtlDestroyQueryDebugBuffer =(RTLDESTROYDEBUGBUFFER )GetProcAddress(hMod,"RtlDestroyQueryDebugBuffer");
	if((hMod==NULL)||(RtlDestroyQueryDebugBuffer==NULL)||(RtlQueryProcessDebugInformation==NULL)||(RtlCreateQueryDebugBuffer==NULL))
	{
		printf("函数定位失败!\n");
		return ;
	}	
	
	PDEBUG_BUFFER Buffer=RtlCreateQueryDebugBuffer(0,FALSE);
	status=RtlQueryProcessDebugInformation(dwPID,PDI_MODULES ,Buffer);
	if(status<0)
	{ 
		printf("RtlQueryProcessDebugInformation函数调用失败,进程开了保护\n");
		return ;
	}
	ULONG count=*(PULONG)(Buffer->ModuleInformation);
	ULONG hModule=NULL;
	PDEBUG_MODULE_INFORMATION ModuleInfo=(PDEBUG_MODULE_INFORMATION)((ULONG)Buffer->ModuleInformation+4);
	for(ULONG i=0;i<count;i++)
	{
		printf("方法4列出的模块:%s\n",ModuleInfo->ImageName);
		ModuleInfo++;
	}
	
	RtlDestroyQueryDebugBuffer(Buffer);
}

void EnumSelfModule()
{
	void *PEB         = NULL,
		*Ldr         = NULL,
		*Flink       = NULL,
		*p           = NULL,
		*BaseAddress = NULL,
		*FullDllName = NULL;
	printf("列举自身模块!\n");
	__asm
	{
		mov     eax,fs:[0x30]
			mov     PEB,eax
	}
	printf( "PEB   = 0x%08X\n", PEB );
	Ldr   = *( ( void ** )( ( unsigned char * )PEB + 0x0c ) );
	printf( "Ldr   = 0x%08X\n", Ldr );
	Flink = *( ( void ** )( ( unsigned char * )Ldr + 0x0c ) );
	printf( "Flink = 0x%08X\n", Flink );
	p     = Flink;
	do
	{
		BaseAddress = *( ( void ** )( ( unsigned char * )p + 0x18 ) );
		FullDllName = *( ( void ** )( ( unsigned char * )p + 0x28 ) );
		printf( "p     = 0x%08X 0x%08X ", p, BaseAddress );
		wprintf( L"%s\n", FullDllName );
		p = *( ( void ** )p );
	}
	while ( Flink != p );
	return;
	
}

#define PAGE_SIZE 0x1000
void  Search();
bool IsValidModule(ULONG i);
bool PrintModule();
void main();
bool IsValidModule(byte* i)
{   
	if(IsBadReadPtr((void*)i,sizeof(IMAGE_DOS_HEADER)))
		return false;
	IMAGE_DOS_HEADER *BasePoint=(IMAGE_DOS_HEADER *)i;
	PIMAGE_NT_HEADERS32 NtHead=(PIMAGE_NT_HEADERS32)(i+BasePoint->e_lfanew);
	if(IsBadReadPtr((void*)NtHead,PAGE_SIZE))
		return false;
	if((NtHead->FileHeader.Characteristics&IMAGE_FILE_DLL)==0)//过滤掉。exe文件
		return false;
	if(NtHead->OptionalHeader.Subsystem==0x2)
		return true;
	if(NtHead->OptionalHeader.Subsystem==0x3)
		return true;
	return false;
}

void Search()
{   
	printf("暴力搜索列举模块!\n");
	UCHAR* i=(PUCHAR)0x10000000;
	int Num=0;
	for(;i<(PUCHAR)0x7ffeffff;i+=PAGE_SIZE)
	{   
		if(IsValidModule(i))
		{
			printf("\t\t find a module at %08x\n",i);
			Num++;
		}	
		
	}
	printf("\t\t total find module :%03d\n",Num);
}

void main()
{
	EnableDebugPrivilege(true);
	EnumModlueAll(4228);
	ForceLookUpModule(4228);
	getchar();
	GetProcessModule(4228);
	EnumModuleEx(4228);
	getchar();
	EnumSelfModule();
	getchar();
	Search();
	printf("按任意键退出........");
	getchar();
}


vc 是 Visual C++ 编程语言的简称,可以用于开发 Windows 系统的应用程序。 在 Visual C++ 中,要枚举所有串口,可以使用 Win32 API 来完成。以下是一种实现方法: 首先,需要引入 Windows.h 头文件,该头文件包含了访问串口的相关函数和结构体。 然后,使用 CreateFile 函数打开串口,通过遍历端口号来获取每个串口的句柄。例如,端口号 COM1 对应的句柄为"\\\\.\\COM1"。 接着,使用 GetCommState 函数获取当前串口的配置信息,可以得到波特率、数据位、奇偶校验等参数。 随后,将获取到的串口信息存储到一个数组中,即可完成所有串口的枚举。 最后,使用 CloseHandle 函数关闭串口句柄,释放资源。 下面是示例代码: ```cpp #include <Windows.h> #include <iostream> int main() { for (int i = 1; i <= 255; i++) { std::string portName = "\\\\.\\COM" + std::to_string(i); HANDLE hPort = CreateFile( portName.c_str(), GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL ); if (hPort != INVALID_HANDLE_VALUE) { DCB dcb; if (GetCommState(hPort, &dcb)) { std::cout << "串口号: COM" << i << std::endl; std::cout << "波特率: " << dcb.BaudRate << std::endl; std::cout << "数据位: " << dcb.ByteSize << std::endl; std::cout << "奇偶校验: " << dcb.Parity << std::endl; std::cout << std::endl; } CloseHandle(hPort); } } return 0; } ``` 上述代码通过遍历从 COM1 到 COM255 的端口号,打开每个串口并获取其配置信息,并将其输出到控制台。 总结:以上就是使用 Visual C++ 枚举所有串口的方法及示例代码。通过遍历端口号、使用相应的 Win32 API 函数可以实现串口的枚举
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值