我们知道,可以用CreateProcess执行一个外部程序,或者更简单的调用shellapi执行。我的要求是,知道一个外部程序,可能是(.com,.exe,.pif,.sys,.vxd)等,怎么让这个文件入驻内存,并且将ip指向代码开始段,开始执行这个代码,然后使这个代码执行时空集成为一个进程。然后返回主程序,那个被执行的代码程序和主程序完全没有关系。怎么办?
是不是,就是自己手工实现CreateProcessAPI的功能呀?
是不是,就是自己手工实现CreateProcessAPI的功能呀?
解决方案 »
- 一个简单的语法,放在线程中程序就崩溃,放在BUTTON下就没问题,有代码
- 调用 Acrobat pdfmaker.dll 实现doc转换pdf(超难!!)问题!!
- delphi的工资问题
- 怎样使用Wnd_proc(var message:TMessage)函数过滤掉自己不想要的消息。
- 函數中創建對像要不要釋放?
- 个人闹钟 PPClock 7.1 正式发布,欢迎大家下载使用
- quikreport能不能安装在d7上?
- 怎么样在程序中(也就是通过编程方式)替adoquery1增加计算字段或其它字段?
- ★★★急急急……关于EPSON LQ-1600自定义纸张问题,希望各位帮忙,谢谢!!!
- 要让Qreport不分页,应该如何做
- 普通的主窗口(非MDI的),上面漂浮一个显示窗口(总在最上面),如何让它不能移动到主窗口外?
- 如何在已经关联到数据库集上的ClientDataSet控件增加一个字段,并且该字段允许编辑
这个你找个调式器应该就可以找到类似的代码了。
一般调试器都有这功能的ollydbg、windbg之类的。
unit unit1;interfaceuses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls;const
WM_HOOKED = WM_USER + 3221; {Hook安装成功的消息}type
TThreadProVarList = record {变量列表}
SendMessage: DWORD;
ExitProcess: DWORD;
ExitThread: DWORD; {上面用来保存API真实地址}
WndHandle: DWORD;
end; TForm1 = class(TForm)
Button1: TButton;
Button2: TButton;
procedure Button1Click(Sender: TObject);
procedure Button2Click(Sender: TObject);
private
{在目标进程中申请的内存地址}
ThreadAdd: Pointer;
PID, PHandle: DWORD; {目标窗口进程ID,句柄和线程ID}
ThreadHandle, ThreadID: Thandle; {新的远程线程的ID和句柄}
procedure WMHOOKED(var Msg: TMessage);message WM_HOOKED;
public
{ Public declarations }
end;var
Form1: TForm1;implementation{$R *.dfm}procedure ThreadPro;
var
VarList: TThreadProVarList;
begin
asm
mov eax, $FFFFFFFF {到$FFFFFFFF的偏移是7}
mov VarList.SendMessage, eax
mov eax, $FFFFFFFF {这个$FFFFFFFF是在上一个偏移位置加8}
mov VarList.WndHandle, eax
mov eax, $FFFFFFFF
mov VarList.ExitProcess, eax
mov eax, $FFFFFFFF
mov VarList.ExitThread, eax
push 0
push 0
push 4245 {4245就是自定义的WM_HOOKED}
push VarList.WndHandle
call VarList.SendMessage
push 0
call VarList.ExitThread
end;
end;procedure TForm1.Button1Click(Sender: TObject);
var
{要注入线程的窗口句柄和临时存放的句柄}
WndHandle, TmpHandle: THandle;
DllModule, SendPro, WriteCount: DWORD;
ExitPro, ExitTPro: DWORD;
begin
{先查找到要注入远程线程的窗口}
WndHandle := FindWindow(nil, '记事本');
{得到其进程和线程ID}
GetWindowThreadProcessId(WndHandle, PID);
{以完全访问权限打开进程句柄}
PHandle := OpenProcess(PROCESS_ALL_ACCESS, False, PID);
{在目标进程中分配内存}
ThreadAdd := VirtualAllocEx(PHandle, nil, 4096, MEM_COMMIT, PAGE_EXECUTE_READWRITE);
{把自定义函数写入到目标进程中}
WriteProcessMemory(PHandle, ThreadAdd, @ThreadPro, 4096, WriteCount);
{以挂起方式建立远端线程,以便修改}
ThreadHandle := CreateRemoteThread(PHandle, nil, 0, ThreadAdd, nil, CREATE_SUSPENDED, ThreadID);
{得到API真实的地址}
DllModule := LoadLibrary('User32.dll');
SendPro := DWORD(GetProcAddress(DllModule, 'SendMessageW'));
DllModule := LoadLibrary('Kernel32.dll');
ExitPro := DWORD(GetProcAddress(DllModule, 'ExitProcess'));
ExitTPro := DWORD(GetProcAddress(DllModule, 'ExitThread'));
{把API真实地址和数据写入到在目标进程中的函数中}
TmpHandle := Self.Handle;
WriteProcessMemory(PHandle, Pointer(LongInt(ThreadAdd)+7), @SendPro, SizeOf(DWORD), WriteCount);
WriteProcessMemory(PHandle, Pointer(LongInt(ThreadAdd)+15), @TmpHandle, SizeOf(DWORD), WriteCount);
WriteProcessMemory(PHandle, Pointer(LongInt(ThreadAdd)+23), @ExitPro, SizeOf(DWORD), WriteCount);
WriteProcessMemory(PHandle, Pointer(LongInt(ThreadAdd)+31), @ExitTPro, SizeOf(DWORD), WriteCount);
{开始运行远端线程}
ResumeThread(ThreadHandle);
CloseHandle(ThreadHandle);
end;procedure TForm1.Button2Click(Sender: TObject);
begin
{释放在目标进程中分配的内存}
VirtualFreeEx(PHandle, ThreadAdd, 4096, MEM_DECOMMIT);
{关闭不用的句柄}
CloseHandle(PHandle);
end;procedure TForm1.WMHOOKED(var Msg: TMessage);
begin
MessageBox(self.Handle, '建立远端线程成功', '!!!', MB_OK);
end;