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时,内存中有多个相同的字符串,但只能替换第一个,为什么?