here the source:
memscan.h
- Code: Select all
// Filename: MemoryScan.cpp
// Author: HadFuny
// Date: 28-05-2010
// Copyright HadFuny 2010
/*
#include <windows.h>
#include <stdio.h>
*/
#define IS_IN_SEARCH(mb,offset) (mb->searchmask[(offset) / 8] & ( 1 << ((offset) % 8)))
#define REMOVE_FROM_SEARCH(mb,offset) mb->searchmask[(offset) / 8] &= ~(1<<((offset) % 8));
typedef struct _MEMBLOCK
{
HANDLE hProc;
unsigned char *addr;
int size;
unsigned char *buffer;
unsigned char *searchmask;
int matches;
int data_size;
struct _MEMBLOCK *next;
} MEMBLOCK;
typedef enum
{
COND_UNCONDITIONAL,
COND_EQUALS,
COND_INCREASED,
COND_DECREASED,
} SEARCH_CONDITION;
// added for debugging
void __cdecl odprintf(const char *format, ...)
{
char buf[4096], *p = buf;
va_list args;
int n;
va_start(args, format);
n = _vsnprintf(p, sizeof buf - 3, format, args); // buf-3 is room for CR/LF/NUL
va_end(args);
p += (n < 0) ? sizeof buf - 3 : n;
while ( p > buf && isspace(p[-1]) )
*--p = '\0';
*p++ = '\r';
*p++ = '\n';
*p = '\0';
OutputDebugString(buf);
}
// added for debugging
MEMBLOCK* create_memblock (HANDLE hProc, MEMORY_BASIC_INFORMATION *meminfo, int data_size)
{
MEMBLOCK *mb = (MEMBLOCK*)malloc(sizeof(MEMBLOCK));
if (mb)
{
mb->hProc = hProc;
mb->addr = (unsigned char*)meminfo->BaseAddress;
mb->size = meminfo->RegionSize;
mb->buffer = (unsigned char*)malloc (meminfo->RegionSize);
mb->searchmask = (unsigned char*)malloc (meminfo->RegionSize/8);
memset (mb->searchmask, 0xff, meminfo->RegionSize/8);
mb->matches = meminfo->RegionSize;
mb->data_size = data_size;
mb->next = NULL;
}
return mb;
}
void free_memblock (MEMBLOCK *mb)
{
if (mb)
{
if (mb->buffer)
{
free (mb->buffer);
}
if (mb->searchmask)
{
free (mb->searchmask);
}
free (mb);
}
}
void update_memblock (MEMBLOCK *mb, SEARCH_CONDITION condition, unsigned int val)
{
static unsigned char tempbuf[128*1024];
unsigned int bytes_left;
unsigned int total_read;
unsigned int bytes_to_read;
unsigned int bytes_read;
if (mb->matches > 0)
{
bytes_left = mb->size;
total_read = 0;
mb->matches = 0;
while (bytes_left)
{
bytes_to_read = (bytes_left > sizeof(tempbuf)) ? sizeof(tempbuf) : bytes_left;
ReadProcessMemory (mb->hProc, mb->addr + total_read, tempbuf, bytes_to_read, (DWORD*)&bytes_read);
if (bytes_read != bytes_to_read) break;
if (condition == COND_UNCONDITIONAL)
{
memset (mb->searchmask + (total_read/8), 0xff, bytes_read/8);
mb->matches += bytes_read;
}
else
{
unsigned int offset;
for (offset = 0; offset < bytes_read; offset += mb->data_size)
{
if (IS_IN_SEARCH(mb,(total_read+offset)))
{
BOOL is_match = FALSE;
unsigned int temp_val;
unsigned int prev_val = 0;
switch (mb->data_size)
{
case 1:
temp_val = tempbuf[offset];
prev_val = *((unsigned char*)&mb->buffer[total_read+offset]);
break;
case 2:
temp_val = *((unsigned short*)&tempbuf[offset]);
prev_val = *((unsigned short*)&mb->buffer[total_read+offset]);
break;
case 4:
default:
temp_val = *((unsigned int*)&tempbuf[offset]);
prev_val = *((unsigned int*)&mb->buffer[total_read+offset]);
break;
}
switch (condition)
{
case COND_EQUALS:
is_match = (temp_val == val);
break;
case COND_INCREASED:
is_match = (temp_val > prev_val);
break;
case COND_DECREASED:
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;
}
}
MEMBLOCK* create_scan (unsigned int pid, int data_size)
{
MEMBLOCK *mb_list = NULL;
MEMORY_BASIC_INFORMATION meminfo;
unsigned char *addr = 0;
HANDLE hProc = OpenProcess(PROCESS_ALL_ACCESS|PROCESS_VM_OPERATION|PROCESS_VM_READ|PROCESS_VM_WRITE|PROCESS_QUERY_INFORMATION, FALSE, pid);
if (hProc)
{
while (1)
{
if (VirtualQueryEx(hProc, addr, &meminfo, sizeof(meminfo)) == 0)
{
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 (hProc, &meminfo, data_size);
if (mb)
{
mb->next = mb_list;
mb_list = mb;
}
}
addr = (unsigned char*)meminfo.BaseAddress + meminfo.RegionSize;
}
}
return mb_list;
}
void free_scan(MEMBLOCK *mb_list)
{
CloseHandle (mb_list->hProc);
while (mb_list)
{
MEMBLOCK *mb = mb_list;
mb_list = mb_list->next;
free_memblock (mb);
}
}
void update_scan (MEMBLOCK *mb_list, SEARCH_CONDITION condition, unsigned int val)
{
MEMBLOCK *mb = mb_list;
while (mb)
{
update_memblock (mb, condition, val);
mb = mb->next;
}
}
void dump_scan_info(MEMBLOCK *mb_list)
{
MEMBLOCK *mb = mb_list;
while (mb)
{
int i;
odprintf("0x%08x %d", mb->addr, mb->size);
for (i = 0; i < mb->size; i++)
{
printf ("%02x", mb->buffer[i]);
}
mb = mb->next;
}
}
void poke (HANDLE hProc, int data_size, unsigned int addr, unsigned int val)
{
if (WriteProcessMemory (hProc, (void*)addr, &val, data_size, NULL) == 0)
{
odprintf("poke failed");
}
}
unsigned int peek(HANDLE hProc, int data_size, unsigned int addr)
{
unsigned int val = 0;
if (ReadProcessMemory (hProc, (void*)addr, &val, data_size, NULL) == 0)
{
odprintf("peek failed");
}
return val;
}
void print_matches (MEMBLOCK *mb_list)
{
unsigned int offset;
MEMBLOCK *mb = mb_list;
while (mb)
{
for (offset = 0; offset < mb->size; offset += mb->data_size)
{
if (IS_IN_SEARCH(mb,offset))
{
unsigned int val = peek (mb->hProc, mb->data_size, (unsigned int)mb->addr + offset);
odprintf("0x%08x: 0x%08x (%d)", mb->addr + offset, val, val);
}
}
mb = mb->next;
}
}
int get_match_count (MEMBLOCK *mb_list)
{
MEMBLOCK *mb = mb_list;
int count = 0;
while (mb)
{
count += mb->matches;
mb = mb->next;
}
return count;
}
unsigned int str2int (char *s)
{
int base = 10;
if (s[0] == '0' && s[1] == 'x')
{
base = 16;
s += 2;
}
return strtoul (s, NULL, base);
}
dllmain.cpp
- Code: Select all
#include <windows.h>
#include <stdio.h>
#include "memscan.h"
#define SCAN_VALUE_SIZE 4 // 4 bytes
#define SCAN_VALUE_START 100 // the value
MEMBLOCK *StartNewScan(void)
{
DWORD dwProcessID = GetCurrentProcessId();
MEMBLOCK *scan = NULL;
scan = create_scan(dwProcessID, SCAN_VALUE_SIZE);
if(!scan)
{
odprintf("[StartNewScan()] SCAN: FALSE | Breaking...");
return FALSE;
}
odprintf("[StartNewScan()] SCAN: TRUE | Continue...");
update_scan(scan, COND_EQUALS, SCAN_VALUE_START);
odprintf("[StartNewScan()] %d matches found!", get_match_count(scan));
return scan;
}
void DoScanning(void)
{
MEMBLOCK *scan;
scan = StartNewScan();
if(scan)
{
odprintf("[DoScanning()] SCAN: TRUE | Continue to search...");
while(true)
{
if(GetAsyncKeyState(VK_F10)&1)
{
update_scan(scan, COND_DECREASED, 0);
odprintf("[DoScanning()] Decreased value: %d matches found!", get_match_count(scan));
}
if(GetAsyncKeyState(VK_F11)&1)
{
odprintf("[DoScanning()] Print matched output:");
print_matches(scan);
}
if(GetAsyncKeyState(VK_F12)&1)
{
odprintf("[DoScanning()] Dumping scan info:");
dump_scan_info(scan);
}
Sleep(10);
}
}
else
{
odprintf("[DoScanning()] SCAN: FALSE | Leaving...");
}
}
BOOL WINAPI Loop(LPVOID lpVoid)
{
while(true)
{
if(GetAsyncKeyState(VK_F9)&1) DoScanning();
Sleep(1);
}
return TRUE;
}
BOOL WINAPI DllMain(HMODULE hDll, DWORD dwReason, LPVOID lpReserved)
{
DisableThreadLibraryCalls(hDll);
if(dwReason == DLL_PROCESS_ATTACH)
{
odprintf("[DllMain()] DLL_PROCESS_ATTACH");
CreateThread(NULL, NULL, (LPTHREAD_START_ROUTINE)Loop, NULL, NULL, NULL);
}
else if(dwReason == DLL_PROCESS_DETACH)
{
odprintf("[DllMain()] DLL_PROCESS_DETACH");
}
return TRUE;
}
please look at this line (memscan.h - create_scan()):
- Code: Select all
#define WRITABLE (PAGE_READWRITE | PAGE_WRITECOPY | PAGE_EXECUTE_READWRITE | PAGE_EXECUTE_WRITECOPY)
if I use PAGE_READWRITE argument, the program that has been injected not responding (high RAM).
but if I don't use PAGE_READWRITE argument, then show some results, but not the actual search result.
What's wrong with that? I hope there is someone who can help me.
Thanks in advance!
PS: I try to injecting Cheat Engine Tutorial (Tutorial.exe) part I for the sample (looking for a value of 100, and will be decreased)