逆--Win7x64 UserTimer结构获取,NtUserSetTimer,_SetTimer,InternalSetTimer 枚举进程定时器

用户层调用SetTimer-->内核NtUserSetTimer处理

NtUserSetTimer -->_SetTimer --> InternalSetTimer-->FindTimer / HMAllocObject

去看看NtUserSetTimer
函数原型
UINT_PTR
APIENTRY
NtUserSetTimer
(
   HWND hWnd,
   UINT_PTR nIDEvent,
   UINT uElapse,
   TIMERPROC lpTimerFunc
)

.text:FFFFF97FFF084BD0 ; __int64 __fastcall NtUserSetTimer(HWND hWnd, __int64 nIDTimer, __int64 uElapse, __int64 lpTimerFunc)
.text:FFFFF97FFF084BD0 NtUserSetTimer  proc near               ; DATA XREF: .text:FFFFF97FFF0D30C0o
.text:FFFFF97FFF084BD0                                         ; .pdata:FFFFF97FFF2E9AF0o ...
.text:FFFFF97FFF084BD0
.text:FFFFF97FFF084BD0 hWnd            = qword ptr  8
.text:FFFFF97FFF084BD0 nIDTime         = qword ptr  10h
.text:FFFFF97FFF084BD0 uElapse         = qword ptr  18h
.text:FFFFF97FFF084BD0 lpTimerFuc      = qword ptr  20h
.text:FFFFF97FFF084BD0
.text:FFFFF97FFF084BD0                 mov     rax, rsp
.text:FFFFF97FFF084BD3                 mov     [rax+8], rbx
.text:FFFFF97FFF084BD7                 mov     [rax+10h], rbp
.text:FFFFF97FFF084BDB                 mov     [rax+18h], rsi
.text:FFFFF97FFF084BDF                 mov     [rax+20h], rdi
.text:FFFFF97FFF084BE3                 push    r12
.text:FFFFF97FFF084BE5                 sub     rsp, 20h
.text:FFFFF97FFF084BE9                 mov     rdi, rcx        ; hWnd
.text:FFFFF97FFF084BEC                 mov     rcx, cs:gpresUser
.text:FFFFF97FFF084BF3                 mov     rbp, r9
.text:FFFFF97FFF084BF6                 mov     esi, r8d
.text:FFFFF97FFF084BF9                 mov     r12, rdx
.text:FFFFF97FFF084BFC                 call    cs:__imp_ExEnterPriorityRegionAndAcquireResourceExclusive
.text:FFFFF97FFF084C02                 xor     ebx, ebx
.text:FFFFF97FFF084C04                 mov     cs:gbValidateHandleForIL, 1
.text:FFFFF97FFF084C0B                 mov     cs:gptiCurrent, rax
.text:FFFFF97FFF084C12                 cmp     rdi, rbx
.text:FFFFF97FFF084C15                 jz      short loc_FFFFF97FFF084C26 ; tagWND*
.text:FFFFF97FFF084C17                 mov     rcx, rdi
.text:FFFFF97FFF084C1A                 call    ValidateHwnd    ; 据我所知这个返回tagWND*
.text:FFFFF97FFF084C1F                 cmp     rax, rbx
.text:FFFFF97FFF084C22                 jnz     short loc_FFFFF97FFF084C29
.text:FFFFF97FFF084C24                 jmp     short loc_FFFFF97FFF084C51
.text:FFFFF97FFF084C26 ; ---------------------------------------------------------------------------
.text:FFFFF97FFF084C26
.text:FFFFF97FFF084C26 loc_FFFFF97FFF084C26:                   ; CODE XREF: NtUserSetTimer+45j
.text:FFFFF97FFF084C26                 mov     rax, rbx        ; tagWND*
.text:FFFFF97FFF084C29
.text:FFFFF97FFF084C29 loc_FFFFF97FFF084C29:                   ; CODE XREF: NtUserSetTimer+52j
.text:FFFFF97FFF084C29                 mov     ecx, 0Ah
.text:FFFFF97FFF084C2E                 mov     r9, rbp         ; lpTimerFunc
.text:FFFFF97FFF084C31                 mov     rdx, r12        ; nTimerID
.text:FFFFF97FFF084C34                 cmp     esi, ecx
.text:FFFFF97FFF084C36                 cmovb   esi, ecx
.text:FFFFF97FFF084C39                 mov     ecx, 7FFFFFFFh
.text:FFFFF97FFF084C3E                 cmp     esi, ecx
.text:FFFFF97FFF084C40                 cmova   esi, ecx
.text:FFFFF97FFF084C43                 mov     rcx, rax        ; tagWND*
.text:FFFFF97FFF084C46                 mov     r8d, esi        ; uElapse
.text:FFFFF97FFF084C49                 call    _SetTimer       ; _SetTimer
.text:FFFFF97FFF084C49                                         ; (
.text:FFFFF97FFF084C49                                         ; tagWND* hWnd_Object
.text:FFFFF97FFF084C49                                         ; __int64 nTimerID
.text:FFFFF97FFF084C49                                         ; __int64 elapse
.text:FFFFF97FFF084C49                                         ; __int64 lpTimerFunc
.text:FFFFF97FFF084C49                                         ; )
.text:FFFFF97FFF084C4E                 mov     rbx, rax
.text:FFFFF97FFF084C51
.text:FFFFF97FFF084C51 loc_FFFFF97FFF084C51:                   ; CODE XREF: NtUserSetTimer+54j
.text:FFFFF97FFF084C51                 call    UserSessionSwitchLeaveCrit
.text:FFFFF97FFF084C56                 mov     rbp, [rsp+28h+nIDTime]
.text:FFFFF97FFF084C5B                 mov     rsi, [rsp+28h+uElapse]
.text:FFFFF97FFF084C60                 mov     rdi, [rsp+28h+lpTimerFuc]
.text:FFFFF97FFF084C65                 mov     rax, rbx
.text:FFFFF97FFF084C68                 mov     rbx, [rsp+28h+hWnd]
.text:FFFFF97FFF084C6D                 add     rsp, 20h
.text:FFFFF97FFF084C71                 pop     r12
.text:FFFFF97FFF084C73                 retn
.text:FFFFF97FFF084C73 ; ---------------------------------------------------------------------------
.text:FFFFF97FFF084C74                 db 8 dup(90h)
.text:FFFFF97FFF084C74 NtUserSetTimer  endp

据我所知
call ValidateHwnd
会得到一个窗口对象 tagWND*
内部某个地方应该call了UserGetWindowObject



这个函数检验了hwnd的有效性,然后就call _SetTimer


看下_SetTimer
SetTimer
(
tagWND* hWnd_Object
__int64 nTimerID
__int64 elapse
__int64 lpTimerFunc
)

.text:FFFFF97FFF084C7C ; __int64 __fastcall SetTimer(__int64 pTagWND, __int64 nTimerID, __int64 elapse, __int64 lpTimerFunc)
.text:FFFFF97FFF084C7C _SetTimer       proc near               ; CODE XREF: NtUserSetTimer+79p
.text:FFFFF97FFF084C7C                                         ; xxxMNDoScroll+86p ...
.text:FFFFF97FFF084C7C
.text:FFFFF97FFF084C7C var_local_flag  = dword ptr -18h
.text:FFFFF97FFF084C7C pTagWnd         = qword ptr  8
.text:FFFFF97FFF084C7C nTimerID        = qword ptr  10h
.text:FFFFF97FFF084C7C elapse          = qword ptr  18h
.text:FFFFF97FFF084C7C
.text:FFFFF97FFF084C7C                 mov     [rsp+pTagWnd], rbx
.text:FFFFF97FFF084C81                 mov     [rsp+nTimerID], rbp
.text:FFFFF97FFF084C86                 mov     [rsp+elapse], rsi
.text:FFFFF97FFF084C8B                 push    rdi
.text:FFFFF97FFF084C8C                 sub     rsp, 30h
.text:FFFFF97FFF084C90                 mov     rdi, r9         ; lpTimerFunc
.text:FFFFF97FFF084C93                 mov     esi, r8d        ; elapse
.text:FFFFF97FFF084C96                 mov     rbp, rdx        ; nTimerID
.text:FFFFF97FFF084C99                 mov     rbx, rcx        ; pTagWND
.text:FFFFF97FFF084C9C                 test    rcx, rcx        ; 如果pTagWND为NULL 跳转
.text:FFFFF97FFF084C9F                 jz      short loc_FFFFF97FFF084CC2 ; flag
.text:FFFFF97FFF084CA1                 call    cs:__imp_PsGetCurrentProcessWin32Process
.text:FFFFF97FFF084CA7                 mov     r10, [rbx+10h]  ; tagWND+0x10是_THRDESKHEAD结构下的tagTHREADINFO
.text:FFFFF97FFF084CAB                 cmp     rax, [r10+158h] ; tagTHREADINFO +0x158是tagPROCESSINFO结构 第一个成员是EPROCESS
.text:FFFFF97FFF084CB2                 jz      short loc_FFFFF97FFF084CC2 ; 相同跳转 如果当前EPROCESS和结构下的EPROCESS相同 判断是不是自己应该
.text:FFFFF97FFF084CB4                 mov     ecx, 5
.text:FFFFF97FFF084CB9                 call    UserSetLastError
.text:FFFFF97FFF084CBE                 xor     eax, eax
.text:FFFFF97FFF084CC0                 jmp     short loc_FFFFF97FFF084CD8
.text:FFFFF97FFF084CC2 ; ---------------------------------------------------------------------------
.text:FFFFF97FFF084CC2
.text:FFFFF97FFF084CC2 loc_FFFFF97FFF084CC2:                   ; CODE XREF: _SetTimer+23j
.text:FFFFF97FFF084CC2                                         ; _SetTimer+36j
.text:FFFFF97FFF084CC2                 and     [rsp+38h+var_local_flag], 0 ; flag
.text:FFFFF97FFF084CC7                 mov     r9, rdi         ; lpTimerFunc
.text:FFFFF97FFF084CCA                 mov     r8d, esi        ; Elapse
.text:FFFFF97FFF084CCD                 mov     rdx, rbp        ; TimerID
.text:FFFFF97FFF084CD0                 mov     rcx, rbx        ; tagWND*
.text:FFFFF97FFF084CD3                 call    InternalSetTimer ; InternalSetTimer
.text:FFFFF97FFF084CD3                                         ; (
.text:FFFFF97FFF084CD3                                         ; tagWND* pWND
.text:FFFFF97FFF084CD3                                         ; __int64 TimerID
.text:FFFFF97FFF084CD3                                         ; __int64 elapse
.text:FFFFF97FFF084CD3                                         ; __int64 lpTimerFunc
.text:FFFFF97FFF084CD3                                         ; __int64 flags //这个应该就是为0
.text:FFFFF97FFF084CD3                                         ; )
.text:FFFFF97FFF084CD8
.text:FFFFF97FFF084CD8 loc_FFFFF97FFF084CD8:                   ; CODE XREF: _SetTimer+44j
.text:FFFFF97FFF084CD8                 mov     rbx, [rsp+38h+pTagWnd]
.text:FFFFF97FFF084CDD                 mov     rbp, [rsp+38h+nTimerID]
.text:FFFFF97FFF084CE2                 mov     rsi, [rsp+38h+elapse]
.text:FFFFF97FFF084CE7                 add     rsp, 30h
.text:FFFFF97FFF084CEB                 pop     rdi
.text:FFFFF97FFF084CEC                 retn
.text:FFFFF97FFF084CEC ; ---------------------------------------------------------------------------
.text:FFFFF97FFF084CED                 align 20h
.text:FFFFF97FFF084CED _SetTimer       endp

这个函数判断当前来设置timer是不是自己

防止应用程序从一个到另一个应用程序窗口中设置一个定时器

然后就
call InternalSetTimer
在这下面就能获得很多我们需要的结构信息了

text:FFFFF97FFF0B8A38 ; =============== S U B R O U T I N E =======================================
.text:FFFFF97FFF0B8A38
.text:FFFFF97FFF0B8A38 ; InternalSetTimer
.text:FFFFF97FFF0B8A38 ; (
.text:FFFFF97FFF0B8A38 ; tagWND* pWND
.text:FFFFF97FFF0B8A38 ; __int64 TimerID
.text:FFFFF97FFF0B8A38 ; __int64 elapse
.text:FFFFF97FFF0B8A38 ; __int64 lpTimerFunc
.text:FFFFF97FFF0B8A38 ; __int64 flags //这个应该就是为0
.text:FFFFF97FFF0B8A38 ; )
.text:FFFFF97FFF0B8A38
.text:FFFFF97FFF0B8A38 ; __int64 __fastcall InternalSetTimer(__int64 pWND, __int64 TimerID, __int64 Elasp, __int64 lpTimerFuc, __int64 flags)
.text:FFFFF97FFF0B8A38 InternalSetTimer proc near              ; CODE XREF: AccessTimeOutReset+48p
.text:FFFFF97FFF0B8A38                                         ; _SetTimer+57p ...
.text:FFFFF97FFF0B8A38
.text:FFFFF97FFF0B8A38 pRetTagWnd      = qword ptr -48h
.text:FFFFF97FFF0B8A38 pFindedTimerObject= qword ptr -38h
.text:FFFFF97FFF0B8A38 var_28          = byte ptr -28h
.text:FFFFF97FFF0B8A38 lpTimerFuc      = qword ptr  20h
.text:FFFFF97FFF0B8A38 flags           = qword ptr  28h
.text:FFFFF97FFF0B8A38
.text:FFFFF97FFF0B8A38                 mov     rax, rsp
.text:FFFFF97FFF0B8A3B                 mov     [rax+8], rbx
.text:FFFFF97FFF0B8A3F                 mov     [rax+10h], rbp
.text:FFFFF97FFF0B8A43                 mov     [rax+18h], rsi
.text:FFFFF97FFF0B8A47                 mov     [rax+20h], r9
.text:FFFFF97FFF0B8A4B                 push    rdi
.text:FFFFF97FFF0B8A4C                 push    r12
.text:FFFFF97FFF0B8A4E                 push    r13
.text:FFFFF97FFF0B8A50                 push    r14
.text:FFFFF97FFF0B8A52                 push    r15
.text:FFFFF97FFF0B8A54                 sub     rsp, 40h
.text:FFFFF97FFF0B8A58                 cmp     cs:gbCleanupInitiated, 0
.text:FFFFF97FFF0B8A5F                 mov     esi, r8d        ; elapse
.text:FFFFF97FFF0B8A62                 mov     r14, rdx        ; TimerID
.text:FFFFF97FFF0B8A65                 mov     r12, rcx        ; tagWND*
.text:FFFFF97FFF0B8A68                 jz      short loc_FFFFF97FFF0B8A71 ; 如果elapse小于10 那么esi = 10
.text:FFFFF97FFF0B8A6A
.text:FFFFF97FFF0B8A6A loc_FFFFF97FFF0B8A6A:                   ; CODE XREF: InternalSetTimer+C0j
.text:FFFFF97FFF0B8A6A                                         ; InternalSetTimer+102j
.text:FFFFF97FFF0B8A6A                 xor     eax, eax
.text:FFFFF97FFF0B8A6C                 jmp     loc_FFFFF97FFF0B8CCD
.text:FFFFF97FFF0B8A71 ; ---------------------------------------------------------------------------
.text:FFFFF97FFF0B8A71
.text:FFFFF97FFF0B8A71 loc_FFFFF97FFF0B8A71:                   ; CODE XREF: InternalSetTimer+30j
.text:FFFFF97FFF0B8A71                 mov     eax, 0Ah        ; 如果elapse小于10 那么esi = 10
.text:FFFFF97FFF0B8A76                 cmp     r8d, eax
.text:FFFFF97FFF0B8A79                 cmovb   esi, eax
.text:FFFFF97FFF0B8A7C                 mov     eax, 7FFFFFFFh  ; 如果elapse大于7ffffff,那么elapse=7ffffff
.text:FFFFF97FFF0B8A81                 cmp     esi, eax
.text:FFFFF97FFF0B8A83                 cmova   esi, eax
.text:FFFFF97FFF0B8A86                 call    cs:__imp_PsGetCurrentThreadWin32Thread
.text:FFFFF97FFF0B8A8C                 mov     edi, dword ptr [rsp+68h+flags]
.text:FFFFF97FFF0B8A93                 mov     r15, rax        ; 当前线程
.text:FFFFF97FFF0B8A96                 mov     r13, rax
.text:FFFFF97FFF0B8A99                 test    rax, rax        ; 如果当前线程为0跳转
.text:FFFFF97FFF0B8A9C                 jz      short loc_FFFFF97FFF0B8AB0 ; 这个应该是全局tagTHREADINFO
.text:FFFFF97FFF0B8A9E                 test    dil, 4          ; flags & 4 > 0不跳
.text:FFFFF97FFF0B8AA2                 jnz     short loc_FFFFF97FFF0B8AB0 ; 这个应该是全局tagTHREADINFO
.text:FFFFF97FFF0B8AA4                 test    r12, r12        ; 如果tagWND为NULL 跳转
.text:FFFFF97FFF0B8AA7                 jz      short loc_FFFFF97FFF0B8AB7
.text:FFFFF97FFF0B8AA9                 mov     r13, [r12+10h]  ; 如果tagWND不为NULL 将tagTHREADINFO给r13
.text:FFFFF97FFF0B8AAE                 jmp     short loc_FFFFF97FFF0B8AB7
.text:FFFFF97FFF0B8AB0 ; ---------------------------------------------------------------------------
.text:FFFFF97FFF0B8AB0
.text:FFFFF97FFF0B8AB0 loc_FFFFF97FFF0B8AB0:                   ; CODE XREF: InternalSetTimer+64j
.text:FFFFF97FFF0B8AB0                                         ; InternalSetTimer+6Aj
.text:FFFFF97FFF0B8AB0                 mov     r13, cs:gptiRit ; 这个应该是全局tagTHREADINFO
.text:FFFFF97FFF0B8AB7
.text:FFFFF97FFF0B8AB7 loc_FFFFF97FFF0B8AB7:                   ; CODE XREF: InternalSetTimer+6Fj
.text:FFFFF97FFF0B8AB7                                         ; InternalSetTimer+76j
.text:FFFFF97FFF0B8AB7                 lea     rax, [rsp+68h+pFindedTimerObject]
.text:FFFFF97FFF0B8ABC                 xor     r9d, r9d        ; lpTimerFunc
.text:FFFFF97FFF0B8ABF                 mov     r8d, edi        ; flags
.text:FFFFF97FFF0B8AC2                 mov     rdx, r14        ; TimerID
.text:FFFFF97FFF0B8AC5                 mov     rcx, r12        ; tagWND*
.text:FFFFF97FFF0B8AC8                 mov     [rsp+68h+pRetTagWnd], rax ; pRetWnd
.text:FFFFF97FFF0B8ACD                 call    FindTimer       ; FindTimer
.text:FFFFF97FFF0B8ACD                                         ; (
.text:FFFFF97FFF0B8ACD                                         ; tagWND* tagWND
.text:FFFFF97FFF0B8ACD                                         ; __int64 TimerID
.text:FFFFF97FFF0B8ACD                                         ; __int64 flags
.text:FFFFF97FFF0B8ACD                                         ; __int64 lpTimerFunc
.text:FFFFF97FFF0B8ACD                                         ; tagWND** tagRetWnd
.text:FFFFF97FFF0B8ACD                                         ; )
.text:FFFFF97FFF0B8AD2                 test    eax, eax
.text:FFFFF97FFF0B8AD4                 jnz     loc_FFFFF97FFF0B8BA8 ; 如果FindTimer返回false不跳
.text:FFFFF97FFF0B8ADA                 mov     r9d, 80h        ; 申请一个0x80的空间 从这里可以知道TIME_OBJECT结构有0x80大
.text:FFFFF97FFF0B8AE0                 mov     r8b, 10h
.text:FFFFF97FFF0B8AE3                 xor     edx, edx
.text:FFFFF97FFF0B8AE5                 mov     rcx, r13        ; tagTHADINFO
.text:FFFFF97FFF0B8AE8                 call    HMAllocObject   ; 这里返回的就是PTIMER空间 PTIME是泄露代码中的结构 也就是这里的TIMER_OBJECT 保存定时器信息的结构
.text:FFFFF97FFF0B8AED                 mov     rbx, rax
.text:FFFFF97FFF0B8AF0                 mov     [rsp+68h+pFindedTimerObject], rax ; 将申请到的空间给pRetTagWnd
.text:FFFFF97FFF0B8AF5                 test    rax, rax        ; 为NULL 就返回0了
.text:FFFFF97FFF0B8AF8                 jz      loc_FFFFF97FFF0B8A6A
.text:FFFFF97FFF0B8AFE                 and     qword ptr [rax+28h], 0 ; rax + 0x28 是ptagWnd
.text:FFFFF97FFF0B8B03                 mov     ebp, 1
.text:FFFFF97FFF0B8B08                 test    r12, r12        ; tagWND为NULL跳转
.text:FFFFF97FFF0B8B0B                 jnz     short loc_FFFFF97FFF0B8B4D ; 如果tagWND有效 那么timer_object + 0x38保存TIMERID
.text:FFFFF97FFF0B8B0D                 mov     eax, cs:g_cTimerId ; 取全局TimerID
.text:FFFFF97FFF0B8B13                 mov     ecx, eax
.text:FFFFF97FFF0B8B15
.text:FFFFF97FFF0B8B15 loc_FFFFF97FFF0B8B15:                   ; CODE XREF: InternalSetTimer+F8j
.text:FFFFF97FFF0B8B15                 sub     eax, ebp        ; --eax
.text:FFFFF97FFF0B8B17                 mov     edx, 7EFFh
.text:FFFFF97FFF0B8B1C                 cmovs   eax, edx        ; if(eax<edx)(edx=7EFF)
.text:FFFFF97FFF0B8B1F                 bts     cs:gTimerId, eax
.text:FFFFF97FFF0B8B26                 mov     cs:g_cTimerId, eax
.text:FFFFF97FFF0B8B2C                 jnb     short loc_FFFFF97FFF0B8B3F ; 如果tagWND为NULL
.text:FFFFF97FFF0B8B2E                 cmp     eax, ecx        ; 如果tagWND是NULL && bts gTimerID == g_cTimerID 就释放??
.text:FFFFF97FFF0B8B30                 jnz     short loc_FFFFF97FFF0B8B15 ; 这里应该是对全局timerID进行赋值,前提是tagWND为NULL ,应该是系统的
.text:FFFFF97FFF0B8B32                 mov     rcx, rbx        ; P
.text:FFFFF97FFF0B8B35                 call    HMFreeObject
.text:FFFFF97FFF0B8B3A                 jmp     loc_FFFFF97FFF0B8A6A
.text:FFFFF97FFF0B8B3F ; ---------------------------------------------------------------------------
.text:FFFFF97FFF0B8B3F
.text:FFFFF97FFF0B8B3F loc_FFFFF97FFF0B8B3F:                   ; CODE XREF: InternalSetTimer+F4j
.text:FFFFF97FFF0B8B3F                 add     eax, 100h       ; 如果tagWND为NULL
.text:FFFFF97FFF0B8B44                 movsxd  rcx, eax
.text:FFFFF97FFF0B8B47                 mov     [rbx+38h], rcx  ; 如果tagWND为NULL timer_object + 0x38h = eax & 0x100
.text:FFFFF97FFF0B8B4B                 jmp     short loc_FFFFF97FFF0B8B51 ; 取全局tmrLishHead
.text:FFFFF97FFF0B8B4D ; ---------------------------------------------------------------------------
.text:FFFFF97FFF0B8B4D
.text:FFFFF97FFF0B8B4D loc_FFFFF97FFF0B8B4D:                   ; CODE XREF: InternalSetTimer+D3j
.text:FFFFF97FFF0B8B4D                 mov     [rax+38h], r14  ; 如果tagWND有效 那么timer_object + 0x38保存TIMERID
.text:FFFFF97FFF0B8B51
.text:FFFFF97FFF0B8B51 loc_FFFFF97FFF0B8B51:                   ; CODE XREF: InternalSetTimer+113j
.text:FFFFF97FFF0B8B51                 mov     rax, cs:gtmrListHead ; 取全局tmrLishHead
.text:FFFFF97FFF0B8B58                 lea     rcx, [rbx+18h]  ; 取timer_object + 0x18处
.text:FFFFF97FFF0B8B5C                 lea     rdx, gtmrListHead ; 取全局tmrLishHead地址
.text:FFFFF97FFF0B8B63                 mov     [rcx], rax      ; timer_object + 0x18处保存全局tmlLishHead
.text:FFFFF97FFF0B8B66                 mov     [rcx+8], rdx    ; timer_object下的gtmrLishHead +8 保存grmrLishHead
.text:FFFFF97FFF0B8B6A                 mov     [rax+8], rcx    ; gtmrLishead + 8处把保存timer_object+0x18处的全局tmlLishHead
.text:FFFFF97FFF0B8B6E                 mov     cs:gtmrListHead, rcx ; 将timer_object下的全局tmrLishHead给全局tmrLishHead 这里就是插入操作
.text:FFFFF97FFF0B8B75                 lea     rdx, [rbx+70h]  ; 取timer_object + 0x70处 这里应该是保存hashtable的
.text:FFFFF97FFF0B8B79                 lea     rax, gTimerHashTable ; 取gTimerHashTable
.text:FFFFF97FFF0B8B80                 mov     rcx, r12        ; mov rvx,tagWND*
.text:FFFFF97FFF0B8B83                 shr     rcx, 8          ; tagWND >> 8
.text:FFFFF97FFF0B8B87                 add     ecx, [rbx+38h]  ; tagWND >> 8 + timerID
.text:FFFFF97FFF0B8B8A                 and     ecx, 3Fh        ; tagWND >> 8 + timerID & 0x3f
.text:FFFFF97FFF0B8B8D                 shl     rcx, 4          ; tagWND >> 8 + timerID & 0x3f << 4
.text:FFFFF97FFF0B8B91                 add     rcx, rax        ; tagWND >> 8 + timerID & 0x3f << 4 + gTimerHashTable
.text:FFFFF97FFF0B8B94                 mov     rax, [rcx+8]    ; mov rax,[tagWND >> 8 + timerID & 0x3f << 4 + gTimerHashTable +8]
.text:FFFFF97FFF0B8B98                 mov     [rdx], rcx      ; 将计算好的hash数据给timer_object + 0x70处的数据
.text:FFFFF97FFF0B8B9B                 mov     [rdx+8], rax    ; 将timer_object + 0x70下的hashtable中的+8处保存为计算好的数据
.text:FFFFF97FFF0B8B9F                 mov     [rax], rdx      ; 将timer_object + 0x70的数据给计算好的hash数据
.text:FFFFF97FFF0B8BA2                 mov     [rcx+8], rdx    ; 将计算好的hash数据+8处赋值为timer_object + 0x70处的数据 典型的hash插入操作
.text:FFFFF97FFF0B8BA6                 jmp     short loc_FFFFF97FFF0B8BE4 ; 这里的rbx是申请到的Timer_object +0x28是什么暂时不知道
.text:FFFFF97FFF0B8BA8 ; ---------------------------------------------------------------------------
.text:FFFFF97FFF0B8BA8
.text:FFFFF97FFF0B8BA8 loc_FFFFF97FFF0B8BA8:                   ; CODE XREF: InternalSetTimer+9Cj
.text:FFFFF97FFF0B8BA8                 mov     rbx, [rsp+68h+pFindedTimerObject] ; 取到找到的返回到的Timer_Object空间头
.text:FFFFF97FFF0B8BAD                 mov     ebp, 1
.text:FFFFF97FFF0B8BB2                 test    [rbx+48h], bpl  ; if([rbx+0x48]^1)
.text:FFFFF97FFF0B8BB6                 jz      short loc_FFFFF97FFF0B8BE4 ; if(![rbx+0x48]^1)
.text:FFFFF97FFF0B8BB8                 mov     rax, [rbx+68h]  ; UnKnow
.text:FFFFF97FFF0B8BBC                 mov     rcx, [rbx+60h]  ; UnKnow
.text:FFFFF97FFF0B8BC0                 mov     rdx, [rbx+30h]  ; tagTHREADINFO
.text:FFFFF97FFF0B8BC4                 mov     [rax], rcx      ; timer_object+0x68处数据的值为timer_object+0x60处的值
.text:FFFFF97FFF0B8BC7                 mov     [rcx+8], rax    ; timer_object+0x60处的值的+8的值等于timer_object+0x68的值
.text:FFFFF97FFF0B8BCB                 add     dword ptr [rdx+1E4h], 0FFFFFFFFh ; +0x30是tagTHREADINFO 这个结构下的1E4处是cTimersReady 执行-1操作
.text:FFFFF97FFF0B8BD2                 jnz     short loc_FFFFF97FFF0B8BE4 ; 如果cTimersReady为0跳转
.text:FFFFF97FFF0B8BD4                 mov     rax, [rdx+170h] ; /*0x170*/     struct _tagCLIENTTHREADINFO* pcti;
.text:FFFFF97FFF0B8BDB                 mov     ecx, 0FFEFh
.text:FFFFF97FFF0B8BE0                 and     [rax+6], cx     ; /*0x006*/     UINT16       fsWakeBits; fsWakeBits &= 0xFFEF
.text:FFFFF97FFF0B8BE4
.text:FFFFF97FFF0B8BE4 loc_FFFFF97FFF0B8BE4:                   ; CODE XREF: InternalSetTimer+16Ej
.text:FFFFF97FFF0B8BE4                                         ; InternalSetTimer+17Ej ...
.text:FFFFF97FFF0B8BE4                 lea     rcx, [rbx+28h]  ; 这里的rbx是申请到的Timer_object +0x28是什么暂时不知道
.text:FFFFF97FFF0B8BE8                 mov     rdx, r12        ; tagWND*
.text:FFFFF97FFF0B8BEB                 call    HMAssignmentLock
.text:FFFFF97FFF0B8BF0                 mov     rax, [rsp+68h+lpTimerFuc] ; 得到lptimerFunc参数
.text:FFFFF97FFF0B8BF8                 mov     [rbx+44h], esi  ; timer_object + 0x44处是Elapse
.text:FFFFF97FFF0B8BFB                 xor     r12d, r12d
.text:FFFFF97FFF0B8BFE                 mov     [rbx+40h], esi  ; timer_object + 0x44处也是Elapse
.text:FFFFF97FFF0B8C01                 mov     [rbx+50h], rax  ; timer_object + 0x50处保存lptimerFunc
.text:FFFFF97FFF0B8C05                 mov     [rbx+58h], r12  ; 0????
.text:FFFFF97FFF0B8C09                 test    dil, dil
.text:FFFFF97FFF0B8C0C                 jns     short loc_FFFFF97FFF0B8C14 ; if(flags>=0)
.text:FFFFF97FFF0B8C0E                 btr     edi, 7          ; 将flags第7位送给CF标志
.text:FFFFF97FFF0B8C12                 jmp     short loc_FFFFF97FFF0B8C1E ; flags ^ 8
.text:FFFFF97FFF0B8C14 ; ---------------------------------------------------------------------------
.text:FFFFF97FFF0B8C14
.text:FFFFF97FFF0B8C14 loc_FFFFF97FFF0B8C14:                   ; CODE XREF: InternalSetTimer+1D4j
.text:FFFFF97FFF0B8C14                 bt      edi, 8          ; 将flags第8为送给CF标志
.text:FFFFF97FFF0B8C18                 jnb     short loc_FFFFF97FFF0B8C1E ; if(cf==0)
.text:FFFFF97FFF0B8C1A                 mov     [rbx+58h], r15  ; timer_object + 0x58保存当前线程
.text:FFFFF97FFF0B8C1E
.text:FFFFF97FFF0B8C1E loc_FFFFF97FFF0B8C1E:                   ; CODE XREF: InternalSetTimer+1DAj
.text:FFFFF97FFF0B8C1E                                         ; InternalSetTimer+1E0j
.text:FFFFF97FFF0B8C1E                 or      edi, 8          ; flags ^ 8
.text:FFFFF97FFF0B8C21                 mov     [rbx+48h], edi  ; timer_object + 0x48保存flags相关 这个应该是跟是否过期有关
.text:FFFFF97FFF0B8C24                 mov     [rbx+30h], r13  ; timer_object + 0x30 处保存tagTHADINFO
.text:FFFFF97FFF0B8C28                 cmp     cs:gbRITAlerted, r12b ; 至此 结构的大部分需要的信息已经得到
.text:FFFFF97FFF0B8C2F                 jnz     loc_FFFFF97FFF0B8CC2
.text:FFFFF97FFF0B8C35                 cmp     cs:gbTimersProcActive, r12b
.text:FFFFF97FFF0B8C3C                 jnz     short loc_FFFFF97FFF0B8CBB
.text:FFFFF97FFF0B8C3E                 mov     rcx, ds:7FFE0320h
.text:FFFFF97FFF0B8C46                 mov     eax, ds:7FFE0004h
.text:FFFFF97FFF0B8C4D                 mov     edx, cs:gdmsNextTimer
.text:FFFFF97FFF0B8C53                 imul    rcx, rax
.text:FFFFF97FFF0B8C57                 shr     rcx, 18h
.text:FFFFF97FFF0B8C5B                 sub     ecx, cs:gcmsLastTimer
.text:FFFFF97FFF0B8C61                 cmp     ecx, edx
.text:FFFFF97FFF0B8C63                 ja      short loc_FFFFF97FFF0B8C9E
.text:FFFFF97FFF0B8C65                 lea     eax, [rsi+rcx]
.text:FFFFF97FFF0B8C68                 cmp     eax, esi
.text:FFFFF97FFF0B8C6A                 jb      short loc_FFFFF97FFF0B8C9E
.text:FFFFF97FFF0B8C6C                 and     dword ptr [rbx+48h], 0FFFFFFF7h
.text:FFFFF97FFF0B8C70                 add     [rbx+40h], ecx
.text:FFFFF97FFF0B8C73                 sub     edx, ecx
.text:FFFFF97FFF0B8C75                 cmp     edx, esi
.text:FFFFF97FFF0B8C77                 jbe     short loc_FFFFF97FFF0B8CB4
.text:FFFFF97FFF0B8C79                 mov     eax, [rbx+40h]
.text:FFFFF97FFF0B8C7C                 mov     rcx, cs:gptmrMaster ; Timer
.text:FFFFF97FFF0B8C83                 movsxd  rdx, esi
.text:FFFFF97FFF0B8C86                 imul    rdx, 0FFFFFFFFFFFFD8F0h ; DueTime
.text:FFFFF97FFF0B8C8D                 xor     r8d, r8d        ; Dpc
.text:FFFFF97FFF0B8C90                 mov     cs:gdmsNextTimer, eax
.text:FFFFF97FFF0B8C96                 call    cs:__imp_KeSetTimer
.text:FFFFF97FFF0B8C9C                 jmp     short loc_FFFFF97FFF0B8CB4
.text:FFFFF97FFF0B8C9E ; ---------------------------------------------------------------------------
.text:FFFFF97FFF0B8C9E
.text:FFFFF97FFF0B8C9E loc_FFFFF97FFF0B8C9E:                   ; CODE XREF: InternalSetTimer+22Bj
.text:FFFFF97FFF0B8C9E                                         ; InternalSetTimer+232j
.text:FFFFF97FFF0B8C9E                 mov     rcx, cs:gpkthreadRIT
.text:FFFFF97FFF0B8CA5                 xor     edx, edx
.text:FFFFF97FFF0B8CA7                 mov     cs:gbRITAlerted, bpl
.text:FFFFF97FFF0B8CAE                 call    cs:__imp_KeAlertThread
.text:FFFFF97FFF0B8CB4
.text:FFFFF97FFF0B8CB4 loc_FFFFF97FFF0B8CB4:                   ; CODE XREF: InternalSetTimer+23Fj
.text:FFFFF97FFF0B8CB4                                         ; InternalSetTimer+264j
.text:FFFFF97FFF0B8CB4                 mov     rbx, [rsp+68h+pFindedTimerObject]
.text:FFFFF97FFF0B8CB9                 jmp     short loc_FFFFF97FFF0B8CC2
.text:FFFFF97FFF0B8CBB ; ---------------------------------------------------------------------------
.text:FFFFF97FFF0B8CBB
.text:FFFFF97FFF0B8CBB loc_FFFFF97FFF0B8CBB:                   ; CODE XREF: InternalSetTimer+204j
.text:FFFFF97FFF0B8CBB                 mov     cs:gbRITRescan, bpl
.text:FFFFF97FFF0B8CC2
.text:FFFFF97FFF0B8CC2 loc_FFFFF97FFF0B8CC2:                   ; CODE XREF: InternalSetTimer+1F7j
.text:FFFFF97FFF0B8CC2                                         ; InternalSetTimer+281j
.text:FFFFF97FFF0B8CC2                 mov     rax, [rbx+38h]
.text:FFFFF97FFF0B8CC6                 cmp     rax, r12
.text:FFFFF97FFF0B8CC9                 cmovz   rax, rbp
.text:FFFFF97FFF0B8CCD
.text:FFFFF97FFF0B8CCD loc_FFFFF97FFF0B8CCD:                   ; CODE XREF: InternalSetTimer+34j
.text:FFFFF97FFF0B8CCD                 lea     r11, [rsp+68h+var_28]
.text:FFFFF97FFF0B8CD2                 mov     rbx, [r11+30h]
.text:FFFFF97FFF0B8CD6                 mov     rbp, [r11+38h]
.text:FFFFF97FFF0B8CDA                 mov     rsi, [r11+40h]
.text:FFFFF97FFF0B8CDE                 mov     rsp, r11
.text:FFFFF97FFF0B8CE1                 pop     r15
.text:FFFFF97FFF0B8CE3                 pop     r14
.text:FFFFF97FFF0B8CE5                 pop     r13
.text:FFFFF97FFF0B8CE7                 pop     r12
.text:FFFFF97FFF0B8CE9                 pop     rdi
.text:FFFFF97FFF0B8CEA                 retn
.text:FFFFF97FFF0B8CEA ; ---------------------------------------------------------------------------
.text:FFFFF97FFF0B8CEB                 db 9 dup(90h)
.text:FFFFF97FFF0B8CEB InternalSetTimer endp

