挖掘操作系统内部未导出函数,将注入进行到底

作 者: Anskya
时 间: 2006-06-29,15:43
链 接: http://bbs.pediy.com/showthread.php?threadid=28211

InjectCode for Win9x..
文章作者:Anskya
原文出处:看雪论坛
转载请保留版权~谢谢

现在注入方式很多,不过无外复三种:
1.使用映射代码然后创建远程线程
2.利用消息钩子插入DLL两种
3.使用调试API.GetThreadContext,SetThreadContext来改变线程的环境启动代码

4.不过基本上Win9x下差不多都是使用消息钩子挂钩模式
当然EliCZ叔叔发布的~EliRT可以让我们在Win9x下也可以使用
CreateRemoteThread注入函数...这里偶简单的说一下另外一种注入方式
利用系统内部函数进行创建远程线程.


这里我就不多说一大堆理论了~相关文献请参见EliCZ叔叔的文章...
当然这里使用的注入方式~他的文章中并没有提及...

1.原理
[1]定位目标
既然是夸进程的创建进程,首先我们怀疑的就是调试API
他们是如何作到调试远程进程的,比如DebugActiveProcess,
他是如何挂起目标进程的...所以对目标进程进行逆向分析..
(关于次问题请到...exetools里面查看相关文章吧...里面有讨论过)

(一下代码是反汇编DebugActiveProcess函数的...这里贴的是关键部分分析)
其实就在DebugActiveProcess下面几行的位置处...自己分析一下就知道了

代码:--------------------------------------------------------------------------------
; IDA output:
;.text:BFF9490D                 push    8                   ; const
;.text:BFF9490F                 push    edi
;.text:BFF94910                 push    offset sub_BFF9494D ; thread
;.text:BFF94915                 push    0FFFFF000h          ; tells kernel to allocate stack
;.text:BFF9491A                 push    edi                 ; pdb
;.text:BFF9491B                 call    CreateRemoteThread9x; arbitrary name
;0xE8 = call; 0x85 = push edi; 0xFFFF = higher part of 0xFFFFF000

特征码:0E857FFFFh(看不懂吗?自己反一下这个函数就知道了...16进制码...请问IDA这里怎么用???为显示不出...)
--------------------------------------------------------------------------------


至少跟踪发现这个函数不是WIndows导出的函数所以我们不能直接调用这个函数
(至少无法通过GetProcAddress函数搜索出地址来...但是我们完全可以定位函数地址和传入参数...分析代码看下面的文章)

2.定位
知道原理了..开始逆向分析...这里分析的目标是国外的一款非常恐怖的"Trojan"程序
Spirit(反向连接+远程注入代码,上传DLL或者EXE并运行之...体积:1.55k,
还有注册表添加,自删除等功能...支持Win9x下进程插入--一开始就对他很好奇^_^)

关键函数逆向分析部分:OD反出来的...

代码:--------------------------------------------------------------------------------
00400158    68 40000000     push    40
0040015D    68 00300008     push    8003000
00400162    68 D5050000     push    5D5
00400167    57              push    edi
00400168    FF15 42144000   call    [401442]                         ; kernel32.VirtualAlloc
0040016E    68 08000000     push    8
00400173    57              push    edi
00400174    50              push    eax
00400175    57              push    edi
00400176    68 D1040000     push    4D1
0040017B    8D15 0E114000   lea     edx, [40110E]  ;这个地址是需要插入的代码内存地址

00400181    52              push    edx
00400182    50              push    eax
00400183    56              push    esi
00400184    FF15 32144000   call    [401432]                         ; kernel32.WriteProcessMemory
0040018A    FF15 3E144000   call    [40143E]                         ; kernel32.GetCurrentProcessId
00400190    64:3305 3000000>xor     eax, fs:[30]
00400197    31C3            xor     ebx, eax
00400199    8B35 3A144000   mov     esi, [40143A]                    ;kernel32.DebugActiveProcess
0040019F    46              inc     esi
004001A0    813E FFFF57E8   cmp     dword ptr [esi], E857FFFF  ;比较是否是CreateRemoteThread9x内存特征
004001A6  ^ 75 F7           jnz     short 0040019F    ;不等继续跳转
004001A8    AD              lods    dword ptr [esi]    ;搜索到以后开始获取地址(扫描两次)
004001A9    AD              lods    dword ptr [esi]
004001AA    01F0            add     eax, esi      
004001AC    68 00F0FFFF     push    -1000
004001B1    53              push    ebx
004001B2    FFD0            call    eax
004001B4    57              push    edi
004001B5    50              push    eax
004001B6    8B35 2A144000   mov     esi, [40142A]                    ; kernel32.OpenProcess
004001BC    46              inc     esi
004001BD    813E 50FF32E8   cmp     dword ptr [esi], E832FF50
004001C3  ^ 75 F7           jnz     short 004001BC
004001C5    AD              lods    dword ptr [esi]
004001C6    AD              lods    dword ptr [esi]
004001C7    01F0            add     eax, esi
004001C9    53              push    ebx
004001CA    FFD0            call    eax        ;调用此函数
004001CC    61              popad
004001CD    C3              retn
--------------------------------------------------------------------------------


