SE:
is_match = (temp_val < prev_val);
break;
default:
break;
}
if (is_match)
{
mb->matches++;
}
else
{
REMOVE_FROM_SEARCH(mb, (total_read + offset));
}
}
}
}
memcpy(mb->buffer + total_read, tempbuf, bytes_read);
bytes_left -= bytes_read;
total_read += bytes_read;
}
mb->size = total_read;
}
}
接下来我们实现扫描器
创建扫描器主要是利用VirutualQueryEx API函数,对目标进程的虚拟内存块进行过滤。即只选择内存保护属性带有可写(write)属性的且已经被分配了物理内存的内存,为其申请内存。可写属性包括以下:PAGE_READWRITE|PAGE_WRITECOPY|PAGE_EXECUTE_READWRITE|PAGE_EXECUTE_WRITECOPY
释放扫描器和更新扫描器则只是调用我们的内存块的相关函数。
点击查看代码
MEMBLOCK* create_scan(int pid, int data_size)
{
MEMBLOCK* mb_list = NULL;
MEMORY_BASIC_INFORMATION meminfo;
PVOID addr = 0;
HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, pid);
if (hProcess)
{
while (1)
{
//查询失败,返回
if (!VirtualQueryEx(hProcess, addr, &meminfo, sizeof(meminfo)))
{
break;
}
#define WRITABLE (PAGE_READWRITE|PAGE_WRITECOPY|PAGE_EXECUTE_READWRITE|PAGE_EXECUTE_WRITECOPY)
if ((meminfo.State & MEM_COMMIT) && (meminfo.Protect & WRITABLE))
{
MEMBLOCK* mb = create_memblock(hProcess, &meminfo, data_size);
//头插法将扫描的内存块存入内存块列表中
if (mb)
{
mb->next = mb_list;
mb_list = mb;
}
}
addr = (LPVOID)((SIZE_T)meminfo.BaseAddress + meminfo.RegionSize);void free_scan(MEMBLOCK* mb_list)
{
CloseHandle(mb_list->hProcess);
while (mb_list)
{
MEMBLOCK* mb = mb_list;
mb_list = mb_list->next;
free_memblock(mb);
}
}
void update_scan(MEMBLOCK* mb_list, SEARCH_CONDITION condition, int val)
{
MEMBLOCK* mb = mb_list;
while (mb)
{
update_memblock(mb, condition, val);
mb = mb->next;
}
}
}
}
return mb_list;
}
void free_scan(MEMBLOCK* mb_list)
{
CloseHandle(mb_list->hProcess);
while (mb_list)
{
MEMBLOCK* mb = mb_list;
mb_list = mb_list->next;
free_memblock(mb);
}
}
void update_scan(MEMBLOCK* mb_list, SEARCH_CONDITION condition, int val)
{
MEMBLOCK* mb = mb_list;
while (mb)
{
update_memblock(mb, condition, val);
mb = mb->next;
}
}
之后我们再封装一下内存读写函数
点击查看代码
void poke(HANDLE hProcess, int data_size, PVOID addr, int val)//写内存
{
if (!WriteProcessMemory(hProcess, addr, &val, data_size, NULL))
{
printf("poke failed\r\n");
}
}
int peek(HANDLE hProcess, int data_size, PVOID addr)
{
int val = 0;
if (!ReadProcessMemory(hProcess, addr, &val, data_size, NULL))
{
printf("peek failed\r\n");
}
return val;
}
至此,我们的内存扫描器的核心功能已完全实现
最后附上运行示例及完整源码:
完整源码:
点击查看代码
#pragma once
#include<Windows.h>
#include<iostream>
typedef struct _MEMBLOCK
{
HANDLE hProcess;
PVOID addr; //内存块地址
int size; //内存块大小
char* buffer; //内存数据
char* searchmask;//搜索标识符,标识每一字节的数据是否在搜索列表中
int matches; //匹配的数据个数
int data_size; //数据大小(单位字节)
struct _MEMBLOCK* next;
}MEMBLOCK;
typedef enum
{
COND_UNCONDITIONAL, //每个字节
COND_EQUALS, //数值为特定值的字节
COND_INCREASE, //数值增大的字节
COND_DECREASE, //数值减小的字节
}SEARCH_CONDITION;
MEMBLOCK* create_memblock(HANDLE hProcess, MEMORY_BASIC_INFORMATION* meminfo, int data_size);
void upda