基本大致需要的信息在这个函数都能发现了,
这里有两个函数函数可以看看

一个FindTimer,另一个HMAllocObject


FindTimer里面也可以获得一些信息

FindTimer
(
tagWND* tagWND
__int64 TimerID
__int64 elapse
__int64 lpTimerFunc
tagWND** tagRetWnd
)
.text:FFFFF97FFF0B8938 ; __int64 __fastcall FindTimer(__int64 pTagWnd, __int64 TimerID, __int64 flags, __int64 lpTimerFuc, __int64 pRetTagWnd)
.text:FFFFF97FFF0B8938 FindTimer       proc near               ; CODE XREF: AccessTimeOutReset+20p
.text:FFFFF97FFF0B8938                                         ; SetMouseTrails+3B2p ...
.text:FFFFF97FFF0B8938
.text:FFFFF97FFF0B8938 pTagWnd         = qword ptr  8
.text:FFFFF97FFF0B8938 TimerID         = qword ptr  10h
.text:FFFFF97FFF0B8938 Elapse          = qword ptr  18h
.text:FFFFF97FFF0B8938 lpTimerFunc     = qword ptr  20h
.text:FFFFF97FFF0B8938 pRetTagWnd      = qword ptr  28h
.text:FFFFF97FFF0B8938
.text:FFFFF97FFF0B8938                 mov     rax, rsp
.text:FFFFF97FFF0B893B                 mov     [rax+8], rbx
.text:FFFFF97FFF0B893F                 mov     [rax+18h], rbp
.text:FFFFF97FFF0B8943                 mov     [rax+20h], rsi
.text:FFFFF97FFF0B8947                 mov     [rax+10h], rdx
.text:FFFFF97FFF0B894B                 push    rdi
.text:FFFFF97FFF0B894C                 push    r12
.text:FFFFF97FFF0B894E                 push    r13
.text:FFFFF97FFF0B8950                 push    r14
.text:FFFFF97FFF0B8952                 push    r15
.text:FFFFF97FFF0B8954                 sub     rsp, 20h
.text:FFFFF97FFF0B8958                 mov     r12, rcx        ; pTagWnd
.text:FFFFF97FFF0B895B                 xor     edi, edi
.text:FFFFF97FFF0B895D                 mov     r13, rcx        ; pTagWnd
.text:FFFFF97FFF0B8960                 shr     r12, 8          ; pTagWnd >> 8
.text:FFFFF97FFF0B8964                 lea     rcx, gTimerHashTable ; 取全局TimerHashTable
.text:FFFFF97FFF0B896B                 mov     r15d, r9d       ; lpTimerFunc
.text:FFFFF97FFF0B896E                 add     r12, rdx        ; pTagWnd >> 8 + TimerID
.text:FFFFF97FFF0B8971                 mov     r14d, r8d       ; Elapse
.text:FFFFF97FFF0B8974                 mov     rax, rdx        ; TimerID
.text:FFFFF97FFF0B8977                 and     r12d, 3Fh       ; pTagWnd >> 8 + TimerID & 3F
.text:FFFFF97FFF0B897B                 mov     esi, edi
.text:FFFFF97FFF0B897D                 shl     r12, 4          ; pTagWnd >> 8 + TimerID & 3F << 4
.text:FFFFF97FFF0B8981                 add     r12, rcx        ; pTagWnd >> 8 + TimerID & 3F << 4 + 全局timerHashTable
.text:FFFFF97FFF0B8984                 mov     rbp, [r12]      ; hash表中的值给rbp
.text:FFFFF97FFF0B8988                 cmp     rbp, r12        ; 是否存在
.text:FFFFF97FFF0B898B                 jz      short loc_FFFFF97FFF0B89F9 ; 不存在就跳 返回false
.text:FFFFF97FFF0B898D
.text:FFFFF97FFF0B898D loc_FFFFF97FFF0B898D:                   ; CODE XREF: FindTimer+A8j
.text:FFFFF97FFF0B898D                 lea     rbx, [rbp-70h]  ; hash数据中-0x70 应该是TIMER_OBJECT 这个就是我们需要逆的结构
.text:FFFFF97FFF0B8991                 cmp     [rbx+28h], r13  ; timer_object + 0x28处应该是存放pTagWnd
.text:FFFFF97FFF0B8995                 jnz     short loc_FFFFF97FFF0B89D7 ; if([rbx+0x28] != r13) 跳转 不相等就跳
.text:FFFFF97FFF0B8997                 cmp     [rbx+38h], rax  ; timer_object + 0x38处应该是TimerID
.text:FFFFF97FFF0B899B                 jnz     short loc_FFFFF97FFF0B89D7 ; if([rbx+0x38] != rax) 跳转 不相等就跳
.text:FFFFF97FFF0B899D                 mov     eax, [rbx+48h]  ; 暂时不知道timer_object + 0x48干什么的
.text:FFFFF97FFF0B89A0                 xor     eax, r14d       ; eax ^ elapse
.text:FFFFF97FFF0B89A3                 test    al, 6           ; eax ^ elapse & 6
.text:FFFFF97FFF0B89A5                 jnz     short loc_FFFFF97FFF0B89D2 ; if(eax ^ elapse & 6)
.text:FFFFF97FFF0B89A7                 test    byte ptr [rbx+48h], 40h ; if([rbx+0x48]^0x40)
.text:FFFFF97FFF0B89AB                 jnz     short loc_FFFFF97FFF0B89E2 ; goto End
.text:FFFFF97FFF0B89AD                 call    cs:__imp_PsGetCurrentProcessWin32Process
.text:FFFFF97FFF0B89B3                 mov     r11, rax        ; 返回tagPROCESSINFO
.text:FFFFF97FFF0B89B6                 mov     rax, [rbx+30h]  ; 这个可以知道timer_object + 0x30 是存在tagTHREADINFO
.text:FFFFF97FFF0B89BA                 cmp     r11, [rax+158h] ; 比较当前的和结构下的tagPROCESSINF是否相同
.text:FFFFF97FFF0B89C1                 jz      short loc_FFFFF97FFF0B89E2 ; 相等就跳
.text:FFFFF97FFF0B89C3                 cmp     r13, rdi        ; r13 = pTagWnd rdi应该是0
.text:FFFFF97FFF0B89C6                 jnz     short loc_FFFFF97FFF0B89D2 ; 相等不跳
.text:FFFFF97FFF0B89C8                 mov     eax, [rbx+48h]
.text:FFFFF97FFF0B89CB                 xor     eax, r14d
.text:FFFFF97FFF0B89CE                 test    al, 4           ; [rbx+0x48]^elapse & 4
.text:FFFFF97FFF0B89D0                 jz      short loc_FFFFF97FFF0B89E2 ; if(([rbx+0x48]^elapse & 4))
.text:FFFFF97FFF0B89D2
.text:FFFFF97FFF0B89D2 loc_FFFFF97FFF0B89D2:                   ; CODE XREF: FindTimer+6Dj
.text:FFFFF97FFF0B89D2                                         ; FindTimer+8Ej
.text:FFFFF97FFF0B89D2                 mov     rax, [rsp+48h+TimerID]
.text:FFFFF97FFF0B89D7
.text:FFFFF97FFF0B89D7 loc_FFFFF97FFF0B89D7:                   ; CODE XREF: FindTimer+5Dj
.text:FFFFF97FFF0B89D7                                         ; FindTimer+63j
.text:FFFFF97FFF0B89D7                 mov     rbp, [rbp+0]
.text:FFFFF97FFF0B89DB                 cmp     rbp, r12        ; 如果在hashtable张发现等于自己 就跳转 其实就是遍历hashtable
.text:FFFFF97FFF0B89DE                 jz      short loc_FFFFF97FFF0B89FE ; 遍历完了 还是没有找到
.text:FFFFF97FFF0B89E0                 jmp     short loc_FFFFF97FFF0B898D ; hash数据中-0x70 应该是TIMER_OBJECT 这个就是我们需要逆的结构
.text:FFFFF97FFF0B89E2 ; ---------------------------------------------------------------------------
.text:FFFFF97FFF0B89E2
.text:FFFFF97FFF0B89E2 loc_FFFFF97FFF0B89E2:                   ; CODE XREF: FindTimer+73j
.text:FFFFF97FFF0B89E2                                         ; FindTimer+89j ...
.text:FFFFF97FFF0B89E2                 cmp     r15d, edi       ; 如果timefunc存在就释放当InternalSetTimer来调用的话 这个参数是NULL
.text:FFFFF97FFF0B89E5                 jz      short loc_FFFFF97FFF0B89F2 ; 如果lptimeFunc为NULL就跳
.text:FFFFF97FFF0B89E7                 mov     rcx, rbx        ; P
.text:FFFFF97FFF0B89EA                 call    FreeTimer
.text:FFFFF97FFF0B89EF                 mov     rbx, rdi
.text:FFFFF97FFF0B89F2
.text:FFFFF97FFF0B89F2 loc_FFFFF97FFF0B89F2:                   ; CODE XREF: FindTimer+ADj
.text:FFFFF97FFF0B89F2                 mov     esi, 1          ; esi应该找的的一个标志
.text:FFFFF97FFF0B89F7                 jmp     short loc_FFFFF97FFF0B89FE
.text:FFFFF97FFF0B89F9 ; ---------------------------------------------------------------------------
.text:FFFFF97FFF0B89F9
.text:FFFFF97FFF0B89F9 loc_FFFFF97FFF0B89F9:                   ; CODE XREF: FindTimer+53j
.text:FFFFF97FFF0B89F9                 mov     rbx, [rsp+48h+TimerID]
.text:FFFFF97FFF0B89FE
.text:FFFFF97FFF0B89FE loc_FFFFF97FFF0B89FE:                   ; CODE XREF: FindTimer+A6j
.text:FFFFF97FFF0B89FE                                         ; FindTimer+BFj
.text:FFFFF97FFF0B89FE                 mov     rcx, [rsp+48h+pRetTagWnd]
.text:FFFFF97FFF0B8A03                 cmp     rcx, rdi        ; 如果pRetTagWnd为就跳
.text:FFFFF97FFF0B8A06                 jz      short loc_FFFFF97FFF0B8A12
.text:FFFFF97FFF0B8A08                 cmp     esi, 1          ; 如果esi = 1
.text:FFFFF97FFF0B8A0B                 cmovz   rdi, rbx        ; 做返回值的处理
.text:FFFFF97FFF0B8A0F                 mov     [rcx], rdi
.text:FFFFF97FFF0B8A12
.text:FFFFF97FFF0B8A12 loc_FFFFF97FFF0B8A12:                   ; CODE XREF: FindTimer+CEj
.text:FFFFF97FFF0B8A12                 mov     rbx, [rsp+48h+pTagWnd]
.text:FFFFF97FFF0B8A17                 mov     rbp, [rsp+48h+Elapse]
.text:FFFFF97FFF0B8A1C                 mov     eax, esi
.text:FFFFF97FFF0B8A1E                 mov     rsi, [rsp+48h+lpTimerFunc]
.text:FFFFF97FFF0B8A23                 add     rsp, 20h
.text:FFFFF97FFF0B8A27                 pop     r15
.text:FFFFF97FFF0B8A29                 pop     r14
.text:FFFFF97FFF0B8A2B                 pop     r13
.text:FFFFF97FFF0B8A2D                 pop     r12
.text:FFFFF97FFF0B8A2F                 pop     rdi
.text:FFFFF97FFF0B8A30                 retn
.text:FFFFF97FFF0B8A30 ; ---------------------------------------------------------------------------
.text:FFFFF97FFF0B8A31                 align 8
.text:FFFFF97FFF0B8A31 FindTimer       endp

