Bueno, yo tuve ese problema y lo que hice fue un nuevo Stream heredado de TMemoryStream y sobrescribo el método Write y ahí hago lo que quiero con los datos que me pasa en el parámetro Buffer. Yo utilizé un TMemoryStream porque lo cargo de un campo en la base de datos, pero si vas a leer un archivo, puedes heredarlo de TFileStream.
Código:
function TReplaceStream.Write(const Buffer; Count: Integer): Longint;
begin
MiFuncionReplace( Buffer... );
Result := inherited Write( Buffer, NewSize );
end;
El tema que creo de AIG, es que quiere modificar algo que pertenece al RTF, si utilizamos un StringReplace o AnsiReplaceText sobre los Lines de un RichEdit, es que accedemos al texto plano del RTF.