ANTICHAT.XYZ    VIDEO.ANTICHAT.XYZ    НОВЫЕ СООБЩЕНИЯ    ФОРУМ  
Баннер 1   Баннер 2
Antichat снова доступен.
Форум Antichat (Античат) возвращается и снова открыт для пользователей. Здесь обсуждаются безопасность, программирование, технологии и многое другое. Сообщество снова собирается вместе.
Новый адрес: forum.antichat.xyz
Вернуться   Форум АНТИЧАТ > ИНФО > Статьи > Авторские статьи
   
Ответ
 
Опции темы Поиск в этой теме Опции просмотра

Жизнь после смерти
  #1  
Старый 15.02.2007, 00:51
Аватар для _Great_
_Great_
Флудер
Регистрация: 27.12.2005
Сообщений: 2,372
Провел на форуме:
5339610

Репутация: 4360


Отправить сообщение для _Great_ с помощью ICQ
По умолчанию Жизнь после смерти

Article: Жизнь после смерти
Author: Great
ICQ #: 893-894
Date: 14.02.2007
Lang: C/C++ kernel & user mode
Note: Эта тема затрагивалась уже многими авторами. Как пережить BSoD и не уронить систему? Предлагались варианты поставить загрушки вида RET или JMP $ на KeBugCheckEx. Мы снова затронем эту тему, но поподробнее.

Что же происходит, например, при выполнении следующего кода в режиме ядра:
XOR EAX,EAX
MOV [EAX],EAX
Как нетрудно догадаться, производится попытка обращения по нулевому указателю. Первые 10000 байт как раз зарезервированы для отлова таких ошибок и памяти там быть не может. Результат очевиден - Page Fault, за которым следует сразу BSoD. Но зачем рушить всю систему, если один драйвер что-то сделал не так?
С одной стороны, ход мыслей разработчиков ОС вполне очевиден. Они ориентируются на худшее, ведь если ошибка будет в драйвере файловой системы, можно так и винт угробить.
С другой стороны, ошибки в коде ОС и драйверах, с ней поставляемых, случаются довольно редко. Наиболее распространенная причина ошибок - драйвера сторонних производителей, в том и числе и тех, кто только начинает разбираться в программировании на ядерном уровне в Windows. И показ синего экрана с остановкой системы тут не лучший выход. Идеальный вариант с моей точки зрения - показ диалогового окна с ошибкой и выгрузка проблемного драйвера.
До выгрузки драйвера мы замахиваться не будем, а вот заморозить выполнение проблемного кода - легко!
Разберемся, что нам надо сделать, чтобы продолжить работу.
1) размаскировать все прерывания, если они были замаскированы. Это сделает вызов KeLowerIrql(PASSIVE_LEVEL).
2) в бесконечном цикле вызывать ZwYieldExecution, чтобы заморозить поток.
Между этими двумя основными действиями мы сделаем дополнительные:
3) залогируем ошибку через DbgPrint()
4) сохраним параметры багчека (стоп-код и аргументы)
5) установим и сбросим заранее заготовленный объект "событие" (Event), который просигнализирует нашей юзермодной программе о том, что произошла ошибка. Она запросит у нашего драйвера параметры багчека, которые мы аккуратно сохранили в пункте 4) и выдаст месажбокс.
Юзермодная часть будет делать просто ожидание объекта "событие", запрос у драйвера параметров ошибки и вывод месажбокса.

Теперь перейдем подробнее к реализации. Нам потребуется реализовать маленький движок для сплайсинга кода ядра.
Я накатал вот что:
Код:
//
// Splicing routines
//

NTSTATUS SetKernelSplicingHook(PVOID pfnDst, PVOID pfnHook, BYTE buffer[5])
{
	__try
	{
		// Backup
		RtlCopyMemory(buffer, pfnDst, 5);

		// Write JMP
		DWORD offset = (DWORD) pfnHook - (DWORD) pfnDst - 5;
		*(BYTE*)pfnDst = 0xE9; // JMP FAR
		*(DWORD*)((DWORD)pfnDst+1) = offset;

		return STATUS_SUCCESS;
	}
	__except(EXCEPTION_EXECUTE_HANDLER)
	{
		return GetExceptionCode();
	}
}

