var
BaseAddress : array of Pointer;
RegionSize : array of integer;
Readed : Boolean = False;
PHandle : THandle;
Function OpenProcessMemory(PID : integer) : integer;
var
StartPos : LongWord;
Buffer : TMemoryBasicInformation;
SysInfo : TSystemInfo;
begin
Result := -1;
GetSystemInfo(SysInfo);
StartPos := LongWord(SysInfo.lpMinimumApplicationAddress);
ZeroMemory(@Buffer,Sizeof(Buffer));
PHandle := OpenProcess(PROCESS_ALL_ACCESS,True,PID);
//如果要申请特权,写在这里
if PHandle<=0 then exit;
SetLength(BaseAddress,0);
SetLength(RegionSize,0);
while not VirtualQueryEx(PHandle,
Ptr(StartPos),
Buffer,
Sizeof(Buffer))>0 do begin
StartPos := LongWord(Buffer.BaseAddress) + LongWord(Buffer.RegionSize);
if StartPos > LongWord(SysInfo.lpMaximumApplicationAddress) then Break;
if Buffer.State = MEM_COMMIT then begin
if BOOL(Buffer.Protect and (PAGE_READWRITE or PAGE_EXECUTE_READWRITE or PAGE_EXECUTE_WRITECOPY)) Then begin
SetLength(BaseAddress,Length(BaseAddress)+1);
BaseAddress[High(BaseAddress)] := Buffer.BaseAddress;
SetLength(RegionSize,Length(RegionSize)+1);
RegionSize[High(RegionSize)] := Buffer.RegionSize;
end;
end;
end;
Result := 0;
Readed := True;
end;
Function PosStr(Key , Sour : PChar; KeyLen , SourLen : integer) : integer ; stdcall;
asm
PUSH ESI;
PUSH EDI;
PUSH EBX;
PUSH ECX;
PUSH EDX;
MOV ESI , [Sour];
MOV EDI , [Key];
MOV ECX , 0;
MOV EAX , 0;
MOV BL , [EDI];
@Loop1:
CMP EAX , SourLen;
JZ @NoFindExit;
CMP BL , ESI[EAX];
JNZ @NextLoop;
MOV EDX , 0;
@Loop2:
CMP EDX , KeyLen;
JZ @ExitThisProc;
MOV ECX , EDX;
ADD ECX , EAX;
MOV BH , ESI[ECX];
CMP BH , EDI[EDX];
JNZ @ExitLoop2;
INC EDX;
JMP @Loop2;
@ExitLoop2:
@NextLoop:
Inc EAX;
JMP @Loop1;
@NoFindExit :
MOV EAX , -1;
@ExitThisProc:
POP EDX;
POP ECX;
POP EBX;
POP EDI;
POP ESI;
end;
Function ChangeMemory(OldValue , NewValue : String) : integer;
var
Buf : PChar;
i , Len , Pos : integer;
lpNumberOfBytesRead : DWORD;
begin
if Not Readed then begin
Result := -1;
Exit;
end;
Result := 0;
Len := Length(OldValue);
for i:=0 to High(BaseAddress) do begin
GetMem(Buf,RegionSize[i]);
ZeroMemory(Buf,RegionSize[i]);
ReadProcessMemory(PHandle,BaseAddress[i],Buf,RegionSize[i],lpNumberOfBytesRead);
if lpNumberOfBytesRead>0 then begin
Pos := PosStr(@OldValue[1],Buf,Len,RegionSize[i]);
if Pos<>-1 then begin
WriteProcessMemory(PHandle,
Ptr(LongWord(BaseAddress[i])+LongWord(Pos)),
@NewValue[1],
Len,
lpNumberOfBytesRead);
end;
end;
FreeMem(Buf);
end;
end;
Procedure CloseProcessMemory;
begin
CloseHandle(PHandle);
SetLength(BaseAddress,0);
SetLength(RegionSize,0);
Readed := False;
end;
end.
调用ChangeMemory时,内存中有多个相同的字符串,但只能替换第一个,为什么?
BaseAddress : array of Pointer;
RegionSize : array of integer;
Readed : Boolean = False;
PHandle : THandle;
Function OpenProcessMemory(PID : integer) : integer;
var
StartPos : LongWord;
Buffer : TMemoryBasicInformation;
SysInfo : TSystemInfo;
begin
Result := -1;
GetSystemInfo(SysInfo);
StartPos := LongWord(SysInfo.lpMinimumApplicationAddress);
ZeroMemory(@Buffer,Sizeof(Buffer));
PHandle := OpenProcess(PROCESS_ALL_ACCESS,True,PID);
//如果要申请特权,写在这里
if PHandle<=0 then exit;
SetLength(BaseAddress,0);
SetLength(RegionSize,0);
while not VirtualQueryEx(PHandle,
Ptr(StartPos),
Buffer,
Sizeof(Buffer))>0 do begin
StartPos := LongWord(Buffer.BaseAddress) + LongWord(Buffer.RegionSize);
if StartPos > LongWord(SysInfo.lpMaximumApplicationAddress) then Break;
if Buffer.State = MEM_COMMIT then begin
if BOOL(Buffer.Protect and (PAGE_READWRITE or PAGE_EXECUTE_READWRITE or PAGE_EXECUTE_WRITECOPY)) Then begin
SetLength(BaseAddress,Length(BaseAddress)+1);
BaseAddress[High(BaseAddress)] := Buffer.BaseAddress;
SetLength(RegionSize,Length(RegionSize)+1);
RegionSize[High(RegionSize)] := Buffer.RegionSize;
end;
end;
end;
Result := 0;
Readed := True;
end;
Function PosStr(Key , Sour : PChar; KeyLen , SourLen : integer) : integer ; stdcall;
asm
PUSH ESI;
PUSH EDI;
PUSH EBX;
PUSH ECX;
PUSH EDX;
MOV ESI , [Sour];
MOV EDI , [Key];
MOV ECX , 0;
MOV EAX , 0;
MOV BL , [EDI];
@Loop1:
CMP EAX , SourLen;
JZ @NoFindExit;
CMP BL , ESI[EAX];
JNZ @NextLoop;
MOV EDX , 0;
@Loop2:
CMP EDX , KeyLen;
JZ @ExitThisProc;
MOV ECX , EDX;
ADD ECX , EAX;
MOV BH , ESI[ECX];
CMP BH , EDI[EDX];
JNZ @ExitLoop2;
INC EDX;
JMP @Loop2;
@ExitLoop2:
@NextLoop:
Inc EAX;
JMP @Loop1;
@NoFindExit :
MOV EAX , -1;
@ExitThisProc:
POP EDX;
POP ECX;
POP EBX;
POP EDI;
POP ESI;
end;
Function ChangeMemory(OldValue , NewValue : String) : integer;
var
Buf : PChar;
i , Len , Pos : integer;
lpNumberOfBytesRead : DWORD;
begin
if Not Readed then begin
Result := -1;
Exit;
end;
Result := 0;
Len := Length(OldValue);
for i:=0 to High(BaseAddress) do begin
GetMem(Buf,RegionSize[i]);
ZeroMemory(Buf,RegionSize[i]);
ReadProcessMemory(PHandle,BaseAddress[i],Buf,RegionSize[i],lpNumberOfBytesRead);
if lpNumberOfBytesRead>0 then begin
Pos := PosStr(@OldValue[1],Buf,Len,RegionSize[i]);
if Pos<>-1 then begin
WriteProcessMemory(PHandle,
Ptr(LongWord(BaseAddress[i])+LongWord(Pos)),
@NewValue[1],
Len,
lpNumberOfBytesRead);
end;
end;
FreeMem(Buf);
end;
end;
Procedure CloseProcessMemory;
begin
CloseHandle(PHandle);
SetLength(BaseAddress,0);
SetLength(RegionSize,0);
Readed := False;
end;
end.
调用ChangeMemory时,内存中有多个相同的字符串,但只能替换第一个,为什么?
解决方案 »
- 创建bpl子窗体时怎样把变量传递方法。
- delphi如何判断端口是否被占用
- 如何定义sql语句中的返回值
- 请问除了CppWebBrowser还有什么控件可以显示网页吗?
- 在d7中为什么不能使用自带的TLCDNumber组件?
- 我觉得Combobox不能实现我想实现的功能:
- 如何在TreeView中用右键选中后弹出快捷菜单?(急)
- 怎样在调用API函数打开画图软件的同时将图片将某张图片加载到画图里直接编辑,而不用再次打开文件.
- 如何动态的把用户名,注册码写入exe文件,过后如何读出来,(BCB or delphi)
- 求救,请各位大侠帮帮忙,这里先谢谢大家了
- dbgrid里修改cell的值或者删除记录后,有时候会出现记录的重复行的问题!为什么?救急!
- 多线程,指针,TThreadList,Out of memory求救
我一下子,也没弄明白,应该是PosStr这个函数没有循环完。