📄 addprocessinitx.txt
字号:
AddProcessInitX package allows user to do 2 things with newly created
& suspended NT process:
*) to execute user code before statically loaded modules are initialized
(= DllMains called with DLL_PROCESS_ATTACH)
- AddProcessInitHandler.h
*) to load module before statically loaded modules are loaded
- AddProcessInitDLL.h
These 2 things are possible in Windows 9x via AH functions.
AH Scouts in NT are executed after process is initialized.
When you need to perform some actions before NT process is fully initialized
(rare cases) use AddProcessInitX. You do not get private thread like in case
of AH functions - you mustn't manipulate with calling thread.
AddProcessInitX was not tested on Windows XP.
Important note: DON'T CALL WHAT IS NOT INITIALIZED!
(don't call what you've not imported)
----------------------------------------------------------------------------
AddProcessInitHandler.h contains function hAddProcessInitHandler
that allows to execute user code before DllMains & TlsCallbacks of
statically loaded modules are called with DLL_PROCESS_ATTACH in NT.
hAddProcessInitHandler is similar to hRemoteExecute AH function.
BOOL WINAPI hAddProcessInitHandler(HANDLE hProcess,
PVOID ProcessInitHandler,
DWORD ProcessInitHandlerSize,
PVOID UserPointer);
hProcess .. handle to newly created & suspended process (check it
using hGetProcFlags(hProcess) & RC_PF_NOTINITED). It
must have PROCESS_VM_OPERATION, PROCESS_VM_READ and
PROCESS_VM_WRITE access.
ProcessInitHandler .. pointer to block of self-relative code (similar
to AH scout).
Code will be called as DllMain:
ProcessInitHandler(hntdll, fdwReason, lpvReserved).
hntdll .. handle to NTDLL.DLL module. Can be used with
LdrGetProcedureAddress.
Developer can call functions in initialized modules only
(at DLL_PROCESS_ATTACH/DETACH it is NTDLL.DLL only).
If developer wants to stop process execution, ProcessInitHandler
must return FALSE when fdwReason is DLL_PROCESS_ATTACH.
Error box will be displayed. Return TRUE means to return nonzero
AL x86 register.
If developer doesn't want to receive DLL_THREAD_* notifications
can call LdrDisableThreadCalloutsForDll (equiv. to
DisableThreadLibraryCalls).
ProcessInitHandlerSize .. (dword aligned) size of ProcessInitHandler
block.
UserPointer .. every occurence of APIHUserMark in ProcessInitHandler
will be replaced with UserPointer.
Other marks:
APIHCodeBodyMark - will be replaced with pointer to
ProcessInitHandler in Target process.
APIHPreviousProcessInitHandlerMark - will be replaced
with pointer to previous handler. If it is equal 0
simply return.
Minimum ProcessInitHandler function:
BOOL APIENTRY ProcessInitHandler(hntdll, fdwReason, lpvReserved) {
return(CallNextProcessInitHandler(hntdll, fdwReason, lpvReserved));
}
Because you never know if the new process you've created wasn't
initialized already (in CreateProcess hook, for example GlobalC.dll)
you should check it:
CreateProcess(...., CREATE_SUSPENDED,..,&pi);
if(hGetProcFlags(pi.hProcess) & RC_PF_NOTINITED)
hAddProcessInitHandler(...);
else
hRemoteExecute(...);
ResumeThread(pi.hThread);
----------------------------------------------------------------------------
AddProcessInitDLL.h contains function hAddProcessInitDLL (both ANSI/UNICODE)
that allows to load user I_DLL before other statically modules are loaded.
I_DLL is initialized after the whole module tree I_DLL imports is initialized.
Example: I_DLL imports from KERNEL32.DLL and OLE32.DLL.
1) I_DLL is loaded.
2) KERNEL32.DLL is loaded (and its import tree is loaded).
3) OLE32.DLL is loaded (and its import tree is loaded).
4) Other static DLLs are loaded.
--- All statically imported modules are loaded now
5) KERNEL32.DLL's import tree is initialized.
6) KERNEL32.DLL is initialized.
7) OLE32.DLL's import tree is initialized.
8) OLE32.DLL is initialized.
9) I_DLL is initialized.
10) Other statically loaded modules are initialized.
I_DLL is first initialized module in process when it doesn't have static import
or when it imports from NTDLL.DLL only. Such a I_DLL can intercept even API/code
called during KERNEL32.DLL initialization. When you're using ApiHooks for hooking,
KERNEL32.DLL is initialized before hooks are applied because ApiHooks imports
from KERNEL32.DLL. For the case of intercepting APIs/code called during KERNEL32.DLL
initialization, link your I_DLL with NtApiWorks libraries.
I_DLL is loaded statically (= forever) and can't be unloaded (is unloaded with
Target termination).
Because you never know if the new process you've created wasn't
initialized already (in CreateProcess hook, for example GlobalC.dll)
you should check it:
CreateProcess(...., CREATE_SUSPENDED,..,&pi);
if(hGetProcFlags(pi.hProcess) & RC_PF_NOTINITED)
hAddProcessInitDLL(...);
else
hLoadAndCall(...);
ResumeThread(pi.hThread);
hAddProcessInitDLL function is similar to hLoadAndCall AH function:
BOOL WINAPI hAddProcessInitDLL( HANDLE hProcess,
LPCTSTR DllName,
DWORD TimeDateStamp,
LPCTSTR lpHomeDirectory);
LPCTSTR lpCurrentDirectory);
hProcess .. handle to newly created & suspended process (check it
using hGetProcFlags(hProcess) & RC_PF_NOTINITED). It
must have PROCESS_VM_OPERATION, PROCESS_VM_READ and
PROCESS_VM_WRITE.
DllName .. (full) name of I_DLL. If name has extension it must contain it
('dll' extension is not appended).
TimeDateStamp .. contents of TimeDateStamp field in PE header of DllName.
0 if not known.
lpHomeDirectory .. Target's home directory, NULL when Target's home directory
is in calling process' search path.
lpCurrentDirectory .. Target's current directory, NULL for calling process'
current directory. Ignored when TimeDateStamp is not 0.
In order to load I_DLL to Target when DllName doesn't contain path, I_DLL
must be present in Target's search path. If it is not, Target is terminated
with DLL_NOT_FOUND and error box is displayed.
I_DLL must export at least one code/data starting with ordinal 1.
Last added I_DLL is loaded first.
When you know TimeDateStamp, specify it. When you don't know it (it is 0)
DllName must contain path or it must be in calling process' search path or in
lpHomeDirectory or in lpCurrentDirectory.
TimeDateStamp, lpHomeDirectory, lpCurrentDirectory are ignored when Target
doesn't have bound import. In this case I_DLL must export something. I_DLL
can be relocated in this case.
When Target has bound import (MS executables) I_DLL mustn't be relocated
and doesn't have to export anything. I_DLL must have nonzero TimeDateStamp.
Important note: I_DLL must have "good" image base so that I_DLL is not relocated!
If I_DLL is relocated, Target's initialization fails with OBJECT_NOT_FOUND error box.
"Good" base is not: main module's , NTDLL's, KERNEL32's, USER32's and OLE32's image
base and base < 0x400000.
"Good" base is base of 0x3???0000 type.
When you're adding more I_DLLs, they must have different bases.
Adding the same I_DLL more times makes no sense.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -