 |
Cheat Engine The Official Site of Cheat Engine
|
| View previous topic :: View next topic |
| Author |
Message |
Shalvaid95 How do I cheat?
Reputation: 0
Joined: 26 Feb 2012 Posts: 9
|
Posted: Sun Feb 26, 2012 4:01 pm Post subject: [C++] Help reading string from memory process |
|
|
Hello everybody, I must say I am a bit new programming on c++. I usually develop my applications in vb6 or c#.
Now I'm in the middle of a trouble trying to make a Win32 COM DLL in C++ to find in a process memory a certain string, for example "CheatEn". (7 len)
To do this, and also test & debug it with my vb6 application, i programmed this function:
| Code: | int _stdcall ReadString(char *window, int Point, int Len)
{
char* value;
HWND hWnd = FindWindow(NULL, window);
DWORD proc_id;
GetWindowThreadProcessId(hWnd, &proc_id);
HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS, 0, proc_id);
ReadProcessMemory(hProcess, (LPVOID)Point, &value, 7, 0);
//if (value == 'CheatEn')
//{
// return 10;
//}
//CloseHandle(hProcess); Is actually necessary this?
return 0;
} |
For example, i would like to read the string in a certain address i would especify like 0x00F15130. In that address there's a string: "CheatEn" (7 len). I would like to compare it and verify if actually it is "CheatEn" or is another string like "asdagjkf" or whatever.
I tried many things but the part of the IF sentence still not working.
When i debug my dll and "add watches" y can see that &value has a value of 0xADDRESSHERE and then "CheatEn" the string i'm looking for.
Than you so much for reading my post.
I hope you can understand me without problems because my english is not the best.
Shalvaid |
|
| Back to top |
|
 |
SpaceUrkel How do I cheat?
Reputation: 0
Joined: 25 Feb 2012 Posts: 8
|
Posted: Sun Feb 26, 2012 9:38 pm Post subject: |
|
|
In c++ you can only compare two variables of the same >type< in an if statement.
This makes sure that both variables have the same size. For example numbers: a LONG is 4 bytes long (int) for example.
strings don't have that, they are not even a type in c++. The only means
to tell the length of a string is by attaching a NULL at the end.
0x01 'H'
0x02 'e'
0x03 'l'
0x04 'l'
0x05 'o'
0x06 '\0' (zero)
You could either write your own routine that compares the strings CHAR by CHAR (or preferably DWORD by
DWORD) or use one of the many functions that the C runtime and windows provide (strings.h gives you strcmp for
example). i.e.: if( strcmp( string, string ) == NULL )
[/code] _________________
et illus fugit |
|
| Back to top |
|
 |
