 |
Cheat Engine The Official Site of Cheat Engine
|
View previous topic :: View next topic |
Author |
Message |
Pasukaru How do I cheat?
Reputation: 0
Joined: 15 Dec 2011 Posts: 8
|
Posted: Thu Dec 15, 2011 4:34 pm Post subject: [SOLVED] [C++] Find program's entry point/base address. |
|
|
Hello!
I'm experimenting with reading/writing memory of a program and having trouble finding a specific address based on the program's entry point.
(My test program is Windows 7's Solitaire)
In CE the address pointer looks like this: solitaire.exe+97074 offset: 2C
How do I realize this with C++ code?
I have no problems finding values and static addresses with other programs/games I used, but in this case I have to use the module name because even static(green) addresses are changing.
So, what I need is something like this:
Code: | DWORD entryPoint = 0x00000000//Here's my problem, how do i get this from solitaire.exe?
DWORD entryOffset = 97074;
DWORD offset = 0x2C;
DWORD address = entryPoint+entryOffset+offset; |
Thanks in advance for your help!
Last edited by Pasukaru on Fri Dec 16, 2011 12:42 pm; edited 1 time in total |
|
Back to top |
|
 |
atom0s Moderator
Reputation: 205
Joined: 25 Jan 2006 Posts: 8587 Location: 127.0.0.1
|
Posted: Fri Dec 16, 2011 12:12 am Post subject: |
|
|
You can find this information using:
- CreateToolhelp32Snapshot
- Process32First / Process32Next
- Module32First / Module32Next
_________________
- Retired. |
|
Back to top |
|
 |
Pasukaru How do I cheat?
Reputation: 0
Joined: 15 Dec 2011 Posts: 8
|
Posted: Fri Dec 16, 2011 11:14 am Post subject: |
|
|
Thanks Wiccaan!
I tried to find the BaseAddress using the CreateToolhelp32Snapshot.
Here is what I got so far:
Code: |
HWND window = FindWindow(0, _T("Solitaire"));
if( window == 0 ){
cerr << "Window not found!" << endl;
return 0;
}
DWORD pID = 0;
GetWindowThreadProcessId(window, &pID);
cout << "Window found. PID: " << pID << endl;
HANDLE snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, pID);
MODULEENTRY32 module;
module.dwSize = sizeof(MODULEENTRY32);
Module32First(snapshot, &module);
do {
printf("ModuleName: %S\n" , module.szExePath);
printf("Base Addr : 0x%08X\n\n", module.modBaseAddr);
} while( Module32Next(snapshot, &module) );
CloseHandle(snapshot);
|
This is what it looks like in CE, just for reference:
httpX//img339.imageshack.us/img339/9048/87808589.png
(Replace 'X' with ':'. Sorry, I can't post URLs yet...)
The first entry seems to be the correct one(solitaire.exe).
However, the modBaseAddr was 0x001D0000 and CE found 0x0157ACE8. (It's 0150ACE8 in the picture, it was another test run.)
My question is: How do I get the address of the pointer that CE finds? I tried calculating the offset (0x0157ACE8 - 0x001D0000), but this one changes everytime I restart the program as well. :/
|
|
Back to top |
|
 |
atom0s Moderator
Reputation: 205
Joined: 25 Jan 2006 Posts: 8587 Location: 127.0.0.1
|
Posted: Fri Dec 16, 2011 11:34 am Post subject: |
|
|
CE is reading the solitare.exe+97074 as a pointer. Then adding 0x2c to the result. Then reading that new address as a pointer, then adding 0x10 to that for the final address.
when you have the correct module base (The first one returned should be the .exe) use the base from that and add 97074 to it and read that address as a DWORD value.
So in summary:
- Get solitare.exe base from Module32First when you have the procid.
- ReadProcessMemory solitare.exe+0x97074 as a DWORD
- Add 0x2c to the result.
- ReadProcessMemory again using the result as the address.
- Add 0x10 to the new result.
And you should have your address. Read/Write to it then.
_________________
- Retired. |
|
Back to top |
|
 |
Pasukaru How do I cheat?
Reputation: 0
Joined: 15 Dec 2011 Posts: 8
|
Posted: Fri Dec 16, 2011 12:42 pm Post subject: |
|
|
Thanks a bunch!
I tried that, just had a little error, I used 97074 as static offset, instead of 0x97074 (stupid me!).
I got it working now.
Here's the complete code, maybe someone else will find it useful.
I copied the first function from a thread on this forum. Couldn't find it again, sorry. :/
It does pretty much the same as my code, just with an added check to make sure you find the correct address.
Code: | #include "stdafx.h"
#include <windows.h>
#include <TlHelp32.h>
#include <iostream>
using namespace std;
DWORD dwGetModuleBaseAddress(DWORD dwProcessIdentifier, TCHAR *lpszModuleName)
{
HANDLE hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, dwProcessIdentifier);
DWORD dwModuleBaseAddress = 0;
if(hSnapshot != INVALID_HANDLE_VALUE)
{
MODULEENTRY32 ModuleEntry32 = {0};
ModuleEntry32.dwSize = sizeof(MODULEENTRY32);
if(Module32First(hSnapshot, &ModuleEntry32))
{
do
{
if(_tcscmp(ModuleEntry32.szModule, lpszModuleName) == 0)
{
dwModuleBaseAddress = (DWORD)ModuleEntry32.modBaseAddr;
break;
}
}
while(Module32Next(hSnapshot, &ModuleEntry32));
}
CloseHandle(hSnapshot);
}
return dwModuleBaseAddress;
}
int main()
{
HWND window = FindWindow(0, _T("Solitaire"));
if( window == 0 ){
printf("Window not found!\n");
char f;
cin >> f;
return 0;
}
DWORD pID = 0;
GetWindowThreadProcessId(window, &pID);
DWORD baseAddr = dwGetModuleBaseAddress(pID, _T("solitaire.exe"));
DWORD staticOffset = 0x97074;
HANDLE handle = OpenProcess(PROCESS_ALL_ACCESS, FALSE, pID);
DWORD value;
DWORD numBytesRead;
ReadProcessMemory(handle, (LPCVOID)(baseAddr+staticOffset), &value, sizeof(DWORD), &numBytesRead);
value+=0x2C;
ReadProcessMemory(handle, (LPCVOID)value, &value, sizeof(DWORD), &numBytesRead);
value+=0x10; //Points offset
ReadProcessMemory(handle, (LPCVOID)value, &value, sizeof(DWORD), &numBytesRead);
CloseHandle(handle);
printf("Found value: %d", value);
char f;
cin >> f;
return 0;
} |
|
|
Back to top |
|
 |
NullBy7e Cheater
Reputation: 0
Joined: 23 Jul 2014 Posts: 47
|
Posted: Fri Aug 01, 2014 4:47 pm Post subject: |
|
|
_tscmp is undefined for me, what do I do?
|
|
Back to top |
|
 |
atom0s Moderator
Reputation: 205
Joined: 25 Jan 2006 Posts: 8587 Location: 127.0.0.1
|
Posted: Fri Aug 01, 2014 7:50 pm Post subject: |
|
|
NullBy7e wrote: | _tscmp is undefined for me, what do I do? |
Include the TCHAR.h header file.
_________________
- Retired. |
|
Back to top |
|
 |
NullBy7e Cheater
Reputation: 0
Joined: 23 Jul 2014 Posts: 47
|
Posted: Sat Aug 02, 2014 11:23 am Post subject: |
|
|
I've got a similar issue, I find the base address but in cheat engine its a different address.
Some code:
Code: | CSettings::phandle = phandle;
CSettings::base = dwGetModuleBaseAddress(pid, _T("program.exe"));
byte* buffer = new byte[24];
unsigned long base = CSettings::base;
unsigned long addr = ( base + 0x00FD1D9C + 0x60 + 0xA4 );
ReadProcessMemory(CSettings::phandle, (LPCVOID*)addr, &buffer, sizeof(buffer), 0);
printf("CNAME : %x\n\n", buffer);
delete buffer; |
Function:
Code: | DWORD dwGetModuleBaseAddress(DWORD dwProcessIdentifier, TCHAR *lpszModuleName)
{
HANDLE hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, dwProcessIdentifier);
DWORD dwModuleBaseAddress = 0;
if(hSnapshot != INVALID_HANDLE_VALUE)
{
MODULEENTRY32 ModuleEntry32 = {0};
ModuleEntry32.dwSize = sizeof(MODULEENTRY32);
if(Module32First(hSnapshot, &ModuleEntry32))
{
do
{
if(_tcsicmp(ModuleEntry32.szModule, lpszModuleName) == 0)
{
printf("ModuleName: %S\n" , ModuleEntry32.szExePath);
printf("Base Addr : 0x%08X\n\n", ModuleEntry32.modBaseAddr);
dwModuleBaseAddress = (DWORD)ModuleEntry32.modBaseAddr;
break;
}
}
while(Module32Next(hSnapshot, &ModuleEntry32));
}
CloseHandle(hSnapshot);
}
return dwModuleBaseAddress;
} |
|
|
Back to top |
|
 |
