Solved

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

Posted on 2014-03-13
14
1,308 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
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 7
  • 4
  • 2
14 Comments
 
LVL 101

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 27

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
What Is Transaction Monitoring and who needs it?

Synthetic Transaction Monitoring that you need for the day to day, which ensures your business website keeps running optimally, and that there is no downtime to impact your customer experience.

 

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 27

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
 
LVL 27

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 101

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 27

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

The Ultimate Checklist to Optimize Your Website

Websites are getting bigger and complicated by the day. Video, images, custom fonts are all great for showcasing your product/service. But the price to pay in terms of reduced page load times and ultimately, decreased sales, can lead to some difficult decisions about what to cut.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

In my programming career I have only very rarely run into situations where operator overloading would be of any use in my work.  Normally those situations involved math with either overly large numbers (hundreds of thousands of digits or accuracy re…
When there is a disconnect between the intentions of their creator and the recipient, when algorithms go awry, they can have disastrous consequences.
The viewer will learn how to use the return statement in functions in C++. The video will also teach the user how to pass data to a function and have the function return data back for further processing.
I've attached the XLSM Excel spreadsheet I used in the video and also text files containing the macros used below. https://filedb.experts-exchange.com/incoming/2017/03_w12/1151775/Permutations.txt https://filedb.experts-exchange.com/incoming/201…

705 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