首页
社区
课程
招聘
[求助]看看这个vc调用门机制的问题啊
2006-8-1 10:45 4885

[求助]看看这个vc调用门机制的问题啊

2006-8-1 10:45
4885
各位大侠
我想调用门机制使我可以从ring3跳到ring0,从而实现一些特殊功能

大家先看看这个资料
#include <windows.h>
#include <string.h>
#include <stdio.h>

#include "gate.h"

/* Global array to hold the page directory */

DWORD PageDirectory[1024];

这是 SHOWDIR.C 文件的开头部分,除了头文件的包含,还包括了用于保存页表的全局变量数组的定义。 所包含的头文件 GATE.H 是很有意思的。这个头文件里有使用调用门机制的函数的原型。使用调用门机制就可以在内核模式下执行自己的代码,而不用写新的驱动程序。

XREF: 我们在第10张讨论调用门机制。

我们在这个样例程序程序中使用此机制是因为页表不能从用户模式代码下访问。现在只要知道此机制使得一般可执行文件中的函数能在内核模式下执行就足够了。转到页表的定义上来,我们已经讲到了每个页表项的大小是4字节,一个页目录有1024个表项。因此,PageDirectory 是一个 1024 个 DWORDs的数组。数组中的每一个 DWORD 都代表着相应的目录项。

/* C function called from the assembly stub */

void _stdcall CFuncGetPageDirectory()
{
    DWORD *PageDir = (DWORD *)0xC0300000;
    int i = 0;

    for (i = 0; i < 1024; i++) {
        PageDirectory[i] = PageDir[i];
    }
}

CfuncGetPageDirectory() 是通过调用门机制在内核模式下执行的函数。此函数仅仅在用户模式内存区中拷贝一分页目录,这样程序中其它的用户模式的代码就能访问了。页目录被映射在每个进程的虚地址 0xC0300000 中。这个地址是无法在用户模式访问的。CFuncGetPageDirectory() 函数从地址 0xC0300000 处拷贝 1024 个 DWORDs 到全局变量 PageDirectory 中,这个变量可由程序中的用户模式代码访问。

/* Displays the contents of page directory. Starting
* virtual address represented by the page directory
* entry is shown followed by the physical page
* address of the page table
*/

void DisplayPageDirectory()
{
    int i;
    int ctr = 0;

    printf("Page directory for the process, pid=%x\n", GetCurrentProcessId());

    for (i = 0; i<1024; i++) {
        if (PageDirectory[i] & 0x01) {
            if ((ctr % 3) == 0) {
                printf("\n");
            }
            printf("%08x:%08x ", i << 22, PageDirectory[i] & 0xFFFFF000);
            ctr++;
        }
    }
    printf("\n");
}

DisplayPageDirectory() 函数在用户模式下运行并打印出由 CfuncGetPageDirectory() 初始化的 PageDirectory 数组。函数检查每一个表项的最低位(Least Significant Bit,LSB)。仅当最低位置位时页表项才有效。对于无效表项函数跳过不打印。 函数每行打印3个页表项,换句话说,每三个表项后打印一个换行字符。对每个目录项都打印其逻辑地址,所打印的相应的页表地址则是从页目录中取得的。如前所述,逻辑地址的前10位(或者说最高10位)用作页目录的索引。换句话说,索引值为 i 的页表项代表着前10位为 i 的逻辑地址。对于每一个目录项,函
数打印逻辑地址范围的基址。这个基地址(即范围中最低的地址)的低22位(或叫 22 LSBs)为 0。此基地址是由索引值 i 左移至前10位得到的。对应于逻辑地址的页表的地址保存在页目录项的前20位(或叫 20 MSBs)中。12 LSBs 为页目录项的标志。函数通过掩闭标志位来计算页表地址。

main()
{
WORD CallGateSelector;
int rc;
static short farcall[3];

/* Assembly stub that is called through callgate */

extern void GetPageDirectory(void);

/* Creates a callgate to read the page directory
* from Ring 3 */

rc = CreateCallGate(GetPageDirectory, 0, &CallGateSelector);

if (rc == SUCCESS) {

farcall[2] = CallGateSelector;
_asm {
call fword ptr [farcall]
}
DisplayPageDirectory();
getchar();

/* Releases the callgate */

rc=FreeCallGate(CallGateSelector);

if (rc!=SUCCESS) {
printf("FreeCallGate failed, "
"CallGateSelector=%x, rc=%x\n",
CallGateSelector, rc);
}
} else {
printf("CreateCallGate failed, rc=%x\n", rc);
}
return 0;
}

main() 开始先创建调用门,使得 GetPageDirectory() 函数在内核模式下执行。GetPageDirectory() 用汇编语言
编写,是 RING0.ASM 的一部分。CreateCallGate() 函数被程序用来创建调用门,它是由 CALLGATE.DLL 提供的。函数返回一个调用门描述符。

为什么我的程序老说找不到那个gate.h
我应该怎么做啊
谢谢

[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课

收藏
点赞7
打赏
分享
最新回复 (3)
雪    币: 2134
活跃值: (14)
能力值: (RANK:170 )
在线值:
发帖
回帖
粉丝
Aker 4 2006-8-1 11:52
2
0
不在同一个目录下?
雪    币: 236
活跃值: (26)
能力值: ( LV8,RANK:130 )
在线值:
发帖
回帖
粉丝
红火蚁 3 2006-8-1 12:01
3
0
我没找到这个
gate.h
雪    币: 2134
活跃值: (14)
能力值: (RANK:170 )
在线值:
发帖
回帖
粉丝
Aker 4 2006-8-1 12:31
4
0
最初由 红火蚁 发布
我没找到这个
gate.h

要不你试着自己由dll导出头文件
游客
登录 | 注册 方可回帖
返回