我们知道,可以用CreateProcess执行一个外部程序,或者更简单的调用shellapi执行。我的要求是,知道一个外部程序,可能是(.com,.exe,.pif,.sys,.vxd)等,怎么让这个文件入驻内存,并且将ip指向代码开始段,开始执行这个代码,然后使这个代码执行时空集成为一个进程。然后返回主程序,那个被执行的代码程序和主程序完全没有关系。怎么办?
是不是,就是自己手工实现CreateProcessAPI的功能呀?
是不是,就是自己手工实现CreateProcessAPI的功能呀?
解决方案 »
- 求助DataSnap客户端insert数据时候错误,说数据类型未知
- 求教IOCP里面如何封装数据库的操作
- IdUDPClient和idUDPServer在局域网可以使用,但是外网ip没办法
- 请问variant和vector之间可以转换吗?
- Delphi8的第一个ASP.Net程序调试通过!
- 当我们双击csdn的搜索栏时,会显示以前的搜索内容。请问操作系统把这些字符串存在什么地方??
- 请问如何让窗体控件随窗体最大化而改变,还有如何让最大化键无效?
- 关于DELPHI的网络编程,大家近来讨论讨论啊(问了好几天了)
- 请推荐几个好的表格组件(不跟数据源连接的)
- 操作文本文件的问题
- 普通的主窗口(非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;