【发布时间】:2021-05-01 17:13:16
【问题描述】:
- thread entry and thread start 之间的确切区别是什么?和
- RIP(在动态分析中执行前端所在的位置)是否总是以相同的可预测顺序到达它们?
- 线程入口是否动态变化(在动态分析中我想我看到它在寄存器和堆栈中报告)?
到目前为止,我了解thread start 是从某个角度定义的,例如,在Windows 中,它始终是ntdll.RtlUserThreadStart+21(用户),但在程序库级别,它可以是任何函数。但是thread start在创建线程之前不会被调用ntdll.NtCreateThreadEx+14(系统)。
thread entry 是作为thread create 函数的参数的(库,即导出或私有)函数。
使用 x64dbg 制作的带有线程(threadID、Address、to、from、size、comment、party)的调用堆栈示例:
4200
00000076EBDFF9A8 00007FFEC900A34E 00007FFECB4EC034 A0 ntdll.NtWaitForSingleObject+14 System
00000076EBDFFA48 00007FF7987B48A1 00007FFEC900A34E 30 kernelbase.WaitForSingleObjectEx+8E User
00000076EBDFFA78 00007FF7988961A0 00007FF7987B48A1 30 mylibrarydll0.00007FF7987B48A1 User
00000076EBDFFAA8 00007FF7987B13DF 00007FF7988961A0 30 mylibrarydll0.00007FF7988961A0 User
00000076EBDFFAD8 00007FF798B4A175 00007FF7987B13DF 30 mylibrarydll0.00007FF7987B13DF User
00000076EBDFFB08 00007FFECA637034 00007FF798B4A175 30 mylibrarydll0.sub_7FF798B4A0B4+C1 System
00000076EBDFFB38 00007FFECB49D0D1 00007FFECA637034 80 kernel32.BaseThreadInitThunk+14 System
00000076EBDFFBB8 0000000000000000 00007FFECB49D0D1 ntdll.RtlUserThreadStart+21 User
2736
00000076EB5FF648 00007FFECB4623D7 00007FFECB4EFA04 300 ntdll.NtWaitForWorkViaWorkerFactory+14 System
00000076EB5FF948 00007FFECA637034 00007FFECB4623D7 30 ntdll.TppWorkerThread+2F7 System
00000076EB5FF978 00007FFECB49D0D1 00007FFECA637034 80 kernel32.BaseThreadInitThunk+14 System
00000076EB5FF9F8 0000000000000000 00007FFECB49D0D1 ntdll.RtlUserThreadStart+21 User
2468
00000076EBBFFB78 00007FFEC900A34E 00007FFECB4EC034 A0 ntdll.NtWaitForSingleObject+14 System
00000076EBBFFC18 00007FF7987B48A1 00007FFEC900A34E 30 kernelbase.WaitForSingleObjectEx+8E User
00000076EBBFFC48 00007FF7988961A0 00007FF7987B48A1 30 mylibrarydll0.00007FF7987B48A1 User
00000076EBBFFC78 00007FF7987B13DF 00007FF7988961A0 30 mylibrarydll0.00007FF7988961A0 User
00000076EBBFFCA8 00007FF798B4A175 00007FF7987B13DF 30 mylibrarydll0.00007FF7987B13DF User
00000076EBBFFCD8 00007FFECA637034 00007FF798B4A175 30 mylibrarydll0.sub_7FF798B4A0B4+C1 System
00000076EBBFFD08 00007FFECB49D0D1 00007FFECA637034 80 kernel32.BaseThreadInitThunk+14 System
00000076EBBFFD88 0000000000000000 00007FFECB49D0D1 ntdll.RtlUserThreadStart+21 User
3784
00000076EB6FFB88 00007FFECB4623D7 00007FFECB4EFA04 300 ntdll.NtWaitForWorkViaWorkerFactory+14 System
00000076EB6FFE88 00007FFECA637034 00007FFECB4623D7 30 ntdll.TppWorkerThread+2F7 System
00000076EB6FFEB8 00007FFECB49D0D1 00007FFECA637034 80 kernel32.BaseThreadInitThunk+14 System
00000076EB6FFF38 0000000000000000 00007FFECB49D0D1 ntdll.RtlUserThreadStart+21 User
1928
00000076EB7FFA48 00007FFEC900A34E 00007FFECB4EC034 A0 ntdll.NtWaitForSingleObject+14 System
00000076EB7FFAE8 00007FF7987B48A1 00007FFEC900A34E 30 kernelbase.WaitForSingleObjectEx+8E User
00000076EB7FFB18 00007FF7988961A0 00007FF7987B48A1 30 mylibrarydll0.00007FF7987B48A1 User
00000076EB7FFB48 00007FF7987B13DF 00007FF7988961A0 30 mylibrarydll0.00007FF7988961A0 User
00000076EB7FFB78 00007FF798B4A175 00007FF7987B13DF 30 mylibrarydll0.00007FF7987B13DF User
00000076EB7FFBA8 00007FFECA637034 00007FF798B4A175 30 mylibrarydll0.sub_7FF798B4A0B4+C1 System
00000076EB7FFBD8 00007FFECB49D0D1 00007FFECA637034 80 kernel32.BaseThreadInitThunk+14 System
00000076EB7FFC58 0000000000000000 00007FFECB49D0D1 ntdll.RtlUserThreadStart+21 User
2276
00000076EB8FF7C8 00007FFEC900A34E 00007FFECB4EC034 A0 ntdll.NtWaitForSingleObject+14 System
00000076EB8FF868 00007FF7987B48A1 00007FFEC900A34E 30 kernelbase.WaitForSingleObjectEx+8E User
00000076EB8FF898 00007FF7988961A0 00007FF7987B48A1 30 mylibrarydll0.00007FF7987B48A1 User
00000076EB8FF8C8 00007FF7987B13DF 00007FF7988961A0 30 mylibrarydll0.00007FF7988961A0 User
00000076EB8FF8F8 00007FF798B4A175 00007FF7987B13DF 30 mylibrarydll0.00007FF7987B13DF User
00000076EB8FF928 00007FFECA637034 00007FF798B4A175 30 mylibrarydll0.sub_7FF798B4A0B4+C1 System
00000076EB8FF958 00007FFECB49D0D1 00007FFECA637034 80 kernel32.BaseThreadInitThunk+14 System
00000076EB8FF9D8 0000000000000000 00007FFECB49D0D1 ntdll.RtlUserThreadStart+21 User
12168
00000076EB9FF6E8 00007FFECB4623D7 00007FFECB4EFA04 300 ntdll.NtWaitForWorkViaWorkerFactory+14 System
00000076EB9FF9E8 00007FFECA637034 00007FFECB4623D7 30 ntdll.TppWorkerThread+2F7 System
00000076EB9FFA18 00007FFECB49D0D1 00007FFECA637034 80 kernel32.BaseThreadInitThunk+14 System
00000076EB9FFA98 0000000000000000 00007FFECB49D0D1 ntdll.RtlUserThreadStart+21 User
2428
00000076EBAFF5D8 00007FFECB4623D7 00007FFECB4EFA04 300 ntdll.NtWaitForWorkViaWorkerFactory+14 System
00000076EBAFF8D8 00007FFECA637034 00007FFECB4623D7 30 ntdll.TppWorkerThread+2F7 System
00000076EBAFF908 00007FFECB49D0D1 00007FFECA637034 80 kernel32.BaseThreadInitThunk+14 System
00000076EBAFF988 0000000000000000 00007FFECB49D0D1 ntdll.RtlUserThreadStart+21 User
【问题讨论】:
-
您在哪里阅读了“线程入口”和“线程启动”这两个术语?什么是“RIP/Horizon”?
-
我认为 RIP 指的是 x86-64 64 位指令指针,尽管我不知道 Horizon 在这种情况下是什么。
-
@Kevin 我更新了帖子以澄清。
-
“线程入口”是给
CreateThread或类似地址的地址,“线程开始”是当 Windows 向调试器发送“线程创建”事件时 RIP 所在的地址。它通常位于稍后将调用线程条目的ntdll函数上。在给定的 Windows 版本上,它应该始终具有相同的功能。线程开始被赋予线程入口的地址作为参数,因此您可以在内存或寄存器中找到它。注意SetThreadContext可以改变一个(暂停的)线程的入口点,所以线程入口可能是一个诱饵地址。 -
@MargaretBloom 所以,当我暂停然后恢复一个线程时,线程条目发生了变化,是吗?最终我可以以可预测的方式追踪它(比如在装配的动态分析中)?
标签: c multithreading debugging assembly disassembly