Autor Beitrag
aksdb
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 29
Erhaltene Danke: 1

Windows 7, ArchLinux
D7 Prof, Kylix 3, Lazarus
BeitragVerfasst: Do 23.12.04 19:37 
Hallo,

ich stehe momentan vor einem Problem, das mir langsam sämtliche Nerven raubt. Ich den im Menü angezeigten Versions-String von Ultima Online zu verändern, um sicherzustellen, dass es von meinem Loader aus gestartet wurde und nicht über anklicken der Exe.

Dazu gab es eine wunderschöne Library, welche sowohl die Verschlüsselung aus UO entfernte, wie auch eine "Inject" Methode zur Verfügung stellte, die meine DLL Aufruft, um dann den Versions-String zu verändern. Das funktioniert soweit super, doch klappt das ganze nicht unter Windows 9x. Dort wird die DLL gar nicht erst aufgerufen - warum auch immer. Nun war mein Gedanke - warum nicht, wie jeder GameTrainer auch, einfach den Speicher von meinem Programm aus verändern. Das habe ich bisher nicht ohne AccessViolations hinbekommen ... oder anders gesagt: Ich habt keine Ahnung wie!

Von der DLL aus habe ich das bisher folgendermaßen gemacht:
ausblenden volle Höhe Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
procedure InjectVersion;
const
  local_version = ' - MyString';
  s_ver = '%d.%d.%d%s';
  len_ver = 10;
var
  Process: THandle;
  P: PChar;
  ModInfo: ModuleInfo;
  OldProtect, VerFormat: LongWord;
  Buf: PByteArray;
  i: Integer;
begin
  Process := GetCurrentProcess;
  if not (Process < HINSTANCE_ERROR) then
  begin
    GetModuleInformation(Process, GetModuleHandle(nil), @ModInfo, SizeOf(ModInfo));
    VirtualProtect(ModInfo.lpBaseOfDll, ModInfo.SizeOfImage, PAGE_EXECUTE_READWRITE, OldProtect);
    Buf := ModInfo.lpBaseOfDll;

    VerFormat := 0;
    for i := 0 to ModInfo.SizeOfImage - 200 do
    begin
      if (VerFormat = 0and CompareMem(@(buf[i]), PChar(s_ver), len_ver) then
      begin
        VerFormat := i;
        break;
      end;
    end;

    if VerFormat > 0 then
    begin
      P := local_version;
      CopyMemory(@buf[VerFormat + 12], P, Length(local_version));
    end;
  end;
end;


Das hat wie gesagt Funktioniert - doch wie soll ich das von außerhalb des Prozesses machen? (Und bitte - es soll sowohl unter Windows NT wie auch Windows 9x funktionieren!)

P.S.: Ich weiss von ReadProcessMemory und WriteProcessMemory, doch das waren eben die Funktionen, bei denen ich nicht weiter als bis zu einer Access Violation gekommen bin. Also wenn das die einzige Möglichkeit ist, dann schreibt mir bitte auch, wie ich damit den GESAMTEN Speicher des Prozesses nach dem gesuchten String durchsuche.

Ich hoffe jemand kann mir weiterhelfen! Danke.

Moderiert von user profile iconChristian S.: Code- durch Delphi-Tags ersetzt.
Moderiert von user profile iconTino: Überflüssige Absätze entfernt.
Luckie
Ehemaliges Mitglied
Erhaltene Danke: 1



BeitragVerfasst: Do 23.12.04 19:53 
Eventuell liegt es daran:
Zitat:

Windows Me/98/95: You cannot use VirtualProtect on any memory region located in the shared virtual address space (from 0x80000000 through 0xBFFFFFFF).
aksdb Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 29
Erhaltene Danke: 1

Windows 7, ArchLinux
D7 Prof, Kylix 3, Lazarus
BeitragVerfasst: Do 23.12.04 20:04 
Danke für die schnelle Antwort, und auch Danke an den Mod für's Ändern von "Code" nach "Delphi" - hatte ich wohl irgendwie übersehen ... :roll:

Luckie hat folgendes geschrieben:
Eventuell liegt es daran:
Zitat:

Windows Me/98/95: You cannot use VirtualProtect on any memory region located in the shared virtual address space (from 0x80000000 through 0xBFFFFFFF).


Naja die Funktion wie ich sie gepostet habe, ruft ja erst ab, wo der Prozess im Speicher überhaupt erst liegt. Demzufolge habe ich ja dort darauf verzichtet, den Speicher komplett zu durchforsten. Wie gesagt - das Problem bestand mehr darin, dass besagte DLL unter Windows 9x nicht im Stande ist, fremden Code in den Prozess von Ultima Online zu injizieren (warum auch immer ... habe den Autor bisher nicht kontaktiert). Daher wollte ich ja von aussen auf den Prozess selbst zugreifen (über OpenProcess) und dann "einfach" manuell den String darin suchen. Nur weiss ich eben nicht, wie
ich das bewerkstelligen soll.

Moderiert von user profile iconTino: Überflüssige Absätze entfernt.
EUOCheffe
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 124



BeitragVerfasst: Mo 27.12.04 18:34 
Hmmm, das mit dem Versionsstring ist eine gute Idee. Werd ich dann in EasyUO auch noch einbauen, dass man nach einem benutzerdefinierten Versionsstring suchen kann. Danke für den Hinweis :)

Hehe, bin mir sicher, dass du was passendes findest. Sollte nicht allzu schwer sein, deinen Freeshard zu schützen. Nur den Code musst du dazu halt selber schreiben.
aksdb Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 29
Erhaltene Danke: 1

Windows 7, ArchLinux
D7 Prof, Kylix 3, Lazarus
BeitragVerfasst: Do 30.12.04 16:17 
EUOCheffe hat folgendes geschrieben:
Hmmm, das mit dem Versionsstring ist eine gute Idee. Werd ich dann in EasyUO auch noch einbauen, dass man nach einem benutzerdefinierten Versionsstring suchen kann. Danke für den Hinweis :)

Hehe, bin mir sicher, dass du was passendes findest. Sollte nicht allzu schwer sein, deinen Freeshard zu schützen. Nur den Code musst du dazu halt selber schreiben.


Öhm ja den Code hab ich quasi ja schon da oben - mir gehts nur drum, dass das gleiche nich funzt, sobald ich AUSSERHALB des Prozesses bin. Darum ja mein Anfrage hier, ob mir da jemand helfen kann ;-)
Außerdem will ich meinen FreeShard nich gegen Makro-Tools schützen (auch wenns ein positiver Nebeneffekt gewesen wäre), sondern ich will verhindern, dass ein paar Player ankommen und meinen "Hey, da is ja gar kein Haus" und ich denen erst zig mal erklären muss, dass sie zu blöd sind die Regeln etc. zu lesen und meinen Loader (=Updater) nutzen müssen. So käme gleich beim connecten die Meldung, dass sie nicht über den Updater gestartet haben und werden gleich wieder gekickt. ;)