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时,内存中有多个相同的字符串,但只能替换第一个,为什么?
解决方案 »
- 请教windows2003server上dcom的配置
- 有没有哪位好心人给个波形显示的源码啊?
- 请教:程序最小化后,如何取得其显示内容?
- Delphi5环境下编译的dcu文件怎么才能在Delphi7下使用?
- dbgrideditbutton事件
- Rave报表设计器的问题?哪位高手有RAVE的注删码啥?急
- 我是新手:如何导入组件?
- 坚难的开始,一个关于自动累加的问题(一定进来看看)
- win API 到底是个什么东东。谁都用通俗的话解释一下呢?谢谢
- 谁能教我如何使用Tfilestream
- dbgrid里修改cell的值或者删除记录后,有时候会出现记录的重复行的问题!为什么?救急!
- 多线程,指针,TThreadList,Out of memory求救
我一下子,也没弄明白,应该是PosStr这个函数没有循环完。