pango99
驱动牛犊
驱动牛犊
  • 注册日期2001-08-21
  • 最后登录2018-05-29
  • 粉丝0
  • 关注0
  • 积分4分
  • 威望20点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
阅读:43468回复:4

KeI386AllocateGdtSelectors()这些未公开函数到底该怎么用?

楼主#
更多 发布于:2002-01-01 22:03
我在程序中使用了这些函数,可编译老是不成功,错误报告为:
error LNK2001: unresolved external symbol \"__declspec(dllimport) long __stdcall KeI386AllocateGdtSelectors(unsigned short *,unsigned long)\" (__imp_?KeI386AllocateGdtSelectors@@YGJPAGK@Z)
objfre\\i386\\callgate.sys() : error LNK1120: 1 unresolved externals

我想知道的是到底这个函数该怎么声明才能编译成功?我的函数声明是:
NTKERNELAPI                                                    
NTSTATUS  
KeI386AllocateGdtSelectors(
PUSHORT pSelectorArray,
ULONG NumberOfSelectors
);
有什么地方错了吗?如果谁再能提供个使用了这些函数的程序代码,那就太好了!
zdhe
驱动太牛
驱动太牛
  • 注册日期2001-12-26
  • 最后登录2018-06-02
  • 粉丝0
  • 关注0
  • 积分72362分
  • 威望362260点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
  • 社区居民
沙发#
发布于:2002-01-02 00:51
既然你使用了ntoskrnl.exe的export函数,又是undocumented,就不要指望静态连接了。(如果是是在driver中用,应该没有这个问题,ddk 提供的ntoskrnl.lib中有这个东东,虽然头文件中没有)

在usermode下,使用动态方式,

typedef NTSTATUS
( * TYPE_KeI386AllocateGdtSelectors)(
PUSHORT pSelectorArray,
ULONG NumberOfSelectors
);
TYPE_KeI386AllocateGdtSelectors  KeI386AllocateGdtSelectors=NULL;

HMODULE hNtOsKrnl = GetModuleHandle(\"ntoskrnl\");

if (hNtOsKrnl )
{
*(DWORD*)&KeI386AllocateGdtSelectors= (DWORD)GetProcAddress(hNtOsKrnl ,\"KeI386AllocateGdtSelectors\");
....
}

如果只是想作ring3->ring0切换的机能,仔细找一找,这样的文章不少。

不使用你说的那个函数的一个比较晦涩的实装是

(机能是从ring3->ring0, 把page 属性从Read改成writable,
事实上是自己emum gdt.)


long CallRing0(PVOID pvRing0FuncAddr, PVOID pvAddr, DWORD dwPageProtection)
{

  GDT_DESCRIPTOR *pGDTDescriptor;
  GDTR gdtr;
  long Result;

  _asm Sgdt [gdtr]

  // Skip the null descriptor

  pGDTDescriptor = (GDT_DESCRIPTOR *)(gdtr.dwGDTBase + 8);

  // Search for a free GDT descriptor

  for (WORD wGDTIndex = 1; wGDTIndex < (gdtr.wGDTLimit / 8); wGDTIndex++)
  {
    if (pGDTDescriptor->Type == 0     &&
        pGDTDescriptor->System == 0   &&
        pGDTDescriptor->DPL == 0      &&
        pGDTDescriptor->Present == 0)
    {
      // Found one !
      // Now we need to transform this descriptor into a callgate.
      // Note that we\'re using selector 0x28 since it corresponds
      // to a ring 0 segment which spans the entire linear address
      // space of the processor (0-4GB).

      CALLGATE_DESCRIPTOR *pCallgate;

      pCallgate = (CALLGATE_DESCRIPTOR *) pGDTDescriptor;
      pCallgate->Offset_0_15 = LOWORD(pvRing0FuncAddr);
      pCallgate->Selector = 0x28;
      pCallgate->ParamCount = 0;
      pCallgate->Unused = 0;
      pCallgate->Type = 0xc;
      pCallgate->System = 0;
      pCallgate->DPL = 3;
      pCallgate->Present = 1;
      pCallgate->Offset_16_31 = HIWORD(pvRing0FuncAddr);

      // Prepare the far call parameters

      WORD CallgateAddr[3];

      CallgateAddr[0] = 0x0;
      CallgateAddr[1] = 0x0;
      CallgateAddr[2] = (wGDTIndex << 3) | 3;

      // Please fasten your seat belts!
      // We\'re about to make a hyperspace jump into RING 0.

      _asm
      {
        Mov ECX, [pvAddr]
        Mov EDX, [dwPageProtection]
        Cli
        Call FWORD PTR [CallgateAddr]
        Sti
        Mov DWORD PTR [Result], EAX
      }
      
      // Now free the GDT descriptor

      MemSet(pGDTDescriptor, 0, 8);

      return Result;
    }

    // Advance to the next GDT descriptor

    pGDTDescriptor++;
  }

  // Whoops, the GDT is full

  return 0;
}



来源
// ----------------------------------- //
//            APISpy32 v3.0            //
//     Copyright 2000 Yariv Kaplan     //
//          www.internals.com          //
// ----------------------------------- //



pango99
驱动牛犊
驱动牛犊
  • 注册日期2001-08-21
  • 最后登录2018-05-29
  • 粉丝0
  • 关注0
  • 积分4分
  • 威望20点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
板凳#
发布于:2002-01-02 02:52
我是指在DRIVER中用,但编译没成功
zdhe
驱动太牛
驱动太牛
  • 注册日期2001-12-26
  • 最后登录2018-06-02
  • 粉丝0
  • 关注0
  • 积分72362分
  • 威望362260点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
  • 社区居民
地板#
发布于:2002-01-02 03:16
既然是kennel方式下,声明时加个 extern \"C\"{}看看。

extern \"C\"{
NTKERNELAPI
NTSTATUS
KeI386AllocateGdtSelectors(
PUSHORT pSelectorArray,
ULONG NumberOfSelectors
);
};
不是大问题。
pango99
驱动牛犊
驱动牛犊
  • 注册日期2001-08-21
  • 最后登录2018-05-29
  • 粉丝0
  • 关注0
  • 积分4分
  • 威望20点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
地下室#
发布于:2002-01-03 21:10
非常感谢zdhe兄,你的回复非常正确,正确的函数声明应该为:
extern \"C\"
NTKERNELAPI                                                    
NTSTATUS  
KeI386AllocateGdtSelectors(
PUSHORT pSelectorArray,
ULONG NumberOfSelectors
);
现在可以编译了。真是气人,就这么个小失误,另我费解了好长时间,我的程序的文件后缀名为CPP。
游客

返回顶部