欢迎您访问我爱IT技术网,今天小编为你分享的电脑教程是网络协议方面的经验知识教程:如何在Windows NT中隐藏自己(二),下面是详细的分享!
如何在Windows NT中隐藏自己(二)
=====[ 7.2 全局钩子 ]============================================================
枚举进程的问题在前面讲NtQuerySystemInformation这个API的时候已经解决了。系统中有一
些本地进程,所以我们可以通过改写函数的第一条指令的方法来挂钩他们。对于每一个运行
程我们都必须要这么做。我们要在目标进程中分配一块内存,在这里写入我们要挂钩的函数
的新的代码。然后我们用jmp指令来改写这些函数的第一个指令。这个跳转把执行重定位到
我们的代码。所以当被挂钩的函数被调用的时候这个jmp指令会被立即执行。我们必须要保
存每个函数的被改写的第一条指令。我们需要它们去调用原始的被挂钩的函数。保存指令在
我的“挂钩Windows API”一文的第3.2.3节中有描述。
首先我们要通过NtOpenProcess打开目标进程并且得到句柄。如果我们没有足够的权限这会
失败。
NTSTATUS NtOpenProcess(
OUT PHANDLE ProcessHandle,
IN ACCESS_MASK DesiredAccess,
IN POBJECT_ATTRIBUTES ObjectAttributes,
IN PCLIENT_ID ClientId OPTIONAL
);
ProcessHandle是一个指向返回句柄的指针。DesiredAccess应该被设置成PROCESS_ALL_
ACCESS。我们可以把目标进程的PID设置成ClientId结构的UniqueProcess值,Unique-
Thread应该为0。打开的句柄总是可以通过NtClose函数关闭。
#define PROCESS_ALL_ACCESS 0x001F0FFF
现在我们要为我们的代码分配内存。这个可以通过NtAllocateVirtualMemory实现。
NTSTATUS NtAllocateVirtualMemory(
IN HANDLE ProcessHandle,
IN OUT PVOID BaseAddress,
IN ULONG ZeroBits,
IN OUT PULONG AllocationSize,
IN ULONG AllocationType,
IN ULONG Protect
);
ProcessHandle就是NtOpenProcess返回的句柄。BaseAddress是一个指向内存开始处的指针。
这里存放着分配的内存的地址。输入值可以为NULL。AllocationSize是一个指向我们想要申
请的内存大小的指针。同时,它还用来返回分配内存的实际大小。最好把AllocationType设
置成MEM_TOP_DOWN和MEM_COMMIT,因为这样会分配到尽可能靠近动态链接库的高地址。
#define MEM_COMMIT 0x00001000
#define MEM_TOP_DOWN 0x00100000
然后我们可以用NtWriteVirtualMemory把我们的代码写进去。
NTSTATUS NtWriteVirtualMemory(
IN HANDLE ProcessHandle,
IN PVOID BaseAddress,
IN PVOID Buffer,
IN ULONG BufferLength,
OUT PULONG ReturnLength OPTIONAL
);
BaseAddress就是NtAllocateVirtualMemory返回的地址。Buffer指向了函数写入的字节数,
BufferLength是我们要写入的字节数。
现在我们要挂钩单一函数。只有ntdll.dll是每个进程都要加载的。所以我们我们检查我们
要挂钩的ntdll.dll中的函数是不是被进程引入了。但是这个函数(在其他DLL中)在内存中
放置的位置是可分配的,所以在这个地址上改写很容易在目标进程中引发错误。这就是为什
么我们要检查这个库(存放我们要挂钩的函数的地方)是否被目标进程加载了。
我们要通过NtQueryInformationProcess得到目标进程的PEB(进程环境块)。
NTSTATUS NtQueryInformationProcess(
IN HANDLE ProcessHandle,
IN PROCESSINFOCLASS ProcessInformationClass,
OUT PVOID ProcessInformation,
IN ULONG ProcessInformationLength,
OUT PULONG ReturnLength OPTIONAL
);
我们要把ProcessInformationClass设置成ProcessBasicInformation。然后PROCESS_BASIC_
INformATION结构返回到ProcessInformation缓冲,其大小有ProcessInformationLength指定。
#define ProcessBasicInformation 0
typedef struct _PROCESS_BASIC_INformATION {
NTSTATUS ExitStatus;
PPEB PebBaseAddress;
KAFFINITY AffinityMask;
KPRIORITY BasePriority;
ULONG UniqueProcessId;
ULONG InheritedFromUniqueProcessId;
} PROCESS_BASIC_INformATION, *PPROCESS_BASIC_INformATION;
PebBaseAddress是我们想要的。在PebBaseAddress + 0x0c的地方是PPEB_LDR_DATA的地址。
这个可以通过NtReadVirtualMemory调用得到。
NTSTATUS NtReadVirtualMemory(
IN HANDLE ProcessHandle,
IN PVOID BaseAddress,
OUT PVOID Buffer,
IN ULONG BufferLength,
OUT PULONG ReturnLength OPTIONAL
);
参数和NtWriteVirtualMemory函数相似。
在PPEB_LDR_DATA + 0x1c的地方是InInitializationOrderModuleList的地址。这是进程加载
的链接库的列表。我们只关心这个结构的一部分。
typedef struct _IN_INITIALIZATION_ORDER_MODULE_LIST {
PVOID Next,
PVOID Prev,
DWORD ImageBase,
DWORD ImageEntry,
DWORD ImageSize,
...
);
Next是一个指向下一个记录的指针,Prev指向前一个记录,最后一个记录指向第一个。
ImageBase是模块在内存中的地址,ImageEntry是模块的入口,ImageSize是其大小。
对于所有我们有挂钩的库我们都要得到它的ImageBase(比如用GetModuleHandle或者Load-
Library)。我们用这个ImageBase和InInitializationOrderModuleList中的每个入口进行
比较。
现在我们已经为挂钩做好准备了。因为我们要挂钩运行中的进程,有一个可能是我们的代码
可能在被改写的同时被执行。这会发生错误,所以首先我们要停止目标进程中的所有线程。
可以通过在第四节中描述的NtQuerySystemInformation的SystemProcessAndThreadsInformation
类型得到线程列表。但是我们要描述一下用来存放线程信息的SYSTEM_THREADS结构。
typedef struct _SYSTEM_THREADS {
LARGE_INTEGER KernelTime;
LARGE_INTEGER UserTime;
LARGE_INTEGER CreateTime;
ULONG WaitTime;
PVOID StartAddress;
CLIENT_ID ClientId;
KPRIORITY Priority;
KPRIORITY BasePriority;
ULONG ContextSwitchCount;
THREAD_STATE State;
KWAIT_REASON WaitReason;
} SYSTEM_THREADS, *PSYSTEM_THREADS;
对每个线程我们要通过NtOpenThread得到其句柄。我们要对它使用ClientId。
NTSTATUS NtOpenThread(
OUT PHANDLE ThreadHandle,
IN ACCESS_MASK DesiredAccess,
IN POBJECT_ATTRIBUTES ObjectAttributes,
IN PCLIENT_ID ClientId
)
我们要获得的句柄存储在ThreadHandle中。我们要把DesiredAccess设置成THREAD_SUSPEND_
RESUME。
#define THREAD_SUSPEND_RESUME 2
ThreadHandle用来调用NtSuspendThread。
NTSTATUS NtSuspendThread(
IN HANDLE
以上就是关于如何在Windows NT中隐藏自己(二)的网络协议知识分享,更多电脑教程请移步到>>电脑教程。
- 评论列表(网友评论仅供网友表达个人看法,并不表明本站同意其观点或证实其描述)
-
