Форум по Delphi программированию

Delphi Sources



Вернуться   Форум по Delphi программированию > Все о Delphi > ОС и железо
Ник
Пароль
Регистрация <<         Правила форума         >> FAQ Пользователи Календарь Поиск Сообщения за сегодня Все разделы прочитаны

Ответ
 
Опции темы Поиск в этой теме Опции просмотра
  #1  
Старый 15.07.2010, 17:19
Аватар для Vayrus
Vayrus Vayrus вне форума
Исполняемый Ретровирус
 
Регистрация: 09.08.2008
Адрес: Umbrella Corporation
Сообщения: 743
Репутация: 1293
Лампочка Чтение значения из памяти запущенного процесса

Приветствую, необходимо считать данные из памяти игрушки с определенной позиции, в качестве "определенной позиции" выступает некое слово, например, "live", так вот, есть сурс, но никак нехочет отрабатывать, но слово точно находит, а текст из памяти после слова "live" (конкретно "live" отображается), не отображает, под ХП привилегии не потребовались, под 7 возможно понадобятся:

Код:
function FindString(ProcessID: DWORD; RangeFrom, RangeTo: DWORD; StringToFind: AnsiString): AnsiString;
const
  BufferSize = 1000;
var
  hProcess : DWORD;
  BytesRead : DWORD;
  BytesToRead : DWORD;
  I : DWORD;
  Buffer : Array Of AnsiChar;
  OldProtect : DWORD;
begin
  If (RangeTo - RangeFrom) < 1 Then
    begin
    ShowMessage('Invalid Ranges');
    Exit;
  end;
  hProcess := OpenProcess(PROCESS_VM_READ,False,ProcessID);
  If hProcess = 0 Then
    begin
    ShowMessage(SysErrorMessage(GetLastError));
    Exit;
  end;
  Try
    SetLength(Buffer,BufferSize);
    Try
      I := RangeFrom;
      While I < RangeTo Do
        begin
        BytesToRead := BufferSize;
        If (RangeTo - I) < BytesToRead Then
          begin
          BytesToRead := RangeTo - I;
        end;
        VirtualProtectEx(hProcess,Pointer(I),BytesToRead,PAGE_READWRITE,OldProtect);
        ReadProcessMemory(hProcess,Pointer(I),@Buffer[0],BytesToRead,BytesRead);
        VirtualProtectEx(hProcess,Pointer(I),BytesToRead,OldProtect,OldProtect);
        If Pos(StringToFind,AnsiString(Buffer)) > 0 Then
          begin
          SetLength(Result,100);
          Move(Buffer[Pos(StringToFind,AnsiString(Buffer)) - 1],Result[1],100);
          Break;
        end;
        Inc(I,BytesToRead);
      end;
    Finally
      Buffer := nil;
    end;
  Finally
    CloseHandle(hProcess);
  end;
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
showmessage(FindString(strtoint(edit1.text),$0034686C, $003468BC, 'live'));
end;
Ответить с цитированием
  #2  
Старый 16.07.2010, 09:16
Аватар для AleD
AleD AleD вне форума
Активный
 
Регистрация: 21.02.2009
Адрес: г.Краснокаменск
Сообщения: 383
Репутация: 91
По умолчанию

имхо у тебя сам алгоритм поиска не надёжен. ты считываешь по N байт и в них ищешь строку длиной K, а что если эта строка лежит в конце считываемого буфера и заканчивается за его пределами? попробуй просто перебирать все байты буфера и если байт равен первому байту (символу) искомой строки то ты читаешь этот кусок размером K и сравниваешь уже этот кусок с искомой строкой... ну как вариант
__________________
TAleD = class(TUser)
public
function HelpMe(ASubject, ARequest: String): String;
function GiveMeExample(ASubject: String): TStringList;
procedure WriteReview(APost: Integer; ADescription: TStringList);
end;
Ответить с цитированием
  #3  
Старый 16.07.2010, 10:37
Аватар для Vayrus
Vayrus Vayrus вне форума
Исполняемый Ретровирус
 
Регистрация: 09.08.2008
Адрес: Umbrella Corporation
Сообщения: 743
Репутация: 1293
Лампочка

Ну тут речь пока не о надежности алго, а его правильности работы, так как диапозон четко известен и искомое значение не выходит за его пределы, а может лишь перемещаться по данному диапозону, что опять же делает поиск универсальным и скоростным, так как ненужно перебирать каждый байт. Диапозон я определил тестовым путем на разных ОС + некий запас.
Ответить с цитированием
  #4  
Старый 16.07.2010, 11:30
Аватар для AleD
AleD AleD вне форума
Активный
 
Регистрация: 21.02.2009
Адрес: г.Краснокаменск
Сообщения: 383
Репутация: 91
По умолчанию