Shalvaid95 How do I cheat?
Reputation: 0
Joined: 26 Feb 2012 Posts: 9
|
Posted: Sun Feb 26, 2012 10:13 pm Post subject: |
|
|
| SpaceUrkel wrote: | In c++ you can only compare two variables of the same >type< in an if statement.
This makes sure that both variables have the same size. For example numbers: a LONG is 4 bytes long (int) for example.
strings don't have that, they are not even a type in c++. The only means
to tell the length of a string is by attaching a NULL at the end.
0x01 'H'
0x02 'e'
0x03 'l'
0x04 'l'
0x05 'o'
0x06 '\0' (zero)
You could either write your own routine that compares the strings CHAR by CHAR (or preferably DWORD by
DWORD) or use one of the many functions that the C runtime and windows provide (strings.h gives you strcmp for
example). i.e.: if( strcmp( string, string ) == NULL )
[/code] |
Thank you so much for your help. Using strcmp I receive an error: Unhandled exception in MyDll.exe (MYDLL.DLL): 0x0000005: Access Violation, and then crash (running directly from my MyDLL.exe application. And debugging it through vc++ 6.0 y receive the same error but asking me to "Enter the path of STRCMP.ASM.
I've received this error in the past, trying to do something like this, but I dont know how to fix it.
Thanks a lot.
My VB 6.0 Code:
| Code: | Private Declare Function ReadString Lib "MyDLL.dll" (ByVal Window As String, ByVal Pointer As Long, ByVal xLen As Long) As Long
Private Sub Command1_Click()
MsgBox ReadString("WindowToRead", CLng("&H" & "00F15130"), 7)
End Sub |
żDo you think it would be better to create my own function to compare the strings? Is the only solution i think i can get. |
|
| Back to top |
|
 |
SpaceUrkel How do I cheat?
Reputation: 0
Joined: 25 Feb 2012 Posts: 8
|
Posted: Sun Feb 26, 2012 10:59 pm Post subject: |
|
|
Well, the access violation can happen when you try reading from protected
areas. You can't just read out the process from address 0x00000000
to 0xFFFFFFFF.
Ofcourse, writing a routine that compares strings is quite easy. But there
are some tricks to it to make it faster. For example, rather than comparing
byte by byte, as I said earlier, its faster to compare dwords or (if you
run on a 64bit system) qwords.
| Code: |
//return zero when both strings are equal, otherwise return address of the first difference
unsigned char*
compare( char* _cpsource, char* _cpdestination, unsigned long _ullength )
{
unsigned long dw_count = _ullength/sizeof(unsigned long); //we devide by 4. lets say our _ullength is 15 so: 3
unsigned short byte_count = _ullenght%sizeof(unsigned long);//now we need the ammount of the remaining bytes: also 3
//so in theory we can compare 3 DWORDs (4byte) and 3 CHARs (1byte), assuming you want to compare 15 bytes with each other
while( dw_count ) //reading in DWORDs
{
if(*_cpsource != *_cpdestination) //the star is the operator to access the memory that our variables point to
break;
(char*)_cpsource+=sizeof(unsigned long); //here we are here we know that the if statement was false and that
(char*)_cpdestination+=sizeof(unsigned long); //the two DWORDs were identical, so we advance to the next set
dw_cout--; //of DWORDs by increasing the address that our pointer carries by the size of one DWORD.
}
while( byte_count ) //reading in CHARs (1 byte)//once we are here we can assume that we either ran out of DWORDs to
{ //compare or that there was a difference found and now we need to find the exact location of it.
if(*(char*)_cpsource != *(char*)_cpdestination)) //we cast our pointer into the CHAR type so our compiler knows we
goto NOT_EQUAL //only compare 1 byte values now.
(char*)_cpsource+=sizeof(char);
(char*)_cpdestination+=sizeof(char);
byte_count--;
}
return 0; //if we reach this point every single DWORD and BYTE are
//identical.
NOT_EQUAL:
return _cpsource;
}
|
Hope this helps you get into the language some more. C++ is really worth getting into.  _________________
et illus fugit |
|
| Back to top |
|
 |
atom0s Moderator
Reputation: 205
Joined: 25 Jan 2006 Posts: 8585 Location: 127.0.0.1
|
Posted: Mon Feb 27, 2012 2:04 am Post subject: |
|
|
You are getting problems because you don't initialize your pointer.
char* value;
This isn't a valid data type to write into yet because it isn't initialized and since it is a pointer, it points to nothing. If you know the size is always going to be 7, use a char array instead.
If not, use new/malloc and allocate space and initialize value before you use it. (Be sure to free the memory when you are done too.) _________________
- Retired. |
|
| Back to top |
|
 |
Shalvaid95 How do I cheat?
Reputation: 0
Joined: 26 Feb 2012 Posts: 9
|
Posted: Mon Feb 27, 2012 11:55 am Post subject: |
|
|
Thanks all of you, As Wiccaan and most of you said, i didn't initialize my pointer, so now I' ve done and this is my code working:
| Code: |
char* _stdcall ReadString(char *window, int Point, int Len)
{
//char *value = (char*)malloc(Len+1) = {0};
char value[8] = {0};
HWND hWnd = FindWindow(NULL, window);
DWORD proc_id;
GetWindowThreadProcessId(hWnd, &proc_id);
HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS, 0, proc_id);
BOOL bReturn = ReadProcessMemory(hProcess, (LPVOID)Point, &value, 7, 0);
if ( bReturn == 0 )
{
DWORD lastError = GetLastError();
// error
}
else
{
// success
return value;
}
} |
Thank you SpaceUrkel for the idea of making a new routine and your code. But I decided to use strcmp to compare both values because it was the way i had tried 3 days ago, but it was not working because de readprocessmemory was wrong... Now it is reading the correct value, and I'm trying to make a routine to find a text value from visual basic. This is what i've done:
| Code: | int _stdcall SearchString(char *window, char *Text)
{
long int x;
for(x = 0; x < 80000000; x++) // This is a fucking disaster
{
if (strcmp(ReadString(window, x, sizeof(Text)), Text) == 0)
{
return x;
}
}
return 0;
}
|
That routine, i will call through vb6, with the window name and the text to search. I don't know why but it still not working properly. And I know there's a way to get the base address of a process to start searching since it like 0x40000000 but it changes on Windows 7 or Windows Vista, so i guess mi app will crash and not work properly.
I've tried this [C++] Get base Address (sorry, i can't paste here the url, but it's a thread of this great forum) but it gives me errors. And also search examples for EnumProcessModules and thos apis but they only work con 32bits.
Thanks again to all of you, I'll continue trying to improve and fix my routine. If you know how to fix it, thanks again. Hahaha I'm feeling like a noob, sorry for that. |
|
| Back to top |
|
 |
