旁路 Dll 注入常常用于 API Hook,但是对于其加载模块功能却很少有文章提及,其实这些 API 也是很有用的。
BOOL DetourCopyPayloadToProcess(
_In_ HANDLE hProcess,
_In_ REFGUID rguid,
_In_reads_bytes_(cbData) LPCVOID pvData,
_In_ DWORD cbData
);
将有效载荷复制到目标进程。
hProcess : Process into which payload should be copied.
hProcess:应将有效载荷复制的进程。
rguid : GUID
of the specified payload.
rguid : GUID
指定的有效载荷。
pvData : Pointer to payload data.
pvData:有效载荷数据指针。
pcbData : Size in bytes of payload data.
pcbData:有效载荷数据的字节数。
DetourCopyPayloadToProcess
allocated a region of memory in the target process using the VirtualAllocEx API. It then uses the WriteProcessMemory API to create an artificial PE binary module in the target memory. In the artificial module, DetourCopyPayloadToProcess
creates a .detours
section with the specified payload data.
在目标进程中使用 VirtualAllocEx
API 分配了一块内存区域。然后使用 WriteProcessMemory
API 在目标内存中创建一个人工的 PE 二进制模块。在该人工模块中, DetourCopyPayloadToProcess
创建了一个包含指定有效载荷数据的 .detours
节。
Code in the target process can find the payload by enumerating through all modules using the DetourEnumerateModules API and querying each module for the payload using the DetourFindPayload API.
目标进程中的代码可以通过遍历所有模块并使用 DetourEnumerateModules
API 查询每个模块以找到有效载荷来找到有效载荷。
DetourCopyPayloadToProcessEx
_Success_(return != NULL)
PVOID DetourCopyPayloadToProcessEx(
_In_ HANDLE hProcess,
_In_ REFGUID rguid,
_In_reads_bytes_(cbData) LPCVOID pvData,
_In_ DWORD cbData
);
hProcess : Process into which payload should be copied.
hProcess:应将有效载荷复制的进程。
rguid : GUID
of the specified payload.
rguid : GUID
指定的有效载荷。
pvData : Pointer to payload data.
pvData:有效载荷数据指针。
pcbData : Size in bytes of payload data.
pcbData:有效载荷数据的字节数。
Returns non-NULL
pointer if the payload was successfully copied to the target process.
返回非空指针,如果有效负载已成功复制到目标进程。
DetourCopyPayloadToProcessEx
operates like DetourCopyPayloadToProcess but returns a pointer to the payload in the remote process, so that code may further read or write to the payload using ReadProcessMemory
or WriteProcessMemory.
DetourCopyPayloadToProcessEx
运作方式与 DetourCopyPayloadToProcess
相似,但返回远程进程中的有效载荷指针,以便代码可以使用 ReadProcessMemory
或 WriteProcessMemory
进一步读取或写入有效载荷。
DetourCreateProcessWithDlls
创建新进程并将 DLL 加载到其中。根据目标进程选择合适的 32 位或 64 位 DLL。
BOOL DetourCreateProcessWithDlls(
_In_opt_ LPCTSTR lpApplicationName,
_Inout_opt_ LPTSTR lpCommandLine,
_In_opt_ LPSECURITY_ATTRIBUTES lpProcessAttributes,
_In_opt_ LPSECURITY_ATTRIBUTES lpThreadAttributes,
_In_ BOOL bInheritHandles,
_In_ DWORD dwCreationFlags,
_In_opt_ LPVOID lpEnvironment,
_In_opt_ LPCTSTR lpCurrentDirectory,
_In_ LPSTARTUPINFOW lpStartupInfo,
_Out_ LPPROCESS_INFORMATION lpProcessInformation,
_In_ DWORD nDlls,
_In_reads_(nDlls) LPCSTR *rlpDlls,
_In_opt_ PDETOUR_CREATE_PROCESS_ROUTINEW pfCreateProcessW
);
lpApplicationName : Application name as defined for CreateProcess API.
lpApplicationName : 为 CreateProcess API 定义的应用程序名称。
lpCommandLine : Command line as defined for CreateProcess API.
lpCommandLine:为 CreateProcess API 定义的命令行。
lpProcessAttributes : Process attributes as defined for CreateProcess API.
lpProcessAttributes:为 CreateProcess API 定义的进程属性。
lpThreadAttributes : Thread attributes as defined for CreateProcess API.
lpThreadAttributes:为 CreateProcess API 定义的线程属性。
bInheritHandles : Inherit handle flags as defined for CreateProcess API.
bInheritHandles : 继承为 CreateProcess API 定义的句柄标志。
dwCreationFlags : Creation flags as defined for CreateProcess API.
dwCreationFlags:为 CreateProcess API 定义的创建标志。
lpEnvironment : Process environment variables as defined for CreateProcess API.
lpEnvironment:按照 CreateProcess API 定义处理进程环境变量。
lpCurrentDirectory : Process current directory as defined for CreateProcess API.
lpCurrentDirectory:按 CreateProcess API 定义处理当前目录。
lpStartupInfo : Process startup information as defined for CreateProcess API.
lpStartupInfo:CreateProcess API 定义的进程启动信息。
lpProcessInformation : Process handle information as defined for CreateProcess API.
lpProcessInformation:按 CreateProcess API 定义处理进程句柄信息。
nDlls : Count of the number of DLLs in rlpDlls.
nDlls:rlpDlls 中 DLL 数量的计数
rlpDlls : Array of pathnames of the DLL to be insert into the new process. To support both 32-bit and 64-bit applications, The DLL names should end with "32" if the DLL contains 32-bit code and should end with "64" if the DLL contains 64-bit code. If the target process differs in size from the parent process, Detours will automatically replace "32" with "64" or "64" with "32" in the path name.
rlpDlls:要插入到新进程中的 DLL 路径名数组。为了支持 32 位和 64 位应用程序,如果 DLL 包含 32 位代码,则 DLL 名称应以"32"结尾;如果 DLL 包含 64 位代码,则应以"64"结尾。如果目标进程的大小与父进程不同,Detours 将自动在路径名中将"32"替换为"64"或"64"替换为"32"。
pfCreateProcessW : Pointer to program specific replacement for the CreateProcess API, or NULL
if the standard CreateProcess API should be used to create the new process.
pfCreateProcessW:指向特定程序的 CreateProcess API 替换指针,或 NULL
如果应使用标准的 CreateProcess API 创建新进程。
注释:
DetourCreateProcessWithDlls
creates a new process with the specified DLL inserted into it.
DetourCreateProcessWithDlls
创建一个新进程,并将指定的 DLL 插入其中。
The process is created in a suspended state with the CREATE_SUSPENDED flag to CreateProcess. Detours then modifies the image of the application binary in the new process to include the specified DLL as its first import. Execution in the process is then resumed. When execution resumes, the Windows process loader will first load the target DLL and then any other DLLs in the application's import table, before calling the application entry point.
进程以 CREATE_SUSPENDED
标志在 CreateProcess 中创建为挂起状态。然后旁路修改新进程中的应用程序二进制映像,将其指定的 DLL 作为其第一个导入项。随后在进程中的执行将继续。当执行恢复时,Windows 进程加载器将首先加载目标 DLL,然后加载应用程序导入表中的任何其他 DLL,最后调用应用程序入口点。
具体见:https://github.com/microsoft/Detours/blob/main/src/uimports.cpp#L17
DetourCreateProcessWithDlls
modifies the in-memory import table of the target PE binary program in the new process it creates. The updated import table will contain a reference to function ordinal #1 exported from the target DLL. If the target process is 32-bit and the parent process is 64-bit, or if the target process is 64-bit and the parent process is 32-bit, DetourCreateProcessWithDlls
will use rundll32.exe
to load the DLL into a helper process that matches the target process temporarily in order to update the target processes import table with the correct DLL.
DetourCreateProcessWithDlls
修改新创建的进程中目标 PE 二进制程序的内存导入表。更新的导入表将包含对从目标 DLL 导出的函数序号 #1 的引用。如果目标进程是 32 位且父进程是 64 位,或者如果目标进程是 64 位且父进程是 32 位, DetourCreateProcessWithDlls
将使用 rundll32.exe
将 DLL 载入一个临时匹配目标进程的辅助进程,以便用正确的 DLL 更新目标进程的导入表。(注入器和目标进程位数不匹配时候的处理,这一点比较巧妙)
Note: The new process will fail to start if the target DLL does not contain a exported function with ordinal #1.
注意:如果目标 DLL 不包含序号为#1 的导出函数,新进程将无法启动。
After the target DLL has been loaded, it can reverse changes to the in-memory import table by calling DetourRestoreAfterWith. To facilitate reversing these changes, DetourCreateProcessWithDlls
copies relevant reversal data into a payload in the target process using the DetourCopyPayloadToProcess API. The loaded DLL should call the DetourRestoreAfterWith API to restores the contents of the import table.
在目标 DLL 加载后,可以通过调用 DetourRestoreAfterWith
来撤销内存中导入表的更改。为了便于撤销这些更改, DetourCreateProcessWithDlls
使用 DetourCopyPayloadToProcess
API 将相关撤销数据复制到目标进程的有效负载中。加载的 DLL 应调用 DetourRestoreAfterWith
API 来恢复导入表的内容。