您的位置:首页 > 编程语言 > Delphi

[Delphi]利用createRemoteThread远程注入(非DLL插入)

2012-12-19 13:58 519 查看
DELPHI代码,直截注入别的进程,之后直截运行在别的进程中的代码!

效果是弹出一个确认框!

本方法不能在98系统下使用!

function createRemoteThread(hProcess: THandle; lpThreadAttributes: Pointer;

dwStackSize: DWORD; lpStartAddress: TFNThreadStartRoutine; lpParameter: Pointer;

dwCreationFlags: DWORD; var lpThreadId: DWORD): THandle; stdcall;

第一个参数:目标行程 ID

第二个参数:指定 SD (security descriptor), nil 表示使用预设 SD

第三个参数:堆谍大小, 0 表示使用目标行程预设堆谍大小

第四个参数:开始执行函数的位址

第五个参数:餵进上面函数参数的位址

第六个参数:旗标设定

第七个参数:回传成功后產生的 Thread ID

接着来说明一下,使用流程吧..

1. 取得目标 Process ID (用 FindWindow+GetWindowProcessID or createToolhelp32Snapshot)

2. OpenProcess 并设定 PROCESS_ALL_ACCESS (懒,用这最方便)

3. 使用 VirtualAllocEx 在目标行程内要求两块可执行可读写的空间,一块放函数,另一块放参数

4. 使用 WriteProcessMemory 将函数和参数写进刚刚要求的两块空间

5. 准备完毕,createRemoteThread

6. WaitForSingleObject (等待 Thread 结束)

7. VirtualFreeEx 释放刚刚要求的两块位址

需小心的地方:

1. 别使用 VCL, 连 string 也不能用.

2. 在目标行程执行的程式,无法直接使用 API, 需由 LoadLibraryA & GetProcAddress 来动态载入 dll 来使用 API。但是所有 kernel32.dll 的函数可直接使用, 因為每个行程必定会载入这个 dll, 所以可由本地行程先找好 LoadLibraryA & GetProcAddress 的函数位址,然后塞进参数内

3. 在目标行程执行的程式,如果用到字串的话,要小心! 不可直接用, 需将要使用的字串先写入到参数中

4. 很想用 VCL 的话,目非行程执行的程式就直接载入一个用 delphi 写的 dll 吧 XD

最后,以一个例子当结尾

简单在指定的 Process 秀出一个 MessageBox..

使用了 FindWindow+GetWindowProcessId 取得目标 Process Id

1. 要在目标行程内执行的程式

procedure myMessageBegin(param: PParam); stdcall;

type

LoadLibraryFunc = function(lib: PChar): DWORD; stdcall;

GetProcAddressFunc = function(lib: DWORD; name: PChar): DWORD; stdcall;

MessageBoxFunc = function(handle: DWORD; msg, title: PChar; flag: DWORD): DWORD; stdcall;

var

myLoad: LoadLibraryFunc;

myGetProc: GetProcAddressFunc;

myMsg: MessageBoxFunc;

hlib: DWORD;

begin

myLoad := LoadLibraryFunc(param^.fLoadLibrary);

myGetProc := GetProcAddressFunc(param^.fGetProcAddress);

hlib := myLoad(@param^.sUser[0]);

myMsg := MessageBoxFunc(myGetProc(hlib, @param^.sMessage[0]));

myMsg(0, @param^.sUser[0], @param^.sMessage[0], MB_OK);

end;

看的出来,写的相当迂迴 @@

2. 注入函数的参数型别定义

//要呼叫 MessageBox, 需先 LoadLibrary User32.dll

//然后再用 GetProcAddress 取得 MessageBox 位址

//所以需要以下栏位

// PS: 因為系统 DLL 函数位址在每个行程都一样,

// 加上每个程行必定含入 kernel32.dll, 所以可以放心先取得

// LoadLibrary & GetProcAddress 的位址

PParam = ^TParam;

TParam = packed record

fLoadLibrary: DWORD;

fGetProcAddress: DWORD;

sUser: array[0..10] of Char;

sMessage: array[0..11] of Char;

end;

3. 注入的程式

procedure TForm1.btnInjectClick(Sender: TObject);

var

hwin, pid: DWORD;

hprocess: DWORD;

param: TParam;

pparam, pfunc: Pointer;

hlib: DWORD;

hthread: DWORD;

s: string;

v: DWORD;

iSize: DWORD;

begin

// 寻找指定视窗

hwin := FindWindow(nil, PChar(edtName.Text));

if hwin = 0 then begin

MessageBox(self.Handle, '找不到指定的视窗!', '讯息', MB_OK or MB_ICONWARNING);

Exit;

end;

// 取得该视窗所属的 Process Id

GetWindowThreadProcessId(hwin, pid);

if pid = 0 then begin

MessageBox(self.Handle, '找不到行程ID', '讯息', MB_OK or MB_ICONWARNING);

Exit;

end;

// 开啟这个行程,权限设為 ALL

hprocess := OpenProcess(PROCESS_ALL_ACCESS, False, pid);

if hprocess = 0 then begin

MessageBox(self.Handle, '无法开啟行程', '讯息', MB_OK or MB_ICONWARNING);

Exit;

end;

// 在目标行程内要求参数记忆体

pparam := VirtualAllocEx(hprocess, nil, SizeOf(param), MEM_COMMIT, PAGE_READWRITE);

if pparam = nil then begin

MessageBox(self.Handle, '要求参数记忆体失败', '讯息', MB_OK or MB_ICONWARNING);

CloseHandle(hprocess);

Exit;

end;

// 在目标行程内要求函数记忆体

// 这裡定义一个 myMessageEnd 空函数来判断 myMessageBegin 大小

iSize := DWORD(@myMessageEnd)-DWORD(@myMessageBegin)+1;

pfunc := VirtualAllocEx(hprocess, nil, iSize, MEM_COMMIT, PAGE_EXECUTE_READWRITE);

if pfunc = nil then begin

MessageBox(self.Handle, '要求函数记忆体失败', '讯息', MB_OK or MB_ICONWARNING);

CloseHandle(hprocess);

Exit;

end;

// 初始化参数

FillChar(param, SizeOf(param), 0);

hlib := GetModuleHandle('Kernel32.dll');

param.fLoadLibrary := DWORD(GetProcAddress(hlib, 'LoadLibraryA'));

param.fGetProcAddress := DWORD(GetProcAddress(hlib, 'GetProcAddress'));

s := 'user32.dll';

Move(s[1], param.sUser[0], Length(s));

s := 'MessageBoxA';

Move(s[1], param.sMessage[0], Length(s));

// 写入参数

WriteProcessMemory(hprocess, pparam, @param, SizeOf(param), v);

// 写入函数

WriteProcessMemory(hprocess, pfunc, @myMessageBegin, iSize, v);

// 准备完毕,跑吧!!

hthread := createRemoteThread(hprocess, nil, 0, pfunc, pparam, 0, v);

// 等!

WaitForSingleObject(hthread, INFINITE);

// 释放刚刚要求的记忆体

VirtualFreeEx(hprocess, pfunc, iSize, MEM_DECOMMIT);

VirtualFreeEx(hprocess, pparam, SizeOf(param), MEM_DECOMMIT);

// 收尾

CloseHandle(hprocess);

end;
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: