2008-12-20

Загрузка драйверов в Windows

Один из самых простых способов загрузить драйвер в Windows - использльзовать SCM (Service Control Manager). Для быстрой загрузки/выгрузки своих небольших драйверов, я набросал програмку. Програма создаёт службу(Service) типа SERVICE_KERNEL_DRIVER с именем test_driver (соответственно в реестре создаёться раздел HKLM/System/CurrentControlSet/Services/test_driver). Подробнее про cлужбы можно почитать на wasm.ru

//Service Control Programm
#include <windows.h>
#include <stdio.h>
#define MAX_L 256

char *sn="test_driver";
char *dn="test_driver";

int unload()
{
SC_HANDLE hSCM, hService;
SERVICE_STATUS status;

hSCM = OpenSCManager(NULL,NULL,SC_MANAGER_ALL_ACCESS);
if(hSCM == NULL){
printf("[!] Error in OpenSCManager\n");
return -1;
}
hService = OpenService(hSCM, sn , SC_MANAGER_ALL_ACCESS);

if(!hService){
printf("Error in hService\n");
return -1;
}
if(ControlService(hService, SERVICE_CONTROL_STOP, &status) != TRUE){
printf ("[!] Error in ControlService. Code: %.x\n",GetLastError());
return -1;
}
DeleteService(hService);
printf("stoped..\nUnloaded..\n");
CloseServiceHandle(hService);
CloseServiceHandle(hSCM);
return 1;
}

int load(char * path)
{
SC_HANDLE hSCM, hService;
hSCM = OpenSCManager(NULL,NULL,SC_MANAGER_ALL_ACCESS);
if(hSCM == NULL){
printf("[!] Error in OpenSCManager\n");
return -1;
}

GetFullPathName(path,MAX_L,path,NULL);

hService = CreateService(hSCM, sn, dn, SERVICE_ALL_ACCESS,
SERVICE_KERNEL_DRIVER, SERVICE_DEMAND_START, SERVICE_ERROR_IGNORE, path,
NULL, NULL, NULL, NULL, NULL);

if(StartService(hService,0,NULL)!=TRUE){
printf("[!] Error in StartService. Code: %.x\n",GetLastError());
return -1;
}
printf("Now driver loaded in kernel memory.\n");
CloseServiceHandle(hService);
CloseServiceHandle(hSCM);
return 1;
}

void usage(char * p){
printf("Load driver: %s l \nUnload driver: %s u",p,p);
exit(0);
}

int main(int argc, char * argv[])
{
int r = 0;
if(argc<2) usage(argv[0]);
switch(*argv[1])
{
case 'l':
if(argc!=3) usage(argv[0]);
r = load(argv[2]);
case 'u':
if(argc<2) usage(argv[0]);
r = unload();
default:
usage(argv[0]);
}
return r;
}

2008-12-12

SDT

Осваиваюсь с внутреним устройством Windows, вот, набросал кодес для получения данных из SDT. Например получим номер функции NtCreateProcessEx которая в Windows Vista SP1 находиться по адрессу 0x826a8fea, а в Windows XP SP2 - 0x805c5c32:

#include <ntddk.h>

extern PUSHORT NtBuildNumber;
extern PVOID KeServiceDescriptorTable;

NTSTATUS DriverEntry(IN PDRIVER_OBJECT pDriverObject, IN PUNICODE_STRING RegPath)
{
unsigned long t, t2, p, pNtCreateProcessEx;
int i,j;

switch(*NtBuildNumber){
case 2600: //winxp
pNtCreateProcessEx = 0x805c5c32;
break;

case 6001: //vista (at least sp1)
pNtCreateProcessEx = 0x826a8fea;
break;
}

DbgPrint("[+] Driver successfuly loaded\n");
DbgPrint("SDT addr: %x\n", KeServiceDescriptorTable);

t = *((PULONG)KeServiceDescriptorTable);
for (i=j=0;j<=391;i+=4,j++){
t2 = *((PULONG)(t+i));
if(t2 == pNtCreateProcessEx){
DbgPrint("NtCreateProcess index: %d addr:%x\n", j,t2);
}
}
return STATUS_DEVICE_CONFIGURATION_ERROR;
}

Архив