“001b:7c812afb 模块 kernel32.dll 中的异常”中的 001b 是什么意思?

发布于 2024-12-02 05:06:26 字数 234 浏览 1 评论 0原文

例如:

myapp.exe 在模块中导致 Microsoft C++ 异常 (0xe06d7363) kernel32.dll 位于 001b:7c812afb。

我出于好奇而问这个问题,因为我注意到在所有异常和崩溃中,这个数字(001b)始终保持不变,而后一个数字发生变化(我假设它保存指令指针的值)。

那么这个 001b 到底是什么意思呢?

For example:

myapp.exe caused a Microsoft C++ Exception (0xe06d7363) in module
kernel32.dll at 001b:7c812afb.

I'm asking this out of curiosity, because I've noticed that in all exceptions and crashes this number (001b) always stays the same, while the latter number changes (I assume it holds the instruction pointer's value).

So what does this 001b mean, exactly?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

凉墨 2024-12-09 05:06:26

您将看到 CS:EIP 形式的地址,其中处理器上的 CS 对应于 16 位代码段寄存器和 EIP是 32 位指令指针(在 16 位模式下它只是 IP)。

这就是我在研究为什么在您正在研究的所有案例中看到 CS0x001b (0b0000000000011011) 之前所知道的部分。我要说的任何其他内容都是半知情的猜测和/或疯狂的猜测。我正在关注这些:

http://en.wikipedia.org/wiki/X86_memory_segmentation

http://www.cs.cmu.edu/~410/doc/segments/segments.html

所以这里什么也没有。只需在我要说的每句话后面添加一个“也许”,认真从事此类工作的人就可以介入并纠正错误......


在保护模式下,CS 的低两位寄存器是RPL或“请求的特权级别”。保护环是:

  • 0 - 操作系统内核
  • 1 和 2 - 操作系统服务
  • 3 - 应用程序

您位于 3 (0b11),因为这些应用程序可能在调用系统 DLL 时崩溃。这与……比如说……操作系统本身有一个错误——这会给你一个蓝屏死机而不是一个漂亮的 Windows 对话框。事实上,如果您通过 Google 搜索一些蓝屏,它们通常以 0x0028 (0b0000000000101000) 开头,我们可以看到这是内核级崩溃。

下一个最高有效位是 TI 或“表指示符”...对于全局描述符表为 0,对于本地描述符表为 1< /em>。 (这提供了一种解释我们还没有讨论过的 CS 寄存器的剩余高 13 位中保存的索引含义的方法。)

在崩溃中,您看到了第三位为0表示使用全局描述符表。这是因为每个应用程序都不会加载同一 DLL 的自己的副本,并且您的崩溃发生在 DLL 内部(大概是从您的应用程序传递了不正确的数据)。如果您的崩溃发生在 EXE 代码中,我们预计这是 1。我的 Windows 体验很模糊,但我似乎记得当崩溃实际上发生在您的程序中时,您会收到不同类型的消息,而您没有不能像在 DLL 中那样获取 CS 寄存器输出。

现在我们只剩下剩下的了。全局描述符表中的索引 3 (0b0000000000011)。瓦扎特的意思是?手头没有 Windows 的源代码,但我确实在此内核教程中找到了一些参考:

http://www.jamesmolloy.co.uk/tutorial_html/4.-%20GDT%20and%20IDT.html

如果您从中查看 init_gdt(),您会发现:

gdt_set_gate(0, 0, 0, 0, 0);                // Null segment
gdt_set_gate(1, 0, 0xFFFFFFFF, 0x9A, 0xCF); // Code segment
gdt_set_gate(2, 0, 0xFFFFFFFF, 0x92, 0xCF); // Data segment
gdt_set_gate(3, 0, 0xFFFFFFFF, 0xFA, 0xCF); // User mode code segment
gdt_set_gate(4, 0, 0xFFFFFFFF, 0xF2, 0xCF); // User mode data segment

因此 Windows 可能使用类似的数字(甚至相同)。也许 kernel32.dll 正在运行用户模式代码段,因为它尚未验证您传递给它的内容,不足以切换到代码段 1。

...也许吧。 :-P

You are seeing an address of the form CS:EIP, where on your processor CS corresponds to the 16-bit Code Segment register and the EIP is the 32-bit Instruction Pointer (it would be just IP in a 16-bit mode).

That's the part I knew before looking into why you are seeing a CS of 0x001b (0b0000000000011011) in all the cases you're studying. Anything else I'm about to say is semi-informed guess-work and/or wild speculation. I'm kind of following along with these:

http://en.wikipedia.org/wiki/X86_memory_segmentation

http://www.cs.cmu.edu/~410/doc/segments/segments.html

So here goes nothing. Just add a "maybe" after every sentence I'm about to say, and someone who does this kind of work for serious can step in and correct the mistakes...


In protected mode, the lower two bits of the CS register are the RPL or "Requested Privilege Level". The protection rings are:

  • 0 - Operating System Kernel
  • 1 and 2 - Operating System Services
  • 3 - Applications

You're in 3 (0b11) because presumably these are applications that are crashing while calling a system DLL. That's in contrast to...say...the OS itself having a bug--which would be giving you a blue screen of death instead of a nice Windows dialog. In fact, if you Google around for some blue screens they often start with 0x0028 (0b0000000000101000) and we can see that's a kernel-level crash.

The next most significant bit is the TI or "Table Indicator"...which is either 0 for the global descriptor table or 1 for the local descriptor table. (This provides a way of interpreting the meaning of the index held in the remaining upper 13 bits of the CS register we haven't talked about yet.)

In the crash you're seeing you've got 0 in the third bit to indicate use a global descriptor table. That's because every app doesn't load its own copy of the same DLL, and your crash is happening inside of a DLL (presumably of it being passed improper data from your app). If your crash was in the code of an EXE we'd expect this to be a 1. My Windows experience is hazy but I seem to remember you get a different sort of message when the crash is actually in your program, and you don't get the CS register output like you do when it happens in a DLL.

Now we're left with the rest of it. Index 3 (0b0000000000011) in the Global Descriptor Table. Wazzat mean? Don't have the source code for Windows on hand, but I did find some references in this kernel tutorial:

http://www.jamesmolloy.co.uk/tutorial_html/4.-The%20GDT%20and%20IDT.html

If you look into the init_gdt() from that, you see:

gdt_set_gate(0, 0, 0, 0, 0);                // Null segment
gdt_set_gate(1, 0, 0xFFFFFFFF, 0x9A, 0xCF); // Code segment
gdt_set_gate(2, 0, 0xFFFFFFFF, 0x92, 0xCF); // Data segment
gdt_set_gate(3, 0, 0xFFFFFFFF, 0xFA, 0xCF); // User mode code segment
gdt_set_gate(4, 0, 0xFFFFFFFF, 0xF2, 0xCF); // User mode data segment

So Windows might use similar numbers (or even the same). Perhaps kernel32.dll is running the user mode code segment because it hasn't validated the stuff you passed into it yet enough to switch over into code segment 1.

...maybe. :-P

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文