?
Solved

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

Posted on 2014-03-13
14
Medium Priority
?
1,354 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
Optimize your web performance

What's in the eBook?
- Full list of reasons for poor performance
- Ultimate measures to speed things up
- Primary web monitoring types
- KPIs you should be monitoring in order to increase your ROI

 

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

Get MySQL database support online, now!

At Percona’s web store you can order your MySQL database support needs in minutes. No hassles, no fuss, just pick and click. Pay online with a credit card.

Question has a verified solution.

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

Iteration: Iteration is repetition of a process. A student who goes to school repeats the process of going to school everyday until graduation. We go to grocery store at least once or twice a month to buy products. We repeat this process every mont…
Having just graduated from college and entered the workforce, I don’t find myself always using the tools and programs I grew accustomed to over the past four years. However, there is one program I continually find myself reverting back to…R.   So …
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 be introduced to the technique of using vectors in C++. The video will cover how to define a vector, store values in the vector and retrieve data from the values stored in the vector.
Suggested Courses

771 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