扫描内存,实现内存读写是杀毒软件必备的功能,这个功能如何实现呢,

请见代码实现与分析

调用美国大牛写的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();
}