写了一段Hook API的代码,拿出来和大家共享

golden_alvin 2002-10-22 05:50:15
最近写了一段Hook API的代码,可以Hook API函数MessageBoxA,当有程序调用这个函数的时候,会把文字改为Hooked,利用同样的技术,可以实现鼠标抓词,系统变速等功能。当然由于用到了ring3转ring0的代码,程序只能在win9x下面运行
FREE_INT_NUM=5


include e:\tasm\include\windows.inc

.386P
.model flat,stdCall

;APIs being used in the program

extrn ExitProcess:Proc
extrn CreateFileMappingA:Proc
extrn MapViewOfFileEx:Proc
extrn MessageBoxA:Proc
extrn LoadLibraryA:Proc
extrn GetProcAddress:Proc
extrn GetMessageA:Proc
extrn TranslateMessage:Proc
extrn DispatchMessageA:Proc
extrn UpdateWindow:Proc
extrn CreateWindowExA:Proc
extrn ShowWindow:Proc
extrn RegisterClassA:Proc
extrn LoadIconA:Proc
extrn LoadCursorA:Proc
extrn GetStockObject:Proc
extrn GetModuleHandleA:Proc
extrn PostQuitMessage:Proc
extrn DefWindowProcA:Proc

POINT struc
xx dd ?
yy dd ?
ends

WNDCLASS struc
clsStyle dd ?
clsLpfnWndProc dd ?
clsCbClsExtra dd ?
clsCbWndExtra dd ?
clsHInstance dd ?
clsHIcon dd ?
clsHCursor dd ?
clsHbrBackground dd ?
clsLpszMenuName dd ?
clsLpszClassName dd ?
ends

MSG struc
hwnd dd ?
emsg dd ?
wParam dd ?
lParam dd ?
etime dd ?
pt POINT<>
ends





.data

DllName db "User32.dll",0
ProcName db "MessageBoxA",0
HookName db "HookMsg",0
ErrText db "Error!",0
ErrCaption db "HookMsg",0
Caption db "Information",0
Text db "Processing",0
WindowCaption db "HookMsg",0
ClassName db "HookMsgClass",0
hInst dd ?
hWnd dd ?
align 4
msg MSG<>
wc WNDCLASS<>
.code
start:
;create a memory mapping file
call CreateFileMappingA,0FFFFFFFFh,NULL,4,0,10000h,offset HookName
cmp eax,NULL
jz DisplayErr
push eax

;apply a memory whose address is higer than 80000000 which will be shared by all proecsses
mov ebx,80000000h
LoopMapping:
mov eax,[esp]
call MapViewOfFileEx,eax,2,0,0,0,ebx
cmp eax,NULL
jz AddEbx ;if failed,add ebx and retry
jmp CopyCode
AddEbx:
add ebx,10000h
jmp LoopMapping
CopyCode:
add esp,4

;copy code to the high address
mov edi,eax
mov esi,offset HookCode
mov ecx,EndCopy-StartCopy
cld
rep movsb


call LoadLibraryA,offset DllName
cmp eax,NULL
jz DisplayErr
call GetProcAddress,eax,offset ProcName
cmp eax,NULL
jz DisplayErr
mov [ebx+ProcAddress-StartCopy],eax ;let's store the original MessageBoxA address to the data buffer in the high address

;let's stroe ebx into esp and then use ebp to represent the base address
mov ebp,ebx

push ebx ;store the base of the code mapped into the high address


sub ebx,eax ;now ebx is the relative address of the two instructions
sub ebx,5 ;add the lenth of the first intruction

mov dword ptr [ebp+NewInstruction+1-StartCopy],ebx ;store the new instruction which will take the place of the first 5 bytes of instrucion in MessageBoxA

mov bl,byte ptr [eax]
mov byte ptr [ebp+OldInstruction-StartCopy],bl ;save the first byte
mov ebx,dword ptr[eax+1]
mov dword ptr [ebp+OldInstruction+1-StartCopy],ebx ;save the next four bytes

mov ebx,[esp] ;ebx is the base of the code

