windows 7 x86 中内核模块nt(ntkrpamp 模块)源码学习

windows 7 x86 中内核模块 nt(即 ntkrpamp 模块)的实现:

偏移      机器码         指令
nt!memset:
83c8ce40 8b54240c        mov     edx,dword ptr [esp+0Ch]
83c8ce44 8b4c2404        mov     ecx,dword ptr [esp+4]
83c8ce48 85d2            test    edx,edx
83c8ce4a 744f            je      nt!memset+0x5b (83c8ce9b)
83c8ce4c 33c0            xor     eax,eax
83c8ce4e 8a442408        mov     al,byte ptr [esp+8]
83c8ce52 57              push    edi
83c8ce53 8bf9            mov     edi,ecx
83c8ce55 83fa04          cmp     edx,4
83c8ce58 7231            jb      nt!memset+0x4b (83c8ce8b)
83c8ce5a f7d9            neg     ecx
83c8ce5c 83e103          and     ecx,3
83c8ce5f 740c            je      nt!memset+0x2d (83c8ce6d)
83c8ce61 2bd1            sub     edx,ecx
83c8ce63 8807            mov     byte ptr [edi],al
83c8ce65 83c701          add     edi,1
83c8ce68 83e901          sub     ecx,1
83c8ce6b 75f6            jne     nt!memset+0x23 (83c8ce63)
83c8ce6d 8bc8            mov     ecx,eax
83c8ce6f c1e008          shl     eax,8
83c8ce72 03c1            add     eax,ecx
83c8ce74 8bc8            mov     ecx,eax
83c8ce76 c1e010          shl     eax,10h
83c8ce79 03c1            add     eax,ecx
83c8ce7b 8bca            mov     ecx,edx
83c8ce7d 83e203          and     edx,3
83c8ce80 c1e902          shr     ecx,2
83c8ce83 7406            je      nt!memset+0x4b (83c8ce8b)
83c8ce85 f3ab            rep stos dword ptr es:[edi]
83c8ce87 85d2            test    edx,edx
83c8ce89 740a            je      nt!memset+0x55 (83c8ce95)
83c8ce8b 8807            mov     byte ptr [edi],al
83c8ce8d 83c701          add     edi,1
83c8ce90 83ea01          sub     edx,1
83c8ce93 75f6            jne     nt!memset+0x4b (83c8ce8b)
83c8ce95 8b442408        mov     eax,dword ptr [esp+8]
83c8ce99 5f              pop     edi
83c8ce9a c3              ret
83c8ce9b 8b442404        mov     eax,dword ptr [esp+4]
83c8ce9f c3              ret
nt!strcpy:
83c8cea0 57              push    edi
83c8cea1 8b7c2408        mov     edi,dword ptr [esp+8]
83c8cea5 eb6e            jmp     nt!strcat+0x65 (83c8cf15)
83c8cea7 8da42400000000  lea     esp,[esp]
83c8ceae 8bff            mov     edi,edi
nt!strcat:
83c8ceb0 8b4c2404        mov     ecx,dword ptr [esp+4]
83c8ceb4 57              push    edi
83c8ceb5 f7c103000000    test    ecx,3
83c8cebb 7413            je      nt!strcat+0x20 (83c8ced0)
83c8cebd 8a01            mov     al,byte ptr [ecx]
83c8cebf 83c101          add     ecx,1
83c8cec2 84c0            test    al,al
83c8cec4 743d            je      nt!strcat+0x53 (83c8cf03)
83c8cec6 f7c103000000    test    ecx,3
83c8cecc 75ef            jne     nt!strcat+0xd (83c8cebd)
83c8cece 8bff            mov     edi,edi
83c8ced0 8b01            mov     eax,dword ptr [ecx]
83c8ced2 bafffefe7e      mov     edx,7EFEFEFFh
83c8ced7 03d0            add     edx,eax
83c8ced9 83f0ff          xor     eax,0FFFFFFFFh
83c8cedc 33c2            xor     eax,edx
83c8cede 83c104          add     ecx,4
83c8cee1 a900010181      test    eax,81010100h
83c8cee6 74e8            je      nt!strcat+0x20 (83c8ced0)
83c8cee8 8b41fc          mov     eax,dword ptr [ecx-4]
83c8ceeb 84c0            test    al,al
83c8ceed 7423            je      nt!strcat+0x62 (83c8cf12)
83c8ceef 84e4            test    ah,ah
83c8cef1 741a            je      nt!strcat+0x5d (83c8cf0d)
83c8cef3 a90000ff00      test    eax,0FF0000h
83c8cef8 740e            je      nt!strcat+0x58 (83c8cf08)
83c8cefa a9000000ff      test    eax,0FF000000h
83c8ceff 7402            je      nt!strcat+0x53 (83c8cf03)
83c8cf01 ebcd            jmp     nt!strcat+0x20 (83c8ced0)
83c8cf03 8d79ff          lea     edi,[ecx-1]
83c8cf06 eb0d            jmp     nt!strcat+0x65 (83c8cf15)
83c8cf08 8d79fe          lea     edi,[ecx-2]
83c8cf0b eb08            jmp     nt!strcat+0x65 (83c8cf15)
83c8cf0d 8d79fd          lea     edi,[ecx-3]
83c8cf10 eb03            jmp     nt!strcat+0x65 (83c8cf15)
83c8cf12 8d79fc          lea     edi,[ecx-4]
83c8cf15 8b4c240c        mov     ecx,dword ptr [esp+0Ch]
83c8cf19 f7c103000000    test    ecx,3
83c8cf1f 741d            je      nt!strcat+0x8e (83c8cf3e)
83c8cf21 8a11            mov     dl,byte ptr [ecx]
83c8cf23 83c101          add     ecx,1
83c8cf26 84d2            test    dl,dl
83c8cf28 7466            je      nt!strcat+0xe0 (83c8cf90)
83c8cf2a 8817            mov     byte ptr [edi],dl
83c8cf2c 83c701          add     edi,1
83c8cf2f f7c103000000    test    ecx,3
83c8cf35 75ea            jne     nt!strcat+0x71 (83c8cf21)
83c8cf37 eb05            jmp     nt!strcat+0x8e (83c8cf3e)
83c8cf39 8917            mov     dword ptr [edi],edx
83c8cf3b 83c704          add     edi,4
83c8cf3e bafffefe7e      mov     edx,7EFEFEFFh
83c8cf43 8b01            mov     eax,dword ptr [ecx]
83c8cf45 03d0            add     edx,eax
83c8cf47 83f0ff          xor     eax,0FFFFFFFFh
83c8cf4a 33c2            xor     eax,edx
83c8cf4c 8b11            mov     edx,dword ptr [ecx]
83c8cf4e 83c104          add     ecx,4
83c8cf51 a900010181      test    eax,81010100h
83c8cf56 74e1            je      nt!strcat+0x89 (83c8cf39)
83c8cf58 84d2            test    dl,dl
83c8cf5a 7434            je      nt!strcat+0xe0 (83c8cf90)
83c8cf5c 84f6            test    dh,dh
83c8cf5e 7427            je      nt!strcat+0xd7 (83c8cf87)
83c8cf60 f7c20000ff00    test    edx,0FF0000h
83c8cf66 7412            je      nt!strcat+0xca (83c8cf7a)
83c8cf68 f7c2000000ff    test    edx,0FF000000h
83c8cf6e 7402            je      nt!strcat+0xc2 (83c8cf72)
83c8cf70 ebc7            jmp     nt!strcat+0x89 (83c8cf39)
83c8cf72 8917            mov     dword ptr [edi],edx
83c8cf74 8b442408        mov     eax,dword ptr [esp+8]
83c8cf78 5f              pop     edi
83c8cf79 c3              ret
83c8cf7a 668917          mov     word ptr [edi],dx
83c8cf7d 8b442408        mov     eax,dword ptr [esp+8]
83c8cf81 c6470200        mov     byte ptr [edi+2],0
83c8cf85 5f              pop     edi
83c8cf86 c3              ret
83c8cf87 668917          mov     word ptr [edi],dx
83c8cf8a 8b442408        mov     eax,dword ptr [esp+8]
83c8cf8e 5f              pop     edi
83c8cf8f c3              ret
83c8cf90 8817            mov     byte ptr [edi],dl
83c8cf92 8b442408        mov     eax,dword ptr [esp+8]
83c8cf96 5f              pop     edi
83c8cf97 c3              ret

fasm实现示例:

;-----------------------------------------------------------------------
;*--==--* fasm memset.asm memset.exe By G-Spider
;-----------------------------------------------------------------------
format PE console
entry start
include 'win32a.inc'

COUNT=64
;-----------------------------------------------------------------------
section '.text' code readable executable
  start:
  ccall nt_memset,buffer,0x12,COUNT
  xor ecx,ecx
  @@:
    push ecx
    movzx eax,byte [buffer+ecx]
    
    cinvoke printf,fmt,eax
    pop ecx
    inc ecx
    cmp ecx,COUNT
    jb  @B
    
    cinvoke system,szPause
    ret
 
;----------------------------------------------------------------------- 
;//void *nt_memset(
;//   void *dest,
;//   int c,
;//   size_t count 
;//);
;//Return Value:The value of dest.
;-----------------------------------------------------------------------
align 16
nt_memset:
;[esp+4]     ->dest
;[esp+8]     ->c
;[esp+0Ch]   ->count
             mov     edx,dword [esp+0Ch]
             mov     ecx,dword [esp+4]
             test    edx,edx              
             je      .A03                 ;如果count=0 ,直接返回dest
             xor     eax,eax
             mov     al ,byte [esp+8]     ;c只有低8位有效,高位忽略
             push    edi                  ;保存将要改变的寄存器edi,esp=esp-4
             mov     edi,ecx              ;edi=dest
             cmp     edx,4
             jb      @F                   ;count小于4字节时,跳转
             neg     ecx
             and     ecx,3
             je      .A01                 ;地址对齐,能被4整除时,跳转
             sub     edx,ecx              ;dest未4字节对齐,则处理头部,count=cout-ecx