atom0s Moderator
Reputation: 205
Joined: 25 Jan 2006 Posts: 8587 Location: 127.0.0.1
|
Posted: Sat Aug 02, 2014 2:08 pm Post subject: |
|
|
Be sure that Cheat Engine is using that same module (the executable) as the base address and not something else.
_________________
- Retired. |
|
Back to top |
|
 |
NullBy7e Cheater
Reputation: 0
Joined: 23 Jul 2014 Posts: 47
|
Posted: Sat Aug 02, 2014 3:28 pm Post subject: |
|
|
I think that it is?
I open the process and it shows an address next to the name, I assume that it's the module base address.
Odd thing is that when I read a pointer it returns 0 instead of a char* when using printf.
It shouldnt return a zero because the pointer and offsets i'm using work with my C# version.
Something else must be wrong..
|
|
Back to top |
|
 |
Dark Byte Site Admin
Reputation: 470
Joined: 09 May 2003 Posts: 25796 Location: The netherlands
|
Posted: Sat Aug 02, 2014 4:12 pm Post subject: |
|
|
Quote: |
unsigned long addr = ( base + 0x00FD1D9C + 0x60 + 0xA4 );
|
I doubt that will do what you think it will do
I suggest reading http://forum.cheatengine.org/viewtopic.php?t=422516
_________________
Do not ask me about online cheats. I don't know any and wont help finding them.
Like my help? Join me on Patreon so i can keep helping |
|
Back to top |
|
 |
