如何在内核模式下读取特定内核的程序计数器/指令指针?

问题描述 投票:0回答:1

Windows 10,x64,x86

我目前的知识

让我们说它是四核的,将有4个单独的程序计数器,它们将指向4个不同的代码位置以并行执行。

每个程序计数器指示计算机在其程序序列中的位置。

它指向的地址在上下文​​切换后发生更改,在该上下文切换中,另一个线程程序计数器被放置到程序计数器上以执行。

我想做什么:

我处于内核模式,我的线程正在内核1上运行,我想读取内核2的当前指令指针。

预期结果:

0x203123是指令指针的地址,该地址属于该线程,并且该线程属于该进程...等等。

任何人都知道该怎么做,或者可以给我很好的参考书,链接等...

c++ c windows assembly x86-64
1个回答
0
投票

任何人都知道该怎么做,或者可以给我很好的参考书,链接等...

对于80x86硬件(与操作系统无关); (我知道)只有3种方法:

a)向另一个CPU发送处理器间中断,并具有一个中断处理程序,该中断处理程序将“返回EIP”(来自其堆栈)存储在内存中的已知地址,以便您的CPU可以在读取“ EIP值”之前中断”(具有同步功能,以便在写入值之前不会读取CPU等)。

b)将另一个CPU置于某种“调试模式”(单步执行,最后一个分支记录,...),以便(调试异常处理程序中的代码或CPU的硬件本身)不断写入EIP值存储到您可以读取的内存中。

当然,这两个选项都会破坏性能,并且您获得的价值可能会毫无用处(因为在获得EIP之后但可以使用获得的价值之前,EIP会发生变化)。确保该值仍然有用;您需要另一个CPU等待,直到消耗完获得的值(并准备好下一个值)为止;为此,您必须诉诸于单步调试功能(在调试异常处理程序中进行等待),如果您可以将性能提高慢一千倍(并且可以提高性能),您将很幸运。只需完全禁用其他CPU)。

还要注意,它们仍然不能在所有情况下都准确地告诉您EIP(例如,如果CPU处于SMM /系统管理模式,并且不受操作系统的控制);我怀疑Windows内核是否支持其中的任何一种(例如,内核应支持用户空间进程/线程的单步执行以允许调试器正常工作,但不支持内核的单步执行,并且由于各种原因可能会锁定计算机“等待锁释放6天”的问题)。

3个选项的最后一个是:

c)在仿真器/模拟器中运行OS,而不是在实际硬件上运行它。在那种情况下,您可能可以修改仿真器/仿真器的代码以在某个地方注入EIP值(也许是某种虚拟的“ EIP报告设备”?)。这将破坏仿真器/仿真器的性能,但是您可以隐藏它(例如,“仿真器内部的虚拟时间以每1000秒仿真器外部的实时速度流逝一秒钟”)。

最新问题
© www.soinside.com 2019 - 2024. All rights reserved.