Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > Delphi программирование > Общие вопросы Delphi
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 22.08.2018, 09:32   #1
fucil
Форумчанин
 
Регистрация: 24.02.2010
Сообщений: 148
По умолчанию Работа с памятью 64 битного приложения

Доброго времени суток, суть проблемы следующая: Пишу софт по поиску строк по сигнатуре, программа составлена на делфи под 32 бита и код написан под поиск строки в памяти 32-х битных приложений, все работает все гуд, но столкнулся с проблемой что в некоторых приложениях не работает, по итогу долгого дебага выяснилось что проблема возникала только в приложениях которые 64 бита, начал искать решения, но рабочего кода так и не нашлось, код ниже кидал на коленке не судите строго, но суть не поменялась, там же добавлены наработки по поиску строки в памяти 64 битного приложения, но они не рабочие так как я пока не понимаю как организована работа памяти в 64 битных приложениях. И главный вопрос: Возможно ли из 32 битного приложения обработать память 64 битного приложения, эксперты прошу помощи !

Информацию по обработке памяти 64битных приложений брал тут https://stackoverflow.com/questions/32746356/32-64-bit-readprocessmemory-issues

Сам код на текущий момент имеет вид:

Код:
{$IFDEF WIN64}
  PMEMORY_BASIC_INFORMATION64 = ^MEMORY_BASIC_INFORMATION64;
  {$ALIGN 16}
  MEMORY_BASIC_INFORMATION64 = record
    BaseAddress: ULONGLONG;
    AllocationBase: ULONGLONG;
    AllocationProtect: DWORD;
    _alignment1: DWORD;
    RegionSize: ULONGLONG;
    State: DWORD;
    Protect: DWORD;
    _Type: DWORD;
    _alignment2: DWORD;
  end;
  {$ENDIF}
type
  WinIsWow64 = function( Handle: THandle; var Iret: BOOL ): Windows.BOOL; stdcall;

type
  TForm1 = class(TForm)
    Button1: TButton;
    Edit1: TEdit;
    Memo1: TMemo;
    Edit2: TEdit;
    procedure Button1Click(Sender: TObject);

  private
    { Private declarations }
  public

  {$IFDEF WIN64}
  function VirtualQueryEx64(hProcess: THandle; lpAddress: Pointer; var lpBuffer: MEMORY_BASIC_INFORMATION64; dwLength: SIZE_T): SIZE_T; stdcall; external 'kernel32' name 'VirtualQueryEx';
  {$ENDIF}
    { Public declarations }
  end;

var
  Form1: TForm1;
implementation

{$R *.dfm}
var
  READABLE : Cardinal = (PAGE_EXECUTE_READ or PAGE_EXECUTE_READWRITE or PAGE_EXECUTE_WRITECOPY or PAGE_READONLY or PAGE_READWRITE or PAGE_WRITECOPY);

type
  TMBIArray = array of MEMORY_BASIC_INFORMATION;
  TPointerArray = array of Cardinal;
  TCharArray = array of char;

procedure push_to_bmi(var arr : TMBIArray; el : MEMORY_BASIC_INFORMATION);
var
  len : integer;
begin
  len := Length(arr);
  SetLength(arr, len + 1);
  arr[len] := el;
end;

procedure push_to_pointer_array(var arr : TPointerArray; el : Cardinal);
var
  len : integer;
begin
  len := Length(arr);
  SetLength(arr, len + 1);
  arr[len] := el;
end;

function get_mem_pages(h : Cardinal) : TMBIArray;
var
  pages : TMBIArray;
  mbi : MEMORY_BASIC_INFORMATION;
  addr : Cardinal;
  ret : Cardinal;
begin

  addr := 0;
  SetLength(pages, 0);
  while true do
  begin
    ret := VirtualQueryEx(h, Pointer(addr), mbi, SizeOf(mbi));
    if(ret = 0) then break;
    if (mbi.State and MEM_COMMIT) <> 0 then
    begin
      if (mbi.AllocationProtect and READABLE) <> 0 then
      begin
        push_to_bmi(pages, mbi);
      end;
    end;
    addr := Cardinal(mbi.BaseAddress) + Cardinal(mbi.RegionSize);
  end;

  result := pages;
end;

{$IFDEF WIN64}
function get_mem_pages64(h : Cardinal) : TMBIArray;
var
  pages : TMBIArray;
  mbi : MEMORY_BASIC_INFORMATION;
  addr : Cardinal;
  ret : Cardinal;
begin

  addr := 0;
  SetLength(pages, 0);
  while true do
  begin
    //ret := VirtualQueryEx(h, Pointer(addr), mbi, SizeOf(mbi));
    ret := VirtualQueryEx64(h, Pointer(addr), mbi, SizeOf(mbi));
    if(ret = 0) then break;
    if (mbi.State and MEM_COMMIT) <> 0 then
    begin
      if (mbi.AllocationProtect and READABLE) <> 0 then
      begin
        push_to_bmi(pages, mbi);
      end;
    end;
    addr := Cardinal(mbi.BaseAddress) + Cardinal(mbi.RegionSize);
  end;

  result := pages;
end;
{$ENDIF}

