山东001在线

 找回密码
 立即注册
搜索
查看: 135|回复: 0

[美女] 研究发现:驱动开发:内核枚举IoTimer定时器2023/3/31 11:26:18

[复制链接]
  • TA的每日心情
    开心
    2023-10-11 21:31
  • 签到天数: 104 天

    [LV.6]常住居民II

    发表于 2023-3-31 11:26:49 | 显示全部楼层 |阅读模式

    今天继续分享内核枚举系列知识,这次我们来学习如何通过代码的方式枚举内核IT定时器,内核定时器其就是在内核中现的时钟,该定时器的枚举非常简单,因为在IIT初始化部分就可以找到ITQH地址,该变量内存储的就是定时器的链表头部。枚举IO定时器的案例并不多见,即便有也是法使用过时的,此教程学到肯定就是赚到了。游戏数据分析的相关资讯可以到我们网站了解一下,从专业角度出发为您解答相关问题,给您优质的服务!












    枚举I定时器过程是这样的:



    1找到IIT函数,该函数可以通过MGSRA得到。
    2找到地址以后,我们向下增加0FF偏移量,并搜索特征定位到ITQH链表头。
    3将链表头转换为IO_TIMER结构体,并循环链表头输出。

    这里解释一下为什么要找IIT这个函数他是一个初始化函数,既然是初始化里面一定会涉及到链表的存储问题,找到他就能找到定时器链表基址,该函数的定义如下。







    1


    2


    3


    4


    5


    6




    NTSTATUS



    IIT(



    INPDEVICE_OBJECTDO,


    设备对象指针



    INPIO_TIMER_ROUTINETR,


    定时器例程



    INPVOIDC


    传给定时器例程的函数



    );





    接着我们需要得到IO定时器的结构定义,在DEVICE_OBJECT设备对象指针中存在一个T属性。







    1


    2


    3


    4


    5


    6


    7


    8


    9


























































    :_DEVICE_OBJECT


    !_DEVICE_OBJECT



    +
    0000
    T
    :I2B



    +
    00
    S:U2B



    +
    00
    RC:I4B



    +
    00
    DO:P64_DRIVER_OBJECT



    +
    00
    ND:P64_DEVICE_OBJECT



    +

    AD:P64_DEVICE_OBJECT



    +
    00
    CI:P64_IRP



    +

    T:P64_IO_TIMER



    +
    00
    F:U4B



    +

    C:U4B



    +

    V:P64_VPB



    +
    00
    DE:P64V



    +

    DT:U4B



    +
    0
    SS:C



    +
    00
    Q:
    -




    +
    08
    AR:U4B



    +
    000
    DQ:_KDEVICE_QUEUE



    +
    0
    D:_KDPC



    +

    ATC:U4B



    +

    SD:P64V



    +

    DL:_KEVENT



    +

    SS:U2B



    +
    32
    S1:U2B



    +
    38
    DOE:P64_DEVOBJ_EXTENSION



    +
    40
    R:P64V











    这里的这个+T定时器是一个结构体_IO_TIMER其就是IO定时器的所需结构体。







    1


    2


    3


    4


    5


    6


    7


    8




    :_IO_TIMER


    !_IO_TIMER



    +
    0000
    T
    :I2B



    +
    00
    TF:I2B



    +
    00
    TL:_LIST_ENTRY



    +

    TR:P64



    +
    00
    C:P64V



    +

    DO:P64_DEVICE_OBJECT











    如上方的基础知识有了也就够了,接着就是际开发部分,首先我们需要编写一个GIITA()函数,让该函数可以定位到IIT所在内核中的基地址上面,具体现调用代码如下所示。







    1


    2


    3


    4


    5


    6


    7


    8


    9




































































    32


    33


    34




    #







    得到IIT基址




    B:LS内核开发系列教程


    PVOIDGIITA()


    {



    PVOIDVA
    =
    0
    ;



    UNICODE_STRINGT
    =
    {
    0
    };






    RIUS(T,L
    "IIT"
    );



    VA
    =
    (PVOID)MGSRA(T);




    (VA!
    =
    0
    )



    {




    VA;



    }




    0
    ;


    }





    VOIDUD(PDRIVER_OBJECT)


    {



    DP((
    "UDIOK\"
    ));


    }





    NTSTATUSDE(INPDRIVER_OBJECTD,PUNICODE_STRINGRP)


    {



    DP((
    "\"
    ));








    得到基址



    PUCHARIIT
    =
    GIITA();



    DP(
    "IITA=%\"
    ,IIT);






    D
    -
    DU
    =
    UD;




    STATUS_SUCCESS;


    }





    运行这个驱动程序,然后对比下是否一致:











    接着我们在反汇编代码中寻找ITQH,此处在LS系统内这个偏移位置是!IIT+具体输出位置如下。







    1


    2


    3


    4


    5


    6


    7


    8


    9







    :IIT





    !IIT
    +

    :


    8`
    7485
    48850
    ,[
    +
    8
    ]


    8`
    74851
    488978
    [
    +

    ],


    8`
    74855
    4844750
    8,[!ITL(8`
    74980
    )]


    8`
    7485
    488978
    [
    +

    ],


    8`
    748500
    488
    ,[!ITQH(8`
    7486390
    )]


    8`
    7485
    88!EIITL(8`
    745
    )


    8`
    74850
    3
    ,





    在WDBG中标注出颜色,[!ITQH(87486390)]`更容易看到。











    接着就是通过代码现对此处的定位,定位我们就采用特征码搜索的方式,如下代码是特征搜索部分。



    SSA代表开始位置
    ESA代表结束位置,粗略计算0就可以定位到了。






    1


    2


    3


    4


    5


    6


    7


    8


    9




































































    32


    33


    34


    35


    36


    37


    38


    39


    40


    41


    42


    43


    44


    45


    46


    47


    48


    49


    50


    51


    52


    53


    54


    55


    56


    57


    58


    59


    60




    #







    得到IIT基址




    B:LS内核开发系列教程


    PVOIDGIITA()


    {



    PVOIDVA
    =
    0
    ;



    UNICODE_STRINGT
    =
    {
    0
    };






    RIUS(T,L
    "IIT"
    );



    VA
    =
    (PVOID)MGSRA(T);




    (VA!
    =
    0
    )



    {




    VA;



    }




    0
    ;


    }





    VOIDUD(PDRIVER_OBJECT)


    {



    DP((
    "UDIOK\"
    ));


    }





    NTSTATUSDE(INPDRIVER_OBJECTD,PUNICODE_STRINGRP)


    {



    DP((
    "\"
    ));








    得到基址



    PUCHARIIT
    =
    GIITA();



    DP(
    "IITA=%\"
    ,IIT);






    INT32O
    =
    0
    ;



    PLIST_ENTRYITQH
    =
    NULL;






    PUCHARSSA
    =
    IIT;



    PUCHARESA
    =
    IIT
    +
    0FF
    ;



    UCHAR1
    =
    0
    ,2
    =
    0
    ,3
    =
    0
    ;







    (PUCHAR
    =
    SSA;ESA;
    +
    +
    )



    {




    (MIAV()MIAV(
    +
    1
    )MIAV(
    +
    2
    ))



    {



    1
    =
    *
    ;



    2
    =
    *
    (
    +
    1
    );



    3
    =
    *
    (
    +
    2
    );








    个特征码




    (1
    =
    =
    8
    2
    =
    =

    3
    =
    =
    00
    )



    {



    (O,
    +
    3
    ,
    4
    );



    ITQH
    =
    (PLIST_ENTRY)(O
    +
    (ULONG64)
    +
    7
    );



    DP(
    "ITQH=%\"
    ,ITQH);




    ;



    }



    }



    }






    D
    -
    DU
    =
    UD;




    STATUS_SUCCESS;


    }





    搜索个特征码1==82==3==00从而得到内存位置,运行驱动对比下。



    运行代码会取出指令后面的操作数,而不是取出指令的内存地址。





    比较后一步就是枚举部分,我们需要前面提到的IO_TIMER结构体定义。



    PIO_TIMERT=CONTAINING_RECORD(NE,IO_TIMER,TL)得到结构体,循环输出即可。






    1


    2


    3


    4


    5


    6


    7


    8


    9




































































    32


    33


    34


    35


    36


    37


    38


    39


    40


    41


    42


    43


    44


    45


    46


    47


    48


    49


    50


    51


    52


    53


    54


    55


    56


    57


    58


    59


    60


    61


    62


    63


    64


    65


    66


    67


    68


    69


    70


    71


    72


    73


    74


    75


    76


    77


    78


    79


    80


    81


    82


    83


    84


    85


    86


    87


    88


    89


    90


    91


    92


    93


    94


    95


    96


    97


    98


    99


    0


    1


    1


    1


    1


    1


    1


    1


    1


    1






    B:LS内核开发系列教程




    :




    LS



    784393


    #


    #





    _IO_TIMER


    {



    INT
    T
    ;



    INTTF;



    LONG32U;



    LIST_ENTRYTL;



    PVOIDTR;



    PVOIDC;



    PVOIDDO;


    }IO_TIMER,
    *
    PIO_TIMER;










    得到IIT基址


    PVOIDGIITA()


    {



    PVOIDVA
    =
    0
    ;



    UNICODE_STRINGT
    =
    {
    0
    };






    RIUS(T,L
    "IIT"
    );



    VA
    =
    (PVOID)MGSRA(T);




    (VA!
    =
    0
    )



    {




    VA;



    }




    0
    ;


    }





    VOIDUD(PDRIVER_OBJECT)


    {



    DP(
    "卸载完成\"
    );


    }





    NTSTATUSDE(INPDRIVER_OBJECTD,PUNICODE_STRINGRP)


    {



    DP((
    "\"
    ));








    得到基址



    PUCHARIIT
    =
    GIITA();



    DP(
    "IITA=%\"
    ,IIT);








    搜索ITQH地址




    *



    !IIT
    +

    :



    8`
    349963
    48850
    ,[
    +
    8
    ]



    8`
    34996
    488978
    [
    +

    ],



    8`
    3499635
    486480
    8,[!ITL(8`
    34790
    )]



    8`
    349963
    488978
    [
    +

    ],



    8`
    34996
    48896
    ,[!ITQH(8`
    3467580
    )]



    8`
    3499637
    843598!EIITL(8`
    34390
    )



    8`
    349963
    3
    ,



    *




    INT32O
    =
    0
    ;



    PLIST_ENTRYITQH
    =
    NULL;






    PUCHARSSA
    =
    IIT;



    PUCHARESA
    =
    IIT
    +
    0FF
    ;



    UCHAR1
    =
    0
    ,2
    =
    0
    ,3
    =
    0
    ;







    (PUCHAR
    =
    SSA;ESA;
    +
    +
    )



    {




    (MIAV()MIAV(
    +
    1
    )MIAV(
    +
    2
    ))



    {



    1
    =
    *
    ;



    2
    =
    *
    (
    +
    1
    );



    3
    =
    *
    (
    +
    2
    );








    8`
    34996
    48
    8
    0
    99
    6,[!ITQH(8`
    3467580
    )]




    (1
    =
    =
    8
    2
    =
    =

    3
    =
    =
    00
    )



    {



    (O,
    +
    3
    ,
    4
    );



    ITQH
    =
    (PLIST_ENTRY)(O
    +
    (ULONG64)
    +
    7
    );



    DP(
    "ITQH=%\"
    ,ITQH);




    ;



    }



    }



    }








    枚举列表



    KIRQLOI;








    获得特权级



    OI
    =
    KRITDL();







    (ITQHMIAV((PVOID)ITQH))



    {



    PLIST_ENTRYNE
    =
    ITQH
    -
    F;




    (MIAV(NE)NE!
    =
    (PLIST_ENTRY)ITQH)



    {



    PIO_TIMERT
    =
    CONTAINING_RECORD(NE,IO_TIMER,TL);







    (TMIAV(T))



    {



    DP(
    "IO对象地址:%\"
    ,T);



    }



    NE
    =
    NE
    -
    F;



    }



    }








    恢复特权级



    KLI(OI);






    D
    -
    DU
    =
    UD;




    STATUS_SUCCESS;


    }





    运行这段源代码,并可得到以下输出,由于没有IO定时器所以输出结果是空的:











    至此IO定时器的枚举就介绍完了,在教程中你已经学会了使用特征码定位这门技术,相信你完全可以输出内核中想要得到的任何结构体。
    您需要登录后才可以回帖 登录 | 立即注册

    本版积分规则

    QQ|手机版|小黑屋|Archiver|山东001在线 ( ICP11027147 )

    GMT+8, 2026-4-4 17:14 , Processed in 0.039521 second(s), 19 queries , Gzip On.

    Powered by Discuz! X3.4

    © 2001-2023 Discuz! Team.

    快速回复 返回顶部 返回列表