Acubra Advanced Cheater
Reputation: 0
Joined: 19 Jun 2011 Posts: 64 Location: C:\Windows\System32\HoG
|
Posted: Mon Feb 27, 2012 5:07 pm Post subject: |
|
|
Hey,
if you want to get the base address of a process look at the following API's:
CreateToolhelp32Snapshot
Process32First
Process32Next
If you need I can post a function I wrote using these API's. |
|
| Back to top |
|
 |
Dark Byte Site Admin
Reputation: 473
Joined: 09 May 2003 Posts: 25909 Location: The netherlands
|
Posted: Mon Feb 27, 2012 5:13 pm Post subject: |
|
|
EnumProcessModulesEx has support for 64-bit target processes
And the base address will only change in windows vista+ if it was compiled with the relocation flag set _________________
Tools give you results. Knowledge gives you control.
Like my help? Join me on Patreon so i can keep helping |
|
| Back to top |
|
 |
Shalvaid95 How do I cheat?
Reputation: 0
Joined: 26 Feb 2012 Posts: 9
|
Posted: Mon Feb 27, 2012 6:32 pm Post subject: |
|
|
| Acubra wrote: | Hey,
if you want to get the base address of a process look at the following API's:
CreateToolhelp32Snapshot
Process32First
Process32Next
If you need I can post a function I wrote using these API's. |
Yes please, if you have an example I'll really apreciate it.
Thank you. |
|
| Back to top |
|
 |
Stylo Grandmaster Cheater Supreme
Reputation: 3
Joined: 16 May 2007 Posts: 1073 Location: Israel
|
Posted: Mon Feb 27, 2012 10:48 pm Post subject: |
|
|
Another way to get the process's base address is to access the PEB of the current process and get ImageBaseAddress.
Read about PEB( Process Environment Block ) http://undocumented.ntinternals.net/UserMode/Undocumented%20Functions/NT%20Objects/Process/PEB.html
an example for that:
| Code: |
PVOID get_process_base_address() {
PVOID pBaseAddr;
__asm {
push eax
mov eax,fs:[0x30]
mov eax,[eax+0x8]
mov dword ptr ds:[pBaseAddr],eax
pop eax
}
return pBaseAddr;
}
|
_________________
Stylo |
|
| Back to top |
|
 |
Shalvaid95 How do I cheat?
Reputation: 0
Joined: 26 Feb 2012 Posts: 9
|
Posted: Tue Feb 28, 2012 12:36 am Post subject: |
|
|
Thank you so much Stylo, tomorrow I'll try your routine and I'll implement to my project.
You were right, it was not working again...
Now i fix it. It's reading the fine the memory, but I'm trying to verify in my loop if the value is a certain Text...
| Code: |
char* _stdcall ReadString(char *window, int Point, int Len)
{
//char *value = (char*)malloc(Len+1) = {0};
char value[8] = {0};
HWND hWnd = FindWindow(NULL, window);
DWORD proc_id;
GetWindowThreadProcessId(hWnd, &proc_id);
HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS, 0, proc_id);
BOOL bReturn = ReadProcessMemory(hProcess, (LPVOID)Point, value, 7, 0);
if ( bReturn == 0 )
{
DWORD lastError = GetLastError();
return 0;
// error
}
else
{
// success
return value;
}
}
int _stdcall SearchString(char *window, char *Text)
{
long int x;
for(x = 0; x < 80000000; x++)
{
if (!strcmp(ReadString(window, x, 7),Text)) //This don't work fine :S...
{
return x;
}
}
return 0;
} |
Debugging it, i realized that it reads fine the value... but at the time to compare both, it's not working.
Thank you.
Regards |
|
| Back to top |
|
 |
