阅读:4410回复:15
如何实现NtUserGetWindowLong?
shadow ssdt中并没有NtUserGetWindowLong对应的索引号,为了实现GetWindowLong的功能,我尝试通过两次调用NtUserSetWindowLong,实现NtUserGetWindowLong,因为NtUserSetWindowLong在为一个窗口设置一个索引值的时候,会返回原来的值,借助于这一点的确可以通过两次调用NtUserSetWindowLong实现NtUserGetWindowLong。不过结果很不理想。如何在内核中实现NtUserGetWindowLong函数的调用。比如说WIndows 2000/xp/2003
|
|
沙发#
发布于:2007-12-06 09:06
killvxk ,用你的法轮大法拦截一下
NtUserCallNextHookEx( HHOOK Hook, int Code, WPARAM wParam, LPARAM lParam) 试试,为什么替换的函数获得控制权后,对应的几个参数驴头不对马嘴啊?为了获得这些参数我还要费劲千辛万苦,从ebp跟踪Win32 API CallNextHookEx的调用堆栈,把这些入口参数找出来。什么原因造成我的 NewNtUserCallNextHookEx,入口参数紊乱啊? |
|
板凳#
发布于:2007-12-06 09:10
我看了一下User32!GetWindowLong的汇编代码(Windows xp sp2),没有找到user32.dll->ntdll.dll,调用ntuser*系列函数的痕迹。
|
|
地板#
发布于:2007-12-07 10:49
谢谢楼上两位。看来在拦截NtUser*函数时,尝试得到窗口的各种属性值是非常麻烦的一件事。如果这样做
DWORD MyNtUserGetWindowLong(HWND hWnd, int nIndex) { DWORD OldValue = NtUserSetWindowLong( hWnd, nIndex,0); NtUserSetWindowLong( hWnd, nIndex, OldValue); return OldValue; } 结果使用dwStyle 调用上述函数后,某些程序开始紊乱,一些窗口打开后将被立即关闭。主要原因是某些窗口设置零的窗口风格。 |
|
地下室#
发布于:2007-12-07 10:55
NtUserCallNextHookEx函数汇编代码包含retn 10h,意味着这是一个四个参数的函数调用,联系到CallNextHookEx函数的四个参数,我们很容易把它们对应起来,事实上可能是个误区,我分别跟踪了这两个函数,发现CallNextHookEx->NtUserCallNextHookEx的过程中,第一个参数hHook钩子句柄不见了,剩余的三个参数逐个往前移了一个位置,变成了
NtUserCallNextHookEx(int code,WPARAM wParam,LPARAM lParam, DWORD dwKnown); 为了得到CallNextHookEx调用的hHook参数,不得已从系统调用NtUserCallNextHookEx的EBP寄存器中遍历调用堆栈,得到了CallNextHookEx入口的四个参数,方法十分烦琐。 GNiDiA能告诉咱,NtUserCallNextHookEx真正的原型是如何定义的,最后一个参数到底是什么含义。 |
|
5楼#
发布于:2007-12-07 15:48
引用第9楼slwqw于2007-12-07 14:00发表的 : 多谢! |
|
6楼#
发布于:2007-12-10 09:29
引用第11楼killvxk于2007-12-09 02:24发表的 : 是在NtUserCallTwoParam函数实现中找NtUserGetWindowLong入口地址,还是通过调用NtUserCallTwoParam函数,实现NtUserGetWindowLong雷同的功能啊?好人做到底,送佛送西天 #define TWOPARAM_ROUTINE_ENABLEWINDOW 0x53 #define TWOPARAM_ROUTINE_UNKNOWN 0x54 #define TWOPARAM_ROUTINE_SHOWOWNEDPOPUPS 0x55 #define TWOPARAM_ROUTINE_SWITCHTOTHISWINDOW 0x56 #define TWOPARAM_ROUTINE_VALIDATERGN 0x57 #define TWOPARAM_ROUTINE_SETWNDCONTEXTHLPID 0x58 #define TWOPARAM_ROUTINE_CURSORPOSITION 0x59 #define TWOPARAM_ROUTINE_SETCARETPOS 0x60 DWORD STDCALL NtUserCallTwoParam( DWORD Param1, DWORD Param2, DWORD Routine); 是否存在 #define TWOPARAM_ROUTINE_GETWINDOWLONG xxxxxx 然后传入一个句柄,一个索引。返回值就是对应的属性值。 |
|
7楼#
发布于:2007-12-10 13:15
反汇编和跟踪GetWindowLongW的结果是没有发现调用NtUserCallTwoParam函数。
|
|
8楼#
发布于:2007-12-11 16:38
没有办法,只好根据不同的操作系统搜索NtUserMessageCall,
查找 :u0008:bf80efa5 L30 0008:bf80efa5 8bff mov edi,edi 0008:bf80efa7 55 push ebp 0008:bf80efa8 8bec mov ebp,esp 0008:bf80efaa 83ec0c sub esp,0c 0008:bf80efad 56 push esi 0008:bf80efae 57 push edi 0008:bf80efaf e8361bffff call bf800aea 0008:bf80efb4 8b4d08 mov ecx,[ebp+08] 0008:bf80efb7 e8e425ffff call bf8015a0 0008:bf80efbc 8b4d1c mov ecx,[ebp+1c] 0008:bf80efbf 8bf0 mov esi,eax 0008:bf80efc1 85f6 test esi,esi 得到bf8015a0地址后,使用fastcall调用,得到HWND对应的PWND结构,然后在这个结构中某某个成员(+20h)即为对应的dwStyle。谁给贴一份完整的PWND结构啊。 typedef struct tagWND { // wnd THRDESKHEAD head; WW; // WOW-USER common fields. Defined in wowuserp.h // The presence of "state" at the start of this structure is assumed // by the STATEOFFSET macro. PWND spwndNext; // Handle to the next window PWND spwndParent; // Backpointer to the parent window. PWND spwndChild; // Handle to child PWND spwndOwner; // Popup window owner field RECT rcWindow; // Window outer rectangle RECT rcClient; // Client rectangle WNDPROC_PWND lpfnWndProc; // Can be WOW address or standard address PCLS pcls; // Pointer to window class KHRGN hrgnUpdate; // Accumulated paint region PPROPLIST ppropList; // Pointer to property list PSBINFO pSBInfo; // Words used for scrolling PMENU spmenuSys; // Handle to system menu PMENU spmenu; // Menu handle or ID KHRGN hrgnClip; // Clipping region for this window LARGE_UNICODE_STRING strName; int cbwndExtra; // Extra bytes in window PWND spwndLastActive; // Last active in owner/ownee list KHIMC hImc; // Associated input context handle KERNEL_ULONG_PTR dwUserData; // Reserved for random application data } WND; 上面的WW第二个成员是什么东东, GETFNID(pwnd) #define GETFNID(pwnd) ((pwnd)->fnid & ~FNID_STATUS_BITS) 神秘的fnid偏移量是多少啊? |
|