NTSTATUS UnsetKernelSplicingHook(PVOID pfnDst, BYTE buffer[5])
{
	__try
	{
		// Restore
		RtlCopyMemory(pfnDst, buffer, 5);
		return STATUS_SUCCESS;
	}
	__except(EXCEPTION_EXECUTE_HANDLER)
	{
		return GetExceptionCode();
	}
}
Думаю тут ничего в комментариях не нуждается, я и так все подробно расписал в своей статье про сплайсинг.
Надо еще узнать адрес, чего, собственно, сплайсить-то. Тут есть один нюанс. Реализация функций KeBugCheck* в Win2000 и WinXP разная.

Windows2000:
Код:
KeBugCheck(code)
{
KeBugCheckEx(code,0,0,0,0);
}

KeBugCheckEx(code,par1,par2,par3,par4)
{
// основная работа по показу BSoD'а
}
Windows XP:
Код:
KeBugCheck(code)
{
KeBugCheck2(code,0,0,0,0,0);
}

KeBugCheckEx(code,par1,par2,par3,par4)
{
KeBugCheck2(code,par1,par2,par3,par4,0);
}

KeBugCheck2(code,par1,par2,par3,par4,unknown)
{
// основная работа по показу BSoD'а
}
В случае Win2000 всю работу выполняет функция KeBugCheckEx.
В случае WinXP KeBugCheck и KeBugCheckEx - обертки для специальной неэкспортируемой функции ядра KeBugCheck2, которая и показывает синий экран.

Мы будем ориентироваться на XP по причине того, что она больше сейчас распространена.
Поэтому и сплайсить мы будем функцию KeBugCheck2. Нужно получить ее адрес. Вот тут облом.. она же не экспортируется ядром. Но мы найдем ссылку на нее из KeBugCheckEx. За подробностями прошу в мою статью "цветной экран смерти", а тут я только лишь приведу код вычисления адреса KeBugCheck2:
Код:
PVOID GetKeBugCheck2Address()
{
	// Acquire KeBugCheck2 address
	DWORD addr = (DWORD) &KeBugCheckEx;
	addr += 0x17;                       // offset of CALL _KeBugCheck2@20
	return (PVOID) (addr + 4 + *(DWORD*)addr);    // jump to KeBugCheck2
}
Все готово. Пора приступать к написанию драйвера.
Сперва рассмотрим DriverEntry. Нам надо создать девайс. Мы его назовем "bugcheckeventdevice". Код создания девайса и символической ссылки весьма стандартен для не-PnP драйверов и пояснений не требует:
Код:
NTSTATUS DriverEntry(IN PDRIVER_OBJECT DriverObject, IN PUNICODE_STRING RegistryPath)
{
	NTSTATUS status;
	DPRINT("[~] Driver loading");

	RtlInitUnicodeString(&DeviceName, L"\\Device\\bugcheckeventdevice");
    RtlInitUnicodeString(&SymbolicLinkName, L"\\DosDevices\\bugcheckeventdevice");

	status = IoCreateDevice(DriverObject,
				0, 
				&DeviceName, 
				FILE_DEVICE_UNKNOWN, 
				0, 
				TRUE, 
				&deviceObject);
	
	if (!NT_SUCCESS(status))
	{
		DPRINT("[-] Failed to create first device. IoCreateDevice returned %x", status);
		return STATUS_UNSUCCESSFUL;
	}
	
	deviceObject->Flags |= DO_BUFFERED_IO;
	status = IoCreateSymbolicLink(&SymbolicLinkName, &DeviceName);
	if (!NT_SUCCESS(status))
	{
		DPRINT("[-] Failed to create first symbolic link. IoCreateSymbolicLink returned %x", status);
		IoDeleteDevice(deviceObject);
		return STATUS_UNSUCCESSFUL;
	}
Дальше мы создаем объект "событие" под названием "BugCheckEvent" с начальным состоянием Nonsignaled.
Следующий код отвечает за это:
Код:
	RtlInitUnicodeString(&EventName, L"\\BaseNamedObjects\\BugCheckEvent");
	OBJECT_ATTRIBUTES oa;
	InitializeObjectAttributes(&oa, &EventName, 0, 0, 0);
	status = ZwCreateEvent(&hEvent, EVENT_ALL_ACCESS, &oa, SynchronizationEvent, FALSE);
	if (!NT_SUCCESS(status))
	{
		DPRINT("[-] Failed to create event. ZwCreateEvent returned %x", status);
		IoDeleteDevice(deviceObject);
		IoDeleteSymbolicLink(&SymbolicLinkName);
		return STATUS_UNSUCCESSFUL;
	}
	DPRINT("[+] Event created, handle is %08x", hEvent);
Дальше мы устанавливаем функции диспетчеризации:
Код:
	DriverObject->DriverUnload = DriverUnload;
	DriverObject->MajorFunction [IRP_MJ_CREATE] =
    DriverObject->MajorFunction [IRP_MJ_CLOSE ] = DriverCreateClose;
    DriverObject->MajorFunction [IRP_MJ_DEVICE_CONTROL ] = DriverIoControl;
После чего делаем сплайсинг на KeBugCheck2 и завершаем загрузку драйвера:
Код:
	__try
	{
		status = SetKernelSplicingHook(GetKeBugCheck2Address(), KeBugCheck2, SplicingBuffer);
	}
	__except(EXCEPTION_EXECUTE_HANDLER)
	{
		status = GetExceptionCode();
	}
	if(!NT_SUCCESS(status))
	{
		DPRINT("[-] Cannot set splicing hook [%08x]", status);
		IoDeleteDevice(deviceObject);
		IoDeleteSymbolicLink(&SymbolicLinkName);
		ZwClose(hEvent);
		return STATUS_UNSUCCESSFUL;
	}

	DPRINT("[+] Driver initialization successful");
	return STATUS_SUCCESS;
}
Для девайса определяем функцию-заглушку на пакеты IRP_MJ_CREATE/IRP_MJ_CLOSE:
Код:
NTSTATUS DriverCreateClose(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
{
	// Dummy. Simply indicate success.
    Irp->IoStatus.Information = 0;
    Irp->IoStatus.Status = STATUS_SUCCESS;
    IoCompleteRequest(Irp, IO_NO_INCREMENT);
    return STATUS_SUCCESS;
}
Теперь определим функцию для обработки IRP_MJ_DEVICE_CONTROL. Юзермодная часть будет обращаться к нам через DeviceIoControl и требовать параметры багчека.

Следующий код их отдаст:
Код:
// IOCTL
#define FILE_DEVICE_BUGCHECKDRIVER 0x00003656
#define IOCTL_BUGCHECKDRIVER_GET_BUGCHECK_INFO CTL_CODE( FILE_DEVICE_BUGCHECKDRIVER, 0x00, METHOD_BUFFERED, FILE_ANY_ACCESS)

NTSTATUS DriverIoControl(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
{
    PIO_STACK_LOCATION pisl     = IoGetCurrentIrpStackLocation(Irp);
	NTSTATUS           status   = STATUS_UNSUCCESSFUL;
	ULONG              BuffSize = pisl->Parameters.DeviceIoControl.InputBufferLength;
	PUCHAR             pBuff    = (PUCHAR)Irp->AssociatedIrp.SystemBuffer;

	Irp->IoStatus.Information = 0;

	switch(pisl->Parameters.DeviceIoControl.IoControlCode)
	{
		case IOCTL_BUGCHECKDRIVER_GET_BUGCHECK_INFO:
			__try
			{
				// If bug check info present & buffer's length is greater or equal necessary length, write info to system buffer
				if( bBugCheckInfoPresent && pBuff && pisl->Parameters.DeviceIoControl.OutputBufferLength >= (sizeof(DWORD)*5) )
				{
					((DWORD*)pBuff)[0] = BugCheckCode;
					for(int i=0;i<4;i++) // Copy bug check parameters
						((DWORD*)pBuff)[i+1] = BugCheckParameters[i];

					Irp->IoStatus.Information = sizeof(DWORD)*5; // Copy 5 DWORDs to user buffer
					status = STATUS_SUCCESS;
				}
			}
			__except(EXCEPTION_EXECUTE_HANDLER)
			{
				status = GetExceptionCode();
				DPRINT("[!] IOCTL_BUGCHECKDRIVER_GET_BUGCHECK_INFO: Exception occurred: %08x", status);
			}
		break;
	}   

    Irp->IoStatus.Status = status;
    IoCompleteRequest(Irp, IO_NO_INCREMENT);
    return status;
}
Функция выгрузки драйвера полностью противоположна загрузке:

Код:
void DriverUnload(IN PDRIVER_OBJECT DriverObject)
{
	// Delete device
	IoDeleteSymbolicLink (&SymbolicLinkName);
	if(deviceObject)
		IoDeleteDevice (deviceObject);

	// Delete event
	ZwClose(hEvent);

	// Remove hook from KeBugCheck2
	NTSTATUS status;
	__try
	{
		status = UnsetKernelSplicingHook(GetKeBugCheck2Address(), SplicingBuffer);
	}
	__except(EXCEPTION_EXECUTE_HANDLER)
	{
		status = GetExceptionCode();
	}
	if(!NT_SUCCESS(status))
		DPRINT("[-] Cannot unset splicing hook [%08x]", status);

	DPRINT ("[+] Driver unloaded");
}
Удаление ссылки, устройства, события и снятие хука.

Прежде, чем реализовывать новый обработчик KeBugCheck2, мы напишем функцию, которая быстро поставит и снимет сигнализированное состояние для "события" BugCheckEvent:
Код:
// Pulse event
NTSTATUS PulseEvent()
{
	__try
	{
		// Initialize
		NTSTATUS status;
		HANDLE NewHandle;
		OBJECT_ATTRIBUTES oa;
		InitializeObjectAttributes(&oa, &EventName, 0, 0, 0);
		
		// Open
		status = ZwOpenEvent(&NewHandle, EVENT_MODIFY_STATE, &oa);
		if(!NT_SUCCESS(status))
			return status;
		
		// Pulse
		DPRINT("[~] Trying to pulse event %08x", NewHandle);
		status = ZwPulseEvent(NewHandle, 0);
		if(!NT_SUCCESS(status))
			return status;

		// Close
		ZwClose(NewHandle);
		return STATUS_SUCCESS;
	}
	__except(EXCEPTION_EXECUTE_HANDLER)
	{
		// Exception occurred
		return GetExceptionCode();
	}
}
Тут все просто. Теперь самое главное - новый обработчик KeBugCheck2:

Код:
BOOLEAN bBugCheckInfoPresent = 0;
DWORD   BugCheckCode, BugCheckParameters[4];
BYTE SplicingBuffer[5];

void NTAPI KeBugCheck2(
					 IN DWORD iBugCheckCode,
					 IN DWORD iBugCheckParameter1,
					 IN DWORD iBugCheckParameter2,
					 IN DWORD iBugCheckParameter3,
					 IN DWORD iBugCheckParameter4,
					 IN DWORD iUnknown)
{
	// 
	// Lower IRQL to PASSIVE_LEVEL
	//

	KIRQL Irql = KeGetCurrentIrql();
	if(Irql > PASSIVE_LEVEL)
		KeLowerIrql(PASSIVE_LEVEL);

	// Log error
	DPRINT("[*] KeBugCheck2 call - FATAL SYSTEM ERROR. BugCheck code %08x", iBugCheckCode);

	//
	// Write bug check info
	//

	__try
	{
		BugCheckCode = iBugCheckCode;
		BugCheckParameters[0] = iBugCheckParameter1;
		BugCheckParameters[1] = iBugCheckParameter2;
		BugCheckParameters[2] = iBugCheckParameter3;
		BugCheckParameters[3] = iBugCheckParameter4;
		bBugCheckInfoPresent = TRUE;
	}
	__except(EXCEPTION_EXECUTE_HANDLER)
	{
		DPRINT("[!] KeBugCheck2: Exception occurred while saving bug check parameters: %08x", GetExceptionCode());
	}

	//
	// Pulse event, user mode process will wake up and show dialog box
	//

	PulseEvent();

	//
	// Hang current thread
	//

	while(1)
		ZwYieldExecution();
}
Все, как мы и распланировали. Ядерная часть нашей системы готова. Драйвер можно собрать и, вообще говоря, загрузить. По логам DbgPrint'а можно убедиться, что все идет нормально.
Примемся за пользовательскую часть. Опишем функцию, которая будет ждать событие по его имени:
Код:
bool WaitForEvent(char* name)
{
	HANDLE hEvent;
	DWORD error;

	do
	{
		hEvent = OpenEvent(SYNCHRONIZE, FALSE, name);
		error = GetLastError();
		Sleep(1);
	}
	while(!hEvent && error == ERROR_FILE_NOT_FOUND);

	if(!hEvent)
	{
		return false;
	}
	
	WaitForSingleObject(hEvent, INFINITE);
	CloseHandle(hEvent);
	return true;
}
Ею мы будем пользоваться. Мы будем в цикле ждать наступления события и, когда оно наступит, выполнять нужные нам действия:
Код:
int APIENTRY WinMain(HINSTANCE,HINSTANCE,LPSTR,int)
{
	while(1)
	{
		if(!WaitForEvent("BugCheckEvent"))
			return printf("[!] Failed\n");
		EventSet();
	}
	return 0;
}
Все действия будет выполнять функция EventSet(). Она запросит у драйвера BugCheck-код и аргументы и покажет месажбокс:

Код:
// IOCTL
#define FILE_DEVICE_BUGCHECKDRIVER 0x00003656
#define IOCTL_BUGCHECKDRIVER_GET_BUGCHECK_INFO CTL_CODE( FILE_DEVICE_BUGCHECKDRIVER, 0x00, METHOD_BUFFERED, FILE_ANY_ACCESS)

void EventSet()
{
	struct
	{
		DWORD BugCheckCode;
		DWORD BugCheckParameters[4];
	} BugCheckInfo = {0};

	BOOL res = 0;

	HANDLE hFile = CreateFile("\\\\.\\bugcheckeventdevice", GENERIC_READ, FILE_SHARE_READ|FILE_SHARE_WRITE, 0, OPEN_EXISTING, 0, 0);
	DWORD ret;
	if(hFile != INVALID_HANDLE_VALUE)
	{
		res = DeviceIoControl(hFile, IOCTL_BUGCHECKDRIVER_GET_BUGCHECK_INFO, 0, 0, &BugCheckInfo, sizeof(BugCheckInfo), &ret, 0);
		CloseHandle(hFile);
	}

	char buffer[1024];
	if(res)
		sprintf(buffer,
			"Warning!! The fatal kernel mode error occurred at address 0x%08x\n"
			"\n"
			"BugCheck code: %08x\n"
			"Parameters:\n"
			"  BugCheckParameter1: 0x%08x\n"
			"  BugCheckParameter2: 0x%08x\n"
			"  BugCheckParameter3: 0x%08x\n"
			"  BugCheckParameter4: 0x%08x\n"
			"\n"
			"It is HIGHLY RECOMMENDED to reboot as soon as possible, because if you\n"
			" continue working, it may cause unrecoverable errors or simply system hang.\n",
			0,
			BugCheckInfo.BugCheckCode, BugCheckInfo.BugCheckParameters[0], BugCheckInfo.BugCheckParameters[1],
			BugCheckInfo.BugCheckParameters[2], BugCheckInfo.BugCheckParameters[3]
			);
	else
		sprintf(buffer,
			"Warning!! The fatal kernel mode error occurred at address 0x%08x\n"
			"\n"
			"Unfortunately, it was unable to get bugcheck information.\n"
			"Additional information is not available.\n"
			"\n"
			"It is HIGHLY RECOMMENDED to reboot as soon as possible, because if you\n"
			" continue working, it may cause unrecoverable errors or simply system hang.\n",
			0,
			BugCheckInfo.BugCheckCode, BugCheckInfo.BugCheckParameters[0], BugCheckInfo.BugCheckParameters[1],
			BugCheckInfo.BugCheckParameters[2], BugCheckInfo.BugCheckParameters[3]
			);
	MessageBox(0, buffer, "Fatal system error", MB_ICONERROR|MB_OK);
}
Вот и все. Программу можно собрать и запустить. Она спокойно и мирно будет ждать наступления события, а пока оно не наступит, она не будет жрать процессорное время, потому что я написал вызов Sleep(1).

Теперь проверка. Попробуем вызвать KeBugCheckEx(1,2,3,4,5). Результат не заставит себя ждать:

Все ништяк. Теперь "боевая" проверка, попробуем сделать ошибку страницы при высоком IRQL:

Как видно, нас спасли от краха. Если бы не наш драйвер, уже давно бы красовался синий экран IRQL_NOT_LESS_OR_EQUAL.

Теперь несколько замечаний.
Во-первых, система еще очень сырая и требует доработки и тщательной наладки. Было бы неплохо заставить драйвер определять и причину сбоя. Пока что сбойный адрес я смело забиваю нулями.
Во-вторых, это далеко не панацея от всех бед. Можно так продержаться от 3-4 до 6 раз, дальше система начнет тормозить из-за того, что мы не выгружаем проблемные драйвера, а просто их "вешаем". Было бы кстати реализовать выгрузку проблемного драйвера из памяти вместо входа в бесконечный цикл.
В-третьих, я это писал для разработчиков драйверов с целью, чтобы можно было посмотреть на свою ошибку, сохранить все данные и ребутнуться. Продолжать работу после "краха" системы (который не произошел все же) не желательно по причинам, описанным мной в самом начале статьи.
Еще было бы неплохо скидывать крешдамп так же, как это делает винда, для последующего анализа. Использовать "родной" IoWriteCrashDump тут не получится, потому что винда записывает крешдамп аккурат в сектора, занимаемые страничным файлом, чтобы не дергать лишний раз драйвер ФС, а при загрузке потом она уже извлекает из страничного файла дамп. Нас это не совсем устраивает и нужно реализовать нормальный сброс крешдампа сразу в обычный файл.

Но все равно, это лучше, чем ничего, то есть, чем простое зависание системы с синим экраном. Это позволяет, по крайней мере, выяснить причину ошибки и корректно завершить работу.
Если что-то не понятно, спрашивай. Как всегда, сорсы можно забрать у меня на сайте: http://cribble.by.ru/bugcheck/

На последок хочу выразить отдельную благодартность W[4Fh]LF за ответы на вопросы по поводу создания событий в режиме ядра =) Респект те, чувак
Удачи, пока!
 
Ответить с цитированием

  #2  
Старый 15.02.2007, 03:08
Аватар для Cr4sh
Cr4sh
Познающий
Регистрация: 25.08.2005
Сообщений: 57
Провел на форуме:
216363

Репутация: 76
Отправить сообщение для Cr4sh с помощью ICQ
По умолчанию

протев, кк об этом писал =/

Цитата:
Как пережить BSoD и не уронить систему?
поставить сайс и не ипаццо...

и ещё, не обижайся плз, но ф-ции GetKeBugCheck2Address и SetKernelSplicingHook это ЛОЛ =))
 
Ответить с цитированием

  #3  
Старый 15.02.2007, 14:22
Аватар для _Great_
_Great_
Флудер
Регистрация: 27.12.2005
Сообщений: 2,372
Провел на форуме:
5339610

Репутация: 4360


Отправить сообщение для _Great_ с помощью ICQ
По умолчанию

Цитата:
протев, кк об этом писал =/
Поставить RET? Если будет каскад исключений, все повиснет.
Поставить JMP $? Повиснет сразу же.
Цитата:
поставить сайс и не ипаццо...
Не у всех он ставится )
Цитата:
и ещё, не обижайся плз, но ф-ции GetKeBugCheck2Address и SetKernelSplicingHook это ЛОЛ =))
кучу проверок будет ставить не красиво
Вообще я собирался сделать switch() на *NtBuildNumber и для вин2000 ставить хук на KeBugCheckEx сразу, а для XP вычислять офсет. Ну а вообще я еще в начале написал, что драйвер только для XP пока что.

Последний раз редактировалось _Great_; 15.02.2007 в 14:32..
 
Ответить с цитированием

  #4  
Старый 15.02.2007, 17:12
Аватар для Cr4sh
Cr4sh
Познающий
Регистрация: 25.08.2005
Сообщений: 57
Провел на форуме:
216363

Репутация: 76
Отправить сообщение для Cr4sh с помощью ICQ
По умолчанию

Цитата:
кучу проверок будет ставить не красиво
писать нестабильный код тоже некрасиво)))

Цитата:
Вообще я собирался сделать switch() на *NtBuildNumber и для вин2000 ставить хук на KeBugCheckEx сразу, а для XP вычислять офсет. Ну а вообще я еще в начале написал, что драйвер только для XP пока что.
NtBuildNumber-ом дело не ограничится, т.к. в комплект поставки дистриба входят несколько ядер, которые выбираются в зависимости от аппаратной платформы (например, у меня на ноуте дефолтно ставится ядро с PAE) плюс билды ядра меняются в сервиспаках или даже в отдельных патчах
 
Ответить с цитированием

  #5  
Старый 15.02.2007, 17:16
Аватар для _Great_
_Great_
Флудер
Регистрация: 27.12.2005
Сообщений: 2,372
Провел на форуме:
5339610

Репутация: 4360


Отправить сообщение для _Great_ с помощью ICQ
По умолчанию

Цитата:
писать нестабильный код тоже некрасиво)))
на XP 2600 он стабильный :P

Цитата:
NtBuildNumber-ом дело не ограничится, т.к. в комплект поставки дистриба входят несколько ядер, которые выбираются в зависимости от аппаратной платформы (например, у меня на ноуте дефолтно ставится ядро с PAE) плюс билды ядра меняются в сервиспаках или даже в отдельных патчах
есесно, что не ограничится.
 
Ответить с цитированием

  #6  
Старый 17.02.2007, 16:39
Аватар для _Great_
_Great_
Флудер
Регистрация: 27.12.2005
Сообщений: 2,372
Провел на форуме:
5339610

Репутация: 4360


Отправить сообщение для _Great_ с помощью ICQ
По умолчанию

я кое-че добавил:
- теперь херачит на Windows 2000 и Windows XP
- можно выбрать - продолжить работу или все-таки свалить систему. (пока что просто выдается сохраненный багчек с параметрами, было бы неплохо еще и скопировать стек, чтобы получившийся крешдамп можно было анализировать)
- добавил, наконец, отключение WP
- все же вставил проверку на всякий случай, как посоветовал Cr4sh %)

Надо бы еще добавить:
- определение сбойного драйвера
- выгрузку сбойного драйвера
- если юзер решил все же свалить систему, сымитировать ошибочный контекст, чтобы получился читабельный крешдамп
- "живую" генерацию крешдампа работающей системы (это вообще можно отдельной прогой +))

сцылко: http://gr8.cih.ms/bugcheck2/
 
Ответить с цитированием

  #7  
Старый 19.02.2007, 21:52
Аватар для _Great_
_Great_
Флудер
Регистрация: 27.12.2005
Сообщений: 2,372
Провел на форуме:
5339610

Репутация: 4360


Отправить сообщение для _Great_ с помощью ICQ
По умолчанию

Воообщем-то я фигню сморозил насчет while(1) ZwYieldExecution();
Это все равно тормозит поток, правда, не так сильно, как while(1);, но все же.
Лучший вариант:
Код:
	//
	// Hang current thread
	//

	LARGE_INTEGER i;
	i.QuadPart = -9223372036854775807;
	KeDelayExecutionThread(KernelMode, FALSE, &i);
Планировщик не передаст управление нашему потоку ближайший 701 миллион лет. Надеюсь, я не доживу )
 
Ответить с цитированием
Ответ



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Цветной экран смерти _Great_ Авторские статьи 11 14.09.2009 10:48
Чёрная полоса..... S|\/|eliyK()T Болталка 12 13.10.2006 01:35
Windows XP SP3 будет!.. после выхода Windows Vista -=ka$at1k=- Мировые новости 0 02.07.2006 07:47
Bsod экран смерти silveran Чужие Статьи 1 21.12.2005 22:34
ЗВОНИТ МОБИЛЬНИК? ГОТОВЬСЯ К СМЕРТИ! silveran Сотовый фрикинг 1 08.08.2005 13:28



Здесь присутствуют: 1 (пользователей: 0 , гостей: 1)
 


Быстрый переход




ANTICHAT.XYZ