|
|
Регистрация | << Правила форума >> | FAQ | Пользователи | Календарь | Поиск | Сообщения за сегодня | Все разделы прочитаны |
|
Опции темы | Поиск в этой теме | Опции просмотра |
#1
|
||||
|
||||
Чтение значения из памяти запущенного процесса
Приветствую, необходимо считать данные из памяти игрушки с определенной позиции, в качестве "определенной позиции" выступает некое слово, например, "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
|
||||
|
||||
имхо у тебя сам алгоритм поиска не надёжен. ты считываешь по 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
|
||||
|
||||
Ну тут речь пока не о надежности алго, а его правильности работы, так как диапозон четко известен и искомое значение не выходит за его пределы, а может лишь перемещаться по данному диапозону, что опять же делает поиск универсальным и скоростным, так как ненужно перебирать каждый байт. Диапозон я определил тестовым путем на разных ОС + некий запас.
|
#4
|
||||
|
||||
Цитата:
Код:
If Pos(StringToFind,AnsiString(Buffer)) > 0 Then Цитата:
Цитата:
Цитата:
TAleD = class(TUser) public function HelpMe(ASubject, ARequest: String): String; function GiveMeExample(ASubject: String): TStringList; procedure WriteReview(APost: Integer; ADescription: TStringList); end; |
#5
|
||||
|
||||
Кажется дошло о чем речь, размер буфера у меня фиксированный, так что если у меня диапозон выходит за размеры буфера то я ничего и не найду, те выход заключается в увеличении буфера, а лучше в динамическом его создании. Насчет нуль-терминированной строки, то вроде нет, обычные ACSII строки. Извиняюсь заранее за ляпы, я в этой теме "плаваю" впервые. Вот скрин, может он поможет хоть немного разобраться и сделать то что я хочу:
|
#6
|
||||
|
||||
вот попробуй, на досуге написал:
Код:
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
|
||||
|
||||
Спасибо, но Не совсем понял что находит данный код, то ли какое то "магическое число", непонятно для чего, то ли смещение текста-маркера, после которого находится произвольный искомый текст (в данном случае набор цифр), которое я и так в своем коде нахожу
Код испробовал, нашел какой то набор цифр, не сильно далекий от того что нужно... |
#8
|
||||
|
||||
Цитата:
Код:
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
|
||||
|
||||
Нет, тут речь о правах идет для помощников)
Суть в том что ГЛАВНЫЙ искомый ПРОИЗВОЛЬНЫЙ текст находится ВСЕГДА на НЕБОЛЬШОМ ПРОИЗВОЛЬНОМ расстоянии от ПОСТОЯННОГО текста-маркера, и только ПОСЛЕ текста-маркера, все это дело перемещается ПРОИЗВОЛЬНО в некотором ПОСТОЯННОМ диапазоне ОФФСЕТОВ. Почему все так сложно? Так как искомый текст постоянно меняет свою позицию в памяти, но не сильно, и еще оно само постоянно меняется, но остается постоянным количество символов и то, что это числа (последнее 2 факта не так важно). Вот, мне нужно выдрать определенный участок памяти, небольшой, в который входит текст-маркер и сам искомый текст, уже оттуда, путем отброса не ASCII символов (вроде прально выразился или по-другому скажу - символов не входящих в ту или иную кодовую страницу), ненужного текста и пробелов я и собираюсь брать искомый текст. |
#10
|
||||
|
||||
Цитата:
TAleD = class(TUser) public function HelpMe(ASubject, ARequest: String): String; function GiveMeExample(ASubject: String): TStringList; procedure WriteReview(APost: Integer; ADescription: TStringList); end; |
#11
|
||||
|
||||
Цитата:
Под указателем Вы подразумеваете смещение ? Если да, то оно постоянно меняется, о чем и идет здесь речь, я знаю что было бы проще, так мы читать и писать умеем) Последний раз редактировалось Vayrus, 16.07.2010 в 16:36. |
#12
|
||||
|
||||
Цитата:
TAleD = class(TUser) public function HelpMe(ASubject, ARequest: String): String; function GiveMeExample(ASubject: String): TStringList; procedure WriteReview(APost: Integer; ADescription: TStringList); end; |
#13
|
||||
|
||||
Цитата:
ОК, как то читал на форумах, но там говорили что указатели тоже бывает меняются |
#14
|
||||
|
||||
Вот АртМони мне показывает адреса, которые я, возможно, ошибочно, принимал за смещение, так вот эти адреса постоянно меняются.
А где найти указатели незнаю, а в справке даже поиска нет. |
#15
|
||||
|
||||
10) Использование указателей и "Авто изменение адресов". На примере игры "Warcraft 3"
Цитата:
TAleD = class(TUser) public function HelpMe(ASubject, ARequest: String): String; function GiveMeExample(ASubject: String): TStringList; procedure WriteReview(APost: Integer; ADescription: TStringList); end; |