API후킹 Library
2013년 8월 10일 토요일
예전 언젠가 작성했던 글 Trampoline 후킹을 어셈으로 구현한거 같은데..
주석이 없어서 보기 힘들듯;;
C++ 로 구현한것도 있을텐데 그게 보기 더 편할거 같다.
#!asm
; apihook frame
;
; + DLL Injection은 Windows Hook을 이용하는 기법을 사용
; + API Hooking은 5byte Patch기법을 이용
; + 윈도우API만 염두해 두었으며, C Runtime API들은 동작안함 (stdcall만 처리, cdecl에대해선 처리X)
.386
.model flat, stdcall
option casemap:none
include c:masm32includewindows.inc
include c:masm32macrosmacros.asm
include c:masm32macrosucmacros.asm
include c:masm32includeuser32.inc
include c:masm32includekernel32.inc
include c:masm32includepsapi.inc
includelib c:masm32libuser32.lib
includelib c:masm32libkernel32.lib
includelib c:masm32libpsapi.lib
LoadApiHook proto, pApihookStruct:dword
RemoveApiHook proto, pApihookStruct:dword
GetMsgProc proto, nCode:dword, wParam:dword, lParam:dword
LoadHookFunctionList proto
RemoveHookFunctionList proto
LoadHookFunction proto, pstrDll:dword, pstrProc:dword
HookStruct struct
pNext dword 0
pOrgProc dword 0
pHookProc dword 0
dwOrgProtect dword 0
StubOrg byte 5 dup(0)
StubHook byte 5 dup(0)
HookStruct ends
.data
pHookStructResent dword 0
pHookStructTable dword 0
hUserDefineDll dword 0
bUserDefineDll byte 0
ListLoadLibrary byte 512 dup(0)
pListLoadLibrary dword 0
.data?
szUserDefineDll byte MAX_PATH dup(?)
hCBTHook dword ?
hMyInstance dword ?
ListTarget byte 512 dup(?)
pListTarget dword ?
ListHookDll byte 512 dup(?)
ListHookProc byte 512 dup(?)
pListHookDll dword ?
pListHookProc dword ?
.code
@HookFunctionSkel:
byte 90h ; nop
byte 90h ; nop
byte 90h ; nop
byte 58h ; pop eax
byte 56h ; push esi
byte 57h ; push edi
byte 52h ; push edx
byte 8Bh,0D0h ; mov edx, eax
byte 0B8h ; mov eax,
@HookFunctionSkelStruct1:
dword 0 ; [HookStruct]
byte 8Dh,70h,10h ; lea esi, dword ptr [eax + 16]
byte 8Bh,78h,04h ; mov edi, dword ptr [eax + 4]
byte 0A5h ; mobsd
byte 0A4h ; mobsb
byte 8Bh,70h,08h ; mov esi, dword ptr [eax + 8]
byte 89h,56h,3Bh ; mov dword ptr [esi + 59], edx
byte 5Ah ; pop edx
byte 5Fh ; pop edi
byte 5Eh ; pop esi
byte 0FFh,70h,04h ; push dword ptr [eax + 4]
byte 0E8h ; call
@HookFunctionSkelHookFunc:
dword 0 ; [MyHookFunc]
; byte 83h,0C4,04h ; add esp, 4
byte 50h ; push eax
byte 56h ; push esi
byte 57h ; push edi
byte 0B8h ; mov eax,
@HookFunctionSkelStruct2:
dword 0 ; [HookStruct]
byte 8Dh,70h,15h ; lea esi, dword ptr [eax + 21]
byte 8Bh,78h,04h ; mov edi, dword ptr [eax + 4]
byte 0A5h ; mobsd
byte 0A4h ; mobsb
byte 5Fh ; pop edi
byte 5Eh ; pop esi
byte 58h ; pop eax
byte 68h ; push
dword 0 ; [Return]
byte 0C3h ; ret
@HookFunctionSkelEnd:
DllEntry proc hInstance:HINSTANCE, reason:dword, reserved1:dword
local pstrTarget:dword
.if reason==DLL_PROCESS_ATTACH
.if hMyInstance==0
mov eax, hInstance
mov hMyInstance, eax
.endif
.if pListTarget!=0
mov pstrTarget, offset ListTarget
.while 1
invoke GetModuleHandle, pstrTarget
.if eax!=0
invoke LoadHookFunctionList
.break
.endif
invoke lstrlen, pstrTarget
add eax, pstrTarget
inc eax
.break .if byte ptr [eax]==0
mov pstrTarget, eax
.endw
.else
invoke LoadHookFunctionList
.endif
.elseif reason==DLL_PROCESS_DETACH
.if pHookStructTable!=0
invoke RemoveHookFunctionList
.endif
.endif
mov eax, 1
ret
DllEntry endp
GetMsgProc proc, nCode:dword, wParam:dword, lParam:dword
invoke CallNextHookEx, hCBTHook, nCode, wParam, lParam
ret
GetMsgProc endp
LoadHookFunctionList proc
local pstrDll:dword
local pstrProc:dword
invoke GetModuleHandle, addr szUserDefineDll
mov hUserDefineDll, eax
.if eax==0
invoke LoadLibrary, addr szUserDefineDll
mov hUserDefineDll, eax
mov bUserDefineDll, 1
.if eax==0
jmp LoadHookFunctionListExit
.endif
.endif
mov pstrDll, offset ListHookDll
mov pstrProc, offset ListHookProc
.if pListHookDll!=0 && pListHookProc!=0
.while 1
invoke LoadHookFunction, pstrDll, pstrProc
invoke lstrlen, pstrDll
add eax, pstrDll
inc eax
.break .if byte ptr [eax]==0
mov pstrDll, eax
invoke lstrlen, pstrProc
add eax, pstrProc
inc eax
.break .if byte ptr [eax]==0
mov pstrProc, eax
.endw
.endif
LoadHookFunctionListExit:
ret
LoadHookFunctionList endp
RemoveHookFunctionList proc uses esi edi ebx
mov eax, pHookStructTable
assume eax:ptr HookStruct
.while eax!=0
mov ebx, eax
assume ebx:ptr HookStruct
; 원본 stub 복구
lea esi, [ebx].StubOrg
mov edi, [ebx].pOrgProc
movsd
movsb
; Protect 복구
invoke VirtualProtect, [ebx].pOrgProc, 5, [ebx].dwOrgProtect, 0
mov eax, [ebx].pNext
push eax
invoke VirtualFree, [ebx].pHookProc, (@HookFunctionSkelEnd - @HookFunctionSkel), MEM_RELEASE
invoke VirtualFree, ebx, sizeof HookStruct, MEM_RELEASE
pop eax
.endw
mov eax, offset ListLoadLibrary
xor esi, esi
.if pListLoadLibrary > 0
.while 1
add eax, esi
invoke FreeLibrary, dword ptr [eax]
add esi, 4
.break .if esi >= pListLoadLibrary
.endw
.endif
.if bUserDefineDll==1 && hUserDefineDll!=0
invoke FreeLibrary, hUserDefineDll
.endif
RemoveHookFunctionListExit:
ret
RemoveHookFunctionList endp
LoadHookFunction proc uses esi edi ebx, pstrDll:dword, pstrProc:dword
local MyHookName[52]:byte
local pMyHookFunc:dword
local pOrgProc:dword
local mbi:MEMORY_BASIC_INFORMATION
.if hUserDefineDll==0
xor eax, eax
jmp LoadHookFunctionExit
.endif
invoke GetModuleHandle, pstrDll
.if eax==0
.if pListLoadLibrary >= sizeof ListLoadLibrary
jmp LoadHookFunctionExit
.endif
invoke LoadLibrary, pstrDll
.if eax==0
jmp LoadHookFunctionExit
.else
mov esi, offset ListLoadLibrary
add esi, pListLoadLibrary
mov dword ptr [esi], eax
add pListLoadLibrary, 4
.endif
.endif
invoke GetProcAddress, eax, pstrProc
.if eax==0
jmp LoadHookFunctionExit
.endif
mov pOrgProc, eax
invoke lstrcpy, addr MyHookName, chr$("My")
invoke lstrcat, addr MyHookName, pstrProc
invoke GetProcAddress, hUserDefineDll, addr MyHookName
.if eax==0
jmp LoadHookFunctionExit
.endif
mov pMyHookFunc, eax
invoke VirtualAlloc, 0, sizeof HookStruct, MEM_COMMIT, PAGE_READWRITE
.if eax==0
jmp LoadHookFunctionExit
.endif
mov ebx, eax
assume ebx:ptr HookStruct
.if pHookStructResent==0
mov pHookStructTable, eax
mov pHookStructResent, eax
.else
mov eax, pHookStructResent
assume eax:ptr HookStruct
mov [eax].pNext, ebx
assume eax:nothing
mov pHookStructResent, ebx
.endif
mov eax, pOrgProc
mov [ebx].pOrgProc, eax
invoke VirtualAlloc, 0, (@HookFunctionSkelEnd - @HookFunctionSkel), MEM_COMMIT, PAGE_EXECUTE_READWRITE
.if eax==0
jmp LoadHookFunctionExit
.endif
mov [ebx].pHookProc, eax
mov esi, offset @HookFunctionSkel
mov edi, eax
mov ecx, (@HookFunctionSkelEnd - @HookFunctionSkel)
rep movsb
mov dword ptr [eax + (@HookFunctionSkelStruct1 - @HookFunctionSkel)], ebx
mov dword ptr [eax + (@HookFunctionSkelStruct2 - @HookFunctionSkel)], ebx
mov esi, pMyHookFunc
lea edi, dword ptr [eax + (@HookFunctionSkelHookFunc - @HookFunctionSkel)]
sub esi, edi
sub esi, 4
mov dword ptr [eax + (@HookFunctionSkelHookFunc - @HookFunctionSkel)], esi
invoke VirtualQuery, [ebx].pOrgProc, addr mbi, sizeof mbi
.if eax==0
jmp LoadHookFunctionExit
.endif
lea esi, mbi
assume esi:ptr MEMORY_BASIC_INFORMATION
mov eax, mbi.Protect
and eax, not PAGE_NOACCESS
and eax, not PAGE_READONLY
and eax, not PAGE_WRITECOPY
and eax, not PAGE_READWRITE
and eax, not PAGE_EXECUTE
and eax, not PAGE_EXECUTE_READ
and eax, not PAGE_EXECUTE_WRITECOPY
or eax, PAGE_EXECUTE_READWRITE
lea esi, [ebx].dwOrgProtect
invoke VirtualProtect, [ebx].pOrgProc, 5, eax, esi
.if eax==0
jmp LoadHookFunctionExit
.endif
; 원본 stub 백업
mov esi, [ebx].pOrgProc
lea edi, [ebx].StubOrg
movsd
movsb
; Hook 함수로 점프하는 stub
mov eax, [ebx].pHookProc
sub eax, [ebx].pOrgProc
sub eax, 5
mov byte ptr [ebx].StubHook, 0E9h
mov dword ptr [ebx].StubHook + 1, eax
; hook stub으로 교체
lea esi, [ebx].StubHook
mov edi, [ebx].pOrgProc
movsd
movsb
xor eax, eax
inc eax
LoadHookFunctionExit:
ret
LoadHookFunction endp
; export functions
InitHook proc, pstrUserDefineDll:dword
invoke GetCurrentDirectory, sizeof szUserDefineDll, addr szUserDefineDll
invoke lstrcat, addr szUserDefineDll, chr$("")
invoke lstrcat, addr szUserDefineDll, pstrUserDefineDll
invoke RtlZeroMemory, addr ListTarget, sizeof ListTarget
invoke RtlZeroMemory, addr ListHookDll, sizeof ListHookDll
invoke RtlZeroMemory, addr ListHookProc, sizeof ListHookProc
mov pListTarget, 0
mov pListHookDll, 0
mov pListHookProc, 0
xor eax, eax
inc eax
InitHookExit:
ret
InitHook endp
AddTarget proc, pstrTarget:dword
local lenTarget:dword
invoke lstrlen, pstrTarget
mov lenTarget, eax
add eax, pListTarget
.if eax >= sizeof ListTarget
xor eax, eax
jmp AddTargetExit
.endif
mov eax, offset ListTarget
add eax, pListTarget
invoke lstrcpy, eax, pstrTarget
mov eax, pListTarget
add eax, lenTarget
inc eax
mov pListTarget, eax
xor eax, eax
inc eax
AddTargetExit:
ret
AddTarget endp
AddHook proc, pstrDll:dword, pstrProc:dword
local lenDll:dword
local lenProc:dword
invoke lstrlen, pstrDll
mov lenDll, eax
add eax, pListHookDll
.if eax >= sizeof ListHookDll
xor eax, eax
jmp AddHookExit
.endif
invoke lstrlen, pstrProc
mov lenProc, eax
add eax, pListHookProc
.if eax >= sizeof ListHookProc
xor eax, eax
jmp AddHookExit
.endif
mov eax, offset ListHookDll
add eax, pListHookDll
invoke lstrcpy, eax, pstrDll
mov eax, pListHookDll
add eax, lenDll
inc eax
mov pListHookDll, eax
mov eax, offset ListHookProc
add eax, pListHookProc
invoke lstrcpy, eax, pstrProc
mov eax, pListHookProc
add eax, lenProc
inc eax
mov pListHookProc, eax
xor eax, eax
inc eax
AddHookExit:
ret
AddHook endp
StartHook proc
invoke SetWindowsHookEx, WH_CBT, addr GetMsgProc, hMyInstance, 0
mov hCBTHook, eax
ret
StartHook endp
EndHook proc uses ebx
.if hCBTHook!=0
invoke UnhookWindowsHookEx, hCBTHook
.endif
EndHookExit:
ret
EndHook endp
end DllEntry