|
|
Регистрация | << Правила форума >> | 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; |