HMAllocObject:
HMAllocObject(PTHREADINFO pti, PDESKTOP pdesk, BYTE btype, DWORD size);

w2k中的代码private\ntos\w32\ntuser\kernel\timer.c
ptmr = (PTIMER)HMAllocObject(NULL, NULL, TYPE_TIMER, sizeof(TIMER));
根据泄露的NT代码来看,这个函数返回的就是保存USER定时器TIMER_OBJECT空间
根据上层函数的传参,可以知道TIMER_OBJECT结构有0x80大小



从汇编代码来看
我们需要的TIMER结构应该是这样的


typedef struct _User_Timer{
        ULONG64                 UnKnow1;//8
        ULONG64                 UnKnow2;//10
        LIST_ENTRY        		gtmrLish;//18
        ULONG64                 UnKnow3;//20
        ULONG64                 hWnd_Object;//28
        ULONG64                 pTagTHADINFO;//30
        ULONG64                 TimerId;//38
        ULONG                 	uElapse;//40
        ULONG					uElapse;//44
        ULONG64                 flag;//48
        ULONG64                 lpTimerFunc;//50
        ULONG64                 UnKnow4;//58
        ULONG64					UnKnow5;//60
        ULONG64					UnKnow6//68
        LIST_ENTRY        		List_UnKnow1;//70 timerhash相关
        ULONG64					UnKnow7;//78
        ULONG64					UnKnow8;//80
}User_Timer,*pUser_Timer;


不过移除定时器 还需要0x70  0x60两个偏移的信息,待有时间再来看看


你可能感兴趣的:(逆向,PTIMER,Win7x64TIMER结构,USERTIMER)