123   2  /  3  页   跳转

编了一个保护杀毒软件的程序

对乐,修改导入表还有个问题,如下面的代码直接在内存中搜寻 GetProcAddress() API函数地址。
moveax, [esp]
andeax, 0FFFF0000h
@@chk:
cmpdword ptr [eax], 00905A4Dh; 比较一下…… 5A4D就是文件头'MZ'
je@@fnd; 找到了文件头基址了!
subeax, 1000h; faint,找不到,减少1000h作为跨度
jmp@@chk; Go on!
@@fnd:
push ebp
push ebx
push esi
push edi
movebp, eax  ;eax中为文件头基址
addeax, [eax][IMAGE_DOS_HEADER.e_lfanew] ;现在eax=[eax+3Ch],也就是PE文件头处
movedi, [eax][IMAGE_NT_HEADERS.OptionalHeader.DataDirectory]
addedi, ebp
movesi, [edi][IMAGE_EXPORT_DIRECTORY.AddressOfNames]
addesi, ebp

;在 kernel32.dll 里面查找 GetProcAddress 这个 API 的线形地址:
xoredx, edx
@@name:
moveax, [esi]
addeax, ebp
@@chgp:; GetProcAddress()
cmpdword ptr [eax+00h], "PteG"; GetP
jne@@next
cmpdword ptr [eax+04h], "Acor"; rocA
jne@@next
cmpdword ptr [eax+08h], "erdd"; ddre
jne@@next
cmpword ptr [eax+0Ch], "ss"; ss
jne@@next
moveax, [edi][IMAGE_EXPORT_DIRECTORY.AddressOfNameOrdinals]
addeax, ebp
movzx ebx, word ptr [edx*2+eax]
moveax, [edi][IMAGE_EXPORT_DIRECTORY.AddressOfFunctions]
addeax, ebp
moveax, [ebx*4+eax]
addeax, ebp
;找到了,储存起来:
mov[_GetProcAddress], eax
@@next:
addesi, 4
incedx
cmpedx, [edi][IMAGE_EXPORT_DIRECTORY.NumberOfNames]
jne@@name
gototop
 

其实在NT系统中TerminateProcess函数最终还是通过调用NtTerminateProcess来实现的,由于这个程序很模块化,只需要把源文件中
DllName1  db "ntdll.dll",0     
ApiName1  db "NtTerminateProcess",0
如此修改一下就可以拦截NtTerminateProcess了。
但还是有很多程序不通过这些函数来结束进程,所以请高手多提意见,看结束进程的方法到底有多少!
gototop
 

一般来说,是C:\Documents and Settings\Administrator\「开始」菜单\程序\启动
把快捷方式拷进去就可以了。
gototop
 

据俺所知嘛,熊猫烧香不感染如下目录里的文件
Microsoft Frontpage
Movie Maker
MSN Gamin Zone
Common Files
Windows NT
Recycled
System Volume Information
Documents and Settings
这就是为什么熊猫不感染系统文件的原因。
至于俺为什么不HOOK ntdll.dll中的NtTerminateProcess。那是因为正常进程退出时ExitProcess最终也需要调用这个函数,如果因此造成内存未被及时释放就糟糕乐。
熊猫烧香感染PE文件的方法真的很搞笑,俺估计作者对PE文件头格式可能不熟,至于特征码嘛,其实*.sys *.dll *.fon *.vxd 还有屏保之类等文件都是PE文件,猫猫为什么不感染?
gototop
 

ntdll.dll中的NtTerminateProcess当然不是ntoskrnl.exe中的系统服务NtTerminateProcess
ntdll.dll只是提供一个接口,具体代码在ntoskrnl.exe中实现。这个俺知道,不过俺不会去HOOK ntoskrnl.exe的,来个高手干脆把IDT HOOK了得了,呵呵
gototop
 

其实修改SSDT来HOOK native Api并不是什么高深莫测的技术。
俺以前经常编个*.sys文件通过Hook ZwQuerySystemInformation函数来隐藏进程。代码也很简单,只可惜后来大家都知道这个秘密了,现在这个技术也就能骗骗Windows的任务管理器、卡卡上网安全助手之类的啦,icesword里给你现个大大的红字,呵呵:
HookFunction        proc

      pushad
      mov eax, [KeServiceDescriptorTable]
      mov esi, [eax]
      mov esi, [esi]
                 
      mov eax,ZwQuerySystemInformation
      inc eax
      inc eax
      mov eax,[eax]
      mov eax,[eax]
      inc eax
      movzx ecx,byte ptr[eax]
      sal ecx,2                 
      add esi,ecx
      mov dwAddr,esi
      mov edi,dword ptr[esi]
   
      mov dwOldNtQuerySystemInformation,edi
      mov edi,offset NewNtQuerySystemInformation
   
      cli
      mov dword ptr[esi],edi
      sti
      popad
      mov eax, STATUS_SUCCESS

      ret

HookFunction    endp
gototop
 