3.实现
不用说了吧~上面的代码逆向写一下就OK了...
既然注入代码我们就作全套...

[1]申请远程进程空间(C代码实现)
WinNT下我就不多说了~反正大家都知道的
关键说说Win9x
逆向分析一下中国黑客病毒
(CreateKernelThread创建线程...和
MoveDataToKnl函数(WHG自己写的具体看ChineseHacker代码))

不过他好像不能让我们将代码注入到别的进程内部...
好了Google搜了一下文章...发现Win9x内核下0x8000000以上空间都是透明的?
Why?你最好别问我,我也不知道..我很菜...

所以以上反汇编出来的代码是

代码:--------------------------------------------------------------------------------
00400158    68 40000000     push    40
0040015D    68 00300008     push    8003000
00400162    68 D5050000     push    5D5
00400167    57              push    edi
00400168    FF15 42144000   call    [401442]                         ; kernel32.VirtualAlloc
--------------------------------------------------------------------------------

啊~好了...写一下具体代码好了

代码:--------------------------------------------------------------------------------
LPVOID My_VirtualAllocEx(HANDLE hProcess, LPVOID lpAddress, DWORD dwSize, DWORD flAllocationType, DWORD 

flProtect) 
{
  if (GetVersion() > 0x80000000)
  {
    return VirtualAlloc(lpAddress, dwSize, 0x8000000 + MEM_COMMIT, PAGE_EXECUTE_READWRITE);
  }else
  {
    return VirtualAllocEx(hProcess, lpAddress, dwSize, flAllocationType, flProtect);
  }
}

BOOL My_VirtualFreeEx(HANDLE hProcess, LPVOID lpAddress, DWORD dwSize, DWORD dwFreeType) 
{
  if (GetVersion() > 0x80000000)
  {
    return VirtualFree(lpAddress, dwSize, MEM_RELEASE);
  }else
  {
    return VirtualFreeEx(hProcess, lpAddress, dwSize, dwFreeType);
  }
}
--------------------------------------------------------------------------------


需要注意的是~在Win9x下申请空间和释放空间以前需要~~OpenProcess
一下....在Win9x下申请空间还有一种方法:SharedMemoryAlloc函数
直接的Windows头部里面好像没有...大家可以从ComCtl32.dll里面导出...
这个函数使用非常简单..就一个参数.申请空间长度...

创建远程线程代码在附件内....(把上面的OD反汇编代码写一遍就OK了~有必要吗???)

具体示例代码看:附件~注入代码到记事本....支持Win9x下注入

参考文献:
[1]EliCZ 的EliRT代码,主页.看雪上有友情连接
[2]y0da 的Invisibility代码,主页.看雪上有友情连接

文章作者:Anskya
原文出处:看雪论坛
转载请保留版权~谢谢

终于可以上传了~


代码:--------------------------------------------------------------------------------
;======================================================
;远程线程注入对话框演示 Ex By Anskya
;支持Win9x下代码注入..
;Email:Anskya@Gmail.com
;======================================================
.586
.model flat
locals @@

include /D.N.ASM/include/useful.inc
include /D.N.ASM/include/MZ.INC
include /D.N.ASM/include/PE.INC

.data

  notepad db 'Notepad',0

injected:
    ;int 3
    pushad
    
    call @@delta
@@delta:
    pop ebp
    sub ebp,offset @@delta
    
    push 0
    lea eax,[ebp+offset cap]
    push eax
    lea eax,[ebp+offset msg]
    push eax
    push 0
    call [ebp+__MessageBoxA]

@@Exit:
    push 0
    call [ebp+__ExitThread]
    ;_invoke [ebp+__ExitThread],0
    popad
    ret
