Форум по 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;
Ответить с цитированием
  #7  
Старый 16.07.2010, 16:02
Аватар для Vayrus
Vayrus Vayrus вне форума
Исполняемый Ретровирус
 
Регистрация: 09.08.2008
Адрес: Umbrella Corporation
Сообщения: 743
Репутация: 1293
Лампочка

Спасибо, но Не совсем понял что находит данный код, то ли какое то "магическое число", непонятно для чего, то ли смещение текста-маркера, после которого находится произвольный искомый текст (в данном случае набор цифр), которое я и так в своем коде нахожу

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

Цитата:
Сообщение от Vayrus
Спасибо, но Не совсем понял что находит данный код, то ли какое то "магическое число", непонятно для чего, то ли смещение текста-маркера, после которого находится произвольный искомый текст (в данном случае набор цифр), которое я и так в своем коде нахожу

Код испробовал, нашел какой то набор цифр, не сильно далекий от того что нужно...
эта функция ищет адрес строки в памяти, можно указать как Pointer, то число которое надо получить оно на фиксированной длине от этого слова стоит? если так то в возвращении результата прибавь этот оффсет
Код:
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; //+offset
          Exit;
        end;
      end;
просто не имею тестового приложения для теста, что-бы всю задачу решить
эм, а тема топика то в чём конкретно? тебе права в 7 нужно настроить?
__________________
TAleD = class(TUser)
public
function HelpMe(ASubject, ARequest: String): String;
function GiveMeExample(ASubject: String): TStringList;
procedure WriteReview(APost: Integer; ADescription: TStringList);
end;

Последний раз редактировалось AleD, 16.07.2010 в 16:16.
Ответить с цитированием
  #9  
Старый 16.07.2010, 16:27
Аватар для Vayrus
Vayrus Vayrus вне форума
Исполняемый Ретровирус
 
Регистрация: 09.08.2008
Адрес: Umbrella Corporation
Сообщения: 743
Репутация: 1293
Лампочка

Нет, тут речь о правах идет для помощников)

Суть в том что ГЛАВНЫЙ искомый ПРОИЗВОЛЬНЫЙ текст находится ВСЕГДА на НЕБОЛЬШОМ ПРОИЗВОЛЬНОМ расстоянии от ПОСТОЯННОГО текста-маркера, и только ПОСЛЕ текста-маркера, все это дело перемещается ПРОИЗВОЛЬНО в некотором ПОСТОЯННОМ диапазоне ОФФСЕТОВ.

Почему все так сложно? Так как искомый текст постоянно меняет свою позицию в памяти, но не сильно, и еще оно само постоянно меняется, но остается постоянным количество символов и то, что это числа (последнее 2 факта не так важно). Вот, мне нужно выдрать определенный участок памяти, небольшой, в который входит текст-маркер и сам искомый текст, уже оттуда, путем отброса не ASCII символов (вроде прально выразился или по-другому скажу - символов не входящих в ту или иную кодовую страницу), ненужного текста и пробелов я и собираюсь брать искомый текст.
Ответить с цитированием
  #10  
Старый 16.07.2010, 16:32
Аватар для AleD
AleD AleD вне форума
Активный
 
Регистрация: 21.02.2009
Адрес: г.Краснокаменск
Сообщения: 383
Репутация: 91
По умолчанию

Цитата:
Сообщение от Vayrus
Нет, тут речь о правах идет для помощников)

Суть в том что ГЛАВНЫЙ искомый ПРОИЗВОЛЬНЫЙ текст находится ВСЕГДА на НЕБОЛЬШОМ ПРОИЗВОЛЬНОМ расстоянии от ПОСТОЯННОГО текста-маркера, и только ПОСЛЕ текста-маркера, все это дело перемещается ПРОИЗВОЛЬНО в некотором ПОСТОЯННОМ диапазоне ОФФСЕТОВ.

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

Цитата:
Сообщение от AleD
если это всё произвольно перемещается то в можно же найти указатель на эти данные с помощью того же ArtMoney и задача упростится до невозможности

Под указателем Вы подразумеваете смещение ?

Если да, то оно постоянно меняется, о чем и идет здесь речь, я знаю что было бы проще, так мы читать и писать умеем)

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

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

Цитата:
Сообщение от AleD
не, указатель это адрес переменной в которой хранится адрес на эти данные, как правило указатель в памяти сидит на одном месте.подробнее можно в справке ArtMoney почитать

ОК, как то читал на форумах, но там говорили что указатели тоже бывает меняются
Ответить с цитированием
  #14  
Старый 16.07.2010, 16:43
Аватар для Vayrus
Vayrus Vayrus вне форума
Исполняемый Ретровирус
 
Регистрация: 09.08.2008
Адрес: Umbrella Corporation
Сообщения: 743
Репутация: 1293
Лампочка

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

10) Использование указателей и "Авто изменение адресов". На примере игры "Warcraft 3"
Цитата:
Сообщение от Справка ArtMoney
Если случается так, что ранее найденные и сохраненные адреса становятся недействительными, это значит, что игра использует динамическое распределение памяти. Недействительные адреса - это значит, что там не то, что в игре или нет никакого значения вообще (пишется <НЕТ>). Итак, рассмотрим природу этого явления "динамическое распределение памяти" по-английски "Dynamic Memory Allocation" сокращенно DMA. Когда игре необходима дополнительная память, она использует функцию Windows для получения памяти. Windows раздает участки памяти случайно, то есть по DMA. Из этого следует, что перезапуск игры приводит к полной переделки всей карты памяти. Блоки памяти меняются местами, адреса меняются.
...
если в задаче используется конкретная программа для поиска, то достаточно проверить есть ли указатель на эти данные и статичен ли он (что скорей всего) артманяй
__________________
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, время: 17:24.


 

Сайт

Форум

FAQ

RSS лента

Прочее

 

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

ВКонтакте   Facebook   Twitter