修改了deroko的Ultimate Hooking Engine,成界面版,比较完善:
.686
.model flat,stdcall
option casemap:none
include windows.inc
include kernel32.inc
include user32.inc
include gdi32.inc
include Comctl32.inc
include comdlg32.inc
include shell32.inc
include masm32.inc
include advapi32.inc
include dbghelp.inc
include Libc.inc
includelib kernel32.lib
includelib user32.lib
includelib gdi32.lib
includelib Comctl32.lib
includelib comdlg32.lib
includelib shell32.lib
includelib masm32.lib
includelib advapi32.lib
includelib dbghelp.lib
includelib LIBC.LIB
DlgProc proto :DWORD,:DWORD,:DWORD,:DWORD
OpenFileProc proto :DWORD
OutputInfo proto :DWORD,:DWORD
HookStart proto :DWORD
EnableDebugPrivilege proto :DWORD
.const
IDD_MAIN equ 1000
IDC_FileName equ 1002
IDC_OPEN equ 1003
IDC_GET equ 1007
IDC_ABOUT equ 1011
IDC_Exit equ 1010
IDC_OutInf equ 1012
ico equ 2001
.data
startinfo STARTUPINFO <>
processInfo PROCESS_INFORMATION <>
OutBuff db 256 dup(0)
.data?
hDlg HINSTANCE ?
hInstance HINSTANCE ?
hOutputCtl dd ?
ProgPath db 256 dup(?)
oldProt dd ?
CTEXT macro Text:VARARG
local szText
.data
szText byte Text, 0
.code
exitm
endm
.code
start:
mov esi, (ProgramEnd-start)
invoke VirtualProtect, 401000h, esi, PAGE_EXECUTE_READWRITE, ADDR oldProt ;代码段可写
invoke EnableDebugPrivilege,TRUE ;提高权限
invoke GetModuleHandle, NULL
mov hInstance,eax
invoke InitCommonControls
invoke DialogBoxParam, hInstance, IDD_MAIN, NULL, addr DlgProc, NULL
invoke ExitProcess,eax
DlgProc proc hWnd:HWND, uMsg:UINT, wParam:WPARAM, lParam:LPARAM
LOCAL FilePath [MAX_PATH+2]:BYTE
LOCAL lpFileData:WIN32_FIND_DATA
.if uMsg == WM_INITDIALOG
push hWnd
pop hDlg
invoke LoadIcon,hInstance,ico
invoke SendMessage,hWnd,WM_SETICON,1,eax
invoke SetFocus,eax
invoke GetDlgItem, hDlg, IDC_OutInf
mov hOutputCtl, eax
.elseif uMsg == WM_COMMAND
mov eax,wParam
.if eax==IDC_OPEN
lea eax,FilePath
mov dword ptr [eax],0
invoke OpenFileProc,eax
.if eax!=0
invoke SetDlgItemText,hWnd,IDC_FileName,addr FilePath
.endif
invoke SetDlgItemText,hWnd,IDC_OutInf,0
.elseif eax==IDC_GET
invoke GetDlgItemText,hWnd,IDC_FileName,addr FilePath,MAX_PATH
invoke RtlZeroMemory, addr ProgPath, sizeof ProgPath
invoke lstrcpy,addr ProgPath,addr FilePath
call GetProgramPath
invoke lstrcat,addr ProgPath,CTEXT("hookdll.dll")
invoke FindFirstFile,addr ProgPath,addr lpFileData
.if eax == INVALID_HANDLE_VALUE
invoke MessageBox,NULL,CTEXT(" hookdll不存在 ") ,CTEXT("错误"),MB_OK
ret
.endif
invoke HookStart,addr FilePath
.elseif eax==IDC_ABOUT
invoke MessageBox,NULL,CTEXT(13," HookAPI_GUI test ",13,13," --===2009.5===-- ",0) ,CTEXT("About"),MB_OK
.elseif eax==IDC_Exit
invoke ExitProcess,0
.endif
.elseif uMsg == WM_CLOSE
invoke EndDialog,hWnd,0
.endif
xor eax,eax
ret
DlgProc endp
OpenFileProc proc OpenFileNameBuffer:DWORD
LOCAL ofn :OPENFILENAME
lea esi, ofn
mov ecx, sizeof OPENFILENAME
zeroloop:
mov byte ptr [esi+ecx-1],0
dec ecx
jnz zeroloop
mov ofn.lStructSize,SIZEOF OPENFILENAME
push hDlg
pop ofn.hWndOwner
mov ofn.lpstrCustomFilter,0
push hInstance
pop ofn.hInstance
mov ofn.lpstrFilter, CTEXT("PE 文件(*.exe)", 0, "*.exe", 0,13,10,"All",0,"*.*",0 , 0)
mov eax,OpenFileNameBuffer
mov ofn.lpstrFile, eax
mov ofn.nMaxFile, MAX_PATH
mov ofn.Flags, OFN_FILEMUSTEXIST or OFN_PATHMUSTEXIST or OFN_LONGNAMES or OFN_EXPLORER or OFN_HIDEREADONLY
mov ofn.lpstrTitle,CTEXT("打开可执行文件…")
invoke GetOpenFileName, ADDR ofn
ret
OpenFileProc endp
GetProgramPath proc
invoke GetModuleFileName, NULL,addr ProgPath,sizeof ProgPath
std
mov edi,offset ProgPath
add edi,sizeof ProgPath-1
mov al,"\"
mov ecx,sizeof ProgPath
repne scasb
cld
mov byte ptr [edi+2],0
ret
GetProgramPath endp
REMOTE_CODE_START equ this byte
pushad
call RemoteThread
popad
goback:
push 12345678h ;返回地址
retn
lpLoadLibrary dd ?
lpGetProcAddress dd ?
lpVirtualProtect dd ?
lpVirtualAlloc dd ?
lpGetModuleHandle dd ?
detoured db "Detoured_"
apiname db 256 dup(0)
lphookmain db "hookmain",0
lpHandle dd ?
lpItem dd ?
detour_buffer dd ?
dummy dd ?
currentdllbase dd ?
currenthookexport dd ?
dllbase dd ?
dllname db "hookdll.dll",0
include HookAPI_GUI.inc
RemoteThread:
call @F
@@:
pop ebp
sub ebp,offset @B
lea eax, [ebp+dllname]
_invoke [ebp+lpLoadLibrary],eax
mov [ebp+dllbase], eax
test eax, eax
jz @nohookmain
call WalkDllsAndHook
_invoke [ebp+lpGetProcAddress],[ebp+dllbase],ecx
test eax, eax
jz @nohookmain
call eax
mov eax,[ebp+lpHandle]
mov dword ptr[esi],eax
mov eax,[ebp+lpItem]
mov dword ptr[edi],eax
@nohookmain:
ret
InstallDetour proc api_address:dword,new_address:dword,detour_variable:dword ;安装钩子
local local_delta:dword
local dummyvar:dword
call @F
@@:
pop ebx
sub ebx,offset @B
lea ecx, dummyvar
_invoke [ebx+lpVirtualProtect], api_address, 1000h, PAGE_EXECUTE_READWRITE, ecx
cmp [ebx+detour_buffer], 0
jne @skip_alloc
_invoke [ebx+lpVirtualAlloc],0, 1000h, MEM_COMMIT, PAGE_EXECUTE_READWRITE
mov [ebx+detour_buffer], eax
@skip_alloc:
mov esi, api_address
mov edi, [ebx+detour_buffer]
xor ecx, ecx
@get_5bytes:
push esi
call ldex86
add esi, eax
add ecx, eax
cmp ecx, 5
jb @get_5bytes
mov esi, api_address
push ecx
rep movsb
pop ecx
push edi
push eax
mov edi, api_address
mov al, 90h
rep stosb
pop eax
pop edi
mov byte ptr[edi], 0e9h
add edi, 5
sub esi, edi
mov dword ptr[edi-4], esi
@install_hook:
mov eax, detour_variable
push [ebx+detour_buffer]
pop dword ptr[eax]
mov eax, api_address
mov ecx, new_address
mov byte ptr[eax], 0e9h
add eax, 5
sub ecx, eax
mov dword ptr[eax-4], ecx
mov [ebx+detour_buffer], edi
ret
InstallDetour endp
WalkDllsAndHook proc ;通过导出表找API名称
call @F
@@:
pop ebp
sub ebp,offset @B
mov ebx, [ebp+dllbase]
add ebx, [ebx+3ch]
mov ebx, [ebx+78h]
add ebx, [ebp+dllbase]
xor eax, eax
mov esi, [ebx+20h]
add esi, [ebp+dllbase]
@cycle_names:
mov ecx, [esi]
add ecx, [ebp+dllbase]
cmp dword ptr[ecx], 'KOOH'
jne @nextname
pushad
mov [ebp+currenthookexport], ecx
mov esi, ecx
add esi, 5
lea edi, [ebp+dllname]
@@:
lodsb
stosb
cmp al, '_'
jne @b
mov byte ptr[edi-1], 0
lea edi, [ebp+apiname]
copystring
lea eax, [ebp+dllname]
_invoke [ebp+lpLoadLibrary],eax
mov [ebp+currentdllbase], eax
_invoke [ebp+lpGetProcAddress],[ebp+dllbase],[ebp+currenthookexport]
mov [ebp+currenthookexport], eax
lea eax, [ebp+apiname]
_invoke [ebp+lpGetProcAddress],[ebp+currentdllbase],eax
mov esi, eax
lea eax, [ebp+detoured]
_invoke [ebp+lpGetProcAddress],[ebp+dllbase],eax
test eax, eax
jz @nodetoured
invoke InstallDetour, esi, [ebp+currenthookexport], eax
jmp @skip0
@nodetoured:
lea ecx, [ebp+dummy]
invoke InstallDetour, esi, [ebp+currenthookexport], ecx
@skip0:
popad
@nextname:
inc eax
add esi, 4
cmp eax, [ebx+18h]
jb @cycle_names
@exit:
ret
WalkDllsAndHook endp
REMOTE_CODE_END equ this byte
REMOTE_CODE_LENGTH equ offset REMOTE_CODE_END - offset REMOTE_CODE_START
HookStart proc FilePath:DWORD
LOCAL lpRemoteCode:dword
LOCAL context:CONTEXT
LOCAL Buffer [64]:byte
invoke GetModuleHandle,CTEXT('Kernel32.dll',0)
mov ebx,eax
invoke GetProcAddress,ebx,CTEXT('LoadLibraryA',0)
mov lpLoadLibrary,eax
invoke GetProcAddress,ebx,CTEXT('GetProcAddress',0)
mov lpGetProcAddress,eax
invoke GetProcAddress,ebx,CTEXT('VirtualProtect',0)
mov lpVirtualProtect,eax
invoke GetProcAddress,ebx,CTEXT('VirtualAlloc',0)
mov lpVirtualAlloc,eax
invoke GetProcAddress,ebx,CTEXT('GetModuleHandle',0)
mov lpGetModuleHandle,eax
mov context.ContextFlags, CONTEXT_FULL
invoke CreateProcess,FilePath,0,0,0,FALSE,CREATE_SUSPENDED,0,0,addr startinfo,addr processInfo
invoke OutputInfo,CTEXT("创建目标进程",13,10,0),0
invoke OpenProcess,PROCESS_ALL_ACCESS,FALSE,processInfo.dwProcessId
invoke VirtualProtectEx,processInfo.hProcess,400000h,1000h,PAGE_EXECUTE_READWRITE,addr Buffer
invoke VirtualAllocEx, processInfo.hProcess, 0, REMOTE_CODE_LENGTH, MEM_COMMIT, PAGE_EXECUTE_READWRITE ;在目标程序中申请内存
mov lpRemoteCode,eax
invoke GetThreadContext, processInfo.hThread, addr context
mov eax,context.regEax
mov dword ptr[goback+1], eax ;给返回地址赋值
mov eax,dword ptr[hDlg]
mov lpHandle,eax
mov eax,dword ptr[IDC_OutInf]
mov lpItem,eax
mov eax,lpRemoteCode
mov context.regEax,eax
invoke SetThreadContext, processInfo.hThread, addr context
invoke OutputInfo,CTEXT("开始注入...",13,10,0),0
invoke WriteProcessMemory,processInfo.hProcess,lpRemoteCode,offset REMOTE_CODE_START, REMOTE_CODE_LENGTH, 0 ;在申请的内存中注入代码
invoke OutputInfo,CTEXT("运行...",13,10,0),0
invoke ResumeThread, processInfo.hThread
ret
HookStart endp
ProgramEnd:
OutputInfo proc OurBuff:DWORD,flag:DWORD
.if flag!=0
invoke SetDlgItemText,hDlg,IDC_OutInf,CTEXT(0)
ret
.endif
invoke SendDlgItemMessage,hDlg,IDC_OutInf,EM_SETSEL,-1,-1
invoke SendDlgItemMessage,hDlg,IDC_OutInf,EM_REPLACESEL,FALSE,OurBuff
ret
OutputInfo endp
EnableDebugPrivilege proc isEnable
local htoken:HANDLE
local uid:LUID
local tp:TOKEN_PRIVILEGES
local isSuccess
mov isSuccess,FALSE
invoke GetCurrentProcess
lea ebx,htoken
invoke OpenProcessToken,eax,TOKEN_ADJUST_PRIVILEGES, ebx ;得到进程的令牌句柄
invoke LookupPrivilegeValue,NULL,CTEXT("SeDebugPrivilege"), addr uid ;查询进程的权限
mov tp.PrivilegeCount,1
push uid.LowPart
pop tp.Privileges[0].Luid.LowPart
push uid.HighPart
pop tp.Privileges[0].Luid.HighPart
.if isEnable
mov tp.Privileges[0].Attributes, SE_PRIVILEGE_ENABLED
.else
mov tp.Privileges[0].Attributes,0
.endif
invoke AdjustTokenPrivileges,htoken,FALSE,addr tp, sizeof tp,NULL,NULL ;判断令牌权限
invoke GetLastError
.if eax == ERROR_SUCCESS
mov isSuccess,TRUE
.endif
invoke CloseHandle,htoken
mov eax,isSuccess
ret
EnableDebugPrivilege endp
end start