2017-01-27 1 views
1

Ich arbeite an einer Videospiel-Cheat-Engine mit einfacher Speichermanipulation, um das Ziel zu erreichen. Ich war erfolgreich in der Lage, ein Stück Code zu schreiben, der den Speicher eines Prozesses in ein Byte [] ablegt und über diese Arrays bei der Suche nach der gewünschten Zeichenkette iteriert. Das Stück Code, das sucht ist somit:Wie finde ich Strings in einem Speicher-Dump-Byte-Array in UTF8-codierte Zeichenfolge konvertiert?

public bool FindString(byte[] bytes, string pName, long offset) 
    { 
     string s = System.Text.Encoding.UTF8.GetString(bytes); 
     var match = Regex.Match(s, "test"); 
     if (match.Success) 
      return true; 
     return false; 
    } 

ich dann eine 32-Bit-Version von Notepad öffnen (denn das ist, was mein Dumpingverfahren für konditioniert) und das Wort „test“ in sie und führen Sie geben mein Programm im Debug-Modus, um zu sehen, ob die Bedingung jemals getroffen wurde. Es tut nicht.

Bei einer weiteren Inspektion ich den Inhalt der Zeichenfolge ‚s‘ Besuche auf einem der Iterationen, es ist so:

\0\0\0\0\0\0\0\0���\f\0\u0001����\u0001\0\0\0 \u0001�\0\0\0\0\0   \u0001�\0\0\0\0\0\0\0�\0\0\0\0\0\0\0�\0\0\0\0\0\u0010\0\0\0\0\0\0\0 \a�\0\0\0\0\0\0\0�\0\0\0\0\0\u000f\0\0\0\u0001\0\0\0\0\0\0\0\0\0\0\0�\u000f�\0\0\0\0\0�\u000f�\0\0\0\0\0\0�\0\0\0\0\0\0\0\0\0\0\0\0\u0010\0\0\0\0\0\0\0\0\0����\f\0\0\0\0\0\0\0�\0\0����\0\0\0\0\0\0\u0010\0\0\0\0\0\0 \0\0\0\0\0\0\0\u0001\0\0\0\0\0\0\0\u0010\0\0\0\0\0\0�\0\0\0\0\0\0\0�����\u007f\0\0\u0002\0�\u0002\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0�\u000f�\0\0\0\0\0�\u000f�\0\0\0\0\0\u001f\0\0\0\0\0\0\0��������\u0010\u0001�\0\0\0\0\0\u0010\u0001�\0\0\0\0\0\u0018\0�\0\0\0\0\0\u0018\0�\0\0\0\0\0\0\0\0\0\0\0\0\0�\u0002�\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\00\a�\0\0\0\0\00\a�\0\0\0\0\0�\u0002�\0\0\0\0\0�M�^\u000e\u000e_\u007f\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\u0001\0\0\0\0\0\0\u0010\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\u0001\0\0\0\u0001\0\0\0\0\0\0\0\0\0\0\0\b\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\u0001\0\0\0\b\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0`\a\0\0\0\0\0\0`\a\0\0\0\0\0\0\u0004\0\0\0\0\0\0\0\0�\u001f\0\0\0\0\0�\u001d\u0014)�\u007f\0\0����\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0�\a\0\u0002\0\0\0\0\0\0\0\0\0\0\0\0�\0\0\0\0\0\0\0\u0001\0\0\0\u0001\0\0\0\0\0\0\0\0\0\0\0P\u0001�\0\0\0\0\0\0\u0003�\0\0\0\0\0\u0010\u0003�\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0� 

ich jedes Pass-Through dieser Methode für den ‚s‘ Variable überprüfen fortgesetzt und stellte fest, dass ich in diesem Format keine Zeichenfolgen sehen konnte.

Meine Frage ist einfach. Was mache ich falsch, dass ich diese Saite nicht finden kann? Das Dumping ist erfolgreich, aber etwas, das mit meiner Methode des Parsens zu tun hat, bereitet mir Probleme.

UPDATE (Code für Speicher Dumping)

