Ring0.cpp
上传用户:nbcables
上传日期:2007-01-11
资源大小:1243k
文件大小:3k
源码类别:

钩子与API截获

开发平台:

Visual C++

  1. #include <windows.h>
  2. #include "ring0.h"
  3. #ifdef WIN95
  4. //DWORD g_result =0, g_eax =0;
  5. // 修改地址属性
  6. __declspec(naked) void Ring0ModifyPageProtection()
  7. {
  8. _asm
  9. {
  10. //Mov [g_result], 1 
  11. Mov EAX, ECX
  12. Shr EAX, 22
  13. Test DWORD PTR [0FFBFE000h + EAX * 4], 1
  14. Jz Fail
  15.   //Mov [g_result], 2 
  16. Mov EAX, ECX
  17. Shr EAX, 12
  18. Mov EBX, EAX
  19. Mov EAX, DWORD PTR [0FF800000h + EAX * 4]
  20. Test EAX, 1
  21. //Jz Fail // changed by Paladin 2003.01.23
  22. //Mov [g_result], 3 //
  23. Mov EAX, 1
  24. Cmp EDX, PAGE_READWRITE
  25. Je PageReadWrite
  26. And DWORD PTR [0FF800000h + EBX * 4], 0xFFFFFFFD
  27. Jmp Done
  28. PageReadWrite:
  29. Or DWORD PTR [0FF800000h + EBX * 4], 2
  30. Jmp Done
  31. Fail:
  32. Xor EAX, EAX
  33. Done:
  34. Retf
  35. }
  36. }
  37. // 使系统进入Ring0模式下
  38. GDTR gdtr;
  39. GDT_DESCRIPTOR *pGDTDescriptor;
  40. bool CallRing0(PVOID pvRing0FuncAddr, PVOID pvAddr, DWORD dwPageProtection)
  41. {
  42. bool Result;
  43. if(pvAddr ==NULL) return false;
  44. _asm Sgdt [gdtr]
  45. pGDTDescriptor = (GDT_DESCRIPTOR *)(gdtr.dwGDTBase + 8);
  46. // Search for a free GDT descriptor
  47. for (WORD wGDTIndex = 1; wGDTIndex < (gdtr.wGDTLimit / 8); wGDTIndex++)
  48. {
  49. if (pGDTDescriptor->Type == 0   &&
  50. pGDTDescriptor->System == 0 &&
  51. pGDTDescriptor->DPL == 0    &&
  52. pGDTDescriptor->Present == 0)
  53. {
  54. // Found one !
  55. // Now we need to transform this descriptor into a callgate.
  56. // Note that we're using selector 0x28 since it corresponds
  57. // to a ring 0 segment which spans the entire linear address
  58. // space of the processor (0-4GB).
  59. CALLGATE_DESCRIPTOR *pCallgate;
  60. pCallgate = (CALLGATE_DESCRIPTOR *) pGDTDescriptor;
  61. pCallgate->Offset_0_15 = LOWORD(pvRing0FuncAddr);
  62. pCallgate->Selector = 0x28;
  63. pCallgate->ParamCount = 0;
  64. pCallgate->Unused = 0;
  65. pCallgate->Type = 0xc;  // 386 call gate
  66. pCallgate->System = 0;  // a system descriptor
  67. pCallgate->DPL = 3;     // ring 3 code can call
  68. pCallgate->Present = 1;
  69. pCallgate->Offset_16_31 = HIWORD(pvRing0FuncAddr);
  70. // Prepare the far call parameters
  71. WORD CallgateAddr[3];
  72. CallgateAddr[0] = 0x0;
  73. CallgateAddr[1] = 0x0;
  74. CallgateAddr[2] = (wGDTIndex << 3) | 3;
  75. // call Ring0ModifyPageProtection
  76. _asm
  77. {
  78. Mov ECX, [pvAddr]
  79. Mov EDX, [dwPageProtection]
  80. Cli
  81. Call FWORD PTR [CallgateAddr]
  82. Sti
  83. Mov DWORD PTR [Result], EAX
  84. }
  85. // Now free the GDT descriptor
  86. memset(pGDTDescriptor, 0, 8);
  87. return Result;
  88. }
  89. // Advance to the next GDT descriptor
  90. pGDTDescriptor++;
  91. }
  92. // Whoops, the GDT is full
  93. return false;
  94. }
  95. // 改变内存状态为可读写
  96. BOOL RemovePageProtection(PVOID pvAddr)
  97. {
  98. return CallRing0((PVOID)Ring0ModifyPageProtection, pvAddr, PAGE_READWRITE);
  99. }
  100. BOOL SetPageProtection(PVOID pvAddr)
  101. {
  102. return CallRing0((PVOID)Ring0ModifyPageProtection, pvAddr, PAGE_READONLY);
  103. }
  104. #endif