Цитата:
Сообщение от Vayrus
диапозон четко известен и искомое значение не выходит за его пределы
У тебя весь диапазон поиска [RangeFrom..RangeTo] и диапазон поиска в буфере [Buffer..Buffer+BytesToRead]. И при
Код:
If Pos(StringToFind,AnsiString(Buffer)) > 0 Then
ты ищешь StringToFind в буфере в котором искомая строка может быть не полностью, вот например
Цитата:
[SEARCH_RANGE]werjqmw[BUFFER]perbqmwqweqli[/BUFFER]vewefgtjmndfgnleporjfwergj[/SEARCH_RANGE]
в итоге строка не может быть найдена
Цитата:
Сообщение от Vayrus
Ну тут речь пока не о надежности алго, а его правильности работы
ну если алгоритм не надёжен он может давать сбои, такие как эта
Цитата:
Сообщение от Vayrus
текст из памяти после слова "live" (конкретно "live" отображается), не отображает
кстати может быть в том тексте после ключевого слова есть нулевые байты? если ты пытаешься отобразить его как строку
__________________
TAleD = class(TUser)
public
function HelpMe(ASubject, ARequest: String): String;
function GiveMeExample(ASubject: String): TStringList;
procedure WriteReview(APost: Integer; ADescription: TStringList);
end;
Ответить с цитированием
  #5  
Старый 16.07.2010, 12:41
Аватар для Vayrus
Vayrus Vayrus вне форума
Исполняемый Ретровирус
 
Регистрация: 09.08.2008
Адрес: Umbrella Corporation
Сообщения: 743
Репутация: 1293
По умолчанию

Кажется дошло о чем речь, размер буфера у меня фиксированный, так что если у меня диапозон выходит за размеры буфера то я ничего и не найду, те выход заключается в увеличении буфера, а лучше в динамическом его создании. Насчет нуль-терминированной строки, то вроде нет, обычные ACSII строки. Извиняюсь заранее за ляпы, я в этой теме "плаваю" впервые. Вот скрин, может он поможет хоть немного разобраться и сделать то что я хочу:

Ответить с цитированием
  #6  
Старый 16.07.2010, 15:41
Аватар для AleD
AleD AleD вне форума
Активный
 
Регистрация: 21.02.2009
Адрес: г.Краснокаменск
Сообщения: 383
Репутация: 91
По умолчанию

вот попробуй, на досуге написал:
Код:
function FindString(PID, RangeFrom, RangeTo: Cardinal;
  AStr: AnsiString): Cardinal;
const
  bufSz = 256;
var
  prc: Cardinal;
  readed: Cardinal;
  oldProt: Cardinal;
  buf: Pointer;
  i, j, strLen: Cardinal;

  function CompProcessMem(AMem, AComp: Pointer; ASz: Cardinal): Boolean;
  var
    i: Integer;
    buf: Pointer;
    oldProt: Cardinal;
  begin
    Result := true;
    buf := GetMemory(ASz);
    try
      VirtualProtectEx(prc, AMem, ASz, PAGE_READONLY, oldProt);
      ReadProcessMemory(prc, AMem, buf, ASz, readed);

      for i:=0 to ASz-1 do
      begin
        if(PByte(Cardinal(buf)+i)^<>PByte(Cardinal(AComp)+i)^)then
        begin
          Result := false;
          Exit;
        end;
      end;

      VirtualProtectEx(prc, AMem, ASz, oldProt, oldProt);
    finally
      FreeMem(buf, ASz);
    end;
  end;

begin
  Result := 0;
  strLen := Length(AStr);
  if(RangeTo-RangeFrom<=0)or(strLen<=0)then
    Exit;

  prc := OpenProcess(PROCESS_VM_READ, false, PID);
  if(prc=0)then
    Exit;

  buf := GetMemory(bufSz);
  try
    i := RangeFrom;

    repeat
      VirtualProtectEx(prc, Pointer(i), bufSz, PAGE_READONLY, oldProt);

      ReadProcessMemory(prc, Pointer(i), buf, bufSz, readed);

      for j:=0 to readed-1 do
      begin
        if(PByte(Cardinal(buf)+j)^=PByte(@AStr[j])^)and
          (CompProcessMem(Pointer(Cardinal(buf)+j), @AStr[j], strLen))then
        begin
          Result := Cardinal(buf)+j;
          Exit;
        end;
      end;

      VirtualProtectEx(prc, Pointer(i), bufSz, oldProt, oldProt);
      Inc(i, readed);
    until(i>=RangeTo);
  finally
    FreeMem(buf, bufSz);
  end;
end;
ищет строку в процессе, там заофсетишь и получишь своё магическое число
__________________
TAleD = class(TUser)
public
function HelpMe(ASubject, ARequest: String): String;
function GiveMeExample(ASubject: String): TStringList;
procedure WriteReview(APost: Integer; ADescription: TStringList);
end;
Ответить с цитированием
Ответ


Delphi Sources

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

Расширенный поиск
Опции просмотра
Комбинированный вид Комбинированный вид

Ваши права в разделе
Вы не можете создавать темы
Вы не можете отвечать на сообщения
Вы не можете прикреплять файлы
Вы не можете редактировать сообщения

BB-коды Вкл.
Смайлы Вкл.
[IMG] код Вкл.
HTML код Выкл.
Быстрый переход


Часовой пояс GMT +3, время: 15:12.


 

Сайт

Форум

FAQ

RSS лента

Прочее

 

Copyright © Форум "Delphi Sources" by BrokenByte Software, 2004-2023

ВКонтакте   Facebook   Twitter