lea eax,[ebx+NewInstruction-StartCopy]
push eax

lea edx,[ebx+offset ModifyCode-StartCopy]


;add ebx,@0-StartCopy

call edx ;call modifycode the modify the first five bytes of instruction of the messageboxa

;now the first five bytes' instruction is a JMP


;let's create a window

call GetModuleHandleA,0
mov [hInst],eax

mov eax,offset ClassName
mov wc.clsLpszClassName,eax
mov eax,[hInst]
mov wc.clsHInstance,eax
mov eax,offset WindowProc
mov wc.clsLpfnWndProc,eax
call LoadIconA,0,IDI_APPLICATION
mov wc.clsHIcon,eax
call LoadCursorA,0,IDC_IBEAM
mov wc.clsHCursor,eax
xor eax,eax
mov wc.clsLpszMenuName,eax
call GetStockObject,WHITE_BRUSH
mov wc.clsHbrBackground,eax
mov eax,CS_HREDRAW or CS_VREDRAW or CS_GLOBALCLASS
mov wc.clsStyle,eax
xor eax,eax
mov wc.clsCbClsExtra,eax
mov wc.clsCbWndExtra,eax

call RegisterClassA,offset wc

call CreateWindowExA,0,offset ClassName,offset WindowCaption,WS_OVERLAPPEDWINDOW,\
100,100,450,300,0,0,\
[hInst],0
mov hWnd,eax
call ShowWindow,[hWnd],1
call UpdateWindow,[hWnd]
...全文
57 7 打赏 收藏 转发到动态 举报
写回复
用AI写文章
7 条回复
切换为时间正序
请发表友善的回复…
发表回复
97132 2002-11-09
  • 打赏
  • 举报
回复
好东东.
收藏
紫郢剑侠 2002-11-09
  • 打赏
  • 举报
回复
up again...
itaolu 2002-11-09
  • 打赏
  • 举报
回复
好东西!!!

不过遗憾的是不能在2000和XP下运行。
我一般用Detours来做API HOOK。
紫郢剑侠 2002-11-01
  • 打赏
  • 举报
回复
gz

收藏学习。。。
rivershan 2002-10-23
  • 打赏
  • 举报
回复
偶看不懂……
偶有VC的代码……
golden_alvin 2002-10-22
  • 打赏
  • 举报
回复
Ring0:
;eax=Address of the code to modify
;ebx=Base Address of the code mapped into the high address

pushad ;protect the original common registers
pushf ;protect the flag register
call @1
@1:
pop ebx ;now ebx is the address of the @1 in the virtual space

cli

mov ecx,[ebx+ProcAddress-@1]

mov dl,byte ptr [ebx+InstructionToModify-@1]
mov byte ptr [ecx],dl
mov edx,dword ptr [ebx+InstructionToModify+1-@1]
mov dword ptr [ecx+1],edx

sti

popf
popad

iret
DataBuffer=$
OldInstruction db ?
dd ?
NewInstruction db 0e9h
dd ?
InstructionToModify db ?
dd ?
OldDescriptor dd ?
dd ?
NewDescriptor dd ?
dd ?
ProcAddress dd ?
NewCaption db "Hooked",0
EndCopy=$

DisplayErr:
call MessageBoxA,NULL,offset ErrText,offset ErrCaption,MB_OK
jmp Exit


Exit:
call ExitProcess,0
end start

下面是这个程序的makefile:
NAME = HookMsg
OBJS = $(NAME).obj
IMPORT=$(MAKEDIR)\..\lib\import32
$(NAME).EXE: $(OBJS)$(DEF)
tlink32 /Tpe /aa /c $(OBJS),$(NAME),, $(IMPORT),
.asm.obj:
tasm32 /ml $&.asm,,,
我初学汇编,程序中肯定有很多不尽人意的地方,还请高手们指教!谢谢
golden_alvin 2002-10-22
  • 打赏
  • 举报
