A forum for reverse engineering, OS internals and malware analysis 

Ask your beginner questions here.
 #8433  by Tigzy
 Tue Sep 06, 2011 11:50 am
Hello

I got a very very newbie question.. Well it's more a weird behaviour than a question actually.

Trying to load a driver of mine
The problem is that CreateService always returns NULL, and the strange thing , GetLastError() always returns ERROR_SUCCESS (0) :o

I don't really know if CreateService checks the driver's code, so don't know if it comes from my User app, or from my driver.

Code: Select all
#define DriverName "MyDrv"
#define DriverDisplay "MyDrv"
#define Driver "\\MyDrv.sys"

...

//******* Driver loading *******
WCHAR path[MAX_PATH], pathDummy[MAX_PATH], Name[MAX_PATH], Display[MAX_PATH];

//Getting whole path
wcscpy_s(path, L"\"");
::GetCurrentDirectory(MAX_PATH, pathDummy);
wcscat_s(path, pathDummy);
wcscat_s(path, _T(Driver));
wcscat_s(path, L"\"");
	
wcscpy_s(Name, _T(DriverName));
wcscpy_s(Display, _T(DriverDisplay));

hService = LoadDriver(Name, Display, path);
Code: Select all
SC_HANDLE LoadDriver(TCHAR* Name, TCHAR* NameDisplay, TCHAR* Path)
{
	SC_HANDLE hSCManager, hService; 
	
    hSCManager = OpenSCManager(NULL, NULL, SC_MANAGER_CREATE_SERVICE);        

    if(hSCManager)
    {
        hService = CreateService(hSCManager, Name, NameDisplay, SERVICE_START | DELETE | SERVICE_STOP, SERVICE_KERNEL_DRIVER, SERVICE_DEMAND_START, SERVICE_ERROR_NORMAL, Path, NULL, NULL, NULL, NULL, NULL);
        
		WCHAR buff[256];
		swprintf(buff, 256, L"Error %d", GetLastError()); 
		MessageBox(NULL, buff, L"Info", MB_OK);

		hService = OpenService(hSCManager, Name, SERVICE_START | DELETE | SERVICE_STOP); 
		StartService(hService, 0, NULL); 	

        CloseServiceHandle(hSCManager);		
		
		return hService;
    }

	return NULL;
}

EDIT: OSRLoader successfully loaded the driver
 #8439  by Alex
 Tue Sep 06, 2011 5:32 pm
Try to call OpenSCManager with SC_MANAGER_ALL_ACCESS instead of the SC_MANAGER_CREATE_SERVICE access...
 #8442  by nullptr
 Wed Sep 07, 2011 6:38 am
try...
Code: Select all
    #define DriverName    _T("MyDrv")
    #define DriverDisplay _T("MyDrv")
    #define Driver        _T("\\MyDrv.sys")

    //******* Driver loading *******
    TCHAR path[MAX_PATH], pathDummy[MAX_PATH], Name[MAX_PATH], Display[MAX_PATH];

    //Getting whole path
    _tcscpy_s(path, MAX_PATH, _T("\""));
    GetCurrentDirectory(MAX_PATH, pathDummy); // **check return value
    _tcscat_s(path, MAX_PATH, pathDummy);
    _tcscat_s(path, MAX_PATH, Driver);
    _tcscat_s(path, MAX_PATH, _T("\""));
    // MessageBox(0, path, path, MB_OK); // check that path is quoted correctly

 #8447  by Tigzy
 Wed Sep 07, 2011 10:24 am
Yep, Already checked the path.
Maybe I got a clue, I guess this is a Handle not closed problem.
Will improve my code with CloseHandle's and reboot / restore VM to see
 #8448  by EP_X0FF
 Wed Sep 07, 2011 10:33 am
Code: Select all
// Driver handle
HANDLE		SysHandle = INVALID_HANDLE_VALUE;

BOOL InstallDriver( IN SC_HANDLE SchSCManager, IN LPCTSTR DriverName, IN LPCTSTR ServiceExe )
{
    SC_HANDLE  schService;

    schService = CreateService( SchSCManager,          // SCManager database
                                DriverName,           // name of service
                                DriverName,           // name to display
                                SERVICE_ALL_ACCESS,    // desired access
                                SERVICE_KERNEL_DRIVER, // service type
                                SERVICE_DEMAND_START,  // start type
                                SERVICE_ERROR_IGNORE,  // error control type
                                ServiceExe,            // service's binary
                                NULL,                  // no load ordering group
                                NULL,                  // no tag identifier
                                NULL,                  // no dependencies
                                NULL,                  // LocalSystem account
                                NULL                   // no password
                                );
    if ( schService == NULL )
        return FALSE;

    CloseServiceHandle( schService );

    return TRUE;
}

