Für alle die einen Purebasic Code zur Orientierung brauchen: Modul und Offsets werden mit Cheatengine erstellt. Beispielprogramm hier ist Fishing Planet.
Code:
;Es braucht die Funktion CreateToolhelp32Snapshot() aus der kernler32.dll
Global kernel32=OpenLibrary(#PB_Any, "kernel32.dll")
;Prozdur liefert den Basepointer (Trampolin) des Moduls.
;Die ProcessID muss via GetWindowThreadProcessId_ vorher gefunden werden.
;Modulname ist einfach die dll (z.b. "mono.dll")
;Module sind nur nötig wenn die pointer aus der exe rausgehen
Procedure.i GetModule(ProcessId.l, ModuleName.s)
;Handle für externen Prozess
Protected snapShot.i
;Struktur für die Eigenschaften eines Moduls
Protected Me32.MODULEENTRY32
;Wenn die Library "kernel32.dll" geladen wurden
If kernel32
;Rufe die Funktion ToolHelp mit der ProcessID auf. Gibt den Handle auf die Module der ProcessID
snapShot=CallFunction(kernel32, "CreateToolhelp32Snapshot", #TH32CS_SNAPMODULE, ProcessId)
;falls erfolgreich
If snapShot
;Bereite eine Struktur des Typs Moduleentry32 vor um die einzelnen Module nacheinander da reinzuschreiben
;Die Größe der Struktur wird in der Struktur festgehalten (Windows-eigen)
Me32\dwSize=SizeOf(MODULEENTRY32)
;Belade die Struktur mit dem ersten Modul des Prozesses
If CallFunction(kernel32, "Module32First", snapShot, [MENTION=321286]me3[/MENTION]2)
;Werte den Modulnamen aus
Repeat
;Lese String aus dem Speicherbereich Me32\szModule bis zur Nullterminierung (-1) aks ASCCI
Protected moduleName$=PeekS [MENTION=321286]me3[/MENTION]2\szModule, -1, #PB_Ascii)
;Ist der String der gesuchten Modulnamen?
If moduleName$=ModuleName
;Falls ja, abbruch und Baseaddresse aus der Struktur auslesen und returnen
ProcedureReturn Me32\modBaseAddr
EndIf
;Sonst: Nächstes Modul bis es kein Nächstes mehr gibt.
Until Not CallFunction(kernel32, "Module32Next", snapShot, [MENTION=321286]me3[/MENTION]2)
EndIf
;Alle Module wurden durchsucht / es wurde das richtige gefunden. Jetzt den Funktionshandle freigaben (max 4048 pro Programm)
CloseHandle_(snapShot)
EndIf
EndIf
;Wenn oben keine Baseadresse ermittelt werden konnte, gebe Null zurück
ProcedureReturn 0
EndProcedure
Procedure.l GefangeneFische(hProcess,ProcessId) ;geht nimmer
;Wenn nötig gehe die Module dieser ProcessID nach einen speziellen Modul durch und ermittle die Startadresse dafür
*moduleAddress=GetModule(ProcessId, "mono.dll")
;Erstelle eine 8-Byte-Variable für Pointer. Die Pointer liegen im Speicher als little-endian vor (Intel).
ergebnis.q
;Lese mit dem Lese/Schreib-Handle von der Moduladresse + Offset und schreibe in die Adresse von Ergebnis alle 8 Byte.
;Die Erfolgsmeldung wird nicht verarbeitet. Die Anzahl der gelesenen Bytes wird ignoriert.
ReadProcessMemory_(hProcess, *moduleAddress+$00500AC8 , [MENTION=2472835]Erge[/MENTION]bnis, 8, #IGNORE)
;Der Ermittelte Pointer wird nun um ein neuen Offsete erhöht und selbst wieder als Zieladresse verwendet.
ReadProcessMemory_(hProcess, ergebnis+$20 , [MENTION=2472835]Erge[/MENTION]bnis, 8, #IGNORE)
ReadProcessMemory_(hProcess, ergebnis+$640 , [MENTION=2472835]Erge[/MENTION]bnis, 8, #IGNORE)
ReadProcessMemory_(hProcess, ergebnis+$0 , [MENTION=2472835]Erge[/MENTION]bnis, 8, #IGNORE)
ReadProcessMemory_(hProcess, ergebnis+$48 , [MENTION=2472835]Erge[/MENTION]bnis, 8, #IGNORE)
ReadProcessMemory_(hProcess, ergebnis+$E0 , [MENTION=2472835]Erge[/MENTION]bnis, 8, #IGNORE)
ReadProcessMemory_(hProcess, ergebnis+$10 , [MENTION=2472835]Erge[/MENTION]bnis, 8, #IGNORE)
ReadProcessMemory_(hProcess, ergebnis+$18 , [MENTION=2472835]Erge[/MENTION]bnis, 8, #IGNORE)
;Solange bis laut CheatEngine das Ergebnis erreicht wurde
;Je nach Ergebnis müssen mehrere Bytes(vorsicht: little endian) aus dem Speicher gelesen werden
;Laut CheatEngine ist das Ergebnis ein 4-Byte Wert. Bei Purebasicx64 sind Integer aber 8 Bytes lang.
;Daher wird das ergebnis als long, also mit 4 byte gelesen
Schnur.l = PeekL [MENTION=2472835]Erge[/MENTION]bnis)
ProcedureReturn Schnur
EndProcedure
;Besorge den Handle der Execuatable aus dem Speicher
Window = FindWindow_(0,"Fishing Planet")
;Wenn der Handle gefunden wurde
If Window <> #Null
;Besorge die dazugehörige ProcessID
GetWindowThreadProcessId_(Window, [MENTION=2699288]Process[/MENTION]ID)
;Besorge einen Handle(hProcess) mit Lese/Schreibzugriff auf diese ProcessID
hProcess = OpenProcess_(#PROCESS_ALL_ACCESS, 0, ProcessID)
Debug GefangeneFische(hProcess,ProcessId)
EndIf
;Unnötig aber sauber: zum Schluss wird auch der Handle auf die kernel32.dll wieder freigegeben
CloseLibrary(kernel32)
Der Code wurde leider irgendwie anstelle der @ Zeichen ersetzt. Im Anhang ist die Orginalfassung.
[TuT]Eigene Programme erstellen mit PureBasic 10/16/2010 - Coding Tutorials - 1 Replies Hallo,
hier lernst du, wie man selbst Programme mit PureBasic programmiert.
Zuerst willst du natärlich wissen, in welcher Programmiersprache sich
dieses Tutorial hier abspielt, oder irre ich mich?
Nun, hier lernst du, wie du mit PureBasic programmierst.
PureBasic (im Folgenden mit PB abgekärzt) ist eine an sich sehr gänstige,
und vor allem sehr einfache Sprache, da es ein Basic-Dialekt ist. Basic
zählt zu den einfachsten Programmiersprachen. Urspränglich wurde PB zwar nur fär Spiele...