扫描内存,实现内存读写是杀毒软件必备的功能,这个功能如何实现呢,
请见代码实现与分析
调用美国大牛写的PSAPI.DLL
#include "stdafx.h" #include "DoProcess.h" #include "DoProcessDlg.h" #ifdef _DEBUG #define new DEBUG_NEW #undef THIS_FILE static char THIS_FILE[] = __FILE__; #endif char ch[]="zhao1234"; ///////////////////////////////////////////////////////////////////////////// // CDoProcessDlg dialog CDoProcessDlg::CDoProcessDlg(CWnd* pParent /*=NULL*/) : CDialog(CDoProcessDlg::IDD, pParent) { //{{AFX_DATA_INIT(CDoProcessDlg) m_Code = _T("zhao1234"); m_Ebase = _T(""); m_Esize = _T(""); m_Eaddress = _T(""); m_Edata = _T(""); m_EAdd_Change = _T(""); //}}AFX_DATA_INIT // Note that LoadIcon does not require a subsequent DestroyIcon in Win32 m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME); } void CDoProcessDlg::DoDataExchange(CDataExchange* pDX) { CDialog::DoDataExchange(pDX); //{{AFX_DATA_MAP(CDoProcessDlg) DDX_Control(pDX, IDC_LIST2, m_list); DDX_Control(pDX, IDC_ScanProcess, m_Scan); DDX_Text(pDX, IDC_Code, m_Code); DDX_Control(pDX, IDC_LIST1, m_lCtrl); DDX_Text(pDX, IDC_Ebase, m_Ebase); DDX_Text(pDX, IDC_Esize, m_Esize); DDV_MaxChars(pDX, m_Esize, 2000); DDX_Text(pDX, IDC_Eaddress, m_Eaddress); DDX_Text(pDX, IDC_Edata, m_Edata); DDX_Text(pDX, IDC_EAdd_Change, m_EAdd_Change); //}}AFX_DATA_MAP } BEGIN_MESSAGE_MAP(CDoProcessDlg, CDialog) //{{AFX_MSG_MAP(CDoProcessDlg) ON_WM_PAINT() ON_WM_QUERYDRAGICON() ON_BN_CLICKED(IDC_GetProcess, OnGetProcess) ON_BN_CLICKED(IDC_GetProcess2, OnGetProcess2) ON_BN_CLICKED(IDC_KillProcess, OnKillProcess) ON_BN_CLICKED(IDC_ScanProcess, OnScanProcess) ON_BN_CLICKED(IDC_ReadMem, OnReadMem) ON_EN_CHANGE(IDC_Code, OnChangeCode) ON_EN_CHANGE(IDC_Ebase, OnChangeEbase) ON_EN_CHANGE(IDC_Esize, OnChangeEsize) ON_NOTIFY(NM_DBLCLK, IDC_LIST1, OnDblclkList1) ON_EN_CHANGE(IDC_Eaddress, OnChangeEaddress) ON_EN_CHANGE(IDC_Edata, OnChangeEdata) ON_BN_CLICKED(IDC_BWriteMem, OnBWriteMem) ON_BN_CLICKED(IDC_BEnumAllDLL, OnBEnumAllDLL) ON_BN_CLICKED(IDC_BChangeAttr, OnBChangeAttr) ON_EN_CHANGE(IDC_EAdd_Change, OnChangeEAddChange) ON_BN_CLICKED(IDC_BgetModule, OnBgetModule) ON_BN_CLICKED(IDC_BGetAllDLL2, OnBGetAllDLL) //}}AFX_MSG_MAP END_MESSAGE_MAP() ///////////////////////////////////////////////////////////////////////////// // CDoProcessDlg message handlers BOOL CDoProcessDlg::OnInitDialog() { CDialog::OnInitDialog(); // Set the icon for this dialog. The framework does this automatically // when the application's main window is not a dialog SetIcon(m_hIcon, TRUE); // Set big icon SetIcon(m_hIcon, FALSE); // Set small icon // TODO: Add extra initialization here ListView_SetExtendedListViewStyleEx(m_lCtrl.m_hWnd, LVS_EX_FULLROWSELECT| LVS_SORTDESCENDING, 0xFFFFFFFF); m_lCtrl.InsertColumn(0,"序号",HDF_LEFT,50,0); m_lCtrl.InsertColumn(1,"进程ID",HDF_LEFT,60,0); m_lCtrl.InsertColumn(2,"路径",HDF_LEFT,560,0); m_lCtrl.InsertColumn(3,"基地址",HDF_LEFT,60,0); return TRUE; // return TRUE unless you set the focus to a control } // If you add a minimize button to your dialog, you will need the code below // to draw the icon. For MFC applications using the document/view model, // this is automatically done for you by the framework. void CDoProcessDlg::OnPaint() { if (IsIconic()) { CPaintDC dc(this); // device context for painting SendMessage(WM_ICONERASEBKGND, (WPARAM) dc.GetSafeHdc(), 0); // Center icon in client rectangle int cxIcon = GetSystemMetrics(SM_CXICON); int cyIcon = GetSystemMetrics(SM_CYICON); CRect rect; GetClientRect(&rect); int x = (rect.Width() - cxIcon + 1) / 2; int y = (rect.Height() - cyIcon + 1) / 2; // Draw the icon dc.DrawIcon(x, y, m_hIcon); } else { CDialog::OnPaint(); } } // The system calls this to obtain the cursor to display while the user drags // the minimized window. HCURSOR CDoProcessDlg::OnQueryDragIcon() { return (HCURSOR) m_hIcon; } void CDoProcessDlg::OnGetProcess() { m_list.ResetContent(); m_lCtrl.DeleteAllItems(); DWORD aProcesses[1024], cbNeeded, cProcesses; unsigned int i; //枚举系统进程ID列表 if(!EnumProcesses( aProcesses, sizeof(aProcesses), &cbNeeded ) )return; // Calculate how many process identifiers were returned. //计算进程数量 cProcesses = cbNeeded / sizeof(DWORD); // 输出每个进程的名称和ID for ( i = 0; i < cProcesses; i++ )PrintProcessNameAndID( aProcesses[i],i); } void CDoProcessDlg::PrintProcessNameAndID( DWORD processID ,int n) { char szProcessName[MAX_PATH] = "unknown"; //取得进程的句柄 HANDLE hProcess=OpenProcess( PROCESS_QUERY_INFORMATION|PROCESS_VM_READ,FALSE,processID); //取得进程名称 if ( hProcess ) { HMODULE hMod; DWORD cbNeeded; if(EnumProcessModules( hProcess, &hMod, sizeof(hMod), &cbNeeded) ) //GetModuleBaseName( hProcess, hMod, szProcessName, sizeof(szProcessName) ); //该函数得到进程文件名 GetModuleFileNameEx(hProcess,hMod,szProcessName, sizeof(szProcessName)); //该函数得到进程全文件名路径 //回显进程名称和ID CString inf0,inf1,inf2,inf3; CFile fp; if(fp.Open(szProcessName,CFile::modeRead)){ IMAGE_DOS_HEADER dos_header; IMAGE_NT_HEADERS nt_header; fp.Read(&dos_header,sizeof(dos_header)); fp.Seek(dos_header.e_lfanew,CFile::begin); fp.Read(&nt_header,sizeof(nt_header)); fp.Close(); inf3.Format("%X",nt_header.OptionalHeader.ImageBase); } else inf3="unknown"; inf0.Format("%d",n); inf1.Format("%s",szProcessName); inf2.Format("%d",processID); m_lCtrl.InsertItem(0,"");//插入行 m_lCtrl.SetItemText(0,0,inf0); m_lCtrl.SetItemText(0,1,inf2);//设置该行的不同列的显示字符 m_lCtrl.SetItemText(0,2,inf1); m_lCtrl.SetItemText(0,3,inf3); CloseHandle( hProcess ); } } void CDoProcessDlg::OnGetProcess2() { //m_List.ResetContent(); //m_ListID.ResetContent(); CString inf; HANDLE hProcessSnap = NULL; PROCESSENTRY32 pe32= {0}; hProcessSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0); if (hProcessSnap == (HANDLE)-1) { AfxMessageBox("不能建立快照"); return ; } pe32.dwSize = sizeof(PROCESSENTRY32); if (Process32First(hProcessSnap, &pe32)) { do{ inf.Format("%s",pe32.szExeFile); // m_List.AddString(inf); inf.Format("%d",pe32.th32ProcessID); // m_ListID.AddString(inf); } while (Process32Next(hProcessSnap, &pe32)); } else{ // printf("\nProcess32Firstt() failed:%d",GetLastError()); } CloseHandle (hProcessSnap); } BOOL CDoProcessDlg::KillProcess(DWORD pid, BOOL bZap) { CString inf; HANDLE hProcess=NULL,hProcessToken=NULL; OSVERSIONINFO ver; ver.dwOSVersionInfoSize=sizeof(ver);//必须的,否则不正确 if(!GetVersionEx(&ver)){ AfxMessageBox("无法判断当前操作系统"); return 0; } if(ver.dwPlatformId==VER_PLATFORM_WIN32_NT){ //为NT,2000,XP //杀死所有进程包括服务,在2000以上需要提升权限 //打开某个进程的访问令牌,第一个参数为进程句柄,第二个参数为访问权限, //第三个参数为函数输出的用来调整权限的句柄 if(!OpenProcessToken(GetCurrentProcess(),TOKEN_ALL_ACCESS,&hProcessToken)) { AfxMessageBox("打开本进程访问令牌失败!"); return 0; } //SE_DEBUG_NAME 为要求调试进程的权限 if(!SetPrivilege(hProcessToken,SE_DEBUG_NAME,TRUE)) { AfxMessageBox("设置权限错误!"); return 0; } if((hProcess=OpenProcess(PROCESS_TERMINATE,FALSE,pid))==NULL) { m_list.AddString("打开进程失败"); return 0; } if(TerminateProcess(hProcess,1))m_list.AddString("杀死进程成功\n"); else m_list.AddString("不能杀死进程\n"); } else{//是95,98操作系统 hProcess = OpenProcess(PROCESS_TERMINATE, FALSE, DWORD(pid)); if(TerminateProcess(hProcess,1))m_list.AddString("杀死进程成功\n"); else m_list.AddString("不能杀死进程\n"); } CloseHandle(hProcess); return 1; } void CDoProcessDlg::OnKillProcess() { char path[256],pID[18]; POSITION pos = m_lCtrl.GetFirstSelectedItemPosition(); if(pos==NULL){ AfxMessageBox("请选择进程!"); return; } int m_nIndex = m_lCtrl.GetNextSelectedItem(pos); // 得到项目索引 m_lCtrl.GetItemText(m_nIndex, 2, path, 256 ); m_lCtrl.GetItemText(m_nIndex, 1, pID, 18 ); DWORD processID=(DWORD)atoi((char*)pID); KillProcess(processID,TRUE); OnGetProcess2(); } BOOL CDoProcessDlg::SetPrivilege(HANDLE hToken,LPCTSTR lpszPrivilege,BOOL bEnablePrivilege) { TOKEN_PRIVILEGES tp;//包含访问令牌的权限设置信息 LUID luid;//局部唯一ID值 //第一个参数是系统名,为NULL,表示在本地系统查询; //第二个参数为要查询的权限名,定义在文件 Winnt.h 中 //如果成功,返回值为非0,其在系统中的 ID 值为第三个参数所指 if(!LookupPrivilegeValue(NULL,lpszPrivilege,&luid)) { AfxMessageBox("查询权限值错误"); return FALSE; } tp.PrivilegeCount = 1; //权限列的个数 tp.Privileges[0].Luid = luid; if (bEnablePrivilege) tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED; //使能权限 else tp.Privileges[0].Attributes = 0; //设置 luid 进程的权限 AdjustTokenPrivileges( hToken, FALSE, &tp, sizeof(TOKEN_PRIVILEGES), (PTOKEN_PRIVILEGES) NULL, (PDWORD) NULL); if (GetLastError() != ERROR_SUCCESS) { AfxMessageBox("调整权限失败"); return FALSE; } return TRUE; } void CDoProcessDlg::OnScanProcess() { UpdateData(); if(m_Code==""){ AfxMessageBox("请选择特征字符!"); return; } char path[256],pID[18]; POSITION pos = m_lCtrl.GetFirstSelectedItemPosition(); if(pos==NULL){ AfxMessageBox("请选择进程!"); return; } int m_nIndex = m_lCtrl.GetNextSelectedItem(pos); // 得到项目索引 m_lCtrl.GetItemText(m_nIndex, 2, path, 256 ); m_lCtrl.GetItemText(m_nIndex, 1, pID, 18 ); DWORD processID=(DWORD)atoi((char*)pID); BYTE *ptr=NULL; ::EnableWindow(m_Scan.m_hWnd,FALSE); HANDLE hprocess=NULL,hProcessToken=NULL; OSVERSIONINFO ver; ver.dwOSVersionInfoSize=sizeof(ver);//必须的,否则不正确 if(!GetVersionEx(&ver)){ ::EnableWindow(m_Scan.m_hWnd,TRUE); AfxMessageBox("无法判断当前操作系统"); return ; } if(ver.dwPlatformId==VER_PLATFORM_WIN32_NT){ //为NT,2000,XP //杀死所有进程包括服务,在2000以上需要提升权限 //打开某个进程的访问令牌,第一个参数为进程句柄,第二个参数为访问权限, //第三个参数为函数输出的用来调整权限的句柄 if(!OpenProcessToken(GetCurrentProcess(),TOKEN_ALL_ACCESS,&hProcessToken)) { ::EnableWindow(m_Scan.m_hWnd,TRUE); AfxMessageBox("打开本进程访问令牌失败!"); return ; } //SE_DEBUG_NAME 为要求调试进程的权限 if(!SetPrivilege(hProcessToken,SE_DEBUG_NAME,TRUE)) { ::EnableWindow(m_Scan.m_hWnd,TRUE); AfxMessageBox("设置权限错误!"); return ; } } if((hprocess=OpenProcess(PROCESS_ALL_ACCESS,FALSE,processID))==NULL) { AfxMessageBox("打开进程失败"); ::EnableWindow(m_Scan.m_hWnd,TRUE); return; } BOOL re=FALSE; DWORD base=0x400000,min=base,max=base; IMAGE_DOS_HEADER dos_header; IMAGE_NT_HEADERS nt_header; IMAGE_SECTION_HEADER section_header[16]; memset(&dos_header,0,sizeof(dos_header)); memset(&nt_header,0,sizeof(nt_header)); memset(section_header,0,16*sizeof(IMAGE_SECTION_HEADER)); re=ReadProcessMemory(hprocess,(LPVOID)base,&dos_header,sizeof(dos_header),NULL); base+=dos_header.e_lfanew; ReadProcessMemory(hprocess,(LPVOID)base,&nt_header,sizeof(nt_header),NULL); if(re==FALSE||nt_header.FileHeader.NumberOfSections==0){ base=max=min=0x1000000; //有的基本地址为0x400000,有的为0x1000000 memset(&dos_header,0,sizeof(dos_header)); re=ReadProcessMemory(hprocess,(LPVOID)base,&dos_header,sizeof(dos_header),NULL); base+=dos_header.e_lfanew; ReadProcessMemory(hprocess,(LPVOID)base,&nt_header,sizeof(nt_header),NULL); } if(re==FALSE||nt_header.FileHeader.NumberOfSections==0){ AfxMessageBox("扫描失败"); ::EnableWindow(m_Scan.m_hWnd,TRUE); return; } base+=sizeof(nt_header); ReadProcessMemory(hprocess,(LPVOID)base,§ion_header,\ nt_header.FileHeader.NumberOfSections*sizeof(IMAGE_SECTION_HEADER),NULL); min+=section_header[0].VirtualAddress; max+=section_header[nt_header.FileHeader.NumberOfSections-1].VirtualAddress +section_header[nt_header.FileHeader.NumberOfSections-1].SizeOfRawData; ptr=new BYTE[max-min]; if(!ptr){ ::EnableWindow(m_Scan.m_hWnd,TRUE); AfxMessageBox("内存不够"); return; } if(!ReadProcessMemory(hprocess,(LPVOID)min,ptr,max-min,NULL)){ ::EnableWindow(m_Scan.m_hWnd,TRUE); AfxMessageBox("读内存错误!"); return; } CString inf=""; CString inf2; re=FALSE; for(DWORD j=0;j<max-min-7;j++){ if(!strcmp((char *)(ptr+j),(char*)m_Code.GetBuffer(0))){ inf="找到了:"; inf2.Format(" %8x,",min+j); inf+=inf2; re=TRUE; } } if(re==FALSE)inf="没有找到"; AfxMessageBox(inf); if(hprocess)CloseHandle(hprocess); ::EnableWindow(m_Scan.m_hWnd,TRUE); } void CDoProcessDlg::OnReadMem() { char path[256],pID[18],based[20]; POSITION pos = m_lCtrl.GetFirstSelectedItemPosition(); if(pos==NULL){ AfxMessageBox("请选择进程!"); return; } int m_nIndex = m_lCtrl.GetNextSelectedItem(pos); // 得到项目索引 m_lCtrl.GetItemText(m_nIndex, 2, path, 256 ); m_lCtrl.GetItemText(m_nIndex, 1, pID, 18 ); m_lCtrl.GetItemText(m_nIndex, 3, based, 20 ); CString sbase=based; if(sbase=="unknown"){ AfxMessageBox("超级进程,无法读!"); return; } DWORD processID=(DWORD)atoi((char*)pID); HANDLE hprocess=NULL,hProcessToken=NULL; OSVERSIONINFO ver; ver.dwOSVersionInfoSize=sizeof(ver);//必须的,否则不正确 if(!GetVersionEx(&ver)){ ::EnableWindow(m_Scan.m_hWnd,TRUE); AfxMessageBox("无法判断当前操作系统"); return ; } if(ver.dwPlatformId==VER_PLATFORM_WIN32_NT){ //为NT,2000,XP //杀死所有进程包括服务,在2000以上需要提升权限 //打开某个进程的访问令牌,第一个参数为进程句柄,第二个参数为访问权限, //第三个参数为函数输出的用来调整权限的句柄 if(!OpenProcessToken(GetCurrentProcess(),TOKEN_ALL_ACCESS,&hProcessToken)) { ::EnableWindow(m_Scan.m_hWnd,TRUE); AfxMessageBox("打开本进程访问令牌失败!"); return ; } //SE_DEBUG_NAME 为要求调试进程的权限 if(!SetPrivilege(hProcessToken,SE_DEBUG_NAME,TRUE)) { ::EnableWindow(m_Scan.m_hWnd,TRUE); AfxMessageBox("设置权限错误!"); return ; } } if((hprocess=OpenProcess(PROCESS_ALL_ACCESS,FALSE,processID))==NULL) { AfxMessageBox("打开进程失败"); ::EnableWindow(m_Scan.m_hWnd,TRUE); return; } BOOL re=FALSE; DWORD base=0x400000; if(sbase=="400000")base=0x400000; if(sbase=="1000000")base=0x1000000; int len=m_Ebase.GetLength(); m_Ebase.MakeUpper(); DWORD data=0; for(int val=len-1;val>=0;val--){ if(((char*)m_Ebase.GetBuffer(0))[val]<=(char)'9') data+=((DWORD)((char*)m_Ebase.GetBuffer(0)[val]-0x30)<<((len-val-1)*4)); else data+=((DWORD)((char*)m_Ebase.GetBuffer(0)[val]-0x41+10)<<((len-val-1)*4)); } base+=data; // CString in; // in.Format("data=%X",data); // AfxMessageBox(in); BYTE *ptr=new BYTE[1024]; memset(ptr,0,1024); re=ReadProcessMemory(hprocess,(LPVOID)base,ptr,1024,NULL); if(re==FALSE){ AfxMessageBox("读内存失败"); return; } CFile fp; fp.Open("c:\\mem.dat",CFile::modeCreate|CFile::modeWrite); fp.Write(ptr,1024); fp.Close(); if(hprocess)CloseHandle(hprocess); } void CDoProcessDlg::OnChangeCode() { UpdateData(); } void CDoProcessDlg::OnChangeEbase() { UpdateData(); } void CDoProcessDlg::OnChangeEsize() { UpdateData(); } void CDoProcessDlg::OnDblclkList1(NMHDR* pNMHDR, LRESULT* pResult) { /* char lpszText[256]; POSITION pos = m_lCtrl.GetFirstSelectedItemPosition(); int m_nIndex = m_lCtrl.GetNextSelectedItem(pos); // 得到项目索引 m_lCtrl.GetItemText(m_nIndex, 2, lpszText, 256 ); // wsprintf(lpszText,"id=%d,%s",m_nIndex); AfxMessageBox(lpszText); */ *pResult = 0; } void CDoProcessDlg::OnChangeEaddress() { UpdateData(); } void CDoProcessDlg::OnChangeEdata() { UpdateData(); } void CDoProcessDlg::OnBWriteMem() { char path[256],pID[18],based[20]; POSITION pos = m_lCtrl.GetFirstSelectedItemPosition(); if(pos==NULL){ AfxMessageBox("请选择进程!"); return; } int m_nIndex = m_lCtrl.GetNextSelectedItem(pos); // 得到项目索引 m_lCtrl.GetItemText(m_nIndex, 2, path, 256 ); m_lCtrl.GetItemText(m_nIndex, 1, pID, 18 ); m_lCtrl.GetItemText(m_nIndex, 3, based, 20 ); CString sbase=based; if(sbase=="unknown"){ AfxMessageBox("超级进程,无法读!"); return; } DWORD processID=(DWORD)atoi((char*)pID); HANDLE hprocess=NULL,hProcessToken=NULL; OSVERSIONINFO ver; ver.dwOSVersionInfoSize=sizeof(ver);//必须的,否则不正确 if(!GetVersionEx(&ver)){ ::EnableWindow(m_Scan.m_hWnd,TRUE); AfxMessageBox("无法判断当前操作系统"); return ; } if(ver.dwPlatformId==VER_PLATFORM_WIN32_NT){ //为NT,2000,XP //杀死所有进程包括服务,在2000以上需要提升权限 //打开某个进程的访问令牌,第一个参数为进程句柄,第二个参数为访问权限, //第三个参数为函数输出的用来调整权限的句柄 if(!OpenProcessToken(GetCurrentProcess(),TOKEN_ALL_ACCESS,&hProcessToken)) { ::EnableWindow(m_Scan.m_hWnd,TRUE); AfxMessageBox("打开本进程访问令牌失败!"); return ; } //SE_DEBUG_NAME 为要求调试进程的权限 if(!SetPrivilege(hProcessToken,SE_DEBUG_NAME,TRUE)) { ::EnableWindow(m_Scan.m_hWnd,TRUE); AfxMessageBox("设置权限错误!"); return ; } } if((hprocess=OpenProcess(PROCESS_ALL_ACCESS,FALSE,processID))==NULL) { AfxMessageBox("打开进程失败"); ::EnableWindow(m_Scan.m_hWnd,TRUE); return; } BOOL re=FALSE; DWORD base=0x400000; if(sbase=="400000")base=0x400000; if(sbase=="1000000")base=0x1000000; CString in; int len=m_Eaddress.GetLength(); m_Eaddress.MakeUpper(); DWORD data=0; for(int val=len-1;val>=0;val--){ if(((char*)m_Eaddress.GetBuffer(0))[val]<=(char)'9') data+=((DWORD)((char*)m_Eaddress.GetBuffer(0)[val]-0x30)<<((len-val-1)*4)); else data+=((DWORD)((char*)m_Eaddress.GetBuffer(0)[val]-0x41+10)<<((len-val-1)*4)); } // in.Format("data=%x,%u",data,data); // AfxMessageBox(in); base+=data; m_Edata.MakeUpper(); len=m_Edata.GetLength(); data=0; for(val=len-1;val>=0;val--){ if(((char*)m_Edata.GetBuffer(0))[val]<=(char)'9') data+=((DWORD)((char*)m_Edata.GetBuffer(0)[val]-0x30)<<((len-val-1)*4)); else data+=((DWORD)((char*)m_Edata.GetBuffer(0)[val]-0x41+10)<<((len-val-1)*4)); } // in.Format("data=%x,%u",data,data); // AfxMessageBox(in); re=WriteProcessMemory(hprocess,(LPVOID)base,&data,4,NULL); if(re==FALSE){ AfxMessageBox("写内存失败"); return; } if(hprocess)CloseHandle(hprocess); } void CDoProcessDlg::OnBEnumAllDLL() { char path[256],pID[18],based[20]; POSITION pos = m_lCtrl.GetFirstSelectedItemPosition(); if(pos==NULL){ AfxMessageBox("请选择进程!"); return; } m_list.ResetContent(); int m_nIndex = m_lCtrl.GetNextSelectedItem(pos); // 得到项目索引 m_lCtrl.GetItemText(m_nIndex, 2, path, 256 ); m_lCtrl.GetItemText(m_nIndex, 1, pID, 18 ); m_lCtrl.GetItemText(m_nIndex, 3, based, 20 ); CString sbase; sbase=based; if(sbase=="unknown"){ AfxMessageBox("超级进程,无法读!"); return; } //AfxMessageBox(path); DWORD processID=(DWORD)atoi((char*)pID); HANDLE hprocess=NULL,hProcessToken=NULL; OSVERSIONINFO ver; ver.dwOSVersionInfoSize=sizeof(ver);//必须的,否则不正确 if(!GetVersionEx(&ver)){ ::EnableWindow(m_Scan.m_hWnd,TRUE); AfxMessageBox("无法判断当前操作系统"); return ; } if(ver.dwPlatformId==VER_PLATFORM_WIN32_NT){ //为NT,2000,XP //杀死所有进程包括服务,在2000以上需要提升权限 //打开某个进程的访问令牌,第一个参数为进程句柄,第二个参数为访问权限, //第三个参数为函数输出的用来调整权限的句柄 if(!OpenProcessToken(GetCurrentProcess(),TOKEN_ALL_ACCESS,&hProcessToken)) { ::EnableWindow(m_Scan.m_hWnd,TRUE); AfxMessageBox("打开本进程访问令牌失败!"); return ; } //SE_DEBUG_NAME 为要求调试进程的权限 if(!SetPrivilege(hProcessToken,SE_DEBUG_NAME,TRUE)) { ::EnableWindow(m_Scan.m_hWnd,TRUE); AfxMessageBox("设置权限错误!"); return ; } } if((hprocess=OpenProcess(PROCESS_ALL_ACCESS,FALSE,processID))==NULL) { AfxMessageBox("打开进程失败"); ::EnableWindow(m_Scan.m_hWnd,TRUE); return; } //枚举内存 MEMORY_BASIC_INFORMATION mbi; // typedef struct _MEMORY_BASIC_INFORMATION { /* mbi */ // PVOID BaseAddress; /* 区域的基本地址 */ // PVOID AllocationBase; /* 分配基本地址 */ // DWORD AllocationProtect; /* 初始访问保护 */ // DWORD RegionSize; /* 区域的字节大小 */ // DWORD State; /* 已提交的、保留的、自由的 */ // DWORD Protect; /* 当前访问保护 */ // DWORD Type; /* 页类型 */ //} MEMORY_BASIC_INFORMATION; // 这个结构,在我们的程序中,最关心的是AllocationBase,BaseAddress // 从代码中可以看出AllocationBase 相当于 HMODULE . // RegionSize则表明了这一块内存的大小。 // ptr += mbi.RegionSize; // 通过者一句,我们接着获取下一个内存块的信息 // 通过 GetModuleFileName 我们获取了模块的详细信息 PBYTE ptr = NULL; DWORD dwBytesReturn = sizeof(MEMORY_BASIC_INFORMATION); char szBuffer[256*100]; char szModuFile[256]; char szTmpBuffer[256]; memset(szBuffer,0,256*100); memset(szModuFile,0,256); memset(szTmpBuffer,0,256); int n=1;CString din; while( dwBytesReturn == sizeof(MEMORY_BASIC_INFORMATION) ) { dwBytesReturn = VirtualQueryEx(hprocess,ptr,&mbi,sizeof(MEMORY_BASIC_INFORMATION) ); if(mbi.Type == MEM_FREE ) mbi.AllocationBase = mbi.BaseAddress; //GetModuleFileName( (HINSTANCE)mbi.AllocationBase,szModuFile,256); GetModuleFileNameEx(hprocess,(HMODULE)mbi.AllocationBase,szModuFile,256); switch(mbi.AllocationProtect){ case PAGE_READONLY: din="PAGE_READONLY"; break; case PAGE_READWRITE: din="PAGE_READWRITE"; break; case PAGE_WRITECOPY: din="PAGE_WRITECOPY"; break; case PAGE_EXECUTE: din="PAGE_EXECUTE"; break; case PAGE_EXECUTE_READ: din="PAGE_EXECUTE_READ"; break; case PAGE_EXECUTE_READWRITE: din="PAGE_EXECUTE_READWRITE"; break; case PAGE_EXECUTE_WRITECOPY: din="PAGE_EXECUTE_WRITECOPY"; break; default: din="OTHER"; } wsprintf(szTmpBuffer,"%3d)模块名=%s,基地址=%x,大小=%x,属性=%s",n++,szModuFile,ptr,mbi.RegionSize,din); m_list.AddString(szTmpBuffer); // if(mbi.AllocationBase == mbi.BaseAddress && mbi.AllocationBase != NULL && // mbi.AllocationBase != GetModuleHandle(NULL) )strcat(szBuffer , szTmpBuffer); ptr += mbi.RegionSize; } if(hprocess)CloseHandle(hprocess); int tnum=m_list.GetCount( ); if(tnum==LB_ERR)return; CFile fp; fp.Open("c:\\dat.txt",CFile::modeCreate|CFile::modeWrite); for(int ii=0;ii<tnum;ii++){ m_list.GetText(ii,din); din+="\r\n"; fp.Write(din.GetBuffer(0),din.GetLength()); } fp.Close(); } void CDoProcessDlg::OnBChangeAttr() { char path[256],pID[18],based[20]; POSITION pos = m_lCtrl.GetFirstSelectedItemPosition(); if(pos==NULL){ AfxMessageBox("请选择进程!"); return; } m_list.ResetContent(); int m_nIndex = m_lCtrl.GetNextSelectedItem(pos); // 得到项目索引 m_lCtrl.GetItemText(m_nIndex, 2, path, 256 ); m_lCtrl.GetItemText(m_nIndex, 1, pID, 18 ); m_lCtrl.GetItemText(m_nIndex, 3, based, 20 ); CString sbase=based; if(sbase=="unknown"){ AfxMessageBox("超级进程,无法读!"); return; } DWORD processID=(DWORD)atoi((char*)pID); HANDLE hprocess=NULL,hProcessToken=NULL; OSVERSIONINFO ver; ver.dwOSVersionInfoSize=sizeof(ver);//必须的,否则不正确 if(!GetVersionEx(&ver)){ ::EnableWindow(m_Scan.m_hWnd,TRUE); AfxMessageBox("无法判断当前操作系统"); return ; } if(ver.dwPlatformId==VER_PLATFORM_WIN32_NT){ //为NT,2000,XP //杀死所有进程包括服务,在2000以上需要提升权限 //打开某个进程的访问令牌,第一个参数为进程句柄,第二个参数为访问权限, //第三个参数为函数输出的用来调整权限的句柄 if(!OpenProcessToken(GetCurrentProcess(),TOKEN_ALL_ACCESS,&hProcessToken)) { ::EnableWindow(m_Scan.m_hWnd,TRUE); AfxMessageBox("打开本进程访问令牌失败!"); return ; } //SE_DEBUG_NAME 为要求调试进程的权限 if(!SetPrivilege(hProcessToken,SE_DEBUG_NAME,TRUE)) { ::EnableWindow(m_Scan.m_hWnd,TRUE); AfxMessageBox("设置权限错误!"); return ; } } if((hprocess=OpenProcess(PROCESS_ALL_ACCESS,FALSE,processID))==NULL) { AfxMessageBox("打开进程失败"); ::EnableWindow(m_Scan.m_hWnd,TRUE); return; } CString din; DWORD oldProtect; m_EAdd_Change.MakeUpper(); int len=m_EAdd_Change.GetLength(); DWORD data=0; for(int val=len-1;val>=0;val--){ if(((char*)m_EAdd_Change.GetBuffer(0))[val]<=(char)'9') data+=((DWORD)((char*)m_EAdd_Change.GetBuffer(0)[val]-0x30)<<((len-val-1)*4)); else data+=((DWORD)((char*)m_EAdd_Change.GetBuffer(0)[val]-0x41+10)<<((len-val-1)*4)); } BOOL re=VirtualProtectEx(hprocess,&data,10*1024,PAGE_EXECUTE_READWRITE,&oldProtect); if(re)din.Format("地址%X--大小%X :修改成功",data,10*1024); else din.Format("地址%X--大小%X :修改失败",data,10*1024); m_list.AddString(din); if(hprocess)CloseHandle(hprocess); } void CDoProcessDlg::OnChangeEAddChange() { UpdateData(); } void CDoProcessDlg::OnBgetModule() { char path[256],pID[18],based[20]; POSITION pos = m_lCtrl.GetFirstSelectedItemPosition(); if(pos==NULL){ AfxMessageBox("请选择进程!"); return; } m_list.ResetContent(); int m_nIndex = m_lCtrl.GetNextSelectedItem(pos); // 得到项目索引 m_lCtrl.GetItemText(m_nIndex, 2, path, 256 ); m_lCtrl.GetItemText(m_nIndex, 1, pID, 18 ); m_lCtrl.GetItemText(m_nIndex, 3, based, 20 ); CString sbase; sbase=based; if(sbase=="unknown"){ AfxMessageBox("超级进程,无法读!"); return; } //AfxMessageBox(path); DWORD processID=(DWORD)atoi((char*)pID); HANDLE hprocess=NULL,hProcessToken=NULL; OSVERSIONINFO ver; ver.dwOSVersionInfoSize=sizeof(ver);//必须的,否则不正确 if(!GetVersionEx(&ver)){ ::EnableWindow(m_Scan.m_hWnd,TRUE); AfxMessageBox("无法判断当前操作系统"); return ; } if(ver.dwPlatformId==VER_PLATFORM_WIN32_NT){ //为NT,2000,XP //杀死所有进程包括服务,在2000以上需要提升权限 //打开某个进程的访问令牌,第一个参数为进程句柄,第二个参数为访问权限, //第三个参数为函数输出的用来调整权限的句柄 if(!OpenProcessToken(GetCurrentProcess(),TOKEN_ALL_ACCESS,&hProcessToken)) { ::EnableWindow(m_Scan.m_hWnd,TRUE); AfxMessageBox("打开本进程访问令牌失败!"); return ; } //SE_DEBUG_NAME 为要求调试进程的权限 if(!SetPrivilege(hProcessToken,SE_DEBUG_NAME,TRUE)) { ::EnableWindow(m_Scan.m_hWnd,TRUE); AfxMessageBox("设置权限错误!"); return ; } } if((hprocess=OpenProcess(PROCESS_ALL_ACCESS,FALSE,processID))==NULL) { AfxMessageBox("打开进程失败"); ::EnableWindow(m_Scan.m_hWnd,TRUE); return; } } void CDoProcessDlg::OnBGetAllDLL() { char path[256],pID[18],based[20]; POSITION pos = m_lCtrl.GetFirstSelectedItemPosition(); if(pos==NULL){ AfxMessageBox("请选择进程!"); return; } m_list.ResetContent(); int m_nIndex = m_lCtrl.GetNextSelectedItem(pos); // 得到项目索引 m_lCtrl.GetItemText(m_nIndex, 2, path, 256 ); m_lCtrl.GetItemText(m_nIndex, 1, pID, 18 ); m_lCtrl.GetItemText(m_nIndex, 3, based, 20 ); CString sbase; sbase=based; if(sbase=="unknown"){ AfxMessageBox("超级进程,无法读!"); return; } //AfxMessageBox(path); DWORD processID=(DWORD)atoi((char*)pID); HANDLE hprocess=NULL,hProcessToken=NULL; OSVERSIONINFO ver; ver.dwOSVersionInfoSize=sizeof(ver);//必须的,否则不正确 if(!GetVersionEx(&ver)){ ::EnableWindow(m_Scan.m_hWnd,TRUE); AfxMessageBox("无法判断当前操作系统"); return ; } if(ver.dwPlatformId==VER_PLATFORM_WIN32_NT){ //为NT,2000,XP //杀死所有进程包括服务,在2000以上需要提升权限 //打开某个进程的访问令牌,第一个参数为进程句柄,第二个参数为访问权限, //第三个参数为函数输出的用来调整权限的句柄 if(!OpenProcessToken(GetCurrentProcess(),TOKEN_ALL_ACCESS,&hProcessToken)) { ::EnableWindow(m_Scan.m_hWnd,TRUE); AfxMessageBox("打开本进程访问令牌失败!"); return ; } //SE_DEBUG_NAME 为要求调试进程的权限 if(!SetPrivilege(hProcessToken,SE_DEBUG_NAME,TRUE)) { ::EnableWindow(m_Scan.m_hWnd,TRUE); AfxMessageBox("设置权限错误!"); return ; } } if((hprocess=OpenProcess(PROCESS_ALL_ACCESS,FALSE,processID))==NULL) { AfxMessageBox("打开进程失败"); ::EnableWindow(m_Scan.m_hWnd,TRUE); return; } //枚举内存 MEMORY_BASIC_INFORMATION mbi; // typedef struct _MEMORY_BASIC_INFORMATION { /* mbi */ // PVOID BaseAddress; /* 区域的基本地址 */ // PVOID AllocationBase; /* 分配基本地址 */ // DWORD AllocationProtect; /* 初始访问保护 */ // DWORD RegionSize; /* 区域的字节大小 */ // DWORD State; /* 已提交的、保留的、自由的 */ // DWORD Protect; /* 当前访问保护 */ // DWORD Type; /* 页类型 */ //} MEMORY_BASIC_INFORMATION; // 这个结构,在我们的程序中,最关心的是AllocationBase,BaseAddress // 从代码中可以看出AllocationBase 相当于 HMODULE . // RegionSize则表明了这一块内存的大小。 // ptr += mbi.RegionSize; // 通过者一句,我们接着获取下一个内存块的信息 // 通过 GetModuleFileName 我们获取了模块的详细信息 PBYTE ptr = NULL; DWORD dwBytesReturn = sizeof(MEMORY_BASIC_INFORMATION); char szBuffer[256*100]; char szModuFile[256]; char szTmpBuffer[256]; memset(szBuffer,0,256*100); memset(szTmpBuffer,0,256); int n=1;CString din; CString old; while( dwBytesReturn == sizeof(MEMORY_BASIC_INFORMATION) ) { memset(szModuFile,0,256); dwBytesReturn = VirtualQueryEx(hprocess,ptr,&mbi,sizeof(MEMORY_BASIC_INFORMATION) ); if(mbi.Type == MEM_FREE ) mbi.AllocationBase = mbi.BaseAddress; //GetModuleFileName( (HINSTANCE)mbi.AllocationBase,szModuFile,256); GetModuleFileNameEx(hprocess,(HMODULE)mbi.AllocationBase,szModuFile,256); // // if(mbi.AllocationBase == mbi.BaseAddress && mbi.AllocationBase != NULL && // mbi.AllocationBase != GetModuleHandle(NULL) )strcat(szBuffer , szTmpBuffer); ptr += mbi.RegionSize; if(strlen(szModuFile)<=1)continue; //不能是等于0,竟然有问号 CString mid=szModuFile; mid.MakeLower(); if(old==mid)continue; old=szModuFile; old.MakeLower(); if(old.Find(".exe",0)!=-1)continue; wsprintf(szTmpBuffer,"%3d)模块名=%s,开始地址=%8X",n++,szModuFile,ptr-mbi.RegionSize); m_list.AddString(szTmpBuffer); } if(hprocess)CloseHandle(hprocess); int tnum=m_list.GetCount( ); if(tnum==LB_ERR)return; CFile fp; fp.Open("c:\\dat.txt",CFile::modeCreate|CFile::modeWrite); for(int ii=0;ii<tnum;ii++){ m_list.GetText(ii,din); din+="\r\n"; fp.Write(din.GetBuffer(0),din.GetLength()); } fp.Close(); }