貌似SSDT是MS公司专门为Hooker准备的一样,内核程序通过修改这张表指向自己的处理程序就可以实现Hook,而内核程序自己调用NT*函数根本就用不着这张表,也就是说内核程序自己调用这些函数的话连恢复SSDT表这一步都可以省了,呵呵!
gototop
 

引用:
【编程小学生的贴子】没学过汇编~~!关注!有一天会学的!
………………

学C语言吧,汇编语言太难用了,不到万不得以谁会用它?
Charles Petzold的《Windows程序设计》是本很好的书,讲的SDK编程,看了后你一定不会后悔的!
gototop
 

花了点时间把软件保护程序For Win9X版编出来了!

原理基本和前几天的ForXp版本一样,还是修改Kernel32.dll模块中的TerminateProcess函数前几个字节jmp到自己的代码段达到Hook的目的(据说这叫Inline Hook,faint!)。但由于该死的MS把Kernel32.dll放在了BFF70000h处(可恨呀,那里是系统内存,Ring3的应用程序没有权限修改!这就是为什么俺以前那个ForXp的程序在Win9X下不起作用的原因。不过喜得好在Win9X下进入Ring0并不是什么难事,呵呵!)

程序下载:http://b.py99.net/zip/f?v=20073/61321259.zip
源代码如下:


.586
.model flat, stdcall
option casemap :none
include \masm32\include\windows.inc
include \masm32\include\kernel32.inc
include \masm32\include\user32.inc
include macros.asm

includelib \masm32\lib\kernel32.lib
includelib \masm32\lib\user32.lib
 
    Call32 macro Selector,Offsetv
      db 09ah
      dd Offsetv
      dw Selector
    endm
   


.data
   
     
    aKernel32        db 'Kernel32.dll',0
    aUser32          db 'User32.dll',0
    AddrKernel32      dd ?
    aTerminateProcess db 'TerminateProcess',0
    AddrTerminate    dd ?

    aMessageboxA      db 'MessageBoxA',0
    AddrMessage      dd ?
    aExitProcess      db 'ExitProcess',0
    AddrExitProcess  dd ?

    lpMappedObject    dd ?

;;-----------------------------------------
.code
  Start:
        invoke GetModuleHandle,addr aKernel32
        mov AddrKernel32,eax
        invoke GetProcAddress,eax,addr aTerminateProcess
        mov AddrTerminate,eax
    detect:
     
        cmp word ptr[eax+5],90c3h   
        jz _ErrHooked

     
        invoke GetProcAddress,AddrKernel32,addr aExitProcess
        mov AddrExitProcess,eax

        invoke GetModuleHandle,addr aUser32
        invoke GetProcAddress,eax,addr aMessageboxA
        mov AddrMessage,eax     
     
        mov    eax,080000000h-1000h   
      Try_next:             
        add    eax,1000h
        cmp    eax,(-1-1000h)       
        jae    _ErrCantAlloc             
        push    eax
        invoke VirtualAlloc,eax,1000h,MEM_COMMIT,PAGE_EXECUTE_READWRITE
        test    eax,eax       
        xchg    eax,ebx     
        pop    eax       
        je      Try_next
        mov lpMappedObject, eax

     
        push offset MyProc 
        call ToRing0Code

     
        cld
        mov edi,lpMappedObject
        mov esi,offset Addr0Proc
       
        mov ecx,Addr0ProcLength+1
        rep movsb


        invoke    MessageBox,0,CTXT("软件已成功运行!"),CTXT("SUCCESS"),MB_ICONWARNING
        jmp Exit
      _ErrCantAlloc:
        invoke    MessageBox,0,CTXT("不能分配内存!"),CTXT("ERROR"),0
        jmp Exit
      _ErrHooked:
        invoke    MessageBox,0,CTXT("程序已经运行过了!"),CTXT("ERROR"),MB_ICONWARNING
      Exit:   
        invoke    ExitProcess,0
      ;-----------------------------------------       
        MyProc proc
         
;进入Ring0了,当然要先叫一声庆祝庆祝!         

    pushad                 

    mov al,0B6h           

    out 43h,al 

    mov al,04h         



    out 42h,al 

    out 42h,al 



 

    in al,61h

    or al,3 

    out 61h,al 

    mov ecx,2000000h        ;延时

    loop $



    and al,0FCh              ;关声音

    out 61h,al 

    popad