{$IFDEF WIN64}
procedure TForm1.ScanMemory64(PIDHandle: THandle; const ProcessName: string);
var
  MemStart: ULONGLONG;
  ReceivedBytes: SIZE_T;
  MemInfo: MEMORY_BASIC_INFORMATION64;
begin
  MemStart := 0;
  while (VirtualQueryEx64(PIDHandle, Pointer(MemStart), MemInfo, SizeOf(MemInfo)) <> 0) do
  begin
    if ((MemInfo.State = MEM_COMMIT) and (not (MemInfo.Protect = PAGE_GUARD)
    or (MemInfo.Protect = PAGE_NOACCESS)) and (MemInfo.Protect = PAGE_READWRITE)) then
    begin
      SetLength(Buff, MemInfo.RegionSize);
      if (ReadProcessMemory(PIDHandle, Pointer(MemInfo.BaseAddress), Buff,
          MemInfo.RegionSize, ReceivedBytes)) then
      begin
        DoSomethingWithBuff(ProcessName);
      end;
    end;
    Inc(MemStart, MemInfo.RegionSize);
  end;
end;
{$ENDIF}

function find_strings_in_page(h : Cardinal; page_start : Cardinal; page_size : Cardinal; needed : String): TPointerArray;
var
  result_addrs : TPointerArray;
  buf_size : integer;
  buf : array [0..4096] of char;
  addr_in_page : Cardinal;
  last_read : boolean;
  can_read : integer;
  nr : Cardinal;
  ret : boolean;
  cycle_end : integer;
  i : integer;
  j : integer;
  cmp_buf : TCharArray;
  cmp : integer;
begin
  SetLength(result_addrs, 0);
  buf_size := 4096;
  last_read := false;
  addr_in_page := 0;
  while true do
  begin
    can_read := 0;
    if(addr_in_page + buf_size) >= page_size then
    begin
       can_read := page_size - addr_in_page;
       last_read := true;
    end else
    begin
      can_read := buf_size;
    end;

    nr := 0;
		ret := ReadProcessMemory(h,Pointer(page_start + addr_in_page), @buf, can_read, nr);
    if not ret then break;

    cycle_end := nr - (Length(needed) - 1);
    //for i := 0 to cycle_end - 1 do
    i := 0;
    while i < cycle_end do
    begin
      cmp := 0;
      //cmp_buf := TCharArray(Cardinal(@buf) + Cardinal(i));
      for j := 0 to Length(needed) - 1 do
      begin
        cmp := Byte(Byte(needed[j+1]) - Byte(buf[j+1 + i]));
        if cmp <> 0 then break;
      end;

      if cmp = 0 then
      begin
        push_to_pointer_array(result_addrs, Cardinal(page_start + addr_in_page + i + 1));

        i := i + Length(needed);
      end;
      i := i + 1;
    end;
    addr_in_page := addr_in_page + can_read - Length(needed);
		if last_read then break;
  end;

  result := result_addrs;
end;

procedure TForm1.Button1Click(Sender: TObject);
var
  pid : integer;
  hProcess : Cardinal;
  find_str : String;
  pages : TMBIArray;
  i,j : integer;
  page_start : Cardinal;
  addr_in_page : Cardinal;
  page_size : Cardinal;
  res : TPointerArray;
  buf : array [0..4096] of char;
  buf_size : integer;
  can_read : Cardinal;
  nr : Cardinal;
  string_list : TStringList;
begin

  string_list := TStringList.Create();
  buf_size := 4096;
  pid := StrToInt(Edit1.Text);
  find_str := Edit2.Text;

  hProcess := OpenProcess(PROCESS_ALL_ACCESS, false, pid);  //PROCESS_ALL_ACCESS
  //ShowMessage('1 - '+SysErrorMessage(GetLastError));
  pages := get_mem_pages(hProcess);
  //ShowMessage('2 - '+SysErrorMessage(GetLastError));
  for i := 0 to Length(pages) - 1 do
  begin
    res := find_strings_in_page(hProcess, Cardinal(pages[i].BaseAddress), pages[i].RegionSize, find_str);
   // ShowMessage('3 - '+SysErrorMessage(GetLastError));

    for j := 0 to Length(res) - 1 do
    begin

      page_start := Cardinal(pages[i].BaseAddress);
		  addr_in_page := Cardinal(res[j] - page_start);
      page_size := pages[i].RegionSize;

      can_read := 0;
      if(addr_in_page + 4096 >= page_size) then
				can_read := page_size - addr_in_page
      else
				can_read := 4096;

      ReadProcessMemory(hProcess,Pointer(page_start + addr_in_page), @buf, can_read, nr);
      Memo1.Lines.Add(buf);
      //string_list.Add(String(buf));
   end;   
  end;
end;

Последний раз редактировалось fucil; 22.08.2018 в 09:38.
fucil вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц

Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск


Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Работа с памятью mufesto Win Api 1 30.01.2012 15:13
работа с памятью в VB Mr_ViK Помощь студентам 1 14.01.2012 16:54
С# работа с памятью Anton07 Помощь студентам 0 13.12.2009 23:06
Работа с памятью. nazavrik Общие вопросы C/C++ 0 07.10.2009 23:17
Цвет и анимация в консоли 32-битного приложения oleg kutkov Общие вопросы C/C++ 3 15.04.2008 14:03