核心提示:uses RichEdit;{$WARN SYMBOL_DEPRECATED OFF}typeTRichEditStreamReader = classprivateFStream: TStream;...
uses RichEdit; {$WARN SYMBOL_DEPRECATED OFF} type TRichEditStreamReader = class private FStream: TStream; FHandle: THandle; protected procedure WndProc(var Message: TMessage); virtual; public constructor Create(AStream: TStream); destructor Destroy; override; property Handle: THandle read FHandle; end; { TRichEditStreamReader } constructor TRichEditStreamReader.Create(AStream: TStream); begin FStream := AStream; FHandle := AllocateHWnd(WndProc); end; destructor TRichEditStreamReader.Destroy; begin DeallocateHWnd(FHandle); inherited; end; procedure TRichEditStreamReader.WndProc(var Message: TMessage); begin case Message.Msg of WM_COPYDATA: begin if not Assigned(FStream) then Exit; FStream.Write(PCopyDataStruct(Message.LParam)^.lpData^, PCopyDataStruct(Message.LParam)^.cbData); end; end; end; function Process_ReadRichEditStream( AHandle: THandle; AStream: TStream; AFormat: Longword): Boolean; type TVclApi = packed record //JMP DWORD PTR [$HHHHHHHH] rJmp: Word; // FF 25 rAddress: PInteger; // API实际地址 end; PVclApi = ^TVclApi; const EditStreamCallBackBytes = #$55 + // PUSH EBP #$8B#$EC + // MOV EBP,ESP #$83#$C4#$F4 + // ADD ESP,$F4 #$8B#$45#$10 + // MOV EAX,DWORD PTR [EBP+$10] #$8B#$55#$14 + // MOV EDX,DWORD PTR [EBP+$14] #$89#$02 + // MOV DWORD PTR [EDX],EAX #$33#$D2 + // XOR EDX,EDX #$89#$55#$F4 + // MOV DWORD PTR [EBP-$0C],EDX #$89#$45#$F8 + // MOV DWORD PTR [EBP-$08],EAX #$8B#$45#$0C + // MOV EAX,DWORD PTR [EBP+$0C] #$89#$45#$FC + // MOV DWORD PTR [EBP-$04],EAX #$8D#$45#$F4 + // LEA EAX,DWORD PTR [EBP-$0C] #$50 + // PUSH EAX #$6A#$00 + // PUSH $00 #$6A#$4A + // PUSH $4A #$8B#$45#$08 + // MOV EAX,DWORD PTR [EBP+$08] #$50 + // PUSH EAX #$FF#$15#$00#$00#$00#$00 + // CALL DWORD PTR [H] -- String Index:43 #$33#$C0 + // XOR EAX,EAX #$8B#$E5 + // MOV ESP,EBP #$5D + // POP EBP #$C2#$10#$00 + // RET $0010 #$00#$00#$00#$00 + // Api Address -- String Index:55 #$00#$00#$00#$00 + // _editstream : dwCookie -- String Index:59 #$00#$00#$00#$00 + // _editstream : dwError #$00#$00#$00#$00; // _editstream : pfnCallback type PEditStream = ^TEditStream; var vEditStreamCallBack: string; vProcessId: DWORD; vProcess: THandle; vPointer: Pointer; vNumberOfBytesRead: Cardinal; vRichEditStreamReader: TRichEditStreamReader; begin Result := False; if not Assigned(AStream) then Exit; if not IsWindow(AHandle) then Exit; GetWindowThreadProcessId(AHandle, @vProcessId); vProcess := OpenProcess(PROCESS_VM_OPERATION or PROCESS_VM_READ or PROCESS_VM_WRITE, False, vProcessId); try vPointer := VirtualAllocEx(vProcess, nil, 4096, MEM_RESERVE or MEM_COMMIT, PAGE_READWRITE); vRichEditStreamReader := TRichEditStreamReader.Create(AStream); try vEditStreamCallBack := EditStreamCallBackBytes; PInteger(@vEditStreamCallBack[43])^ := Integer(vPointer) + 55 - 1; PInteger(@vEditStreamCallBack[55])^ := PVclApi(@SendMessage)^.rAddress^; PEditStream(@vEditStreamCallBack[59])^.dwCookie := vRichEditStreamReader.Handle; PEditStream(@vEditStreamCallBack[59])^.pfnCallback := vPointer; WriteProcessMemory(vProcess, vPointer, @vEditStreamCallBack[1], Length(vEditStreamCallBack), vNumberOfBytesRead); SendMessage(AHandle, EM_STREAMOUT, AFormat, Integer(Integer(vPointer) + 59 - 1)); finally vRichEditStreamReader.Free; VirtualFreeEx(vProcess, vPointer, 0, MEM_RELEASE); end; finally CloseHandle(vProcess); end; end; { Process_ReadRichEditStream } procedure TForm1.Button1Click(Sender: TObject); var vHandle: THandle; vMemoryStream: TMemoryStream; begin vHandle := FindWindow('WordPadClass', nil); if vHandle = 0 then Exit; vHandle := FindWindowEx(vHandle, 0, 'RICHEDIT50W', nil); if vHandle = 0 then Exit; vMemoryStream := TMemoryStream.Create; try Process_ReadRichEditStream(vHandle, vMemoryStream, SF_RTF); vMemoryStream.Position := 0; RichEdit1.PlainText := False; RichEdit1.Lines.LoadFromStream(vMemoryStream); finally vMemoryStream.Free; end; end;
更多详解请访问作者博客:http://blog.csdn.net/zswang/archive/2008/07/13/2645555.aspx