扫描内存,实现内存读写是杀毒软件必备的功能,这个功能如何实现呢,
请见代码实现与分析
调用美国大牛写的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();
}