.A00:                                     ;.A00处理处理头部多余的ecx字节(<4) 
             mov     byte [edi],al
             add     edi,1
             sub     ecx,1
             jne     .A00
             
                                          ;.A00执行完后,edi已4字节对齐
.A01:        ;--------------              ;若c=0x11(高位忽略),则          
             mov     ecx,eax              ;ecx=0000 0012
             shl     eax,8                ;eax=0000 1200
             add     eax,ecx              ;eax=0000 1212
             mov     ecx,eax              ;ecx=eax
             shl     eax,10h              ;eax=1212 0000
             add     eax,ecx              ;eax=1212 1212
             ;--------------
             mov     ecx,edx              
             and     edx,3                ;edx为余下的字节(<4)
             shr     ecx,2                ;ecx=ecx/4 以4字节为单位计数 
             je      @F                   ;此时若ecx=0,则说明:
                                          ;当dest未对齐时,4<=cout<7,跳转
                                          ;当dest对齐时,0<cout<4,跳转
         
             rep stos dword [edi]         ;以4字节为单位处理edx字节(能被4整除) 
             test    edx,edx              ;处理余下的字节
             je      .A02                 
          @@:   
             mov     byte [edi],al
             add     edi,1
             sub     edx,1
             jne     @B
.A02:     
             mov     eax,dword [esp+8]    ;eax=dest
             pop     edi                  ;还原寄存器edi
             ret
.A03:     
             mov     eax,dword [esp+4]
             ret
;-----------------------------------------------------------------------            
section '.data' data readable writeable
  fmt        db '%c',0
  szPause    db 'pause',0

section '.bss' readable writeable
  buffer     rb 1024
             
section '.idata' import data readable writeable
  library msvcrt,'msvcrt.dll'
      
  import msvcrt,\
     printf,'printf',\
     system,'system'          
             

内嵌汇编c实现:

//------------------------------------------------------------
// compile:   cl  memset.c  by G-Spider vc6.0
//------------------------------------------------------------
#include <stdio.h>
void * nt_memset(void *dest,int c,size_t count );

 __declspec(naked) void * nt_memset(void *dest,int c,size_t count )
{
    // Naked functions
    __asm {
             mov     edx,dword ptr [esp+0x0C]
             mov     ecx,dword ptr [esp+4]
             test    edx,edx              
             je      A03                 
             xor     eax,eax
             mov     al ,byte ptr [esp+8]
             push    edi
             mov     edi,ecx
             cmp     edx,4
             jb      _LOOP
             neg     ecx
             and     ecx,3
             je      A01
             sub     edx,ecx
A00:
             mov     byte ptr [edi],al
             add     edi,1
             sub     ecx,1
             jne     A00
A01:        ;--------------             
             mov     ecx,eax              
             shl     eax,8
             add     eax,ecx
             mov     ecx,eax
             shl     eax,0x10
             add     eax,ecx
             ;--------------
             mov     ecx,edx              
             and     edx,3
             shr     ecx,2
             je      _LOOP
             rep stos dword ptr [edi]
             test    edx,edx
             je      A02                
         _LOOP:   
             mov     byte ptr [edi],al
             add     edi,1
             sub     edx,1
             jne     _LOOP
A02:     
             mov     eax,dword ptr [esp+8]
             pop     edi
             ret    
A03:
             mov     eax,dword ptr [esp+4]
             ret
    }
}
void main()
{
    char buffer[1024],*p;
    int i;
    p=nt_memset(buffer,0x12,64);
    for(i=0;i<64;i++)
      printf("%c",p[i]);
     
    system("pause");
}

 

;==========================================================
;部分汇编片段分析(以下片段在多处可见,strcpy,strcat,strlen..)

83c8ced0 8b01            mov     eax,dword ptr [ecx]
83c8ced2 bafffefe7e      mov     edx,7EFEFEFFh
83c8ced7 03d0            add     edx,eax
83c8ced9 83f0ff          xor     eax,0FFFFFFFFh
83c8cedc 33c2            xor     eax,edx
83c8cede 83c104          add     ecx,4
83c8cee1 a900010181      test    eax,81010100h
83c8cee6 74e8            je      nt!strcat+0x20 (83c8ced0)

83c8cee8 8b41fc          mov     eax,dword ptr [ecx-4]
83c8ceeb 84c0            test    al,al
83c8ceed 7423            je      nt!strcat+0x62 (83c8cf12)
83c8ceef 84e4            test    ah,ah
83c8cef1 741a            je      nt!strcat+0x5d (83c8cf0d)
83c8cef3 a90000ff00      test    eax,0FF0000h
83c8cef8 740e            je      nt!strcat+0x58 (83c8cf08)
83c8cefa a9000000ff      test    eax,0FF000000h
83c8ceff 7402            je      nt!strcat+0x53 (83c8cf03)
83c8cf01 ebcd            jmp     nt!strcat+0x20 (83c8ced0)

;----------------------------------------------------------
x0=[ecx]
x1=x0+7EFEFEFFh
x2=!x0
x0=x1 xor x2 =(x0+7EFEFEFFh) xor (!x0)
;----------------------------------------------------------
;0??? ???0 ???? ???0 ???? ???0 ???? ???? 

若byte1为0,设4个0对应的有效位为a1,a2,a3,a4,则有
  a1=(a1+0+7EFEFEFFh) xor (!a1)= a1 xor !a1=1
若byte1不为0,记为x,则
  a1=(a1+x+7EFEFEFFh) xor (!a1)=!a1 xor !a1=0

这就是上面0??? ???0 ???? ???0 ???? ???0 ???? ????第二个byte
的第一个bit是0的来历 ,同理,第二,三,四个byte中的的第一个bit
的0也是在前面所有的byte都不为0的时候才会出现,否则就会出现
至少一个1。

然而你会发现多了下面一个无条件跳转:
  jmp     nt!strcat+0x20 (83c8ced0)

这在什么情况下发生呢?
  taken if bits 24-30 are clear and  bit 31 is set 也即当位31为1,
位24-30位为0的情况下是无法判断的。
因为:
  (0x00******+7EFEFEFFh) xor !0=1
  (0x80******+7EFEFEFFh) xor !1=1
均视为存在0字节的情况。

即只有当[ecx]的低3字节不为0,且最高字节为80h时,形如:0x80123456
将执行jmp nt!strcat+0x20 (83c8ced0)语句。


 

你可能感兴趣的:(windows 7 x86 中内核模块nt(ntkrpamp 模块)源码学习)