void ScanProcess(Process process) 
    { 
     // getting minimum & maximum address 
     var sys_info = new SYSTEM_INFO(); 
     GetSystemInfo(out sys_info); 
     var proc_min_address = sys_info.minimumApplicationAddress; 
     var proc_max_address = sys_info.maximumApplicationAddress; 
     var proc_min_address_l = (long)proc_min_address; 
     var proc_max_address_l = (long)proc_max_address; 

     //Opening the process with desired access level 
     var processHandle = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_WM_READ, false, process.Id); 
     var mem_basic_info = new MEMORY_BASIC_INFORMATION(); 
     var bytesRead = 0; // number of bytes read with ReadProcessMemory 

     while (proc_min_address_l < proc_max_address_l) 
     { 
      VirtualQueryEx(processHandle, proc_min_address, out mem_basic_info, 28); //28 = sizeof(MEMORY_BASIC_INFORMATION) 

      //If this memory chunk is accessible 
      if (mem_basic_info.Protect == PAGE_READWRITE && mem_basic_info.State == MEM_COMMIT) 
      { 
       //Read everything into a buffer 
       byte[] buffer = new byte[mem_basic_info.RegionSize]; 
       ReadProcessMemory((int)processHandle, mem_basic_info.BaseAddress, buffer, mem_basic_info.RegionSize, ref bytesRead); 

       var MemScanner = new MemScan(); 
       Memscanner.FindString(buffer, process.ProcessName, proc_max_address_l); 
      } 

      // move to the next memory chunk 
      proc_min_address_l += mem_basic_info.RegionSize; 
      proc_min_address = new IntPtr(proc_min_address_l); 

      if (mem_basic_info.RegionSize == 0) 
      { 
       break; 
       mem_basic_info.RegionSize = 4096; 
      } 
     } 
    } 
+1

Nun, vielleicht ist das Problem nicht mit dem _searching_, sondern mit dem _dumping und dem anschließenden Laden des besagten Dump_? – MickyD

+1

Mit dem Dump-Code aktualisiert. Es ist eine ziemlich normale Methode, die herumschwebt. –

+1

Danke für das Update – MickyD

Antwort

-1

Für den Anfang nicht Notizbuch verwenden können (oder jede nichtbinäres fähig Betrachtungswerkzeug an Ihren Bytes zu sehen).

Sie müssen die BitConverter APIs verwenden:

https://msdn.microsoft.com/en-us/library/system.bitconverter(v=vs.110).aspx

... die Daten zu gehen und komponieren/die Daten suchen, um zu finden, was Sie suchen (wobei, was Codierung Sie die Daten abgeladen im Sinn).

BTW - Hier ist eine nützliche HexEditor:

+1

_ "Für den Anfang können Sie nicht NotePad (oder jedes nicht-binäre fähige Anzeigewerkzeug verwenden, um Ihre Bytes zu sehen)." _ - OP versucht nicht, _binare Inhalt in NotePad_ zu sehen, eher er benutzt es Als Testbed für das Auslösen, wenn das Wort _test_ _ im Speicher erscheint, wie wenn das Wort test in _NotePad_ – MickyD

0

Ich weiß nicht, was MemScan.FindString() tut, aber ich denke, das Problem ist, dass Sie eine Zeichenfolge für eine Zeichenfolge suchen, anstatt für ein Byte-Array in einem Byte Array.

Indem Sie den Speicherinhalt mit System.Text.Encoding.UTF8.GetString(bytes); transformieren, nehmen Sie an, dass alles, was im Speicher gespeichert ist, als gültige UTF8-Codierung interpretiert werden kann.

Ihr FindString() muss Parameter wie byte[] anstelle von string akzeptieren, und Sie müssen herausfinden, wie der Prozessname im Speicher gespeichert wird (höchstwahrscheinlich UTF-16).

+0

FindString eingegeben wird, wird in diesem Beitrag oben definiert, und akzeptiert Bytearrays. –

+0

Oh, ich habe das übersehen. Dennoch bleibt die Frage, wie der Prozessname im Speicher codiert ist, und Sie müssen auf Byte-Ebene suchen, nicht nach Zeichenfolgen. Siehe http://stackoverflow.com/questions/4859023 – devio

Verwandte Themen