Autor Beitrag
TmpDir
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 53
Erhaltene Danke: 3

Win7HP Win8.1 Deb/Ubuntu
C# [Delphi 6 Pro, Delphi 2005 PE, TurboDelphi PE]
BeitragVerfasst: Do 23.02.06 18:34 
Hi,

ich wollte mit folgender Routine den Speicher in einem Process nach einem String durchsuchen. Jedoch zeigen die Fehlermeldungen von GetLastError (dir Memo1.lines.add Zeilen) immer eine Fehlermeldung beim Zugriff auf den Speicher des Process an.
z.B.:
Addr:PageSize:ErrorMessage
05C38000:00009000:Only part of a ReadProcessMemory or WriteProcessMemory request was completed
05C43000:00012000:Access is denied (und diese Zeile wird fast bei jeder Page ausgegeben)

Mit VirtualProtectEX komme ich leider auch nicht weiter, da die Fehlermeldungen beim ReadProcessMemory immer noch die selben sind.
Auch gibt es ein Problem bei SetLength(ByteContent, SysInfo.RegionSize);
benutze um die ByteArray Größe zu bestimmen. Ich hatte mal am Anfang an Stelle des ByteConten einen WideString, was aber auch nicht geklappt hat.

Wo könnte denn an dieser Procedure das Hauptproblem mit dem Acces is denied behoben werden???

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:
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
procedure SearchInMemory(PID: Cardinal; sSearchString: WideString);
var
  hProcess : Cardinal;
  MemBasicInfo : TMemoryBasicInformation;
  SysInfo : TSystemInfo;
  lpMinAddr: Pointer;
  ret : DWORD;
  sBuffer : WideString;
  lpReadBytes : DWORD;
  lPos        : Integer;
  CalcAddress : DWORD;
  ByteContent : array of Byte;
  lpOldProtect: Cardinal;
begin
  hProcess := OpenProcess(PROCESS_ALL_ACCESS, false, PID);
//  form1.Memo1.Lines.Add('OpenProcess:'+SysErrorMessage(GetLastError));

  GetSystemInfo(SysInfo);
  lpMinAddr := SysInfo.lpMinimumApplicationAddress;
  //  VirtualProtectEx(hProcess,lpMinAddr,MemBasicInfo.RegionSize, PAGE_READWRITE, lpOldProtect);

  while Cardinal(lpMinAddr) < Cardinal(SysInfo.lpMaximumApplicationAddress) do
  begin
    ret := VirtualQueryEx(hProcess, lpMinAddr, MemBasicInfo, SizeOf(MemBasicInfo));
    SetLength(ByteContent, SysInfo.RegionSize);

    if ret = SizeOf(MemBasicInfo) then
      if (MemBasicInfo.State  = MEM_COMMIT)  THEN
      begin
        ReadProcessMemory(hProcess, lpMinAddr, @ByteContent[0],High(ByteContent), lpReadBytes);
        form1.Memo1.Lines.Add(IntToHex(cardinal(lpMinAddr),8)
                +':'+IntToHex(cardinal(MemBasicInfo.RegionSize),8)
                +':'+SysErrorMessage(GetLastError));
        lPos := Pos(sSearchString, sBuffer);
        if lPos > 0 then
        begin
          CalcAddress := Cardinal(lpMinAddr) + lPos;
          Form1.Memo1.Lines.Add(inttohex(CalcAddress,8));
        end;
      end;
    lpMinAddr := Ptr(Cardinal(MemBasicInfo.BaseAddress)+MemBasicInfo.RegionSize);
  end;

// DebugActiveProcessStop(hProcess);
 Form1.Memo1.Lines.Add('fin');
 CloseHandle(hProcess);
end;
TmpDir Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 53
Erhaltene Danke: 3

Win7HP Win8.1 Deb/Ubuntu
C# [Delphi 6 Pro, Delphi 2005 PE, TurboDelphi PE]
BeitragVerfasst: Fr 24.02.06 10:34 
Ich hab das VirtualProtectEx mal in die while-Schleife gepackt. Das ByteArray empfängt auch Daten, aber es werden immer noch Fehlermeldungen von GetLastError zurückgegeben.

mfg
Luckie
Ehemaliges Mitglied
Erhaltene Danke: 1



BeitragVerfasst: Fr 24.02.06 11:08 
user profile iconTmpDir hat folgendes geschrieben:
aber es werden immer noch Fehlermeldungen von GetLastError zurückgegeben.

Und die wären? :roll:
TmpDir Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 53
Erhaltene Danke: 3

Win7HP Win8.1 Deb/Ubuntu
C# [Delphi 6 Pro, Delphi 2005 PE, TurboDelphi PE]
BeitragVerfasst: Fr 24.02.06 11:29 
Die Fehlermeldungen sind im ersten Post beschrieben.

Hab jetzt aber gefunden woran es lag. Hier mal die Procedure mit einem WideString als Buffer. Beim ByteArray müsste es der selbe Fehler gewesen sein. Ich hatte beim ReadProcessmemory leider immer die Größenangabe des Typs überschrieben. :oops:
Und nicht über die komische Schreibweise für die Pointeradresse wundern. In der Online Doku steht zwar das Pointer + Integer eine gültige Operation ist, was aber beim mir (D6pro) nicht funktioniert. :x

Jetzt kommt auch ein 'Operation completed successfully' als GetLastError.

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:
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
48:
procedure SearchInMemory(PID: Cardinal; sSearchString: WideString);
var
  hProcess : Cardinal;
  MemBasicInfo : TMemoryBasicInformation;
  SysInfo : TSystemInfo;
  lpMinAddr: Pointer;
  ret : DWORD;
  sBuffer : WideString;
  lpReadBytes : DWORD;
  lPos        : Integer;
  CalcAddress : DWORD;
  ByteContent : array of Byte;
  lpOldProtect: Cardinal;
  i : Integer;
  cmpstring : widestring;

begin
  hProcess := OpenProcess(PROCESS_ALL_ACCESS, false, PID);
  GetSystemInfo(SysInfo);
  lpMinAddr := SysInfo.lpMinimumApplicationAddress;

  while Cardinal(lpMinAddr) < Cardinal(SysInfo.lpMaximumApplicationAddress) do
  begin
    Application.ProcessMessages;
    ret := VirtualQueryEx(hProcess, lpMinAddr, MemBasicInfo, SizeOf(MemBasicInfo));
    VirtualProtectEx(hProcess,lpMinAddr,MemBasicInfo.RegionSize, PAGE_READWRITE, lpOldProtect);
    SetLength(sBuffer, MemBasicInfo.RegionSize);
    if ret = SizeOf(MemBasicInfo) then
      if  ((MemBasicInfo.Type_9 = MEM_PRIVATE) Or
          (MemBasicInfo.Type_9 = MEM_MAPPED) OR
          (MemBasicInfo.Type_9 = MEM_IMAGE)) AND
          (MemBasicInfo.State  = MEM_COMMIT)  THEN
      begin
        ReadProcessMemory(hProcess, lpMinAddr,@sBuffer[1],MemBasicInfo.RegionSize, lpReadBytes);

        if pos(sBuffer,sSearchString) > 0 then
            begin
              CalcAddress := Cardinal(lpMinAddr) + pos(sBuffer,sSearchString);
              Form1.Memo1.Lines.Add(inttohex(CalcAddress,8));
            end;

      end;
    VirtualProtectEx(hProcess,lpMinAddr,MemBasicInfo.RegionSize, lpOldProtect, lpOldProtect);
    lpMinAddr := Ptr(Cardinal(MemBasicInfo.BaseAddress)+MemBasicInfo.RegionSize);
  end;

 CloseHandle(hProcess);
end;