;开始对Kernel32.dll动手术了!
         
          push esi         
          push edi
          lea esi,AddrMessage
          lea edi,bAddrMessage
          movsd

          lea esi,AddrTerminate
          lea edi,bTerminate
          movsd
          lea esi,lpMappedObject
          lea edi,blpMappedObject
          movsd
 
          mov esi,AddrTerminate   
          lea edi,OldBytes
          xor ecx,ecx
          mov cl,7
          rep movsb

       
          mov eax,AddrTerminate 
          mov byte ptr[eax],68h
          m2m dword ptr[eax+1],lpMappedObject
          mov word ptr[eax+5],90c3h

       
          pop edi
          pop esi
          retf
        MyProc endp

 
    Addr0Proc:   
        push ebx
        push esi
        push edi
        jmp next
      align 4
        Caution  db '注意',0
        Text    db '有程序妄图终止其它进程',0dh,0ah
                  db '阻止吗?',0
        bAddrMessage    dd ?
        bTerminate      dd ?
        blpMappedObject dd ?
      next:
        call tmp
      tmp:
     
        pop esi
        mov eax,offset tmp-offset Addr0Proc
        sub esi,eax   

   
        push MB_YESNOCANCEL or MB_ICONWARNING
        mov ecx, offset Caution-offset Addr0Proc
        add ecx,esi
        push ecx
        mov ecx, offset Text-offset Addr0Proc
        add ecx,esi
        push ecx
        push dword ptr 0
        mov ecx, offset bAddrMessage-offset Addr0Proc
        add ecx,esi
        call dword ptr[ecx]

     
        .if eax==IDYES 
            pop edi
            pop esi
            pop ebx
            mov eax,0
            ret 8
          .elseif eax==IDCANCEL
            mov ecx,offset Restore-offset Addr0Proc
            add ecx,esi
            push ecx
            mov ecx,offset ToRing0Code-offset Addr0Proc
            add ecx,esi
            call ecx
            pop edi
            pop esi
            pop ebx
            mov eax,0
            ret 8
        .endif
     
     
        mov ecx,offset Restore-offset Addr0Proc
        add ecx,esi
        push ecx
        mov ecx,offset ToRing0Code-offset Addr0Proc
        add ecx,esi
        call ecx

     
        mov ecx,dword ptr[esp+5*4]
        mov edx,dword ptr[esp+4*4]
        push ecx
        push edx 

        mov ecx,offset bTerminate-offset Addr0Proc
        add ecx,esi
        mov edx,offset Back-offset Addr0Proc
        add edx,esi
        push edx
        push dword ptr[ecx]
        ret

   
        OldBytes db 7 dup(90h)
      Back: 
        push eax
        mov ecx,offset ReChange-offset Addr0Proc
        add ecx,esi
        push ecx
        mov ecx,offset ToRing0Code-offset Addr0Proc
        add ecx,esi
        call ecx
        pop eax
        pop edi
        pop esi
        pop ebx
        ret 8   

   
    ReChange:   
        mov ecx,offset bTerminate-offset Addr0Proc
        add ecx,esi
        mov eax,[ecx]
        mov byte ptr[eax],68h
        mov ecx,offset blpMappedObject-offset Addr0Proc
        add ecx,esi
        m2m dword ptr[eax+1],[ecx]
        mov word ptr[eax+5],90c3h
        retf
   

    Restore:
        push esi
        push edi
        mov edi,offset bTerminate-offset Addr0Proc
        add edi,esi
        mov edi,dword ptr[edi]
        mov ecx,offset OldBytes-offset Addr0Proc
        add esi,ecx     
        mov ecx,7
        cld
        rep movsb
        pop edi
        pop esi
        retf


ToRing0Code proc Ring0Proc:DWORD;生成调用门并调用Ring0子程序Ring0Proc
LOCAL Temp,Temp1
callGetLdtAddress;取出LDT的地址,返回结果在eax中
movecx,[eax];保存LDT第一个描述符
mov[Temp],ecx;
movecx,[eax+4];
mov[Temp1],ecx;
movedx,Ring0Proc;把调用门的内容写入LDT
mov[eax],dx;偏移量的低16位
movword ptr [eax+2],28h;段选择子
movword ptr [eax+4],0ec00h;属性
shredx,16;偏移量的高16位
mov[eax+6],dx;
pusheax
Call327,0;调用 Ring0 子程序
popebx
movedx,[Temp];恢复LDT第一个描述符
mov[ebx],edx;
movedx,[Temp1];
mov[ebx+4],edx;
ret
ToRing0Code endp

GetLdtAddress proc;取LDT的地址
pushebx;先要取GDT的地址
sgdt[esp-2];
popebx;
sldtax;取LDT内容
andeax,0fff8H;屏蔽掉低3位、eax的高16位清0
addebx,eax;算出LDT描述符的位置
moveax,[ebx+2];从描述符中取出LDT的地址
movdl,[ebx+7];
shledx,24;
andeax,0ffffffh;
oreax,edx;
ret
GetLdtAddress endp
   
    Addr0ProcLength =$-Addr0Proc

END    Start
gototop
 

俺都测试过,Win9X这个还不错,因为在Win9X下想绕过TerminateProcess这个API函数来终止进程很难(Post一个WM_CLOSE?)!但可惜的是现在很少有人用Win9X了。
XP下那个就实在不怎么样了,因为现在调用NtTerminateProcess来结束进程好象更流行,有些甚至于在内核下调用,连SSDT都不过,faint呀!微软的Windows。不过尽然编出来了就发表吧,呵呵!
gototop
 
123   2  /  3  页   跳转
页面顶部
Powered by Discuz!NT