Cheat Engine Forum Index Cheat Engine
The Official Site of Cheat Engine
 
 FAQFAQ   SearchSearch   MemberlistMemberlist   UsergroupsUsergroups   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 


[SOLVED] [C++] Find program's entry point/base address.
Goto page 1, 2  Next
 
Post new topic   Reply to topic    Cheat Engine Forum Index -> General programming
View previous topic :: View next topic  
Author Message
Pasukaru
How do I cheat?
Reputation: 0

Joined: 15 Dec 2011
Posts: 8

PostPosted: Thu Dec 15, 2011 4:34 pm    Post subject: [SOLVED] [C++] Find program's entry point/base address. Reply with quote

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
View user's profile Send private message
atom0s
Moderator
Reputation: 205

Joined: 25 Jan 2006
Posts: 8587
Location: 127.0.0.1

PostPosted: Fri Dec 16, 2011 12:12 am    Post subject: Reply with quote

You can find this information using:
- CreateToolhelp32Snapshot
- Process32First / Process32Next
- Module32First / Module32Next

_________________
- Retired.
Back to top
View user's profile Send private message Visit poster's website
Pasukaru
How do I cheat?
Reputation: 0

Joined: 15 Dec 2011
Posts: 8

PostPosted: Fri Dec 16, 2011 11:14 am    Post subject: Reply with quote

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
View user's profile Send private message
atom0s
Moderator
Reputation: 205

Joined: 25 Jan 2006
Posts: 8587
Location: 127.0.0.1

PostPosted: Fri Dec 16, 2011 11:34 am    Post subject: Reply with quote

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
View user's profile Send private message Visit poster's website
Pasukaru
How do I cheat?
Reputation: 0

Joined: 15 Dec 2011
Posts: 8

PostPosted: Fri Dec 16, 2011 12:42 pm    Post subject: Reply with quote

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
View user's profile Send private message
NullBy7e
Cheater
Reputation: 0

Joined: 23 Jul 2014
Posts: 47

PostPosted: Fri Aug 01, 2014 4:47 pm    Post subject: Reply with quote

_tscmp is undefined for me, what do I do?
Back to top
View user's profile Send private message
atom0s
Moderator
Reputation: 205

Joined: 25 Jan 2006
Posts: 8587
Location: 127.0.0.1

PostPosted: Fri Aug 01, 2014 7:50 pm    Post subject: Reply with quote

NullBy7e wrote:
_tscmp is undefined for me, what do I do?


Include the TCHAR.h header file.

_________________
- Retired.
Back to top
View user's profile Send private message Visit poster's website
NullBy7e
Cheater
Reputation: 0

Joined: 23 Jul 2014
Posts: 47

PostPosted: Sat Aug 02, 2014 11:23 am    Post subject: Reply with quote

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
View user's profile Send private message
atom0s
Moderator
Reputation: 205

Joined: 25 Jan 2006
Posts: 8587
Location: 127.0.0.1

PostPosted: Sat Aug 02, 2014 2:08 pm    Post subject: Reply with quote

Be sure that Cheat Engine is using that same module (the executable) as the base address and not something else.
_________________
- Retired.
Back to top
View user's profile Send private message Visit poster's website
NullBy7e
Cheater
Reputation: 0

Joined: 23 Jul 2014
Posts: 47

PostPosted: Sat Aug 02, 2014 3:28 pm    Post subject: Reply with quote

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
View user's profile Send private message
Dark Byte
Site Admin
Reputation: 470

Joined: 09 May 2003
Posts: 25796
Location: The netherlands

PostPosted: Sat Aug 02, 2014 4:12 pm    Post subject: Reply with quote

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
View user's profile Send private message MSN Messenger
NullBy7e
Cheater
Reputation: 0

Joined: 23 Jul 2014
Posts: 47

PostPosted: Sat Aug 02, 2014 5:21 pm    Post subject: Reply with quote

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
View user's profile Send private message
Dark Byte
Site Admin
Reputation: 470

Joined: 09 May 2003
Posts: 25796
Location: The netherlands

PostPosted: Sat Aug 02, 2014 5:28 pm    Post subject: Reply with quote

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
View user's profile Send private message MSN Messenger
NullBy7e
Cheater
Reputation: 0

Joined: 23 Jul 2014
Posts: 47

PostPosted: Sat Aug 02, 2014 5:41 pm    Post subject: Reply with quote

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



207d743eb7b072e840ff7aba3f3bac94.png
 Description:
 Filesize:  55.3 KB
 Viewed:  38790 Time(s)

207d743eb7b072e840ff7aba3f3bac94.png


Back to top
View user's profile Send private message
NullBy7e
Cheater
Reputation: 0

Joined: 23 Jul 2014
Posts: 47

PostPosted: Sun Aug 03, 2014 9:04 am    Post subject: Reply with quote

Anyone?
Back to top
View user's profile Send private message
Display posts from previous:   
Post new topic   Reply to topic    Cheat Engine Forum Index -> General programming All times are GMT - 6 Hours
Goto page 1, 2  Next
Page 1 of 2

 
Jump to:  
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


Powered by phpBB © 2001, 2005 phpBB Group

CE Wiki   IRC (#CEF)   Twitter
Third party websites