BOOL StartDriver( IN SC_HANDLE SchSCManager, IN LPCTSTR DriverName )
{
    SC_HANDLE  schService;
    BOOL       ret;

    schService = OpenService( SchSCManager,
                              DriverName,
                              SERVICE_ALL_ACCESS
                              );
    if ( schService == NULL )
        return FALSE;

    ret = StartService( schService, 0, NULL )
       || GetLastError() == ERROR_SERVICE_ALREADY_RUNNING 
	   || GetLastError() == ERROR_SERVICE_DISABLED;

    CloseServiceHandle( schService );
    return ret;
}

BOOL OpenDevice( IN LPCTSTR DriverName, HANDLE * lphDevice )
{
    TCHAR    completeDeviceName[64];
    HANDLE   hDevice;

	if( (GetVersion() & 0xFF) >= 5 ) {

		wsprintf( completeDeviceName, TEXT("\\\\.\\Global\\%s"), DriverName );

	} else {

		wsprintf( completeDeviceName, TEXT("\\\\.\\%s"), DriverName );
	}

    hDevice = CreateFile( completeDeviceName,
                          GENERIC_READ | GENERIC_WRITE,
                          0,
                          NULL,
                          OPEN_EXISTING,
                          FILE_ATTRIBUTE_NORMAL,
                          NULL
                          );
    if ( hDevice == ((HANDLE)-1) )
        return FALSE;

	// If user wants handle, give it to them.  Otherwise, just close it.
	if ( lphDevice )
		*lphDevice = hDevice;
	else
	    CloseHandle( hDevice );

    return TRUE;
}

BOOL StopDriver( IN SC_HANDLE SchSCManager, IN LPCTSTR DriverName )
{
    SC_HANDLE       schService;
    BOOL            ret;
    SERVICE_STATUS  serviceStatus;

    schService = OpenService( SchSCManager, DriverName, SERVICE_ALL_ACCESS );
    if ( schService == NULL )
        return FALSE;

    ret = ControlService( schService, SERVICE_CONTROL_STOP, &serviceStatus );

    CloseServiceHandle( schService );

    return ret;
}

BOOL RemoveDriver( IN SC_HANDLE SchSCManager, IN LPCTSTR DriverName )
{
    SC_HANDLE  schService;
    BOOL       ret;

    schService = OpenService( SchSCManager,
                              DriverName,
                              SERVICE_ALL_ACCESS
                              );

    if ( schService == NULL )
        return FALSE;

    ret = DeleteService( schService );
    CloseServiceHandle( schService );
    return ret;
}

BOOL UnloadDeviceDriver( const TCHAR * Name )
{
	SC_HANDLE	schSCManager;

	schSCManager = OpenSCManager(	NULL,                 // machine (NULL == local)
                              		NULL,                 // database (NULL == default)
									SC_MANAGER_ALL_ACCESS // access required
								);

	StopDriver( schSCManager, Name );
	RemoveDriver( schSCManager, Name );
	 
	CloseServiceHandle( schSCManager );

	return TRUE;
}

BOOL LoadDeviceDriver( const TCHAR * Name, const TCHAR * Path, 
					  HANDLE * lphDevice, PDWORD Error )
{
	SC_HANDLE	schSCManager;
	BOOL		okay;

	schSCManager = OpenSCManager( NULL, NULL, SC_MANAGER_ALL_ACCESS );

	// Remove old instances
	RemoveDriver( schSCManager, Name );

	// Ignore success of installation: it may already be installed.
	InstallDriver( schSCManager, Name, Path );

	// Ignore success of start: it may already be started.
	StartDriver( schSCManager, Name );

	// Do make sure we can open it.
	okay = OpenDevice( Name, lphDevice );
	*Error = GetLastError();
 	CloseServiceHandle( schSCManager );

	return okay;
}
 #8863  by Tigzy
 Fri Sep 30, 2011 1:55 pm
Hello

I got another problem, maybe more strange...

You probably knows why, but I want to do the following:
Code: Select all
SC_HANDLE rh = CreateService(sh, theDriverName, NameDisplay, SERVICE_ALL_ACCESS, SERVICE_KERNEL_DRIVER, SERVICE_BOOT_START, SERVICE_ERROR_NORMAL, aPath, "Boot Bus Extender", &tag, NULL, NULL, NULL);
GetLestError() returns ERROR_INVALID_PARAMETER.

When I replace SERVICE_BOOT_START with SERVICE_SYSTEM_START, all works... :|
Any idea why the boot config failed?