回复
MsgLoop:
call GetMessageA,offset msg,0,0,0
or eax,eax
jz PrepExit
call TranslateMessage,offset msg
call DispatchMessageA,offset msg
jmp MsgLoop


;before exiting,we must recover the first five bytes' instruction otherwise when other program calls messageboxa again,it will go wrong

PrepExit:
pop ebx ;ebx is the base of the code mapped into the high address
lea eax,[ebx+OldInstruction-StartCopy]
push eax
lea edx,[ebx+offset ModifyCode-StartCopy]
call edx ;call modifycode again


jmp Exit ;exit process

WindowProc Proc uses ebx edi esi,handle:dword,wMsg:dword,wParam1:dword,lParam1:dword
cmp wMsg,WM_CREATE
jz create
cmp wMsg,WM_DESTROY
jz destroy
cmp wMsg,WM_RBUTTONDOWN
jz rbuttondown
jmp default


create:
xor eax,eax
ret
destroy:
call PostQuitMessage,0
xor eax,eax
ret
rbuttondown:
call PostQuitMessage,0
xor eax,eax
ret
default:
call DefWindowProcA,handle,wMsg,wParam1,lParam1
ret

WindowProc endp



HookCode:
StartCopy=$


call @0
@0:
pop ebx ;now ebx is the address of @0 in the virtual space

lea eax,[ebx+OldInstruction-@0]

push ebx ;store ebx into stack
push eax


call ModifyCode ;recover the first five bytes' instruction

;mov eax,OldInstruction-@0[ebx]

mov ebx,[esp] ;fetch ebx from stack



;let's copy the parameters
cld
mov esi,esp
add esi,8
sub esp,10h
mov edi,esp
mov ecx,10h
rep movsb

lea eax,[ebx+NewCaption-@0] ;modify the parameter "Text",now when a program calls messageboxa,the text will be modified to "Hooked" whatever the original text is
mov [esp+4],eax

mov eax,[ebx+ProcAddress-@0] ;Get the address of the original function
call eax ;call the original MessageBoxA

pop ebx

lea eax,[ebx+NewInstruction-@0] ;modify the first five bytes' instruction to JMP again
push eax
call ModifyCode


ret 10h ;return to the user program
ModifyCode Proc



call @2 ;maybe the relocation here is not necessary
@2:
pop ebx

push eax ;let's modify the IDT
sidt [esp-2]
pop eax
add eax,FREE_INT_NUM*8
mov ecx,[eax+4]
mov [ebx+OldDescriptor+4-@2],ecx

mov ecx,[eax]
mov [ebx+OldDescriptor-@2],ecx

lea edx,[ebx+Ring0-@2]
and edx,0000ffffh
mov cx,dx
mov [ebx+NewDescriptor-@2],ecx

mov ecx,[eax+4]
lea edx,[ebx+Ring0-@2]
and edx,0ffff0000h
and ecx,0000ffffh
or ecx,edx

;an entry in IDT is 8 bytes
cli
mov [eax+4],ecx ;the higher four bytes
mov ecx,[ebx+NewDescriptor-@2]
mov [eax],ecx ;the lower four bytes
sti

push eax

mov eax,[esp+8] ;get the parameter which is the address of the code which will take the place of the first five bytes' instruction of messageboxa
push eax
mov al,byte ptr [eax] ;the first byte
mov [ebx+InstructionToModify-@2],al ;I have tried pass the parameter by register,but failed.
pop eax
mov eax,dword ptr[eax+1]
mov [ebx+InstructionToModify+1-@2],eax

int FREE_INT_NUM ;use the interrupt to enter ring0

pop eax

cli

mov ecx,[ebx+OldDescriptor-@2] ; recover the IDT
mov [eax],ecx
mov ecx,[ebx+OldDescriptor-@2+4]
mov [eax+4],ecx

sti


ret 4
ModifyCode Endp

21,458

社区成员

发帖
与我相关
我的任务
社区描述
汇编语言(Assembly Language)是任何一种用于电子计算机、微处理器、微控制器或其他可编程器件的低级语言,亦称为符号语言。
社区管理员
  • 汇编语言
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