// $(PROJECT_NAME)App.cpp : Defines the entry point for the console application. // //*************************************************************************************** //* IOCTRL Sample Driver //* //* Application for the IoCtrl sample driver //* //*************************************************************************************** //####################################################################################### //# I N C L U D E S //####################################################################################### #include "stdafx.h" #include #include #include "..\\Common.h" /************************************************************************/ /* */ /* Modifed from : GaRY */ /* Modifed from : MyZwDriverControl.c */ /************************************************************************/ //#include //#include #define DRV_NAME "$(SYS_NAME)" #define STATUS_SUCCESS ((NTSTATUS)0x00000000L) //////////////////////////////////////////////////////////////////////////////// typedef LONG NTSTATUS; typedef struct _STRING { USHORT Length; USHORT MaximumLength; PCHAR Buffer; } ANSI_STRING, *PANSI_STRING; typedef struct _LSA_UNICODE_STRING { USHORT Length; USHORT MaximumLength; PVOID Buffer; } LSA_UNICODE_STRING, *PLSA_UNICODE_STRING; typedef LSA_UNICODE_STRING UNICODE_STRING, *PUNICODE_STRING; typedef DWORD (CALLBACK* RTLANSISTRINGTOUNICODESTRING)(PVOID, PVOID,DWORD); RTLANSISTRINGTOUNICODESTRING RtlAnsiStringToUnicodeString; typedef DWORD (CALLBACK* RTLFREEUNICODESTRING)(PVOID); RTLFREEUNICODESTRING RtlFreeUnicodeString; typedef DWORD (CALLBACK* ZWLOADDRIVER)(PVOID); ZWLOADDRIVER ZwLoadDriver; typedef DWORD (CALLBACK* ZWUNLOADDRIVER)(PVOID); ZWUNLOADDRIVER ZwUnloadDriver; BOOL GetLoadDriverPriv() { HANDLE hToken; if(OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY | TOKEN_ADJUST_PRIVILEGES, &hToken)) { LUID huid; if(LookupPrivilegeValue(NULL, "SeLoadDriverPrivilege", &huid)) { LUID_AND_ATTRIBUTES priv; priv.Attributes = SE_PRIVILEGE_ENABLED; priv.Luid = huid; TOKEN_PRIVILEGES tp; tp.PrivilegeCount = 1; tp.Privileges[0] = priv; if(AdjustTokenPrivileges(hToken, FALSE, &tp, 0, NULL, NULL)) { return TRUE; } } } return FALSE; } bool LoadDriver(char * szDrvName, char * szDrvPath) { char szSubKey[MAX_PATH]; char szDrvFullPath[MAX_PATH]; LSA_UNICODE_STRING buf1; LSA_UNICODE_STRING buf2; int iBuffLen; HKEY hkResult; char Data[4]; DWORD dwOK; iBuffLen = sprintf_s(szSubKey, MAX_PATH, "System\\CurrentControlSet\\Services\\%s", szDrvName); szSubKey[iBuffLen]=0; dwOK = RegCreateKey(HKEY_LOCAL_MACHINE,szSubKey,&hkResult); if(dwOK!=ERROR_SUCCESS) return false; DWORD val; val = 1; if(RegSetValueEx(hkResult, "Type", 0, REG_DWORD, (PBYTE)&val, sizeof(val)) != ERROR_SUCCESS) return FALSE; if(RegSetValueEx(hkResult, "ErrorControl", 0, REG_DWORD, (PBYTE)&val, sizeof(val)) != ERROR_SUCCESS) return FALSE; val = 3; if(RegSetValueEx(hkResult, "Start", 0, REG_DWORD, (PBYTE)&val, sizeof(val)) != ERROR_SUCCESS) return FALSE; GetFullPathName(szDrvPath, MAX_PATH, szDrvFullPath, NULL); printf(" Loading driver: %s\r\n", szDrvFullPath); iBuffLen = sprintf_s(szSubKey, MAX_PATH, "\\??\\%s", szDrvFullPath); szSubKey[iBuffLen]=0; dwOK=RegSetValueEx(hkResult,"ImagePath",0,1,(const unsigned char *)szSubKey,iBuffLen); RegCloseKey(hkResult); HMODULE hntdll; hntdll = LoadLibrary( "ntdll.dll" ); VOID (WINAPI *_RtlInitAnsiString) (IN OUT PANSI_STRING DestinationString, IN PCHAR SourceString); *(FARPROC *)&_RtlInitAnsiString = GetProcAddress(hntdll, "RtlInitAnsiString"); ANSI_STRING aStr; _RtlInitAnsiString(&aStr, "\\Registry\\Machine\\System\\CurrentControlSet\\Services\\"DRV_NAME); UNICODE_STRING uStr; if(RtlAnsiStringToUnicodeString(&uStr, &aStr, TRUE) != STATUS_SUCCESS) { return FALSE; } else { if(ZwLoadDriver(&uStr) == STATUS_SUCCESS) { RtlFreeUnicodeString(&uStr); } else { RtlFreeUnicodeString(&uStr); return FALSE; } } iBuffLen=sprintf_s(szSubKey, MAX_PATH, "%s%s\\Enum","System\\CurrentControlSet\\Services\\", szDrvName); szSubKey[iBuffLen]=0; RegDeleteKey(HKEY_LOCAL_MACHINE,szSubKey); iBuffLen=sprintf_s(szSubKey, MAX_PATH, "%s%s\\Security","System\\CurrentControlSet\\Services\\", szDrvName); szSubKey[iBuffLen]=0; RegDeleteKey(HKEY_LOCAL_MACHINE,szSubKey); iBuffLen=sprintf_s(szSubKey, MAX_PATH, "%s%s","System\\CurrentControlSet\\Services\\", szDrvName); szSubKey[iBuffLen]=0; RegDeleteKey(HKEY_LOCAL_MACHINE,szSubKey); iBuffLen=sprintf_s(szSubKey, MAX_PATH, "\\\\.\\%s", szDrvName); szSubKey[iBuffLen]=0; return true; } bool UnloadDriver(char * szDrvName, char * szDrvPath) { char szSubKey[MAX_PATH]; char szDrvFullPath[MAX_PATH]; LSA_UNICODE_STRING buf1; LSA_UNICODE_STRING buf2; int iBuffLen; HKEY hkResult; char Data[4]; DWORD dwOK; iBuffLen = sprintf_s(szSubKey, MAX_PATH, "System\\CurrentControlSet\\Services\\%s", szDrvName); szSubKey[iBuffLen]=0; dwOK = RegCreateKey(HKEY_LOCAL_MACHINE,szSubKey,&hkResult); if(dwOK!=ERROR_SUCCESS) return false; DWORD val; val = 1; if(RegSetValueEx(hkResult, "Type", 0, REG_DWORD, (PBYTE)&val, sizeof(val)) != ERROR_SUCCESS) return FALSE; if(RegSetValueEx(hkResult, "ErrorControl", 0, REG_DWORD, (PBYTE)&val, sizeof(val)) != ERROR_SUCCESS) return FALSE; val = 3; if(RegSetValueEx(hkResult, "Start", 0, REG_DWORD, (PBYTE)&val, sizeof(val)) != ERROR_SUCCESS) return FALSE; GetFullPathName(szDrvPath, MAX_PATH, szDrvFullPath, NULL); printf(" Loading driver: %s\r\n", szDrvFullPath); iBuffLen = sprintf_s(szSubKey, MAX_PATH, "\\??\\%s", szDrvFullPath); szSubKey[iBuffLen]=0; dwOK=RegSetValueEx(hkResult,"ImagePath",0,1,(const unsigned char *)szSubKey,iBuffLen); RegCloseKey(hkResult); HMODULE hntdll; hntdll = LoadLibrary( "ntdll.dll" ); VOID (WINAPI *_RtlInitAnsiString) (IN OUT PANSI_STRING DestinationString, IN PCHAR SourceString); *(FARPROC *)&_RtlInitAnsiString = GetProcAddress(hntdll, "RtlInitAnsiString"); ANSI_STRING aStr; _RtlInitAnsiString(&aStr, "\\Registry\\Machine\\System\\CurrentControlSet\\Services\\"DRV_NAME); UNICODE_STRING uStr; if(RtlAnsiStringToUnicodeString(&uStr, &aStr, TRUE) != STATUS_SUCCESS) { return FALSE; } else { if(ZwUnloadDriver(&uStr) == STATUS_SUCCESS) { RtlFreeUnicodeString(&uStr); } else { RtlFreeUnicodeString(&uStr); return FALSE; } } iBuffLen=sprintf_s(szSubKey, MAX_PATH, "%s%s\\Enum","System\\CurrentControlSet\\Services\\", szDrvName); szSubKey[iBuffLen]=0; RegDeleteKey(HKEY_LOCAL_MACHINE,szSubKey); iBuffLen=sprintf_s(szSubKey, MAX_PATH, "%s%s\\Security","System\\CurrentControlSet\\Services\\", szDrvName); szSubKey[iBuffLen]=0; RegDeleteKey(HKEY_LOCAL_MACHINE,szSubKey); iBuffLen=sprintf_s(szSubKey, MAX_PATH, "%s%s","System\\CurrentControlSet\\Services\\", szDrvName); szSubKey[iBuffLen]=0; RegDeleteKey(HKEY_LOCAL_MACHINE,szSubKey); iBuffLen=sprintf_s(szSubKey, MAX_PATH, "\\\\.\\%s", szDrvName); szSubKey[iBuffLen]=0; return true; } bool MyZwLoadDriver(char * szDrvName, char * szDrvPath) { if(!GetLoadDriverPriv()) { return FALSE; } HMODULE hNtdll = NULL; hNtdll = LoadLibrary( "ntdll.dll" ); RtlAnsiStringToUnicodeString = (RTLANSISTRINGTOUNICODESTRING) GetProcAddress( hNtdll, "RtlAnsiStringToUnicodeString"); RtlFreeUnicodeString = (RTLFREEUNICODESTRING) GetProcAddress( hNtdll, "RtlFreeUnicodeString"); ZwLoadDriver = (ZWLOADDRIVER) GetProcAddress( hNtdll, "ZwLoadDriver"); ZwUnloadDriver = (ZWLOADDRIVER) GetProcAddress( hNtdll, "ZwUnloadDriver"); //עЁE if(LoadDriver(szDrvName, szDrvPath) == false) { FreeLibrary(hNtdll); return false; } FreeLibrary(hNtdll); return true; } bool MyZwUnloadDriver(char * szDrvName, char * szDrvPath) { if(!GetLoadDriverPriv()) { return FALSE; } HMODULE hNtdll = NULL; hNtdll = LoadLibrary( "ntdll.dll" ); RtlAnsiStringToUnicodeString = (RTLANSISTRINGTOUNICODESTRING) GetProcAddress( hNtdll, "RtlAnsiStringToUnicodeString"); RtlFreeUnicodeString = (RTLFREEUNICODESTRING) GetProcAddress( hNtdll, "RtlFreeUnicodeString"); ZwUnloadDriver = (ZWLOADDRIVER) GetProcAddress( hNtdll, "ZwUnloadDriver"); if(UnloadDriver(szDrvName, szDrvPath) == false) { FreeLibrary(hNtdll); return false; } FreeLibrary(hNtdll); return true; } //####################################################################################### //@@@@@@@@ A P P L I C A T I O N E N T R Y P O I N T @@@@@@@@ //####################################################################################### //*************************************************************************************** //* NAME: main //* //* DESCRIPTION: Opens a handle and send IOCTRLs. There are three IOCTRL codes used: //* IOCTL_HELLO_WORLD - Prints Hello World to a debugger //* IOCTRL_REC_FROM_APP - Sends data from GUI to DRIVER //* IOCTRL_SEND_TO_APP - Sends data from DRIVER to GUI //* //* PARAMETERS: None //* //* RETURNS: 0 Success //* 1 Unsuccessful //*************************************************************************************** int _tmain(int argc, _TCHAR* argv[]) { TCHAR szFileName[MAX_PATH] = {0}; if(0 == ::GetModuleFileName( NULL, szFileName, sizeof(szFileName))) { szFileName[0]=_T('\\'); } LPTSTR szPos = _tcsrchr( szFileName,_T('\\') ); szPos++; *szPos = _T('\0'); if( MAX_PATH < (_tcslen(szFileName) + _tcslen(_T("$(SYS_FILENAME)")))) { return -1; } _tcscat_s( szFileName, _T("$(SYS_FILENAME)")); if (0xFFFFFFFF == ::GetFileAttributes(szFileName)) { printf("Please put your sys and exe in the same dir.\r\n"); getchar(); return -1; } if (false == MyZwLoadDriver(_T("$(SYS_NAME)"), szFileName)) { printf("Load driver failed.\r\n"); //return -1; } HANDLE hDriver = NULL; ULONG status = 0L; ULONG bytesReturned = 0L; CHAR dataToDriver[MAX_PATH] = {0}; CHAR dataFromDriver[MAX_PATH] = {0}; CHAR input[MAX_PATH] = {0}; // Open the sample PCI device hDriver = CreateFileA( WIN32_LINK_NAME, GENERIC_READ|GENERIC_WRITE, 0, 0, OPEN_EXISTING, FILE_FLAG_OVERLAPPED, 0 ); if ( hDriver == INVALID_HANDLE_VALUE ) { status = GetLastError(); printf( "Error 0x%x, CreateFile failed. Make sure the sample IOCTRL DRIVER is loaded\n\n", status ); getchar(); return 1; } while ( 1 ) { memset( dataToDriver, 0, MAX_PATH ); memset( dataFromDriver, 0, MAX_PATH ); memset( input, 0, MAX_PATH ); printf( "\t--- IoCtrl Sample Driver: ---\n" ); printf( "\t1. Send HELLO_WORLD_IOCTL\n" ); printf( "\t2. Send data to driver\n" ); printf( "\t3. Receive data from driver\n" ); printf( "\t0. Exit\n" ); printf( "\n\tSelection: " ); StringCchGetsA( input, MAX_PATH - 1 ); switch( input[0] ) { case '0': { // Adios CloseHandle( hDriver ); // Unload SYS if (false == MyZwUnloadDriver(_T("$(SYS_NAME)"), szFileName)) { printf("Unload driver failed.\r\n"); //return -1; } } getchar(); return 0; case '1': { // Test the IOCTL_HELLO_WORLD interface status = DeviceIoControl( hDriver, (DWORD)IOCTL_HELLO_WORLD, 0, 0, 0, 0, &bytesReturned, 0 ); if( status == 0 ) { status = GetLastError(); printf( "\tError 0x%x, failed to send IOCTL_HELLO_WORLD\n\n", status ); } else { printf( "\tDeviceIoControl IOCTL_HELLO_WORLD sucessfully sent. \n\n"); } } break; case '2': { // Send data to driver printf ("\n\tData to send: "); StringCchGetsA( dataToDriver, MAX_PATH - 1 ); /* enforce the NULL terminator */ dataToDriver[ MAX_PATH - 1 ] = 0x00; status = DeviceIoControl( hDriver, (DWORD)IOCTRL_REC_FROM_APP, dataToDriver, MAX_PATH - 1, 0, 0, &bytesReturned, 0 ); if ( status == 0 ) { status = GetLastError(); printf( "\tError 0x%x, failed to send IOCTRL_REC_FROM_APP\n\n", status ); } else { printf( "\tDeviceIoControl IOCTRL_REC_FROM_APP sucessfully sent. \n\n"); } } break; case '3': { // Receive data from driver status = DeviceIoControl( hDriver, (DWORD)IOCTRL_SEND_TO_APP, 0, 0, dataFromDriver, MAX_PATH - 1, &bytesReturned, 0 ); if( status == 0 ) { status = GetLastError(); printf( "\tError 0x%x, failed to send IOCTRL_SEND_TO_APP\n\n", status ); } else { /* enforce the NULL terminator */ dataFromDriver[ MAX_PATH - 1 ] = 0x00; if( bytesReturned > 0 ) { printf( "\tData received: %s\n", dataFromDriver ); } else { printf( "\tNo data received: %s\n", dataFromDriver ); } printf( "\tDeviceIoControl IOCTRL_SEND_TO_APP sucessfully sent. \n\n"); } break; } default: break; } } }