Это ведь GUI. Оно не юзабельно, глючит постоянно и пр. Я не реверсил есчо тот ядерный сервис, но думаю это всеголишь простой запрос на порт, судя по сурцам(там иначе как в XP).
Код (Text): MAXIMUM_HARDERROR_PARAMETERS equ 7 HARDERROR_MSG struct Header PORT_MESSAGE <> Status NTSTATUS ? ErrorTime LARGE_INTEGER <> ValidResponseOptions ULONG ? Response ULONG ? NumberOfParameters ULONG ? UnicodeStringParameterMask ULONG ? Parameters ULONG MAXIMUM_HARDERROR_PARAMETERS DUP (?) HARDERROR_MSG ends PHARDERROR_MSG typedef ptr HARDERROR_MSG HARDERROR_MSG_OVERHEAD equ (sizeof(HARDERROR_MSG) - sizeof(PORT_MESSAGE)) HARDERROR_API_MSG_LENGTH equ (sizeof(HARDERROR_MSG)*10000h) or (HARDERROR_MSG_OVERHEAD) Local Message:HARDERROR_MSG invoke KeQuerySystemTime, addr Message.ErrorTime mov dword ptr [Message.Header.DataSize],HARDERROR_API_MSG_LENGTH mov Message.Header.MessageType,LPC_ERROR_EVENT mov Message.ValidResponseOptions,0 mov Message.NumberOfParameters,0 mov Message.UnicodeStringParameterMask,0 mov Message.Response,OptionOk mov Message.Status,STATUS_SUCCESS invoke PsGetCurrentProcess mov edx,EPROCESS.ExceptionPort[eax] invoke LpcRequestWaitReplyPort, edx, addr Message, addr Message Это запрос на порт, потом csrss мессагу забоксит, сюда и сводится ExRaiseHardError().
Добавлю что порт устанавливает csrss из CsrCreateProcess() при нотификации, которая при создании нового процесса выполняется из юзермода. Если процесс создан средствами RtlCreateUserProcess(), то этот порт не установлен.
Грит, подправь там пост. Это запрос на порт, потом csrss мессагу забоксит, сюда и сводится ExRaiseHardError().
Не знаю мож кому понадобится взял за основу код Great ну и дописал маленько чтобы можно было пользоваться как MessageBox-ом Код (Text): ULONG KernelMessageBox(IN PWSTR pwText, IN PWSTR pwCaption, IN int uType ) { NTSTATUS Status; UNICODE_STRING Mes,Title; ULONG Response = 0; RtlInitUnicodeString (&Mes, pwText); RtlInitUnicodeString (&Title,pwCaption); ULONG_PTR Param[3]; Param[0]=(ULONG_PTR)&Mes; Param[1]=(ULONG_PTR)&Title; Param[2]=uType; Status = ExRaiseHardError ( STATUS_SERVICE_NOTIFICATION , 3, 3, &Param, NULL, &Response ); return Response; } Ну и h файлик сдернутый с Winuser.h Код (Text): #define MB_OK 0x00000000L // answer was 6 #define MB_OKCANCEL 0x00000001L // answer ok-6 Отмена -3 #define MB_ABORTRETRYIGNORE 0x00000002L // answer Прервать-2 Повторить-7 Пропустить -4 #define MB_YESNOCANCEL 0x00000003L // answer да-8 Нет-5 Отмена -3 #define MB_YESNO 0x00000004L // answer да-8 Нет-5 #define MB_RETRYCANCEL 0x00000005L // answer Повторить-7 Отмена-3 #define MB_CANCELTRYCONTINUE 0x00000006L // answer Отмена-3 Попторить поп -9 Продолжить-10 #define MB_ICONHAND 0x00000010L #define MB_ICONQUESTION 0x00000020L #define MB_ICONEXCLAMATION 0x00000030L #define MB_ICONASTERISK 0x00000040L #define MB_USERICON 0x00000080L #define MB_ICONWARNING MB_ICONEXCLAMATION #define MB_ICONERROR MB_ICONHAND #define MB_ICONINFORMATION MB_ICONASTERISK #define MB_ICONSTOP MB_ICONHAND #define MB_DEFBUTTON1 0x00000000L #define MB_DEFBUTTON2 0x00000100L #define MB_DEFBUTTON3 0x00000200L #define MB_DEFBUTTON4 0x00000300L #define MB_APPLMODAL 0x00000000L #define MB_SYSTEMMODAL 0x00001000L #define MB_TASKMODAL 0x00002000L #define MB_HELP 0x00004000L #define MB_NOFOCUS 0x00008000L #define MB_SETFOREGROUND 0x00010000L #define MB_DEFAULT_DESKTOP_ONLY 0x00020000L #define MB_TOPMOST 0x00040000L #define MB_RIGHT 0x00080000L #define MB_RTLREADING 0x00100000L вызов обыкновенно как MessageBox Код (Text): ret = KernelMessageBox(L"Привет из Ring-0",L"hellow",MB_OKCANCEL|MB_ICONSTOP); if (ret==6) { DbgPrint("Ок"); }
Если, кто незнал где взять GetTaskmanWindow() ниже код работает Код (Text): user32dll db "user32.dll",0 hUser32 dd ? GetTaskmanWindow dd ? szGetTaskmanWindow db "GetTaskmanWindow",0 MsgName CHAR "HardError",0 .code Entry proc Local Result:ULONG invoke RegisterWindowMessage, addr MsgName mov MessageId,eax ;invoke GetTaskmanWindow ;'MSTaskSwWClass' invoke GetModuleHandle, addr user32dll mov hUser32, eax test eax, eax jz _end invoke GetProcAddress, hUser32, addr szGetTaskmanWindow mov GetTaskmanWindow, eax call GetTaskmanWindow mov edx,eax invoke SendMessageTimeout, edx, WM_COPYDATA, 0, addr MessageId, SMTO_NORMAL or SMTO_ABORTIFHUNG, 3000, addr Result _end: ret
Как раз таки создать юзермодный поток проблем не составляет. Зарегистрировать у csrss, в принципе, тоже. Надо лишь вызвать csrsrv!CsrCreateRemoteThread()
MessageBox создаётся нормально, а вот при вызове некоторых других функций шелл код вылетает, пока не пойму почему Код (Text): void sc() { STARTUPINFO si; PROCESS_INFORMATION pi; ULONG hUser32; ULONG hKernel32; funcLoadLibraryA fLoadLibraryA; funcMessageBoxA fMessageBoxA; funcExitThread fExitThread; funcwsprintfA fwsprintfA; funcCreateProcessA fCreateProcessA; funcGetLastError fGetLastError; funcExitProcess fExitProcess; char user32name[] = {'U','s','e','r','3','2','.','d','l','l','\0'}; char wsprintfAname[] = {'w','s','p','r','i','n','t','f','A','\0'}; char format[] = {'%','p',' ','%','p',' ','%','p','\0'}; char str[0xff]; PSC_DATA sc_data; ULONG len; __asm mov sc_data, eax hKernel32 = GetKernel32(); fExitProcess = (funcExitProcess) GetProcAddrEx(hKernel32, hExitProcess); fExitThread = (funcExitThread) GetProcAddrEx(hKernel32, hExitThread); fLoadLibraryA = (funcLoadLibraryA) GetProcAddrEx(hKernel32, hLoadLibraryA); fCreateProcessA = (funcCreateProcessA)GetProcAddrEx(hKernel32, hCreateProcessA); fGetLastError = (funcGetLastError) GetProcAddrEx(hKernel32, hGetLastError); hUser32 = fLoadLibraryA(user32name); fwsprintfA = (funcwsprintfA) GetProcAddrEx(hUser32, CalcHash(wsprintfAname) ); fMessageBoxA = (funcMessageBoxA) GetProcAddrEx(hUser32, hMessageBoxA); fwsprintfA(str,format, fCreateProcessA, fExitThread, fExitThread);//ok fMessageBoxA(0, str, str, 1);//ok, fCreateProcessA fExitThread fExitThread верные fMessageBoxA(0, wsprintfAname, wsprintfAname, 1);//ok __stosb(&si, 0, sizeof(STARTUPINFO)); //тут летит fCreateProcessA(NULL, sc_data->cmdline, 0, 0, FALSE, 0, 0, 0, &si, &pi); //fGetLastError(); //так тоже летит //fExitThread(); //так тоже летит fExitThread(0);//ok }
Great Там есть сервис который поток и создаёт, на XP(в сёмке не знаю), но нужен ведь только контекст, среда окружения не нужна сначала, тоесть достаточно нативного треда, а дальше можно заюзать CreateThread(), функа сама зарегает поток у csrss(хотя всё можно вручную заюзать).
Clerk Да, о чем и речь. Создать нативный поток в csrss и вызвать нужный экспорт csrsrv.dll. Процесс/поток зарегистрируется