Solved

How to scan entire process of a memory for byte array?

Posted on 2014-03-13
14
1,165 Views
Last Modified: 2014-03-17
pHandle := OpenProcess(PROCESS_ALL_ACCESS, false, 2928);
      if pHandle <> 0 then
        begin
          Addr := dword(sysinfo.lpMinimumApplicationAddress);
          while (Addr < sysinfo.lpMaximumApplicationAddress) do
          begin
            if VirtualQueryEx(Handle, Ptr(Addr), Mbi, SizeOf(Mbi)) = 0 then
            begin
              err := GetLastError;
              inc(Addr, sysinfo.dwPageSize);
              continue;
            end;
             SetLength(buff, mbi.RegionSize);
             ReadProcessMemory(pHandle, Mbi.BaseAddress, @Buff[0], Mbi.RegionSize,             BytesRead);

            if Addr + Mbi.RegionSize < Addr then
              break;
            Addr := Addr + Mbi.RegionSize;
          end;
          CloseHandle(Handle)
        end;

Open in new window


I have tried this code to read the memory .. if i use SetString on the buffer I get only garbage as the memory it's not text.So .. i'm wondering .. how to search for a specific byte array? and to avoid memory leaks while reading/searching.
0
Comment
Question by:drake08
  • 7
  • 4
  • 2
14 Comments
 
LVL 100

Expert Comment

by:mlmcc
ID: 39927685
Why do you need to search memory?  Much of what you will be searching for is the application code which probably is protected from reading

mlmcc
0
 

Author Comment

by:drake08
ID: 39927997
I want to extract some strings from an application. So .. can you show me a way to do this?
0
 
LVL 25

Expert Comment

by:Sinisa Vuk
ID: 39928582
for what reason do you want to read your app in memory strings?
if it is your app - then you could read anything using "standard/object" way.
0
 

Author Comment

by:drake08
ID: 39928605
Not really memory strings.. it is ok byte array too. Why are you keep asking me for what reason I need this? It is matter?
0
 
LVL 25

Expert Comment

by:Sinisa Vuk
ID: 39928689
This info can really helps us to understand what you need and we can give you another (maybe better) solution. So, if you build some protection stuff - maybe there is something else... if you trying to build some malware - there is no help, if you want to crack some third part component runtime - no help.

all in all... you can use function like this:
function FindByteArrayInArray(pSearchFor: PByte; SearchLen: Cardinal; pBuffer: PByte; BufLen: Cardinal): PByte;
var
  i, j: Cardinal;
  bFound: Boolean;
begin
  Result := nil;

  if SearchLen > BufLen then Exit;
  
  if SearchLen = 0 then
  begin
    Result := pBuffer;
    Exit;
  end;

  for i := 0 to BufLen - SearchLen do //skip length of search string
  begin
    if PByte(Cardinal(pBuffer) + i)^ = pSearchFor^ then //find first byte
    begin
      bFound := True; //assume we ok
      for j := 1 to SearchLen - 1 do
      begin
        if PByte(Cardinal(pBuffer) + i + j)^ <> PByte(Cardinal(pSearchFor) + j)^ then
        begin
          bFound := False;
          Break;
        end;
      end;

      if bFound then //after successful loop
      begin
        Result := PByte(Cardinal(pBuffer) + i);
        Exit;
      end;
    end;
  end;
end;

Open in new window


usage (you can pass any kind of buffer not string only):
  s1 := '1234567890';
  s2 := '890';

  if FindByteArrayInArray(PByte(PChar(s2)), 3, PByte(PChar(s1)), 10) <> nil then
 ....

Open in new window

0
 

Author Comment

by:drake08
ID: 39928796
That's hard stuff..
No I'm not building malware but kind of protecting software. The function you provided is working but not on my need. I can't get it working with readprocessmemory. If I use this:

buf: array of byte;
s1 := '100';
 if FindByteArrayInArray(PByte(PChar(s1), 3, PByte(PChar(buf[0]), sizeOf(buf)) <> nil then
  //do something

Open in new window


 along with ReadProcessMemory function nothing is found. So i'm wondering why.. but  your example works great.
0
6 Surprising Benefits of Threat Intelligence

All sorts of threat intelligence is available on the web. Intelligence you can learn from, and use to anticipate and prepare for future attacks.

 
LVL 25

Expert Comment

by:Sinisa Vuk
ID: 39929061
Try to define:
var
  buff: PByte ;
...
  GetMem(buff, mbi.RegionSize);
  ReadProcessMemory(pHandle, Mbi.BaseAddress, buff, Mbi.RegionSize,             BytesRead);

  if BytesRead>0 then
  begin
     s1:='100'; //which is in bytes:  #$31 + #$30 + #$30
     if FindByteArrayInArray(PByte(PChar(s1), 3, buff, BytesRead) <> nil then
 .....

  end;

  FreeMem(buff);

Open in new window

0
 

Author Comment

by:drake08
ID: 39929589
var s, s1: String;
s3: Integer;

begin
  s := '19';
  s1:= '519';
  s3:= 0;

  if FindByteArrayInArray(PByte(PChar(s)), 3, PByte(PChar(s1)), 10) <> nil then
    s3 := 1;
end;

Open in new window


s3 will get 1 which is not good for me.
@Sinisa, your function is checking only for occurrences in memory not for exact value.
I need to get s3 := 1 only if the value := '19'.( for example)

@mlmcc, I just want to check wether or not a program have some value in memory.Seems like you missunderstood the question.
0
 
LVL 100

Expert Comment

by:mlmcc
ID: 39929975
I understand the question just need to understand the reason for writing the program.

Are you trying to read the memory of the application that is running or another application (exe) file.
0
 

Author Comment

by:drake08
ID: 39929992
Another application.
0
 

Author Comment

by:drake08
ID: 39932476
Only a line of code missed from my code to work like I wanted and nobody was able to write(or to say how should I do) that except Sinisa who wrote something even if wasn't helpfull.. but at least he tried.I tought this community is much helpfull than others which are free of charge.I think I was wrong.No problem ..
0
 
LVL 25

Accepted Solution

by:
Sinisa Vuk earned 500 total points
ID: 39932966
EE is full of similar topics (not in Delphi, but...). One can help too:
http://www.experts-exchange.com/Programming/Editors_IDEs/Q_24029781.html

This is my example, because your is full of errors. I found window handle and get process id for it. Made adjustments to read buffer properly.
function FindByteArrayInArray(pSearchFor: PByte; SearchLen: Cardinal; pBuffer: PByte; BufLen: Cardinal): PByte;
var
  i, j: Cardinal;
  bFound: Boolean;
begin
  Result := nil;

  if SearchLen > BufLen then Exit;
  
  if SearchLen = 0 then
  begin
    Result := pBuffer;
    Exit;
  end;

  for i := 0 to BufLen - SearchLen do //skip length of search string
  begin
    if PByte(Cardinal(pBuffer) + i)^ = pSearchFor^ then //find first byte
    begin
      bFound := True; //assume we ok
      for j := 1 to SearchLen - 1 do
      begin
        if PByte(Cardinal(pBuffer) + i + j)^ <> PByte(Cardinal(pSearchFor) + j)^ then
        begin
          bFound := False;
          Break;
        end;
      end;

      if bFound then //after successful loop
      begin
        Result := PByte(Cardinal(pBuffer) + i);
        Exit;
      end;
    end;
  end;
end;

procedure TForm1.Button7Click(Sender: TObject);
var
  err: DWORD;
  sysinfo: TSystemInfo;
  Handle: THandle;
  Mbi: TMemoryBasicInformation;
  Addr: DWORD_PTR;
  BytesRead: DWORD;
  buff: Array of Byte;
  f: TFileStream;
  hWin, ProcId, BuffSize: Cardinal;
  Process: TPROCESSENTRY32;
  sSearchStr: String;
begin
  ProcId := 0;
  BuffSize := 0;
  sSearchStr := Edit1.Text;

  GetSystemInfo(sysinfo);

  hWin := FindWindow(nil, 'Caption of window put here'); // class can be added too
  if hWin > 0 then
    GetWindowThreadProcessID(hWin, @ProcId);  //get process id - not fixed one as you do
  if ProcId > 0 then
  begin
    Handle := OpenProcess(PROCESS_QUERY_INFORMATION or PROCESS_VM_READ, false, ProcId); //avoid PROCESS_ALL_ACCESS
    if Handle <> 0 then
    begin
      Addr := dword(sysinfo.lpMinimumApplicationAddress);
      while (Addr < DWORD_PTR(sysinfo.lpMaximumApplicationAddress)) do
      begin
        if VirtualQueryEx(Handle, Ptr(Addr), Mbi, SizeOf(Mbi)) = 0 then
        begin
          err := GetLastError;
          inc(Addr, sysinfo.dwPageSize);
          continue;
        end;

        if (Mbi.RegionSize > BuffSize) then //optimization
        begin
          BuffSize := Min(Mbi.RegionSize, 64*1024); //limit buff size
          SetLength(buff, BuffSize);
        end;

        if ReadProcessMemory(Handle, Mbi.BaseAddress, @Buff[0], Min(BuffSize, Mbi.RegionSize), BytesRead) then
        begin
          //go search
          if BytesRead > 0 then
          begin
            if FindByteArrayInArray(PByte(PChar(sSearchStr)), Length(sSearchStr), @Buff[0], BytesRead) <> nil then
              ShowMessage('Found: ');
          end;
        end;

        if Addr + BuffSize < Addr then
          break;
        Addr := Addr + BuffSize;
      end;
      SetLength(buff, 0);
      CloseHandle(Handle);
    end;
  end;
end;

Open in new window

0
 

Author Comment

by:drake08
ID: 39933167
Sinisa, my code isn't just that I posted on the first post and I'm not getting any errors. I am getting process handle (code on first post is only for some test only) and after I'm going with VirtualQueryEx.All was good except I haven't know how to search in memory block.I have used 'Pos' on buffer and was alright.  Thanks anyway.
0

Featured Post

Highfive + Dolby Voice = No More Audio Complaints!

Poor audio quality is one of the top reasons people don’t use video conferencing. Get the crispest, clearest audio powered by Dolby Voice in every meeting. Highfive and Dolby Voice deliver the best video conferencing and audio experience for every meeting and every room.

Join & Write a Comment

Introduction Raise your hands if you were as upset with FireMonkey as I was when I discovered that there was no TListview.  I use TListView in almost all of my applications I've written, and I was not going to compromise by resorting to TStringGrid…
Windows Script Host (WSH) has been part of Windows since Windows NT4. Windows Script Host provides architecture for building dynamic scripts that consist of a core object model, scripting hosts, and scripting engines. The key components of Window…
The goal of this video is to provide viewers with basic examples to understand and use switch statements in the C programming language.
This tutorial covers a step-by-step guide to install VisualVM launcher in eclipse.

758 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

19 Experts available now in Live!

Get 1:1 Help Now