📄 iceext.c
字号:
/*++
Copyright (c) 2002 Sten
Contact information:
mail: stenri@mail.ru
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
Module Name:
IceExt.c
Abstract: Loader application for the IceExt driver.
It loads and unload IceExt.sys.
Revision History:
Sten 08/05/2006
Initial release
--*/
#include <memory.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <windows.h>
#pragma warning (disable : 4005)
#include <ntstatus.h>
#pragma warning (default : 4005)
#define ICEEXT_SERVICE_NAME L"IceExt"
#define ICEEXT_DRIVER_NAME L"IceExt.sys"
/* Below is rip of some DDK definitions. */
#define SE_LOAD_DRIVER_PRIVILEGE (10L)
#define NT_SUCCESS(Status) ((LONG)(Status) >= 0)
typedef LONG NTSTATUS;
typedef struct _UNICODE_STRING
{
USHORT Length;
USHORT MaximumLength;
PWSTR Buffer;
} UNICODE_STRING, *PUNICODE_STRING;
NTSYSAPI
VOID
NTAPI
RtlInitUnicodeString (
OUT PUNICODE_STRING DestinationString,
IN PCWSTR SourceString
);
NTSYSAPI
NTSTATUS
NTAPI
RtlAdjustPrivilege(
IN ULONG Privilege,
IN BOOLEAN NewValue,
IN BOOLEAN ForThread,
OUT PBOOLEAN OldValue
);
NTSYSAPI
ULONG
NTAPI
RtlNtStatusToDosError(
NTSTATUS status
);
NTSYSAPI
NTSTATUS
NTAPI
NtLoadDriver(
// "\\Registry\\Machine\\System\\CurrentControlSet\\Services\\<DriverName>"
IN PUNICODE_STRING RegistryPath
);
NTSYSAPI
NTSTATUS
NTAPI
NtUnloadDriver(
// "\\Registry\\Machine\\System\\CurrentControlSet\\Services\\<DriverName>"
IN PUNICODE_STRING RegistryPath
);
static BOOL WriteBinaryResourceToFile(HMODULE hResourceModule,LPCWSTR lpResourceName,LPCWSTR lpFileName)
{
HRSRC hResource;
HGLOBAL hGlobal;
LPVOID lpData;
DWORD dwSize;
HANDLE hFile = INVALID_HANDLE_VALUE;
BOOL bRet = FALSE;
__try
{
hResource = FindResourceW(hResourceModule, lpResourceName, L"BINARY");
if (hResource == NULL)
__leave;
hGlobal = LoadResource(hResourceModule, hResource);
if (hGlobal == NULL)
__leave;
dwSize = SizeofResource(hResourceModule, hResource);
if (dwSize == 0)
__leave;
lpData = LockResource(hGlobal);
if (lpData == NULL)
{
SetLastError(ERROR_NOT_LOCKED);
__leave;
}
hFile = CreateFileW(lpFileName, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
if (hFile == INVALID_HANDLE_VALUE)
__leave;
if (!WriteFile(hFile, lpData, dwSize, &dwSize, NULL))
__leave;
bRet = TRUE;
}
__finally
{
if (hFile != INVALID_HANDLE_VALUE)
CloseHandle(hFile);
}
return bRet;
}
static BOOL LoadUnloadDeviceDriver(LPCWSTR lpServiceName, LPCWSTR lpImagePath, BOOL bLoad)
{
HKEY hKey = NULL;
LPWSTR szString[MAX_PATH];
BOOL bRet = FALSE;
LONG lStatus;
UNICODE_STRING UnicodeString;
__try
{
_snwprintf((LPWSTR)&szString, MAX_PATH, L"System\\CurrentControlSet\\Services\\%s", lpServiceName);
lStatus = RegCreateKeyW(HKEY_LOCAL_MACHINE, (LPWSTR)&szString, &hKey);
if (lStatus != ERROR_SUCCESS)
{
SetLastError(lStatus);
__leave;
}
lStatus = SERVICE_KERNEL_DRIVER;
RegSetValueExW(hKey, L"Type", 0, REG_DWORD, (LPBYTE)&lStatus, sizeof(lStatus));
if (bLoad)
{
WCHAR szNTICE[] = L"NTICE\0\0";
lStatus = SERVICE_ERROR_NORMAL;
RegSetValueExW(hKey, L"ErrorControl", 0, REG_DWORD, (LPBYTE)&lStatus, sizeof(lStatus));
lStatus = SERVICE_DEMAND_START;
RegSetValueExW(hKey, L"Start", 0, REG_DWORD, (LPBYTE)&lStatus, sizeof(lStatus));
RegSetValueExW(hKey, L"DependOnService", 0, REG_MULTI_SZ, (const BYTE *)szNTICE, (wcslen(szNTICE)+2)*sizeof(WCHAR));
}
_snwprintf((LPWSTR)&szString, MAX_PATH, L"\\Registry\\Machine\\System\\CurrentControlSet\\Services\\%s", lpServiceName);
RtlInitUnicodeString(&UnicodeString, (LPWSTR)&szString);
RtlAdjustPrivilege(SE_LOAD_DRIVER_PRIVILEGE, TRUE, FALSE, (PBOOLEAN)&lStatus);
lStatus = bLoad ? NtLoadDriver(&UnicodeString) : NtUnloadDriver(&UnicodeString);
if (bLoad)
{
_snwprintf((LPWSTR)&szString, MAX_PATH, L"System\\CurrentControlSet\\Services\\%s\\Enum", lpServiceName);
RegDeleteKeyW(HKEY_LOCAL_MACHINE, (LPWSTR)&szString);
_snwprintf((LPWSTR)&szString, MAX_PATH, L"System\\CurrentControlSet\\Services\\%s\\Security", lpServiceName);
RegDeleteKeyW(HKEY_LOCAL_MACHINE, (LPWSTR)&szString);
}
_snwprintf((LPWSTR)&szString, MAX_PATH, L"System\\CurrentControlSet\\Services\\%s", lpServiceName);
RegDeleteKeyW(HKEY_LOCAL_MACHINE, (LPWSTR)&szString);
if (!NT_SUCCESS(lStatus))
{
SetLastError(RtlNtStatusToDosError(lStatus));
__leave;
}
bRet = TRUE;
}
__finally
{
if (hKey)
RegCloseKey(hKey);
}
return bRet;
}
static BOOL PrepareDeviceDriver(LPCWSTR lpServiceName, LPCWSTR lpServiceFileName, HMODULE hResourceModule, LPCWSTR lpDeviceResourceName)
{
LPWSTR szFullDeviceFileName[MAX_PATH];
LPWSTR szSystemDirectory[MAX_PATH];
BOOL bDeleteFile = FALSE;
DWORD dwLastError = NO_ERROR;
__try
{
if (GetSystemDirectoryW((LPWSTR)&szSystemDirectory, MAX_PATH) == 0)
{
dwLastError = GetLastError();
__leave;
}
_snwprintf((LPWSTR)&szFullDeviceFileName, MAX_PATH, L"%s\\Drivers\\%s", szSystemDirectory, lpServiceFileName);
if (WriteBinaryResourceToFile(hResourceModule, lpDeviceResourceName, (LPWSTR)&szFullDeviceFileName) == FALSE)
{
dwLastError = GetLastError();
__leave;
}
bDeleteFile = TRUE;
if (LoadUnloadDeviceDriver(lpServiceName, (LPWSTR)&szFullDeviceFileName, TRUE) == FALSE)
{
dwLastError = GetLastError();
__leave;
}
}
__finally
{
if (bDeleteFile)
DeleteFileW((LPWSTR)&szFullDeviceFileName);
}
SetLastError(dwLastError);
return !dwLastError;
}
static BOOL IsRegistryKeyExists(HKEY hRegKey, LPCWSTR lpszRegSubKey, LPCWSTR lpszValueName)
{
DWORD dwBytesNeeded;
HKEY hkResult = NULL;
DWORD dwLastError = NO_ERROR;
dwLastError = RegOpenKeyExW(HKEY_LOCAL_MACHINE, lpszRegSubKey, 0, KEY_QUERY_VALUE, &hkResult);
if(dwLastError != ERROR_SUCCESS)
goto cleanup;
dwLastError = RegQueryValueExW(hkResult, lpszValueName, 0, NULL, NULL, &dwBytesNeeded);
if (dwLastError != ERROR_SUCCESS)
goto cleanup;
cleanup:
if(hkResult)
RegCloseKey(hkResult);
return !dwLastError;
}
static BOOL GetDwordFromRegistry(LPDWORD lpdwValue, HKEY hRegKey, LPCWSTR lpszRegSubKey, LPCWSTR lpszValueName, DWORD dwDefault)
{
HKEY hkResult = NULL;
DWORD dwLastError = NO_ERROR,
dwBytesNeeded;
dwLastError = RegOpenKeyExW(HKEY_LOCAL_MACHINE, lpszRegSubKey, 0, KEY_QUERY_VALUE, &hkResult);
if(dwLastError != ERROR_SUCCESS)
goto cleanup;
dwBytesNeeded = sizeof(DWORD);
dwLastError = RegQueryValueExW(hkResult, lpszValueName, 0, NULL, (LPBYTE)lpdwValue, &dwBytesNeeded);
if (dwLastError != ERROR_SUCCESS)
goto cleanup;
cleanup:
if(hkResult)
RegCloseKey(hkResult);
if(dwLastError != ERROR_SUCCESS)
*lpdwValue = dwDefault;
SetLastError(dwLastError);
return !dwLastError;
}
static BOOL CheckSoftICEConfig()
{
DWORD dwVal;
if (!IsRegistryKeyExists(HKEY_LOCAL_MACHINE, L"SYSTEM\\CurrentControlSet\\Services\\NTice", L"KDExtensions"))
{
wprintf(L"Error: SoftICE is misconfigured. Add KDExtensions parameter of type REG_SZ under NTIce registry key.\n");
return FALSE;
}
if (!GetDwordFromRegistry(&dwVal, HKEY_LOCAL_MACHINE, L"SYSTEM\\CurrentControlSet\\Services\\NTice", L"KDHeapSize", 0) || (dwVal < 0x8000))
{
wprintf(L"Error: SoftICE is misconfigured. Set KDHeapSize = 0x8000 parameter of type REG_DWORD under NTIce registry key.\n");
return FALSE;
}
if (!GetDwordFromRegistry(&dwVal, HKEY_LOCAL_MACHINE, L"SYSTEM\\CurrentControlSet\\Services\\NTice", L"KDStackSize", 0) || (dwVal < 0x8000))
{
wprintf(L"Error: SoftICE is misconfigured. Set KDStackSize = 0x8000 parameter of type REG_DWORD under NTIce registry key.\n");
return FALSE;
}
return TRUE;
}
static int Usage (void)
{
wprintf(L"Usage IceExt [-s|-e|-v]\n");
wprintf(L" -s - start IceExt service\n");
wprintf(L" -e - stop IceExt service\n");
wprintf(L" -v - print version info\n");
return 1;
}
int _cdecl wmain (int argc, wchar_t *argv[])
{
if (argc != 2)
return Usage();
if ((_wcsicmp(argv[1], L"-s") == 0) || (_wcsicmp(argv[1], L"-start") == 0))
{
//
// Start IceExt service.
//
if (!CheckSoftICEConfig())
return 1;
// Start NTICE prior to IceExt. NtLoadDriver() functio doesn't look
// on DependOnService service object parameter, so we must do it
// here ourselves.
{
NTSTATUS lStatus;
UNICODE_STRING UnicodeString;
RtlInitUnicodeString(&UnicodeString, L"\\Registry\\Machine\\System\\CurrentControlSet\\Services\\NTICE");
RtlAdjustPrivilege(SE_LOAD_DRIVER_PRIVILEGE, TRUE, FALSE, (PBOOLEAN)&lStatus);
lStatus = NtLoadDriver(&UnicodeString);
if (!NT_SUCCESS(lStatus) && (lStatus != STATUS_IMAGE_ALREADY_LOADED))
{
wprintf(L"Error: unable to start NTICE driver [%08X]\n", RtlNtStatusToDosError(lStatus));
return 1;
}
}
if (!PrepareDeviceDriver(ICEEXT_SERVICE_NAME, ICEEXT_DRIVER_NAME, NULL, MAKEINTRESOURCEW(1)))
{
DWORD dwLastError = GetLastError();
if (dwLastError == RtlNtStatusToDosError(STATUS_IMAGE_ALREADY_LOADED))
wprintf(L"Error: IceExt is already loaded.\n");
else
wprintf(L"Error: unable to load IceExt driver [%08X]\n", dwLastError);
return 1;
}
wprintf(L"IceExt has been successfuly started.\n");
}
else
if ((_wcsicmp(argv[1], L"-e") == 0) || (_wcsicmp(argv[1], L"-end") == 0) || (_wcsicmp(argv[1], L"-stop") == 0))
{
//
// Stop IceExt service
//
if (!LoadUnloadDeviceDriver(ICEEXT_SERVICE_NAME, L"", FALSE))
{
DWORD dwLastError = GetLastError();
if (dwLastError == RtlNtStatusToDosError(STATUS_OBJECT_NAME_NOT_FOUND))
wprintf(L"Error: IceExt is not loaded.\n");
else
wprintf(L"Error: unable to unload IceExt driver [%08X]\n", dwLastError);
return 1;
}
wprintf(L"IceExt has been successfuly stopped.\n");
}
else
if ((_wcsicmp(argv[1], L"-v") == 0) || (_wcsicmp(argv[1], L"-ver") == 0))
{
wprintf(L"* IceExt 0.70 *\n");
}
else
return Usage();
return 0;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -