[Last Call] Learn about multicloud storage options and how to improve your company's cloud strategy. Register Now

x
?
Solved

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

Posted on 2014-03-13
14
Medium Priority
?
1,406 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 28

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
Concerto's Cloud Advisory Services

Want to avoid the missteps to gaining all the benefits of the cloud? Learn more about the different assessment options from our Cloud Advisory team.

 

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 28

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 28

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 28

Accepted Solution

by:
Sinisa Vuk earned 1500 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

Free Tool: Site Down Detector

Helpful to verify reports of your own downtime, or to double check a downed website you are trying to access.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

Question has a verified solution.

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

The greatest common divisor (gcd) of two positive integers is their largest common divisor. Let's consider two numbers 12 and 20. The divisors of 12 are 1, 2, 3, 4, 6, 12 The divisors of 20 are 1, 2, 4, 5, 10 20 The highest number among the c…
The purpose of this article is to demonstrate how we can use conditional statements using Python.
The goal of the video will be to teach the user the concept of local variables and scope. An example of a locally defined variable will be given as well as an explanation of what scope is in C++. The local variable and concept of scope will be relat…
The viewer will learn additional member functions of the vector class. Specifically, the capacity and swap member functions will be introduced.
Suggested Courses

656 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