NullBy7e Cheater
Reputation: 0
Joined: 23 Jul 2014 Posts: 47
|
Posted: Sat Aug 02, 2014 5:21 pm Post subject: |
|
|
Ive taken a look at that topic and I think that I understand it now.
Something like this?
I probably have to convert the buffer before using it as an address everytime?
Code: | byte* buffer = new byte[4];
int offset1 = 0x00FD1D9C;
int offset2 = 0x60;
int offset3 = 0xA4;
ReadProcessMemory(CSettings::phandle, (LPCVOID*)CSettings::base + offset1, &buffer, sizeof(buffer), 0);
ReadProcessMemory(CSettings::phandle, (LPCVOID*)buffer + offset2, &buffer, sizeof(buffer), 0);
ReadProcessMemory(CSettings::phandle, (LPCVOID*)buffer + offset3, &buffer, sizeof(buffer), 0);
byte* cname = new byte[24];
ReadProcessMemory(CSettings::phandle, (LPCVOID*)buffer, &cname, sizeof(cname), 0);
printf("CNAME : %x\n\n", cname);
delete buffer;
delete cname; |
|
|
Back to top |
|
 |
Dark Byte Site Admin
Reputation: 470
Joined: 09 May 2003 Posts: 25796 Location: The netherlands
|
Posted: Sat Aug 02, 2014 5:28 pm Post subject: |
|
|
instead of using buffer, use an type that can hold an pointersize object without the need to convert e.g UINT_PTR, or just int if it's 32-bit
_________________
Do not ask me about online cheats. I don't know any and wont help finding them.
Like my help? Join me on Patreon so i can keep helping |
|
Back to top |
|
 |
NullBy7e Cheater
Reputation: 0
Joined: 23 Jul 2014 Posts: 47
|
Posted: Sat Aug 02, 2014 5:41 pm Post subject: |
|
|
Is this code correct?
Its not returning what I want, which is a string, instead it returns nothing.
Sorry for all my noob questions, im just the type of person who learns by getting direct answers to questions.
Tutorials and guides often do me no good, except for that one thread you posted.
FYI: base address is 0x00400000 but CheatEngine shows something else.
EDIT2: I searched for the address with CE by adding the pointer to the table of CE and I still get an access violation, with or without SE_DEBUG (vs is ran as admin aswell).
Code: |
byte* cname = new byte[24];
ReadProcessMemory(CSettings::phandle, (LPCVOID*)(DWORD*)(*(DWORD*)CSettings::base + 0x15423934), &cname, sizeof(cname), 0);
|
EDIT1: I debugged a bit and addr is always 0 or 0x00000000 - whats going on?
Code: |
int buffer;
int offset1 = 0x00FD1D9C;
int offset2 = 0x60;
int offset3 = 0xA4;
ReadProcessMemory(CSettings::phandle, (LPCVOID*)CSettings::base + offset1, &buffer, sizeof(buffer), 0);
ReadProcessMemory(CSettings::phandle, (LPCVOID*)buffer + offset2, &buffer, sizeof(buffer), 0);
ReadProcessMemory(CSettings::phandle, (LPCVOID*)buffer + offset3, &buffer, sizeof(buffer), 0);
byte* cname = new byte[24];
ReadProcessMemory(CSettings::phandle, (LPCVOID*)buffer, &cname, sizeof(cname), 0);
std::string s( reinterpret_cast< char const* >(cname) ) ;
printf("CNAME : %s", s);
delete cname;
|
EDIT:
I now have the following:
Code: |
ReadProcessMemory(CSettings::phandle, (LPCVOID*)(DWORD*)(*(DWORD*)CSettings::base + offset1), &addr, sizeof(addr), 0);
printf("Addr : 0x%08X\n", addr);
ReadProcessMemory(CSettings::phandle, (LPCVOID*)(DWORD*)(*(DWORD*)addr + offset2), &addr, sizeof(addr), 0);
printf("Addr : 0x%08X\n", addr);
ReadProcessMemory(CSettings::phandle, (LPCVOID*)(DWORD*)(*(DWORD*)addr + offset3), &addr, sizeof(addr), 0);
printf("Addr : 0x%08X\n", addr);
|
And I get *memory violation at address baseadress* which is 0x000400000
Description: |
|
Filesize: |
55.3 KB |
Viewed: |
38800 Time(s) |

|
|
|
Back to top |
|
 |
NullBy7e Cheater
Reputation: 0
Joined: 23 Jul 2014 Posts: 47
|
Posted: Sun Aug 03, 2014 9:04 am Post subject: |
|
|
Anyone?
|
|
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
|
|