一. delphi远程注入Dll文件 首先,您必须找到已经在内存中运行的应用程序(EXE)的PID。以下函数将通过名称获得PID1234567891011121314151617181920212223function PIDbyName(ProcessName: PWideChar): DWORD;var ProcessSnap: Int64; ProcessEntry32: TProcessEntry32;begin Result := 0; ProcessSnap := CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0); if ProcessSnap <> INVALID_HANDLE_VALUE then begin ProcessEntry32.dwSize := SizeOf(TPROCESSENTRY32); if Process32First(ProcessSnap, ProcessEntry32) then repeat if lstrcmpi(ProcessEntry32.szExeFile, ProcessName) = 0 then begin Result := ProcessEntry32.th32ProcessID; CloseHandle(ProcessSnap); exit; end; until not Process32Next(ProcessSnap, ProcessEntry32); Result := 0; CloseHandle(ProcessSnap); end;end; 这是32/64位应用程序的DLL注入函数 Source是DLL,Target是EXE123456789101112131415161718192021222324252627282930function InjectDLL(Source, Target : PWideChar) : boolean;var dwThreadID: Cardinal; hProc, hThread: THandle; BytesToWrite, BytesWritten: SIZE_T; pRemoteBuffer, pLoadLibrary: Pointer;begin hProc := OpenProcess(PROCESS_CREATE_THREAD or PROCESS_QUERY_INFORMATION or PROCESS_VM_OPERATION or PROCESS_VM_WRITE or PROCESS_VM_READ, False, PIDbyName(Target)); if hProc = 0 then exit(false); try BytesToWrite := SizeOf(WideChar) * (Length(Source) + 1); pRemoteBuffer := VirtualAllocEx(hProc, nil, BytesToWrite, MEM_COMMIT,PAGE_READWRITE); if pRemoteBuffer = nil then exit(false); try if not WriteProcessMemory(hProc, pRemoteBuffer, Source, BytesToWrite, BytesWritten) then exit(false); pLoadLibrary := GetProcAddress(GetModuleHandle('kernel32.dll'), 'LoadLibraryW'); hThread := CreateRemoteThread(hProc, nil, 0, pLoadLibrary, pRemoteBuffer, 0, dwThreadID); try WaitForSingleObject(hThread, INFINITE); finally Result := true; CloseHandle(hThread); end; finally VirtualFreeEx(hProc, pRemoteBuffer, 0, MEM_RELEASE); end; finally CloseHandle(hProc); end;end; 简单的DLL12345678910111213141516171819202122232425library testDLL; uses System.SysUtils, System.Classes, Winapi.Windows; {$R *.res} procedure DLLEntryPoint(dwReason: DWord);var DLLHandle : DWORD;begin case dwReason of DLL_PROCESS_ATTACH: MessageBox(DLLHandle, 'Process Attach', 'Info', mb_Ok); DLL_PROCESS_DETACH: MessageBox(DLLHandle, 'Process Detach', 'Info', mb_Ok); end;end; begin DllProc := @DLLEntryPoint; DllEntryPoint(DLL_PROCESS_ATTACH);end. 用法:InjectDLL(‘testDLL.dll’, ‘yourapplication.exe’)二. delphi远程直接注入代码执行(非DLL插入是代码注入)12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394//-------------------------注入代码的函数---------------------------- {参数说明: InHWND:被注入的窗口句柄 Func:注入的函数的指针 Param:参数的指针 ParamSize:参数的大小 } procedure InjectFunc(InHWND: HWND; Func: Pointer; Param: Pointer; ParamSize: DWORD); var hProcess_N: THandle; ThreadAdd, ParamAdd: Pointer; hThread: THandle; ThreadID: DWORD; lpNumberOfBytes:DWORD; begin GetWindowThreadProcessId(InHWND, @ThreadID); //获得窗口ID hProcess_N := OpenProcess(PROCESS_ALL_ACCESS, False, ThreadID);//打开被注入的进程 ThreadAdd := VirtualAllocEx(hProcess_N, nil, 4096, MEM_COMMIT, PAGE_READWRITE); //申请写入代码空间 WriteProcessMemory(hProcess_N, ThreadAdd, Func, 4096, lpNumberOfBytes); //写入函数地址 ParamAdd := VirtualAllocEx(hProcess_N, nil, ParamSize, MEM_COMMIT, PAGE_READWRITE); //申请写入代码参数空间 WriteProcessMemory(hProcess_N, ParamAdd, Param, ParamSize, lpNumberOfBytes); //写入参数地址 hThread := CreateRemoteThread(hProcess_N, nil, 0, ThreadAdd, ParamAdd, 0, lpNumberOfBytes); //创建远程线程 ResumeThread(hThread); //直接运行线程 CloseHandle(hThread); //关闭线程 VirtualFreeEx(hProcess_N, ThreadAdd, 4096, MEM_RELEASE); VirtualFreeEx(hProcess_N, ParamAdd, ParamSize, MEM_RELEASE); //释放申请的地址 CloseHandle(hProcess_N); //关闭打开的句柄 end; //-----------------------------定义一个参数类型----------------------- type TPickCallParam = packed record ax, ay: single; end; PPickCallParam = ^TPickCallParam; //指向结构的指针(C中叫这种方式的数据应该叫结构体吧) procedure runCall(p:PPickCallParam);stdcall; // 走路call var addres,addres1,addres2:pointer; x,y:single; begin addres:=pointer($0045ec00); addres1:=pointer($00462620); addres2:=pointer($0045f000); x:=p^.ax; //目的地X坐标 y:=p^.ay; //目的地Y坐标 asm pushad mov eax, dword ptr [$8f207c] mov eax, dword ptr [eax+$1C] mov esi, dword ptr [eax+$20] mov ecx, dword ptr [esi+$ba0] push 1 call addres mov edi, eax lea eax, dword ptr [esp+$18] push eax push 0 mov ecx, edi call addres1 push 0 push 1 push edi mov ecx, dword ptr [esi+$ba0] push 1 call addres2 mov eax, dword ptr [$8f207c] mov eax, dword ptr [eax+$1C] mov eax, dword ptr [eax+$20] mov eax, dword ptr [eax+$ba0] mov eax, dword ptr [eax+$30] mov ecx, dword ptr [eax+4] mov eax, x mov [ecx+$20], eax mov eax, y mov [ecx+$28], eax popad end; END; procedure TForm1.Button1Click(Sender: TObject);//在控件中做个按钮 测试 var CallParam:TPickCallParam; begin; getmem(pname,33); myhwnd := FindWindow(nil,'Element Client');{查找窗口句柄} GetWindowThreadProcessId(myhwnd, aproc); {得到窗口ID} phnd := OpenProcess(PROCESS_VM_READ , False, aproc);{以完全访问权限打开进程句柄} if (phnd<>0 ) then begin CallParam.ax:= 1860.0; //给注入代码函数赋值 CallParam.ay:=120.0; //给注入代码函数赋值 InjectFunc(myhWnd,@runCall,@CallParam,SizeOf(CallParam)); //运行注入代码函数 sleep(100); CloseHandle(PHND) //关闭进程 end; end; 三. 远程代码或DLL注入x86/x64/Win2k/win7~Win8.1 64位全可用(最重要的隆重登场)上面的一和二远程注入,在win7 64位系统下,不能成功注入service服务程序,下面代码实现在64位系统,可以注入系统进程,服务进程等!看关键函数NtCreateThreadEx,而在win7 64位下的注入问题http://forum.sources.ru/index.php?showtopic=313636有相应讨论123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116program Inject; {$APPTYPE CONSOLE} {$IF CompilerVersion >= 21.0}{$WEAKLINKRTTI ON}{$RTTI EXPLICIT METHODS([]) PROPERTIES([]) FIELDS([])}{$IFEND} uses Winapi.Windows; Type NtCreateThreadExProc = Function(Var hThread:THandle; Access:DWORD; Attributes:Pointer; hProcess:THandle; pStart:Pointer; pParameter:Pointer; Suspended:BOOL; StackSize, u1, u2:DWORD; Unknown:Pointer):DWORD; stdcall; Function CheckOs():Boolean;Var lpVersionInformation :TOSVersionInfoW;begin Result := False; if GetVersionExW(lpVersionInformation) then begin if lpVersionInformation.dwPlatformId = VER_PLATFORM_WIN32_NT Then begin if (lpVersionInformation.dwMajorVersion < 6) then begin Result := True; end; end; end;end; Function EnableDebugPrivilege():Boolean;Var hToKen :THandle; TokenPri :TTokenPrivileges;begin Result := False; if(OpenProcessToken(GetCurrentProcess(),TOKEN_ADJUST_PRIVILEGES, hToKen)) Then begin TokenPri.PrivilegeCount := 1; If LookupPrivilegeValueW(Nil, 'SeDebugPrivilege', TokenPri.Privileges[0].Luid) Then begin TokenPri.Privileges[0].Attributes := SE_PRIVILEGE_ENABLED; Result := AdjustTokenPrivileges(hToken, False, TokenPri, SizeOf(TTokenPrivileges), Nil, PDWORD(Nil)^); end Else Writeln('LookupPrivilege Error'); CloseHandle(hToKen); end;end; Function RemoteThread(hProcess:THandle; pThreadProc:Pointer; pRemote:Pointer):THandle;Label NtCreate, Create;Var pFunc :Pointer; hThread :THandle;begin hThread := 0; if Not CheckOs() then //根据系统版本来选择使用的API begin NtCreate: pFunc := GetProcAddress(LoadLibraryW('ntdll.dll'), 'NtCreateThreadEx'); if pFunc = Nil then Goto Create; NtCreateThreadExProc(pFunc)(hThread, $1FFFFF, Nil, hProcess, pThreadProc, pRemote, False, 0, 0, 0, Nil); if hThread = 0 then Goto Create; end Else begin Create: hThread := CreateRemoteThread(hProcess, Nil, 0, pThreadProc, pRemote, 0, PDWORD(Nil)^); end; Writeln('RemoteThread Ok!'); Result := hThread;end; Function InjectDll2Pid(szPath:PWideChar; uPID:DWORD):Boolean;Var hProcess :THandle; hThread :THandle; szRemote :PWideChar; uSize :SIZE_T; uWrite :SIZE_T; pStartAddr:Pointer;begin Result := False; if EnableDebugPrivilege then begin //先提升下进程的权限 hProcess := OpenProcess(PROCESS_ALL_ACCESS, false, uPID); if hProcess > 0 then begin uSize := lstrlenW(szPath) * 2 + 4; szRemote := VirtualAllocEx(hProcess, Nil, uSize, MEM_COMMIT, PAGE_EXECUTE_READWRITE); if WriteProcessMemory(hProcess, szRemote, szPath, uSize, uWrite) And (uWrite = uSize) then begin pStartAddr := GetProcAddress(LoadLibrary('Kernel32.dll'), 'LoadLibraryW'); hThread := RemoteThread(hProcess, pStartAddr, szRemote); Result := hThread <> 0; CloseHandle(hThread); end Else begin Writeln('WriteMemory Error'); end; end; end; end; Function StrToInt(S: String): Integer;Var E: Integer;Begin Val(S, Result, E);End; begin InjectDll2Pid(PWideChar(ParamStr(2)), StrToInt(ParamStr(1)));end. NtCreateThreadEx注入注意事项:64位的进程,只能使用64位的dll注入,注入程序本身也必须编译为64位程序,32位的进程,只能使用32位的dll注入,注入程序本身编译为32位程序,不然会注入不成功!比如你把程序编译为32程序,想在win7 64位下往services.exe注入,是不会成功的,services.exe在win7 64位下是64位程序!