Delphi利用CreateRemoteThread远程注入 详细 (非dll注入,是代码注入)

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;

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 示例代码:#include <windows.h> #include <stdio.h> #include <tlhelp32.h> // 远程线程注入dll BOOL InjectDLL(DWORD dwPID, char *szDLLName); int main(int argc, char *argv[]) { printf("远程线程注入dll演示程序\n"); if (argc == 3) { DWORD dwPID = atoi(argv[1]); char *szDLLName = argv[2]; InjectDLL(dwPID, szDLLName); } else { printf("用法:InjectDLL.exe <PID> <DLLName>\n"); } return 0; } // 远程线程注入dll BOOL InjectDLL(DWORD dwPID, char *szDLLName) { HANDLE hProcess, hThread; LPVOID lpBaseAddress; LPTHREAD_START_ROUTINE lpStartAddress; DWORD dwSize, dwThreadId; char szPath[256]; char szBuffer[1024]; // 打开进程 hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, dwPID); if (hProcess == NULL) { printf("OpenProcess() Error: %d\n", GetLastError()); return FALSE; } // 获取DLL的完整路径 GetFullPathName(szDLLName, 256, szPath, NULL); // 在进程中申请虚拟内存 dwSize = strlen(szPath) + 1; lpBaseAddress = VirtualAllocEx(hProcess, NULL, dwSize, MEM_COMMIT, PAGE_READWRITE); if (lpBaseAddress == NULL) { printf("VirtualAllocEx() Error: %d\n", GetLastError()); return FALSE; } // 将DLL路径写入到虚拟内存 int nBytesWritten; WriteProcessMemory(hProcess, lpBaseAddress, szPath, dwSize, &nBytesWritten); if (nBytesWritten != dwSize) { printf("WriteProcessMemory() Error: %d\n", GetLastError()); return FALSE; } // 加载Kernel32.dll HMODULE hKernel32 = GetModuleHandle("Kernel32"); if (hKernel32 == NULL) { printf("GetModuleHandle() Error: %d\n", GetLastError()); return FALSE; } // 获取LoadLibraryA函数地址 lpStartAddress = GetProcAddress(hKernel32, "LoadLibraryA"); if (lpStartAddress == NULL) { printf("GetProcAddress() Error: %d\n", GetLastError()); return FALSE; } // 创建远程线程 hThread = CreateRemoteThread(hProcess, NULL, 0, lpStartAddress, lpBaseAddress, 0, &dwThreadId); if (hThread == NULL) { printf("CreateRemoteThread() Error: %d\n", GetLastError()); return FALSE; } // 等待远程线程结束 WaitForSingleObject(hThread, INFINITE); // 读取线程退出码 DWORD dwExitCode; GetExitCodeThread(hThread, &dwExitCode); if (dwExitCode == 0) { printf("LoadLibrary() Error: %d\n", GetLastError()); return FALSE; } // 关闭句柄 CloseHandle(hProcess); CloseHandle(hThread); return TRUE; }我不能帮助你编写代码,但是我可以提供一些参考资料,帮助你编写远程线程注入dll代码。 ### 回答2: 远程线程注入DLL是一种技术,用于在目标进程中注入自定义的动态链接库(DLL)并执行其中的代码。以下是一个使用C语言编写的远程线程注入DLL代码示例: ```c #include <stdio.h> #include <stdlib.h> #include <windows.h> int main() { // 目标进程的进程ID DWORD pid = 1234; // 加载要注入DLL路径 char dllPath[] = "C:\\path_to_dll\\mydll.dll"; // 获取目标进程句柄 HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, pid); if (hProcess == NULL) { printf("无法打开目标进程"); return -1; } // 在目标进程中为DLL路径分配内存 LPVOID dllPathAddr = VirtualAllocEx(hProcess, NULL, sizeof(dllPath), MEM_COMMIT, PAGE_READWRITE); if (dllPathAddr == NULL) { printf("无法在目标进程中分配内存"); CloseHandle(hProcess); return -1; } // 在目标进程中写入DLL路径 if (!WriteProcessMemory(hProcess, dllPathAddr, dllPath, sizeof(dllPath), NULL)) { printf("无法写入DLL路径到目标进程"); VirtualFreeEx(hProcess, dllPathAddr, 0, MEM_RELEASE); CloseHandle(hProcess); return -1; } // 获取Kernel32.dll中LoadLibrary函数的地址 HMODULE kernel32 = GetModuleHandle("kernel32.dll"); FARPROC loadLibrary = GetProcAddress(kernel32, "LoadLibraryA"); // 创建远程线程在目标进程中执行LoadLibrary函数,将DLL路径作为参数 HANDLE hThread = CreateRemoteThread(hProcess, NULL, 0, (LPTHREAD_START_ROUTINE)loadLibrary, dllPathAddr, 0, NULL); if (hThread == NULL) { printf("无法在目标进程中创建远程线程"); VirtualFreeEx(hProcess, dllPathAddr, 0, MEM_RELEASE); CloseHandle(hProcess); return -1; } // 等待远程线程执行结束 WaitForSingleObject(hThread, INFINITE); // 清理资源 VirtualFreeEx(hProcess, dllPathAddr, 0, MEM_RELEASE); CloseHandle(hThread); CloseHandle(hProcess); printf("远程线程注入DLL成功"); return 0; } ``` 这段代码首先通过`OpenProcess`函数打开目标进程,然后使用`VirtualAllocEx`在目标进程中为DLL路径分配内存,并使用`WriteProcessMemory`将DLL路径写入目标进程内存。接着,使用`GetModuleHandle`和`GetProcAddress`获取`LoadLibrary`函数的地址,然后使用`CreateRemoteThread`在目标进程中创建一个远程线程,让其执行`LoadLibrary`函数,将DLL路径作为参数传递给它。最后,使用`WaitForSingleObject`等待远程线程执行完毕,并释放之前分配的资源。 ### 回答3: 使用C语言编写远程线程注入DLL代码可以通过以下步骤实现: 1. 首先,需要创建一个目标进程的句柄。可以使用`OpenProcess`函数来打开目标进程,并获得进程的句柄。 2. 接下来,需要在目标进程中分配一块内存空间,用于存储DLL的路径和名称。可以使用`VirtualAllocEx`函数在目标进程内部分配内存。 3. 在分配的内存空间中写入DLL的路径和名称。可以使用`WriteProcessMemory`函数将DLL的路径和名称写入到目标进程的内存中。 4. 使用`GetProcAddress`函数获取`LoadLibraryA`函数的地址,该函数用于加载DLL。可以使用`GetModuleHandle`函数获取kernel32.dll的句柄,然后再调用`GetProcAddress`函数来获取`LoadLibraryA`函数的地址。 5. 使用`CreateRemoteThread`函数在目标进程中创建一个远程线程,将`LoadLibraryA`函数地址作为线程的入口点,将DLL的路径和名称作为线程的参数传递。这样,在目标进程中就会自动加载并执行DLL。 完整的代码示例如下: ```c #include <windows.h> int main() { // Step 1: 打开目标进程句柄 HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, PROCESS_ID); // Step 2: 分配内存空间 LPVOID lpRemoteBuffer = VirtualAllocEx(hProcess, NULL, MAX_PATH, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE); // Step 3: 写入DLL路径和名称 char dllPath[] = "C:\\path\\to\\dll.dll"; WriteProcessMemory(hProcess, lpRemoteBuffer, (LPVOID)dllPath, sizeof(dllPath), NULL); // Step 4: 获取LoadLibraryA函数地址 HMODULE hKernel32 = GetModuleHandleA("kernel32.dll"); FARPROC lpLoadLibraryA = GetProcAddress(hKernel32, "LoadLibraryA"); // Step 5: 创建远程线程注入DLL HANDLE hThread = CreateRemoteThread(hProcess, NULL, 0, (LPTHREAD_START_ROUTINE)lpLoadLibraryA, lpRemoteBuffer, 0, NULL); // 关闭句柄 CloseHandle(hThread); CloseHandle(hProcess); return 0; } ``` 以上就是使用C语言编写远程线程注入DLL代码。请注意,使用远程线程注入DLL可能存在一些安全风险,请谨慎使用。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值