C++ Pointer Memory

12/22/2010 21:15 Barra Sargtlin#1
Hallo zusammen,

ich bin aktuell dabei meine ganzen autoit botfunctions in c++ umzusetzen.
aktuell habe ich ein problem mit der memory. das auslesen und schreiben geht generell schon.

Beispielaufruf
Code:
m_objFenster.MemoryRead(adr_death, sizeof(int));
Funktion
Code:
int Window::MemoryRead(unsigned adress, short size) {
	int value;
	ReadProcessMemory(m_processHandle, (LPCVOID)adress, &value, size, NULL);
	return value;
}
Das Problem ist, dass ich jetzt einen Pointer benutzen muss.
Der dazu passende Autoit Code ist
Code:
Func HPEP ()
	Local $adr_HPEP = IniRead("Memory.ini", "CHAR", "HP_EP", "")
	Local $mem_p = _MemoryRead(_MemoryRead($adr_HPEP, $hprocess) +0x104, $hprocess)

	Local $HPEP[2][2]
	$HPEP[0][1] = _MemoryRead($mem_p + 0x2C, $hprocess) ; HP MAX
	$HPEP[1][1] = _MemoryRead($mem_p + 0x18, $hprocess) ; EP MAX

	; relativ zu absolut
	$HPEP[0][0] = Floor($HPEP[0][1] * _MemoryRead($mem_p + 0x28, $hprocess, "float")) ; HP CUR
	$HPEP[1][0] = Floor($HPEP[1][1] * _MemoryRead($mem_p + 0x14, $hprocess, "float")) ; EP CUR
	Return $HPEP
EndFunc
Mein Ansatz das jetzt in c++ umzuseten ist
Code:
unsigned Character::HPEP() {
	unsigned adr_HPEP = 0x_____;

	unsigned pointer = m_objFenster.MemoryRead(adr_HPEP, sizeof(long));
	pointer = m_objFenster.MemoryRead(pointer + 0x104, sizeof(long));
	return pointer;
}



int Character::GetHP() {
	unsigned pointer = Character::HPEP();

	int max = m_objFenster.MemoryRead(pointer + 0x2C, sizeof(int));
	int cur = m_objFenster.MemoryRead(pointer + 0x28, sizeof(float)) *max;
	cur = floor(cur);
	return cur;
}





int Character::GetEP() {
	unsigned pointer = Character::HPEP();

	int max = m_objFenster.MemoryRead(pointer + 0x18, sizeof(int));
	int cur = m_objFenster.MemoryRead(pointer + 0x14, sizeof(float)) *max;
	cur = floor(cur);
	return cur;
}
Das Problem ist 1. ich weiß nicht was ich als bitgröße angeben soll... long ist logischerweise falsch. beim aufruf wurde der typ weggelassen, laut nomadmemory.au3 ist der typ dann dword (?). was ja UDINT- 32 bit enspricht ?

und ja... allgemein etwas unsicher bei diesem fall :(
12/22/2010 22:22 nkkk#2
ich habe mir din post nicht ganz durchgelesen, aber der code
Code:
int Window::MemoryRead(unsigned adress, short size) {
	int value;
	ReadProcessMemory(m_processHandle, (LPCVOID)adress, &value, size, NULL);
	return value;
}
ist auf jeden fall falsch. Du hast einen parameter, der die "size" angibt aber dann gibst du doch immer einen int zurück?


Edit:
so konnte man es z.B. besser machen:
Code:
template<class T>
T Window::MemoryRead(unsigned int adress) {
	T value;
	ReadProcessMemory(m_processHandle, (LPCVOID)adress, &value, sizeof(T), NULL);
	return value;
}
hab schon länger nicht mehr c++ gecodet, aber ich denke der funktioniert so.
12/22/2010 22:31 MrSm!th#3
long hat die selbe größe wie dword.

denk einfach an adressen, die sind 4 bytes lang.
und ein pointer ist nichts anderes als eine variable die die adresse einer anderen enthält.

also liest du den wert aus, der in dieser variable gespeichert ist, addierst das offset und hast die adresse, von der du auslesen willst (lässt sich natürlich beliebig oft für multi lvl pointer wiederholen)
12/23/2010 05:53 wurstbrot123#4
Quote:
Originally Posted by nkkk View Post
Code:
template<class T>
T Window::MemoryRead(unsigned int adress) {
	T value;
	ReadProcessMemory(m_processHandle, (LPCVOID)adress, &value, sizeof(T), NULL);
	return value;
}
Ist schonmal ein guter Ansatz jedoch wird ja nirgends
angegeben was nun T ist. So könnte man es richtig verwenden:

Code:
template<class T>
void Window::MemoryRead(unsigned int adress, T buffer )
{
	ReadProcessMemory(m_processHandle, (LPCVOID)adress, &buffer, sizeof(T), NULL);
}
Jedoch wirst du dabei einfach den Ausgelesen wert im 2.n übergebenen
Parameter erhalten anstatt etwas zurückgegeben wird.
12/23/2010 12:00 nkkk#5
Quote:
Originally Posted by wurstbrot123 View Post
Ist schonmal ein guter Ansatz jedoch wird ja nirgends
angegeben was nun T ist. So könnte man es richtig verwenden:

Code:
template<class T>
void Window::MemoryRead(unsigned int adress, T buffer )
{
	ReadProcessMemory(m_processHandle, (LPCVOID)adress, &buffer, sizeof(T), NULL);
}
Jedoch wirst du dabei einfach den Ausgelesen wert im 2.n übergebenen
Parameter erhalten anstatt etwas zurückgegeben wird.


hmm mein compiler (vc++) erlaubt mir die folgende schreibweise(ausgenhend von meiner funktion im ersten post):
Code:
Windows w;
POINT p = w.MemoryRead<POINT>(56486) ;
deine methode kommt mir allerdings komisch vor:
buffer wird bei deiner Methode per value übergeben, es wird also nur mit einer kopie weitergearbeitet.

Code:
template<class T>
void Window::MemoryRead(unsigned int adress, T[COLOR="Red"]&[/COLOR] buffer )
{
	ReadProcessMemory(m_processHandle, (LPCVOID)adress, &buffer, sizeof(T), NULL);
}
müste es meiner meinug nach heissen, kann mich aber auch irren, da ich im moment kein c++ code.
12/24/2010 13:06 Barra Sargtlin#6
entschuligung, dass ich so spät antworte, hatte bisher keine möglichkeit dazu. vielen dank für die schnelle und gute hilfe :)

ja ich kam wie auch ihr drauf, dass die referenz fehlte. zmd beim lesen, beim schreiben wäre dies ja im endeffekt egal. Vielen dank nochmal :handsdown:
folgend der final code, falls den noch wer braucht.

beispielaufruf
Code:
	unsigned int adr_death = 0x0000;
	int death = 0;

	m_objFenster.MemoryRead(adr_death, death);
        return death;

funktion
Code:
template<class T>
void MemoryRead(unsigned int adress, T& buffer) {
        ReadProcessMemory(m_processHandle, (LPCVOID)adress, &buffer, sizeof(T), NULL);
}