Code StuCE 10/08
关于aobscan的实现原理
我发现这里好多人用的语言都不一样,所以我尽量就不针对某种语言来讲了。(我写的C代码)
首先,获得进程PID。
可以根据标题获得,也可以根据进程名获得。各有各的好处吧。还有窗口类名哈。
例如:
HWND hwnd = FindWindow("MainWindow", NULL);
if (hwnd)
{
DWORD dwPid;
GetWindowThreadProcessId(hwnd, &dwPid);
//return dwPid;
}
第二步,获得进程相关信息,例如内存大小。
HANDLE hProcess = ::OpenProcess(PROCESS_ALL_ACCESS, FALSE, dwPid);
PROCESS_MEMORY_COUNTERS pmc;
pmc.cb = sizeof(PROCESS_MEMORY_COUNTERS);
::GetProcessMemoryInfo( hProcess, &pmc, sizeof(pmc));
//printf("%d\n%d\n",dwPid,pmc.WorkingSetSize/1024/1024);
第三步,遍历程序内存。
因为上一步已经获得内存大小了,所以一个循环。
(获得内存数据之前,是否检查一下内存属性呢?我觉得应该需要,但是我这里只讲讲原理,就省掉了)
另外据说Windows一个内存页就是4kb,所以写成这样:
char key[] = {0x80, 0x7f, 0x49, 0x00};//查找的数据以及长度
int len = 4;
PBYTE pAddress = NULL;
int i = 0;
int n = 0;
for (; i < pmc.WorkingSetSize; i += 4096)
{
BYTE arBytes[4096];
if (!::ReadProcessMemory(hProcess, (LPVOID)i, arBytes, 4096, NULL)) continue;
{
if (memstr(key, len, (char*)arBytes, 4096) != 0)
{
printf("%d %d\n", memstr(key, len, (char*)arBytes, 4096), arBytes);
n = memstr(key, len, (char*)arBytes, 4096) - (unsigned char*)arBytes;
break;
}
}
}
i += n;
printf("%x %d", i, n);
现在i变量中的地址,就是我们查找的数据的地址了。
附带一个最简单的menstr函数,几乎没有优化哈。
unsigned char *memstr(char * dst , int dst_len, char *src , int src_len )
{
int i;
char *cp = src;
if (src_len < dst_len)
{
return NULL;
}
for (i = 0; i <= src_len - dst_len; i++)
{
if (memcmp(cp , dst , dst_len) == 0)
{
return (unsigned char *)cp;
}
cp++;
}
return NULL;
}