Dark Byte Site Admin
Reputation: 473
Joined: 09 May 2003 Posts: 25909 Location: The netherlands
|
Posted: Tue Feb 28, 2012 3:15 am Post subject: |
|
|
That is because the local variable named "value" has been destroyed. Don't allocate the memory in ReadString but pass it a pointer it can fill from SearchString _________________
Tools give you results. Knowledge gives you control.
Like my help? Join me on Patreon so i can keep helping |
|
| Back to top |
|
 |
Shalvaid95 How do I cheat?
Reputation: 0
Joined: 26 Feb 2012 Posts: 9
|
Posted: Tue Feb 28, 2012 1:14 pm Post subject: |
|
|
Thank you DarkByte. I've improved my "DLL", now it's working fine:
| Code: | //////////////////////////////////////////////////////////////////
// Set UP the window wich we're gonna work with
//////////////////////////////////////////////////////////////////
void _stdcall SetWindow(char *window)
{
hWnd = FindWindow(NULL, window);
GetWindowThreadProcessId(hWnd, &proc_id);
hProcess = OpenProcess(PROCESS_ALL_ACCESS, 0, proc_id);
}
//////////////////////////////////////////////////////////////////
// ReadString from a certain Address and return as string type
//////////////////////////////////////////////////////////////////
std::string ReadString(int Point, int Len)
{
//char *value = (char*)malloc(Len+1) = {0};
char value[8] = {0};
SIZE_T numBytesRead;
if (ReadProcessMemory(hProcess, (LPVOID)Point, value, 7, &numBytesRead) == 0)
{
DWORD lastError = GetLastError();
return "";
// error - return an empty string
}
return std::string(value, numBytesRead);
}
//////////////////////////////////////////////////////////////////
// ReadLong from a certain Address and return as int (4bytes) type
//////////////////////////////////////////////////////////////////
int ReadLong(int Point) //We don't need Len (4bytes)s
{
int tbuf;
if (ReadProcessMemory(hProcess, (LPVOID)Point, &tbuf, 4, NULL) == 0)
{
DWORD lastError = GetLastError();
return 0;
// error - return 0
}
return tbuf;
}
//////////////////////////////////////////////////////////////////
// Search a Certain String in a process
//////////////////////////////////////////////////////////////////
int _stdcall SearchString(char *Text)
{
long int x;
PVOID ASD = get_process_base_address;
for(x = 0; x < 80000000; x++)
{
if ( ReadString(x, 7) == Text )
{
return x; // Return the address we found
}
}
return 0; //Error Return zero
}
//////////////////////////////////////////////////////////////////
// Search a Certain Long in a process
//////////////////////////////////////////////////////////////////
int _stdcall SearchLong(int Result)
{
long int x;
for(x = 0; x < 80000000; x++)
{
if ( ReadLong(x) == Result )
{
return x; // Return the address we found
}
}
return 0; //Error Return zero
} |
The only thing i would like to do now is to search from the Image Base Address of a process. Almost is 0x00400000 but it also changes in Windows 7 or Windows Vista, and I guess 64bits processors too. And then start searching from the Image Base Address of the process (pid), to make it faster and don't start from 0.
@Stylo: I tried your routine but it gives me the wrong addres, or there's something i miss to do...
Thank you.
Regards |
|
| Back to top |
|
 |
Dark Byte Site Admin
Reputation: 473
Joined: 09 May 2003 Posts: 25909 Location: The netherlands
|
Posted: Tue Feb 28, 2012 1:30 pm Post subject: |
|
|
That works? Without eventually crashing due to out of memory or it returning useless garbage? (I'm not that familiar with c++ but return std::string(value, numBytesRead) seems wrong, but then again, c++ often seems wrong to me )
Edit: if it's one of those function context only objects I guess it'd work _________________
Tools give you results. Knowledge gives you control.
Like my help? Join me on Patreon so i can keep helping |
|
| Back to top |
|
 |
Shalvaid95 How do I cheat?
Reputation: 0
Joined: 26 Feb 2012 Posts: 9
|
Posted: Tue Feb 28, 2012 1:43 pm Post subject: |
|
|
| Yes, luckily it's working fine. I'm also new with C++... but well, asking help, and googling there's nothing you can't do. Now I'm trying to avoid start searching from 0, and do it from the image base address (0x004000 on windows xp 32b), but it seems there's no much information on the net about that. |
|
| 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
|
|