;------------------使用数据----------------------------------
  
  msg  db  "

  •  Hello World Coder! (C) Anskya.",0dh,0ah,0
      cap  db  "MsgBox By Anskya",0
      
        k32_api:
            db  'kernel32',0
              __ExitThread        dd  0058F9201h
              __WinExec          dd  028452C4Fh
              __OpenProcess        dd  033D350C4h
              __WriteProcessMemory    dd  00E9BBAD5h
            dd 0
      
        u32_api:
            db  'user32',0
              __MessageBoxA          dd  0D8556CF7h
              __FindWindowA        dd  085AB3323h
              __GetWindowThreadProcessId  dd  07B46AF5Eh
            dd 0
        
    injected_size equ $-injected

    .code

    public c entry

    entry:
    ;-------获取相关API函数
        lea eax,k32_api
        push eax
        call get_apicrc

        lea eax,u32_api
        push eax
        call get_apicrc
    ;-------获取完毕-------执行主函数部分
        ;call injected
        
        push 5
        push offset notepad
        call __WinExec
          
        push 0
        push offset notepad
        call __FindWindowA    ;获取窗口句柄
        
        push eax
        push esp
        push eax
        call __GetWindowThreadProcessId
        pop eax
        mov ebx,eax

        push eax
        push 0
        push 1f0fffh                    ;PROCESS_ALL_ACCESS
        call __OpenProcess
        mov ebp,eax
        
        push 40h                        ;PAGE_EXECUTE_READWRITE
        push 3000h                  ;MEM_COMMIT or MEM_RESERVE
        push injected_size
        push 0
        push ebp                        ;pid
        call RT32_VirtualAllocEx
        mov edi,eax

        push eax
        push esp
        push injected_size
        lea eax,injected
        push eax
        push edi
        push ebp
        call __WriteProcessMemory
        pop eax

        push eax
        push esp
        push 0
        push esi
        push edi
        push 0
        push 0
        push ebx
        call RT32_CreateRemoteThread
        pop ecx
        
    ExitProc:
        push 0
        callw ExitProcess

        ret

    ;-------使用函数地址
    RT32_VirtualAllocEx:
        pushad
        mov ebx,[esp+8*4+4]
        mov ebp,[esp+8*4+8]
        mov edx,[esp+8*4+12]
        mov esi,[esp+8*4+16]
        mov edi,[esp+8*4+20]
        call get_k32base
        mov ecx,cs
        xor cl,cl
        jecxz @@os_nt
    @@os_9x:
        push edi
        or esi,8000000h
        push esi
        push edx
        push ebp
        push 04402890Eh                ;VirtualAlloc
        push eax
        call get_addr32crc
        call eax
        jmp @@finished
    @@os_nt:
        push 0DA89FC22h                ;VirtualAllocEx
        push eax
        call get_addr32crc
        push edi
        push esi
        push edx
        push ebp
        push ebx
        call eax
    @@finished:
        mov [esp+pushad_eax],eax
        popad
        ret 4*5
        
    RT32_CreateRemoteThread:
        pushad
        mov ebp,[esp+8*4+4]
        call get_k32base
        mov esi,eax
        push ebp
        push 0
        push 1f0fffh                   ;PROCESS_ALL_ACCESS
        push 033D350C4h                ;OpenProcess
        push esi
        call get_addr32crc
        call eax
        mov ebx,eax
        
        push 0CF4A7F65h                ;CreateRemoteThread
        push esi
        call get_addr32crc
        mov ecx,cs
        xor cl,cl
        jecxz @@os_nt
    @@os_9x:
        call get_obfs
        xor ebp,eax
        
        call search_crt9x
        jnc @@error
        mov esi,eax
        
        mov edi,[esp+8*4+16]
        mov eax,[esp+8*4+20]
        push 8
        push eax
        push edi
        push 0fffff000h
        push ebp
        call esi

        push eax
        call search_halloc9x
        jnc @@error
        mov edx,eax
        pop eax
        
        push 0
        push eax
        push ebp
        call edx
        jmp @@finished
    @@os_nt:
    ;   push dwo [esp+8*4+28+ 0]
    ;   push dwo [esp+8*4+24+ 4]
    ;   push dwo [esp+8*4+20+ 8]
    ;   push dwo [esp+8*4+16+12]
    ;   push dwo [esp+8*4+12+16]
    ;   push dwo [esp+8*4+8 +20]
        push 6
        pop ecx
    @@loop_push:
        push dwo [esp+8*4+28]
        loop @@loop_push
        push ebx
        call eax
    @@finished:
        mov [esp+pushad_eax],eax
        popad
        ret 4*7
    @@error:
        sub eax,eax
        dec eax
        mov [esp+pushad_eax],eax
        popad
        ret 4*7
        
    get_obfs:
        pushad
        push 0EB1CE85Ch                ;GetCurrentProcessId
        call get_k32base
        push eax
        call get_addr32crc
        call eax
        mov ebx,eax
        mov eax,fs:[30h]
        xor eax,ebx
        mov [esp+pushad_eax],eax
        popad
        retn

    search_halloc9x:
        pushad

        call get_k32base    
        push 033D350C4h                ;OpenProcess
        push eax
        call get_addr32crc
        mov esi,eax

        mov eax,0E832ff50h
        jmp search_compare
            
    search_crt9x:
        pushad

        call get_k32base    
        push 07FC598E3h                ;DebugActiveProcess
        push eax
        call get_addr32crc
        mov esi,eax

       ; IDA output:
       ;.text:BFF9490D                 push    8                   ; const
       ;.text:BFF9490F                 push    edi
       ;.text:BFF94910                 push    offset sub_BFF9494D ; thread
       ;.text:BFF94915                 push    0FFFFF000h          ; tells kernel to allocate stack
       ;.text:BFF9491A                 push    edi                 ; pdb
       ;.text:BFF9491B                 call    CreateRemoteThread9x; arbitrary name
       ;0xE8 = call; 0x85 = push edi; 0xFFFF = higher part of 0xFFFFF000

    ;  mov eax,0fffff000h    
       mov eax,0E857FFFFh

    ;  DEBUG: CloseHandle
    ;  mov eax,0E8560002h
    search_compare:    
        sub ecx,ecx
        mov cl,255     ;approx. size of DebugActiveProcess, just in case
    @@compare:
        cmp eax,[esi]
        jz @@save
        inc esi
        dec ecx
        jecxz @@exit
        jmp @@compare
    @@save:
        lodsd
        lodsd          ;eax = relative address of CreateRemoteThread9x()
        add eax,esi    ;absolute address
        mov [esp+pushad_eax],eax
        stc
    @@exit:
        popad
        retn

    ;--------The End~~~[^_^]  
    get_apicrc:
        pushad
        mov esi,[esp+8*4+4]
        call get_k32base
        push 04134D1ADh      ;LoadLibraryA
        push eax
        call get_addr32crc
        
        push esi
        call eax
        mov ebx,eax
        
        sub eax,eax
        lodsb
        test al,al
        jnz $-3
        mov edi,esi

    @@loop:
        lodsd
        test eax,eax
        jz @@end
        push eax
        push ebx
        call get_addr32crc
        stosd
        jmp @@loop
    @@end:
        popad
        retn 4

    ;void* get_addr32crc(DWORD base, DWORD crc32)
    get_addr32crc:
        pushad
        mov ebx,[esp+8*4+4]
        mov esi,[esp+8*4+8]
        
        sub ebp,ebp     ;counter
        mov edx,ebx
        add edx,[edx.mz_neptr]
        mov edx,[edx.pe_exportrva]
        add edx,ebx

        mov eax,[edx.ex_numofnamepointers]
        mov edi,[edx.ex_addresstablerva]
        add edi,ebx
        mov edi,[edx.ex_namepointersrva]
        add edi,ebx
        
        push edx
        mov edx,edi
        
    @@next:
        mov edx,[edi]
        add edx,ebx

        inc ebp
        pushad
        mov esi,edx
        sub ecx,ecx
        lodsb
        inc ecx
        test al,al
        jnz $-4
        mov [esp+pushad_ecx],ecx
        popad
        
    @@cmpstr:
        pushad
    ;   mov edx,edx
        sub eax,eax
        call xcrc32
        cmp eax,esi
        popad
        jz @@found
        
    ;    push eax
    ;    sub eax,eax
    ;    scasb
    ;    jnz $-1
    ;    pop eax
        add edi,4
        dec eax
        jz @@error
        jmp @@next
    @@found:
        pop edx
        dec ebp

        mov ecx,[edx.ex_ordinaltablerva]
        add ecx,ebx
        movzx eax,wo [ecx+ebp*2]
        mov ebp,[edx.ex_addresstablerva]
        add ebp,ebx
        mov eax,[ebp+eax*4]
        add eax,ebx
    @@error:
        mov [esp+pushad_eax],eax
        popad
        ret 4*2

    ;void* get_k32base();
    get_k32base:
        pushad
        sub eax,eax
        mov eax,fs:[eax+30h]
        test eax,eax
        js @@os_9x
    @@os_nt:
        mov eax,[eax+0ch]
        mov esi,[eax+1ch]
        lodsd
        mov eax,[eax+8]
        jmp @@finished
    @@os_9x:
        mov eax,[eax+34h]
        lea eax,[eax+7ch]
        mov eax,[eax+3ch]
    @@finished:
        mov [esp+pushad_eax],eax
        popad
        retn

    ; zhengxi's crc32(): optimised by Vecna
    ; input: EDX=data, ECX=size, EAX=crc 
    ; output: EAX=crc, EDX+=ECX, ECX=BL=0 
    xcrc32:
        pushad
        jecxz @@4 
        not eax 
    @@1: 
        xor al, [edx] 
        inc edx 
        mov bl, 8 
    @@2:
        shr eax, 1 
        jnc @@3 
        xor eax, 0EDB88320h 
    @@3:
        dec bl 
        jnz @@2 
        loop @@1 
        not eax 
    @@4:
        mov [esp+pushad_eax],eax
        popad
        ret

    end
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值