c语言跨进程回调函数,关于跨进程使用回调函数的研究,以跨进程获取Richedit中RTF流为例...

核心提示: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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
//官方网站:www.feiyuol.com //郁金香灬老师 //QQ 150330575 //个人网站:www.yjxsoft.com 进程调用CALL 进程调用带多个的参数CALL // myInject_dll.cpp : 定义控制台应用程序的入口点。 // #include "stdafx.h" #include #include"RWA.h" //PVOID 进程分配内存(WORD nSize ); //1、获取进程句柄 //2、读写 分配内存 创建线程 //3、进程分配内存 void mycall() { PVOID p1=进程分配内存(1000); printf("分配的内存地址=%p\n",p1); printf("按回车键 释放内存\n"); getchar(); 进程释放内存(p1,1000); printf("已经 释放内存\n"); } LPTHREAD_START_ROUTINE a; BOOL 进程调用CALL(PVOID pcall地址,PVOID plst参数 ); //LoadLibraryA(dll名字指针) //MessageBeep(1) void Test远程调用MessageBeep() { 进程调用CALL(MessageBeep,(PVOID)0x12768); } //注入my022MFC.dll到目标进程 void Test3() { char szDllName[]="my022MFC.dll"; //全路径 // char szDllName[]="C:\\Users\\yjxsoft\\Documents\\visual studio 2010\\Projects\\my022\\Debug\\my022MFC.dll"; PVOID p1=进程分配内存(1000); printf("分配的内存地址=%p\n",p1); WN((DWORD)p1,szDllName,sizeof(szDllName));//WriteProcessMemory /*进程调用CALL(LoadLibraryA,(PVOID)szDllName);*/ 进程调用CALL(LoadLibraryA,(PVOID)p1); } void Test4() { // char szDllName[]="my022MFC.dll"; //全路径 char szDllName[]="E:\\1905\\代码\\my022-24\\Debug\\my022MFC.dll"; PVOID p1=进程分配内存(1000); printf("分配的内存地址=%p\n",p1); WN((DWORD)p1,szDllName,sizeof(szDllName));//WriteProcessMemory /*进程调用CALL(LoadLibraryA,(PVOID)szDllName);*/ 进程调用CALL(LoadLibraryA,(PVOID)p1); } int _tmain(int argc, _TCHAR* argv[]) { //mycall(); Test3(); Test4(); return 0; } //作业 //1、练习进程注入DLL //2、进程分配的内存内存 使用完后 用VirtualFreeEx释放掉 //3、进程句柄使用完后用CloseHandle释放句柄资源
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值