 |
Cheat Engine The Official Site of Cheat Engine
|
| View previous topic :: View next topic |
| Author |
Message |
TheJAF How do I cheat?
Reputation: 0
Joined: 30 Sep 2010 Posts: 1
|
Posted: Thu Sep 30, 2010 10:56 pm Post subject: [HELP - C++] Failed using PAGE_READWRITE on Memory Scanner |
|
|
I try to using a HadFuny Memory Scanner source code, worked like a charms when I compile to be an executable. But, when I modify and compile to be a DLL (injection), the process that has been injected using RAM resource so high (any program windows is not responding, but the cursor still moveable).
here the source:
memscan.h
| Code: |
// 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: |
#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 lpParam)
{
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: |
#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 without 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)
|
|
| Back to top |
|
 |
justa_dude Grandmaster Cheater
Reputation: 23
Joined: 29 Jun 2010 Posts: 893
|
Posted: Fri Oct 01, 2010 12:01 pm Post subject: |
|
|
A few suggestions for you.
1) If you post 5 lines of code that don't work, someone will find the error. If you post 20 lines of code that don't work, someone might find the error. If you post three pages of code that don't work, most folks won't bother.
2) You should try to understand what the code does before altering it. This code uses a lot of functionality for interacting with /other/ processes. When you inject a dll, you can manipulate memory/etc directly.
3) You can attach a debugger and/or profiler to your code to see exactly what's going on.
4) Creating a thread from inside DLLMain is probably a bad idea. It would be better to have the injecting process initiate the thread.
|
|
| Back to top |
|
 |
tombana Master Cheater
Reputation: 2
Joined: 14 Jun 2007 Posts: 456 Location: The Netherlands
|
Posted: Fri Oct 01, 2010 1:30 pm Post subject: |
|
|
| justa_dude wrote: | | 4) Creating a thread from inside DLLMain is probably a bad idea. It would be better to have the injecting process initiate the thread. |
That's not a problem. That's what most injected dlls do.
|
|
| Back to top |
|
 |
justa_dude Grandmaster Cheater
Reputation: 23
Joined: 29 Jun 2010 Posts: 893
|
Posted: Fri Oct 01, 2010 1:59 pm Post subject: |
|
|
| tombana wrote: | | justa_dude wrote: | | 4) Creating a thread from inside DLLMain is probably a bad idea. It would be better to have the injecting process initiate the thread. |
That's not a problem. That's what most injected dlls do. |
He's calling functions from STDIO inside that thread. AFAIK, any blocking action (which STDIO does a lot of) could cause deadlock. Using functions from anywhere but kernel32 is documented as bad practice, and this code has obviously not been studied to an extent that would qualify it as only doing "safe" things. Not to mention the fact that it confuses the fact that being loaded is not the same thing in Windows parlance as being told to "go." DLLs get loaded without ever doing any real work all the time.
Cheers,
adude
|
|
| Back to top |
|
 |
Jesper Grandmaster Cheater Supreme
Reputation: 9
Joined: 21 Feb 2007 Posts: 1156
|
|
| Back to top |
|
 |
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum You cannot attach files in this forum You can download files in this forum
|
|