Witam napisałem pewien program wysyla on dane do bazy mysql <czyta dane z adresów i wysyła> i problem tkwi w tym iż na windows 7 i vista wysyła on dane ale nie te co powinien dodam że na windows xp smiga u wszystkich proszę o jakieś podpowiedzi co robić z góry dziękuję.
masz błąd w 85 linii
Witam napisałem pewien program wysyla on dane do bazy mysql <czyta dane z adresów i wysyła>
Kod...
problem tkwi w tym iż na windows 7 i vista wysyła on dane ale nie te co powinien
kod......
dodam że na windows xp smiga u wszystkich
KOD!!! Jak mamy Ci pomóc, skoro nie dajesz nam żadnych podstaw?!
niżej przedstawiam funkcje które istnieją w programie :
function GetModuleBaseAddress(ProcessID: Cardinal; MName: String): Pointer;
var
Modules : Array of HMODULE;
cbNeeded, i : Cardinal;
ModuleInfo : TModuleInfo;
ModuleName : Array[0..MAX_PATH] of Char;
PHandle : THandle;
begin
Result := nil;
SetLength(Modules, 1024);
PHandle := OpenProcess(PROCESS_QUERY_INFORMATION + PROCESS_VM_READ, False, ProcessID);
if (PHandle <> 0) then
begin
EnumProcessModules(PHandle, @Modules[0], 1024 * SizeOf(HMODULE), cbNeeded);
SetLength(Modules, cbNeeded div SizeOf(HMODULE));
for i := 0 to Length(Modules) - 1 do
begin
GetModuleBaseName(PHandle, Modules[i], ModuleName, SizeOf(ModuleName));
if AnsiCompareText(MName, ModuleName) = 0 then
begin
GetModuleInformation(PHandle, Modules[i], @ModuleInfo, SizeOf(ModuleInfo));
Result := ModuleInfo.lpBaseOfDll;
CloseHandle(PHandle);
Exit;
end;
end;
end;
end;
var
Form1: TForm1;
XXX : string;
const
dany1 = $949CFC;
dany 2 = $949D18;
procedure TForm1.Timer2Timer(Sender: TObject);
begin
edit1.text := MemReadString(dany1);
edit2.text := MemReadString(dany2);
end;
Sorry za post pod postem ale nie moge edytować, program ma za zadanie czytanie adresu +adres_bazowy i wysyłanie go na serwer na windows vista/7 program sie niby uruchamia ale wysyła różne dziwne rzeczy np. krzaki na xp wszystko chodzi jak powinno.
Jesteś normalnie pr0 7r4in3r0r h4x0r. Fajnie, że pokazałeś nam kod funkcji MemReadString
. Ja bym odczytanie stringa z danego adresu zrobił raczej tak jak poniżej. Wprawdzie string do 260 znaków, ale po co dłuższy. W ogóle po co czytać string w trainerze. Jeżeli trzeba znaleźć w pamięci jakiś ciąg bajtów to ja bym to zrobił kolejną funkcją, jak pokazałem poniżej.
function MemReadString(ProcessId, Address : DWORD) : string;
var
I : integer;
NB : LongWord;
HProcess : Cardinal;
Temp : array[1..MAX_PATH] of Byte;
begin
Result := '';
HProcess := OpenProcess(PROCESS_ALL_ACCESS, False, ProcessId);
if HProcess > 0 then
begin
ReadProcessMemory(HProcess, Ptr(Address), @Temp[1], Length(Temp), NB);
CloseHandle(HProcess);
for I := Low(Temp) to High(Temp) do
begin
if (Temp[I] < 32) then
begin
Break;
end;
Result := Result + Chr(Temp[i]);
end;
end;
end;
Wyszukiwanie tablicy bajtów w pamięci procesu:
type
TOnFindProc = procedure(FindedAddress : Cardinal);
//...
function FindBytesInMemory(APid : DWORD; RangeFrom, RangeTo : Cardinal;
ArrayOfBytes : array of Byte; OnFindProc : TOnFindProc;
StopAfterFirstFinding : boolean) : Cardinal;
const
BufferSize = 65535;
var
Found : boolean;
SizeOfArr : Byte;
HProcess : THandle;
X, Y, Addr : Cardinal;
BytesRead, BytesToRead : DWORD;
Buffer : array[0..BufferSize - 1] of Byte;
begin
Result := 0;
Found := False;
SizeOfArr := Length(ArrayOfBytes);
HProcess := OpenProcess(PROCESS_ALL_ACCESS, False, APid);
if (HProcess > 0) and (RangeFrom < RangeTo) then
begin
Addr := RangeFrom;
while Addr < RangeTo do
begin
BytesToRead := BufferSize;
if (RangeTo - Addr) < BytesToRead then
begin
BytesToRead := RangeTo - Addr;
end;
ReadProcessMemory(HProcess, Pointer(Addr), @Buffer[0], BytesToRead, BytesRead);
if BytesRead > 0 then
begin
for X := 0 to BytesRead - 1 do
begin
Found := True;
for Y := Low(ArrayOfBytes) to High(ArrayOfBytes) do
begin
if Buffer[X + Y] <> ArrayOfBytes[Y] then
begin
Found := False;
Break;
end;
end;
if Found then
begin
Result := Addr + X + Y - SizeOfArr;
if @OnFindProc <> nil then
begin
OnFindProc(Result);
end;
Break;
end;
end;
end;
Addr := Addr + BytesToRead;
if (Found) and (StopAfterFirstFinding) then
begin
Break;
end;
end;
CloseHandle(HProcess);
end;
end;
I nie raz pisałem trainery pod Windows 7, jeżeli wszystko jest napisane z głową oraz prawidłowo to nie ma znaczenia raczej czy trainer uruchamiany pod systemem XP czy nowszym (mogą być cyrki pod ósemką, bo tego nie mam jak sprawdzić). Wszystko powinno działać. Poza tym po co nam pokazać kluczowy kod do wysyłania danych na serwer. Według mnie masz taki błąd: Error #-69: TBrain not installed.
. I niewiele na to poradzimy.
Dobrze przedstawię dokładnie kod programu niżej ale pierw opisze jak on działa ... program ma za zadanie odczytywać stringi z gry z adresów podanych w moim programie do nich jest potrzebna funkcja base_adress i niżej podaje dokładnie jak to wykonuję :
w głównym var daję coś takiego :
var
Form1: TForm1;
SSS : string;
const
test = $949CFC;
test1 = $949D18;
Teraz funkcja która odpowiada za adresy bazowe :
function GetModuleBaseAddress(ProcessID: Cardinal; MName: String): Pointer;
var
Modules : Array of HMODULE;
cbNeeded, i : Cardinal;
ModuleInfo : TModuleInfo;
ModuleName : Array[0..MAX_PATH] of Char;
PHandle : THandle;
begin
Result := nil;
SetLength(Modules, 1024);
PHandle := OpenProcess(PROCESS_QUERY_INFORMATION + PROCESS_VM_READ, False, ProcessID);
if (PHandle <> 0) then
begin
EnumProcessModules(PHandle, @Modules[0], 1024 * SizeOf(HMODULE), cbNeeded); //Getting the enumeration of modules
SetLength(Modules, cbNeeded div SizeOf(HMODULE)); //Setting the number of modules
for i := 0 to Length(Modules) - 1 do //Start the loop
begin
GetModuleBaseName(PHandle, Modules[i], ModuleName, SizeOf(ModuleName)); //Getting the name of module
if AnsiCompareText(MName, ModuleName) = 0 then //If the module name match with the name of module we are looking for...
begin
GetModuleInformation(PHandle, Modules[i], @ModuleInfo, SizeOf(ModuleInfo)); //Get the information of module
Result := ModuleInfo.lpBaseOfDll; //Return the information we want (The image base address)
CloseHandle(PHandle);
Exit;
end;
end;
end;
end;
tutaj funkcja do czytania tych adresów
function MemReadString(Address: Integer): String;
var
NB : LongWord;
Temp : ARRAY [1..255] OF Byte;
I : Byte;
IDProcess, proc_ID : Cardinal;
begin
GetWindowThreadProcessID(FindWindow('TibiaClient', nil), @proc_ID);
IDProcess := OpenProcess(PROCESS_ALL_ACCESS, false, proc_ID);
ReadProcessMemory(IDProcess, Ptr(Address), @Temp[1], 255, NB);
for I := 1 to 255 do
begin
if ((Temp[i] = 0) or (Temp[i] = $0F)) then
Break;
Result := Result + Chr(Temp[i]);
end;
end;
function ReadMemInteger(Address: Cardinal): Cardinal; //Read adress:value
var
ProcId: Cardinal;
tProc: THandle;
NBR: Cardinal;
value:integer;
begin
GetWindowThreadProcessId(FindWindow('TibiaClient',Nil), @ProcId);
tProc:= OpenProcess(PROCESS_ALL_ACCESS, False, ProcId);
ReadProcessMemory(tProc, Ptr(Address), @value, 4, NBR);
CloseHandle(tProc);
Result:=value;
end;
i button odpowiadający za działanie całej aplikacji :
edit2.text := MemReadString(test);
edit3.text := MemReadString(test1);
Czyli co bym musiał tutaj zmodyfikować aby chodziło pod nowszymi systemami ? ten kod co podał olesio ? chodzi mi o to abym nie robił bałaganu tylko wkleił funkcję która jest tataj najbardziej potrzebna.
Nie gram w gimbusowe lame rpgi, więc nie mam pojęcia czy coś konkretnego pod tymi adresami jest. Sprawdziłeś to pod Cheat Engine wcześniej? Pod tymi adresami na pewno są stringi jakich oczekujesz? Kod niesformatowany i nie ma sprawdzania błędów. Sprawdź kod pod debuggerem albo od biedy zrób sobie MessageBoxa, który pokaże Ci co zwraca funkcja GetLastError
. Opis jej wyniku sprawdzisz na MSDNie. I będziesz wiedział czy nie ma żadnych błędów. Bo nie skąd mamy mieć jakieś pojęcie, czy takie okno istnieje i czy można się dostać do procesu. A i ja podałem Tobie gotową funkcję, której przekazujesz tylko PID procesu. Poza tym nigdzie nie widzę wykorzystania funkcj GetModuleBaseAddress
, którą nam wkleasz. I wypadało by według mnie najpierw ogarnąć podstawy języka tak w ogóle, a później brać się za zaawansowane rzeczy jak robienie trainerów i tym podobne.
Dobrze ale tutaj chodziło mi tylko o działanie aplikacji na windows vista i windows 7 :)
Mógłby ktoś pomóc ponieważ bardzo mi na tym zależy :(
a odpalałeś ją jako admin?
nie uruchamiałem jako administrator ponieważ to nie ma sensu chciałem aby aplikacja działała normalnie aby inni użytkownicy z tymi systemami mogli korzystać.
co nie ma sensu? Fakt, że nie możesz grzebać jednym programem w pamięci innego bez uprawnień admina? Bo dla mnie to ma bardzo duży sens...
Jak nie można jak można na xp normalnie działa, i co każdy będzie musiał odpalać program jako admin to będzie nie wygodne dla projektu :(
[ironia]Po kilkunastu latach w Windowsie zmienili coś oprócz interfejsu i podnieśli poziom bezpieczeństwa? No nie możliwe.[/ironia]
widzę, że rośnie nam następny super-hiper, wszystkowiedzący gimbus-programista... No i oczywiście pierwsze co zrobiłeś to poczytałeś opis używanych funkcji (w szczególności komentarze poniżej) http://msdn.microsoft.com/en-us/library/windows/desktop/ms680553(v=vs.85).aspx
Nie wiem jak, ale jeden typek ma napisaną jakąś funkcję i program działa na windows 7 bez uruchamiania jako administrator i wczytuje mu poprawnie dane :) Mógłby ktoś skleić mi to i pokazać działanie ?
No na pewno wujek google by mógł.
już wiem jak to zrobić potrzebuję tylko funkcję memreadstring na taki wzó :
function ReadMemInteger(PHandle: THandle; Address: Integer): Integer;
var
X, Buffer: Cardinal;
begin
// here we subtract 400000 from ADD_BASE and add our address.
ReadProcessMemory(PHandle, Pointer(Integer(ADDR_BASE) - $400000 + Integer(Address)), Addr(Buffer), 4, X);
Result := Buffer;
end;
chodzi mi o memreadstring z tą linijką :
ReadProcessMemory(PHandle, Pointer(Integer(ADDR_BASE) - $400000 + Integer(Address)), Addr(Buffer), 4, X);
Zobacz sobie pod LordPE
czy innym tego typu narzędziem jaki jest ImageBase
dla procesu ktory trainujesz. Dodaj sobie swoj offset do tej wartości i na niej operuj. Poza tym funkcje (Read/Write)ProcessMemory
powinny działać nawet na Windows 7 czy Vista z włączonym UAC. O ile oczywiście proces jak i obszar pamięci, na którym operują to umożłiwia. Jeszcze raz powtórze. Jeżeli chcesz operować na adresie, który Cheat Engine podaje jako na przykład jakas_gibus_game.exe+C0D3
to znaczy, że trzeba albo dodać do adresu po znaku plusa, ten tak zwany ImageBase
albo go pobrać tą funkcją jaką podałeś. Jeżeli pod Cheat Engine dany adres pokazuje Tobie(najlepiej to widać w narzędziu Memory View
) prawidłowe dane, których oczekujesz i można je poza odczytem zmieniać, to znaczy że Twój program też powinien móc to zrobić.
adresy wyglądają tak :
var
ADDR: Integer = $941000;
i mam tutaj takie uzycie:
procedure TForm1.Button1Click(Sender: TObject);
var
WHandle: HWND;
ProcessID : Cardinal;
PHandle: THandle;
exp: integer;
hp: integer;
begin
WHandle := FindWindow('TibiaClient', nil);
GetWindowThreadProcessId(WHandle, @ProcessID);
ADDR_BASE := GetModuleBaseAddress(ProcessID, 'Tibia.exe');
PHandle := OpenProcess(PROCESS_VM_READ, False, ProcessID);
// Here we do the XOR stuff
hp := ReadMemInteger(PHandle, ADDR_HP) xor ReadMemInteger(PHandle, ADDR_XOR);
ShowMessage(inttostr(hp));
end;
Tylko że to pokazuje liczbowe a mi chodzi o zwykły tekst/string ale nie wiem jak to przerobić jak pokazałem wyżej do tego ReadMemInteger jest taka funkcja
function ReadMemInteger(PHandle: THandle; Address: Integer): Integer;
var
X, Buffer: Cardinal;
begin
// here we subtract 400000 from ADD_BASE and add our address.
ReadProcessMemory(PHandle, Pointer(Integer(ADDR_BASE) - $400000 + Integer(Address)), Addr(Buffer), 4, X);
Result := Buffer;
end;
Funkcję na pokazywanie tekstu z pod adresu pokazałem Tobie w pierwszej mojej odpowiedzi w tym wątku. Zresztą podobną już pokazywałeś sam wklejając jej kod. Ja przede wszystkim upewnił się co pod danym adresem widać w programie Cheat Engine
. Natomiast jeżeli nawet nie umiesz zastosować gotowej funkcji, to ja nic na to Ci nie poradzę. Trzeba wtedy raczej zacząć od nauki podstaw języka, a nie brać się za pisanie trainera.
Olesio podałeś mi funkcję czytania tekstu ale chodzi mi o zastosowanie tej funkcji przy czytaniu base adress tak jak tutaj funkcja czytania liczby :
function ReadMemInteger(PHandle: THandle; Address: Integer): Integer;
var
X, Buffer: Cardinal;
begin
// here we subtract 400000 from ADD_BASE and add our address.
ReadProcessMemory(PHandle, Pointer(Integer(ADDR_BASE) - $400000 + Integer(Address)), Addr(Buffer), 4, X);
Result := Buffer;
end;
Spójrz tutaj :
ReadProcessMemory(PHandle, Pointer(Integer(ADDR_BASE) - $400000 + Integer(Address)), Addr(Buffer), 4, X);
w tym urywku jest dodane (ADDR_BASE) a w tej funkcji do czytania tekstu co podałeś nie ma nic o base adresie :D
Olesio mógłbyś pomóc będę bardzo wdzięczny.
Ja pie... prze. Normalnie wszystko co może opada. Ja rozumiem dział Newbie, ale być tak ogaraniczonym. Czego nie rozumiesz? Funkcja ma dwa parametry. Jako PID podajesz identyfikator procesu, który możesz pobrać na przykład tak GetWindowThreadProcessId(UchwytDoOknaTenToJuzMaszChybaPrzezFindWIndow, ZmiennaTypuDWordKtoraZwrociTenPid);
, a jako adres podajesz adres. Ustal sobie pod Cheat Engine czy to ma być bazowy jak na przykład gimbus_game.exe+31337
czy jakiś inny konkretny. Kur... de. Przecież adres to adres. Pisałem już jeżeli jest bazowy to sobie ustal ImageBase
programem LordPE, ktory to już sam sobie musisz wygooglować. I do niego dodaj adres pod którym masz żądaną wartośc. Czyli dla wpisu w Cheat Engine gimbus_game.exe+31337
będzie to 31337 szesnastkowo. Robisz sobie ze mnie/nas jaja czy co? Pisałem, najpierw ogarnj podstawy. Obejrzyj tutoriale Gynvaela Coldwina na YouTube o tym jak mają się kwestie pamięci i procesu PE, napisz kilka programów typu Hello World
. Ogólnie ogarnij jakiś kurs z podstawami Delphi, a dopiero później bierz się za trainery. Ponieważ teraz to się uczepiłeś tego adresu bazowego
, który jeszcze masz w przykładzie ustalany w jakiś dziwny sposób przez odejmowanie. I masz klapki na oczach, wyłączając swój TBrain oraz ignorując wszelkie wcześniejsze moje wyjaśnienia i kody. Jeżeli wszystko zrobisz jak należy to pod danym adresem otrzymasz to samo co w Cheat Engine. Jeżeli nadal się motasz, to ja nie jestem w stanie Tobie pomóc. Otrzymałeś i tak już wystarczająco dużo info.
Ja proponuję dodanie do regulaminu: zakaz pytania o mody do Tibii.
:-)
Program odejmuje te -40000 czy jakoś tak bo musi ;p dokładnie tutaj jest opisana ta funkcja http://tpforums.org/forum/thread-9448.html
tylko że tam jest podane jak czytać życie postaci czyli liczbe a mi tylko chodziło o zastosowanie tego na tekstach .. ;/
Jak umiesz odczytać 4 bajty to nie potrafisz sobie przerobić, aby czytało bajty do napotkania terminatora? Czy nie wiem w czym tam pisana jest gra i jak reprezentowane są stringi. Nie znasz podstaw a zabierasz się za zaawansowane aspekty programowania - brak słów.
programm323r napisał(a):
Program odejmuje te -40000 czy jakoś tak bo musi (...) http://tpforums.org/forum/thread-9448.html
Czyli po prostu bez zrozumienia kopiujesz kod z tamtego forum? Może daruj sobie to pisanie w takim razie, bo to nie ma sensu z takim podejściem.
@programm323r: skoro wiesz lepiej co kod musi, to po co w ogóle nas pytasz? Wedle mnie bez sensu jest odejmowanie $400000 od adresu bazowego. Raczej do tego adresu bazowego należało by dodać jakąś inną wartość, skoro adres bazowy nie wynosi $400000 (tyle zwykle wynosi w wielu procesach, ale oczywiśćie nie we wszystkich, stąd potrzeba jego ustalenia dla tego procesu). A przede wszystkim ja robil bym tak, jak napisałem. Sprawdzil ImageBase pod LordemPE i co w ogołe mi pokazuje Cheat Engine, ale Ty rób po swojemu, jak uważasz. Tylko przydało by się znać i podstawy. Na tamtym forum widzę zupełnie inny sposób (dość logiczny oraz według mnie prawidłowy) ustalania tego ImageBase, przeznaczoną do tego funkcją.