📄 nticedump.asm
字号:
%include "ntice.inc"
%include "ntddk.inc"
BITS 32
PatchData istruc NTIcedumpHdr
at NTIcedumpHdr.ID, db NTICEDUMP_ID ; speaks for itself
at NTIcedumpHdr.Len, dw PATCH_HEADER_SIZE ; header size
at NTIcedumpHdr.PatchVer, dw 0100h ; nticedump patcher version
at NTIcedumpHdr.Ver, dd NTICEDUMP_BUILD ; nticedump version
at NTIcedumpHdr.SiVer, dd NTICE_VERSION ; target SoftICE version
at NTIcedumpHdr.VA, dd Init ; RVA of Call to Init
iend
; insert any extra data here
; i.e. Credits string
; but keep below 64k =)
db 'IceDump ',VERSION_TO_ASCII(NTICEDUMP_BUILD),' for NTICE ',VERSION_TO_ASCII(NTICE_VERSION),0
.End:
PATCH_HEADER_SIZE EQU (PatchData.End - PatchData)
%assign PATCH_ORIGIN_ADJUSTED (PAGEIN_PATCH_ORIGIN - PATCH_HEADER_SIZE)
ORG PATCH_ORIGIN_ADJUSTED
;-------------------------------------------------------------------------------
; Init will be called by NT. Takes 2 DWORDS as params. This call is
; responsible with the debug extension vector init, as well as "normal"
; NTICE initialization. It will replace original DriverEntry. The PE entry
; point will be set to point to this routine.
;-------------------------------------------------------------------------------
Init:
%if NTICE_VERSION = 0x322 || NTICE_VERSION = 0x323
call .delta322
.delta322:
pop eax
sub eax, .delta322
lea ecx, [eax+Init]
push ecx
pop dword [eax+SELF_REF]
%endif ; END 322 & 323 specific initialization patches
push dword [esp+8] ; push pRegistryPath
push dword [esp+8] ; push pDriverObject
call pNticeInit ; call NticeDeviceInit
test eax, eax ; EAX = STATUS_SUCCESS ?
jl near .return ; nope, branch error
pushad ; save'em all
call .delta
.delta:
pop ebp ; EBP: Current Address
sub ebp, .delta ;
.fixups:
mov ecx, MaxSrv ; initialize loop count
lea edi, [ebp+tInternalApiTable] ; EDI: pointer to internal API table
.next_service:
add dword [edi], ebp ; perform fixup
add edi, byte 4 ; advance to next slot
loop .next_service ; more API's ?
.get_ntoskrnl_ptrs:
lea edi, [ebp+CallTable] ; EBX: pointer to Call Table
lea esi, [ebp+tImportNameTable] ; ESI: pointer to API Names
mov ecx, MaxImportId ; intialize loop count
.next_api:
call pExpression2Integer ; return EAX: API virtual address
jb .exit ; Fail extension commands initialization on error
stosd ; store API pointer in Call table
inc esi ; step to next string
loop .next_api
.apply_patches:
mov ebx, cr0 ; EBX: CR0
push ebx ; save it for later use
btr ebx, 16 ; Clear Write Protect bit
mov cr0, ebx
mov byte [ebp+CRS_END], 0xC3 ; patch retn
mov byte [ebp+PAGEIN_CMDLINE], 0xBE ; patch mov esi, imm32
mov dword [ebp+PAGEIN_PARSER+1], Parser - PAGEIN_PARSER - 5
mov dword [ebp+PCI_VENDORS], -1
lea eax, [ebp+Init]
mov dword [ebp+dIGNOREFAULTS1], eax ; let ntoskrnl
lea eax, [ebp+End] ; handle faults
mov dword [ebp+dIGNOREFAULTS2], eax ; in this range
; hook pINT3_CleanupForPAGEIN
lea eax,[ebp+pINT3_CleanupForPAGEIN+0x18] ; call pMemcopy
lea ebx,[ebp+HookCleanupForPAGEIN-4]
sub ebx,eax
mov [eax],ebx
pop ebx
mov cr0, ebx ;revert CR0 to normal state
.hook_idt:
mov dl, 0x60 ; Interrupt Gate DPL = 3
lea edi, [ebp+Icall_handler] ; handler EIP = Icall_handler
mov eax, 0xFF ; target vector 0xFF
call pHookInt_IDT ; Hook IDT
.exit:
popad ; restore all registers
.return:
retn 8 ; return to OS (__stdcall always assumed for DriverEntry )
;-------------------------------------------------------------------------------
;
;-------------------------------------------------------------------------------
Parser:
pushad
call .delta
.delta:
pop ebp ;
sub ebp, .delta
call pSaveRegs ; save client State
call pSkipWord ; skip over PAGEIN
jb Parse_Help
lodsb
and al, 0x5F ; toupper
cmp al, 'D'
jz near Parse_Dump
cmp al, 'S'
jz Parse_Suspend
cmp al, 'R'
jz Parse_Resume
cmp al, 'B'
jz Parse_Bhrama
cmp al, 'L'
jz near Parse_Load
jmp short Parse_Help
.error:
push ebx
call pPrintErrorToCommandWindow
.exit:
call pRestoreRegs ; restore client state
popad
retn
Parse_Help:
lea ebx, [ebp+help_d]
push ebx
call pPrintErrorToCommandWindow
lea ebx, [ebp+help_s]
push ebx
call pPrintErrorToCommandWindow
lea ebx, [ebp+help_r]
push ebx
call pPrintErrorToCommandWindow
lea ebx, [ebp+help_b]
push ebx
call pPrintErrorToCommandWindow
lea ebx, [ebp+help_l]
push ebx
call pPrintErrorToCommandWindow
lea ebx, [ebp+help_v]
push ebx
call pPrintErrorToCommandWindow
jmp short Parser.exit
Parse_Suspend:
; mov dword [ebp+dClient_EAX], Srv_Suspend
lea ebx, [ebp+nim_err]
jmp Parser.error
Parse_Resume:
; mov dword [ebp+dClient_EAX], Srv_Resume
lea ebx , [ebp+nim_err]
jmp Parser.error
Parse_Bhrama:
lea ebx,[ebp+Error_V86]
test byte [ebp+dClient_EFLAGS+2],2 ; is client in V86 mode?
jnz near Parser.error
lea ebx,[ebp+Error_PM16]
lar eax,[ebp+dClient_CS] ; is client 32 bit?
bt eax,22
jnc near Parser.error
lea ebx,[ebp+Error_PMR0]
test byte [ebp+dClient_CS],3 ; is client in ring-0?
jz near Parser.error
lea ebx,[ebp+Error_NoWnd]
call pSkipWhiteSpace
jz near Parser.error
call GetAPIs
lea ebx,[ebp+Error_API]
jc near Parser.error
mov ebx,cr0
push ebx
btr ebx,16
mov cr0,ebx
mov eax,[ebp+dClient_EIP] ; use current EIP
mov [ebp+Bhrama_Struc+BhramaComStruc.EIP],eax
mov edi,esi
mov ecx,-1
xor eax,eax
repnz scasb
sub edi,esi
mov ecx,edi
lea edi,[ebp+Procdump.WindowName]
rep movsb
stosb
lea esi,[ebp+Procdump]
mov ecx,Bhrama_Struc.end-Procdump
call CopyToUserLand
or eax,eax
jnz .1
pop ebx
mov cr0,ebx
lea ebx,[ebp+Error_NoUser]
jmp Parser.error
.1:
mov dword [ebp+dClient_EBP],eax
mov dword [ebp+dClient_EIP],eax ; set client (E)IP
mov dword [ebp+dClient_ESP],eax ; set client (E)SP
sub dword [ebp+dClient_ESP],byte 4
mov dword [ebp+oPAGEIN_INT3],eax ; set address of final INT3
add dword [ebp+oPAGEIN_INT3],byte Procdump.return-Procdump
mov ebx,[ebp+API.oGetCurrentProcessID]
mov [eax+Procdump.oGetCurrentProcessID-Procdump-4],ebx
sub [eax+Procdump.oGetCurrentProcessID-Procdump-4],eax
sub dword [eax+Procdump.oGetCurrentProcessID-Procdump-4],byte Procdump.oGetCurrentProcessID-Procdump
mov ebx,[ebp+API.oFindWindowA]
mov [eax+Procdump.oFindWindowA-Procdump-4],ebx
sub [eax+Procdump.oFindWindowA-Procdump-4],eax
sub dword [eax+Procdump.oFindWindowA-Procdump-4],byte Procdump.oFindWindowA-Procdump
mov ebx,[ebp+API.oSendMessageA]
mov [eax+Procdump.oSendMessageA-Procdump-4],ebx
sub [eax+Procdump.oSendMessageA-Procdump-4],eax
sub dword [eax+Procdump.oSendMessageA-Procdump-4],byte Procdump.oSendMessageA-Procdump
mov [eax+Procdump.DataPointer-Procdump],eax
add dword [eax+Procdump.DataPointer-Procdump],byte Bhrama_Struc-Procdump
lea eax,[eax+Procdump.WindowName-Procdump]
mov [ebp+dClient_ESI],eax ; bhrama server's window name
pop ebx
mov cr0,ebx
xor eax,eax
inc eax
mov [ebp+fPAGEIN_InProgress],eax ; set internal Winice flag to 1
mov [ebp+fExecuteMoreCommands],ah ; set internal Winice flag to 0
popad
retn
; ------------------------------------------------------------------------------
; this is where we call Procdump based on Stone's example
;
; ebp: linear address of Procdump on client stack
; esi: Bhrama window name
; ------------------------------------------------------------------------------
align 4
Procdump:
call .oGetCurrentProcessID
.oGetCurrentProcessID:
mov [ebp+Bhrama_Struc+BhramaComStruc.PID-Procdump],eax
; mov [Bhrama_Struc+BhramaComStruc.EIP],0x0
; mov [Bhrama_Struc+BhramaComStruc.OptL1],0x00000000
; mov [Bhrama_Struc+BhramaComStruc.OptL2],0x01000001
; mov [Bhrama_Struc+BhramaComStruc.OptL3],0x01010001
; mov [Bhrama_Struc+BhramaComStruc.OptL4],0x00010000
; mov [Bhrama_Struc+BhramaComStruc.OptL5],0x00000000
; LookUp for ProcDump Server.
push esi
push byte 0
call .oFindWindowA
.oFindWindowA:
test eax,eax
jz .return
; Send Dump Message to ProcDump Server.
.sendmsg:
add ebp,byte .Service-Procdump
push ebp
push byte 0
push byte WM_COPYDATA
push eax ; ProcDump's hwnd
call .oSendMessageA
.oSendMessageA:
.return:
int3
align 4
.WindowName: times 64 db 0
align 4
.Service: dd 1
.DataLength: dd BhramaComStruc_size
.DataPointer: dd Bhrama_Struc
Bhrama_Struc:
istruc BhramaComStruc
at BhramaComStruc.version, dd 3
at BhramaComStruc.PID, dd 0
at BhramaComStruc.EIP, dd 0
at BhramaComStruc.OptL1, dd 0x00000000
at BhramaComStruc.OptL2, dd 0x01000101
at BhramaComStruc.OptL3, dd 0x01010001
at BhramaComStruc.OptL4, dd 0x00030000
at BhramaComStruc.OptL5, dd 0x00000000
iend
.end:
Parse_Dump:
call pSkipWhiteSpace
jz .set_pth_mode
lea ebx, [ebp+evl_err]
call pExpression2Integer ; Parse address
jb near Parser.error
mov [ebp+dClient_EDI], eax ; store address in Client_EDI
mov dword [ebp+dClient_EAX], Srv_Dump ; srv code goes in EAX
call pSkipWhiteSpace
jz .emulate ; emulate old PAGEIN behaviour
call pExpression2Integer ; Parse Length
jb near Parser.error
call pSkipWhiteSpace ; advance to filename
jnz .cont ; ESI: pointer to file name
jmp Parser.exit
.set_pth_mode:
xor byte [ebp+PathMode], 1
lea ebx, [ebp+msg_p0]
jnz .on
lea ebx, [ebp+msg_p1]
.on:
jmp Parser.error
.emulate:
xor eax, eax ; Zero length
xor esi, esi ; No file name
jmp .exprt_mode
.cont:
cmp byte [ebp+PathMode], 1
jz .exprt_mode
sub esi, 4
mov dword [esi], '\??\'
.exprt_mode:
mov [ebp+dClient_ESI], esi ; pointer to filename
mov [ebp+dClient_ECX], eax ; store length
call CanResume ; are we allowed to play the game ?
test byte [ebp+dClient_CS], 3 ; ring-0 Client ?
jz near .ring0
mov ecx, EntryPoint.end - EntryPoint; number of bytes to copy
push ecx
lea eax, [ebp+EntryPoint] ; EAX: source
push eax
test byte [ebp+dClient_EFLAGS+2], 2 ; V86 mode client?
jz .PM
mov eax,cr4
test eax,1 ; CR4.VME
jz .set_iopl
str ax
call pMapSelectorToLinAddr
jnc .set_redirection
lea ebx, [ebp+tss_err]
push ebx
call pPrintErrorToCommandWindow
jmp Parser.exit
.set_redirection:
movzx edi, word [eax+0x66] ; start of i/o perm map
lea edi, [edi+eax-0x20] ; start of int redir map
mov eax, 0xFF ; our interrupt
bts [edi], eax ; no redirection to V86 handler
.set_iopl:
mov eax, [ebp+dClient_EFLAGS] ; save IOPL
mov [ebp+dClient_EBX], eax
or byte [ebp+dClient_EFLAGS+1], 0x30 ; IOPL=3
movzx eax, word [ebp+dClient_SS]
mov [ebp+dClient_CS], eax ; set new client CS
shl eax, 4
movzx edi, word [ebp+dClient_ESP]
sub edi, ecx ; bug, should handle underflow
add eax, edi
push eax
jmp short .copy
.PM:
movzx eax, word [ebp+dClient_SS]
call pMapSelectorToLinAddr
jnc .got_linaddr
add esp, byte 8
lea ebx, [ebp+sel_err]
jmp Parser.error
.got_linaddr:
mov edi, eax
add edi, [ebp+dClient_ESP] ; EDI: linear Client ESP
sub edi, ecx ; EDI destination ( on client Stack )
push edi
mov word [ebp+dClient_CS], 0x1B ; set new client CS
mov word [ebp+dClient_SS], 0x23 ; set new client SS
.copy:
call pMemcopy ; memcpy with protection from faults
lea ebx, [ebp+stk_err]
test eax, eax
jz near Parser.error
mov ebx, edi ; EBX: new EIP
lea eax, [edi+EntryPoint.i3-EntryPoint]; EAX: INT3 location
mov [ebp+dClient_ESP], edi ; adjust client stack
jmp short .setup
.ring0:
lea eax, [ebp+EntryPoint.i3] ; INT3 location for ring-0 code
lea ebx, [ebp+EntryPoint] ; Get EIP
.setup:
mov [ebp+oPAGEIN_INT3], eax ; register INT3 location
mov [ebp+dClient_EIP], ebx ; set new client EIP
xor eax, eax
inc eax
mov [ebp+fPAGEIN_InProgress], eax ; set PAGEIN internal var
mov [ebp+fExecuteMoreCommands], ah ; leave ntice
popad
retn
PathMode: db 1
Parse_Load:
call pSkipWhiteSpace
jz .set_pth_mode
lea ebx, [ebp+evl_err]
call pExpression2Integer ; Parse address
jb near Parser.error
mov [ebp+dClient_EDI], eax ; store address in Client_EDI
mov dword [ebp+dClient_EAX], Srv_Load ; srv code goes in EAX
call pSkipWhiteSpace
jz near Parser.error
call pExpression2Integer ; Parse Length
jb near Parser.error
call pSkipWhiteSpace ; advance to filename
jnz .cont ; ESI: pointer to file name
jmp Parser.exit
.set_pth_mode:
xor byte [ebp+PathMode], 1
lea ebx, [ebp+msg_p0]
jnz .on
lea ebx, [ebp+msg_p1]
.on:
jmp Parser.error
.cont:
cmp byte [ebp+PathMode], 1
jz .exprt_mode
sub esi, 4
mov dword [esi], '\??\'
.exprt_mode:
mov [ebp+dClient_ESI], esi ; pointer to filename
mov [ebp+dClient_ECX], eax ; store length
call CanResume ; are we allowed to play the game ?
test byte [ebp+dClient_CS], 3 ; ring-0 Client ?
jz near .ring0
mov ecx, EntryPoint.end - EntryPoint; number of bytes to copy
push ecx
lea eax, [ebp+EntryPoint] ; EAX: source
push eax
test byte [ebp+dClient_EFLAGS+2], 2 ; V86 mode client?
jz .PM
mov eax,cr4
test eax,1 ; CR4.VME
jz .set_iopl
str ax
call pMapSelectorToLinAddr
jnc .set_redirection
lea ebx, [ebp+tss_err]
push ebx
call pPrintErrorToCommandWindow
jmp Parser.exit
.set_redirection:
movzx edi, word [eax+0x66] ; start of i/o perm map
lea edi, [edi+eax-0x20] ; start of int redir map
mov eax, 0xFF ; our interrupt
bts [edi], eax ; no redirection to V86 handler
.set_iopl:
mov eax, [ebp+dClient_EFLAGS] ; save IOPL
mov [ebp+dClient_EBX], eax
or byte [ebp+dClient_EFLAGS+1], 0x30 ; IOPL=3
movzx eax, word [ebp+dClient_SS]
mov [ebp+dClient_CS], eax ; set new client CS
shl eax, 4
movzx edi, word [ebp+dClient_ESP]
sub edi, ecx ; bug, should handle underflow
add eax, edi
push eax
jmp short .copy
.PM:
movzx eax, word [ebp+dClient_SS]
call pMapSelectorToLinAddr
jnc .got_linaddr
add esp, byte 8
lea ebx, [ebp+sel_err]
jmp Parser.error
.got_linaddr:
mov edi, eax
add edi, [ebp+dClient_ESP] ; EDI: linear Client ESP
sub edi, ecx ; EDI destination ( on client Stack )
push edi
mov word [ebp+dClient_CS], 0x1B ; set new client CS
mov word [ebp+dClient_SS], 0x23 ; set new client SS
.copy:
call pMemcopy ; memcpy with protection from faults
lea ebx, [ebp+stk_err]
test eax, eax
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -