![]() |
|
|
|||||||
| Регистрация | << Правила форума >> | 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 и сравниваешь уже этот кусок с искомой строкой... ну как вариант
|
|
#3
|
||||
|
||||
|
Ну тут речь пока не о надежности алго, а его правильности работы, так как диапозон четко известен и искомое значение не выходит за его пределы, а может лишь перемещаться по данному диапозону, что опять же делает поиск универсальным и скоростным, так как ненужно перебирать каждый байт. Диапозон я определил тестовым путем на разных ОС + некий запас.
|
|
#4
|
||||
|
||||
|
Цитата:
Код:
If Pos(StringToFind,AnsiString(Buffer)) > 0 Then Цитата:
Цитата:
Цитата:
|
|
#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; |