能力值:
( LV2,RANK:10 )
4 楼
.586p
.model flat, stdcall
option casemap : none
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
includelib \masm32\lib\kernel32.lib
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
Sleep PROTO :DWORD
GetModuleHandleA PROTO :DWORD
GetProcAddress PROTO :DWORD,:DWORD
VirtualQuery PROTO :DWORD,:DWORD,:DWORD
VirtualProtect PROTO :DWORD,:DWORD,:DWORD,:DWORD
VirtualAlloc PROTO :DWORD,:DWORD,:DWORD,:DWORD
VirtualFree PROTO :DWORD,:DWORD,:DWORD
FlushInstructionCache PROTO :DWORD,:DWORD,:DWORD
GetCurrentProcess PROTO
ExitProcess PROTO :DWORD
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
.const
MEMORY_BASIC_INFORMATION_SIZE EQU 28
PAGE_READWRITE DD 04H
PAGE_EXECUTE_READWRITE DD 040H
MEM_COMMIT DD 01000H
MEM_RELEASE DD 08000H
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
.data
kernel_name DB "kernel32.dll",0
sleep_name DB "sleep",0
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
.data?
old_protect DD ?
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
.code
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
start:
push 5000
call Sleep
do_hook:
push offset kernel_name
call GetModuleHandleA
push offset sleep_name
push eax
Call GetProcAddress
mov edi,eax ;finally got Sleep address
push PAGE_READWRITE
push MEM_COMMIT
push MEMORY_BASIC_INFORMATION_SIZE
push 0
call VirtualAlloc
test eax,eax
jz do_sleep
mov esi,eax ;allocation for MBI
push MEMORY_BASIC_INFORMATION_SIZE
push esi
push edi
call VirtualQuery
;typedef struct _MEMORY_BASIC_INFORMATION { // mbi
; PVOID BaseAddress; // base address of region
; PVOID AllocationBase; // allocation base address
; DWORD AllocationProtect; // initial access protection
; DWORD RegionSize; // size, in bytes, of region
; DWORD State; // committed, reserved, free
; DWORD Protect; // current access protection
; DWORD Type; // type of pages
;} MEMORY_BASIC_INFORMATION;
test eax,eax
jz free_mem
call GetCurrentProcess
push 5 ;5 bytes
push edi ;addr
push eax
call FlushInstructionCache ;just to be sure
lea eax,[esi+014h]
push eax
push PAGE_EXECUTE_READWRITE
lea eax,[esi+0Ch]
push [eax]
push [esi]
call VirtualProtect
;we will change protection for a moment, so we will be able to write there
test eax,eax
jz free_mem
mov byte ptr[edi],0E9h ;to write relative jump
mov eax,offset new_sleep
sub eax,edi
sub eax,5
inc edi
stosb ;this is relative address for jump
push offset old_protect
lea eax,[esi+014h]
push [eax]
lea eax,[esi+0Ch]
push [eax]
push [esi]
call VirtualProtect ;return back the protection of page
free_mem:
push MEM_RELEASE
push 0
push esi
call VirtualFree ;free memory
do_sleep:
push 5000
call Sleep
push 0
call ExitProcess
new_sleep:
ret 04h
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
end start
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
能力值:
( LV2,RANK:10 )
7 楼
在使用win XP的电脑上试了一下
把
sleep_name DB "sleep",0
改成
sleep_name DB "Sleep",0
可以获得Sleep的地址,但没有转到:
new_sleep:
ret 04h
好像是
mov eax,offset new_sleep
sub eax,edi
sub eax,5
inc edi
stosb ;this is relative address for jump
这里计算地址有问题。 大家测试是否成功呢?
能力值:
( LV9,RANK:780 )
8 楼
===============hookdll.dll===========================
.486
.model flat,stdcall
option casemap:none
include \masm32\include\windows.inc
include \masm32\include\kernel32.inc
includelib \masm32\lib\kernel32.lib
include \masm32\include\user32.inc
includelib \masm32\lib\user32.lib SEH struct
a byte ?
api DWORD ?
d BYTE ?
e BYTE ?
SEH ends
WriteApi proto :DWORD ,:DWORD,:DWORD,:DWORD
MyAPI proto :DWORD ,:DWORD
GetApi proto :DWORD,:DWORD .data
hInstance dd 0
WProcess dd 0
hacker SEH <>
CommandLine LPSTR ?
Papi1 DWORD ?
Myapi1 DWORD ?
ApiBak1 db 10 dup(?)
DllName1 db "user32.dll",0
ApiName1 db "ExitWindowsEx",0
mdb db "下面的程序想关闭计算机,要保持阻止吗?",0 .data?
hHook dd ?
hWnd dd ? .code
DllEntry proc hInst:HINSTANCE, reason:DWORD, reserved1:DWORD
.if reason==DLL_PROCESS_ATTACH
push hInst
pop hInstance
invoke GetCommandLine
mov CommandLine,eax ;取程序命令行
mov hacker.a,0B8h ;mov eax
mov hacker.d,0FFh ;jmp
mov hacker.e, 0E0h ;eax
invoke GetCurrentProcess ;取进程伪句柄
mov WProcess ,eax
invoke GetApi,addr DllName1,addr ApiName1 ;取API地址
mov Papi1,eax ;保存API地址
invoke ReadProcessMemory,WProcess,Papi1,addr ApiBak1,8,NULL ;备份原API的前8字节
mov hacker.api,offset MyAPI ;要替代API的函数地址
invoke WriteApi,WProcess,Papi1, addr hacker ,size SEH ;HOOK API
.endif
.if reason==DLL_PROCESS_DETACH
invoke WriteApi,WProcess,Papi1, addr ApiBak1 ,8 ;还原API
.endif
mov eax,TRUE
ret
DllEntry Endp
GetMsgProc proc nCode:DWORD,wParam:DWORD,lParam:DWORD
invoke CallNextHookEx,hHook,nCode,wParam,lParam
mov eax,TRUE
ret
GetMsgProc endp
InstallHook proc
invoke SetWindowsHookEx,WH_GETMESSAGE,addr GetMsgProc,hInstance,NULL
mov hHook,eax
ret
InstallHook endp
UninstallHook proc
invoke UnhookWindowsHookEx,hHook
invoke WriteApi,WProcess,Papi1, addr ApiBak1 ,8
ret
UninstallHook endp
GetApi proc DllNameAddress:DWORD,ApiNameAddress:DWORD
invoke GetModuleHandle,DllNameAddress ;取DLL模块句柄
.if eax==NULL
invoke LoadLibrary ,DllNameAddress ;加载DLL
.endif
invoke GetProcAddress,eax,ApiNameAddress ;取API地址
mov eax,eax
ret
GetApi endp WriteApi proc Process:DWORD ,Papi:DWORD,Ptype:DWORD,Psize:DWORD
LOCAL mbi:MEMORY_BASIC_INFORMATION
LOCAL msize:DWORD ;返回页面虚拟信息
invoke VirtualQueryEx,Process, Papi,addr mbi,SIZEOF MEMORY_BASIC_INFORMATION
;修改为可读写模式
invoke VirtualProtectEx,Process, mbi.BaseAddress,8h,PAGE_EXECUTE_READWRITE,addr mbi.Protect
;开始写内存
invoke WriteProcessMemory,Process, Papi, Ptype,Psize ,NULL PUSH eax
;改回只读模式
invoke VirtualProtectEx,Process,mbi.BaseAddress,8h,PAGE_EXECUTE_READ,addr mbi.Protect
pop eax
ret
WriteApi endp
MyAPI proc bs:DWORD ,dwReserved:DWORD ;替代的API,参数要和原来一样
invoke MessageBox, NULL, CommandLine, addr mdb, 4 ;弹出信息框选择是否阻止
.if eax==7 ;如果选择否
invoke WriteApi,WProcess,Papi1, addr ApiBak1 ,8 ;先还原API
invoke ExitWindowsEx,bs,dwReserved ;再调用API
invoke WriteApi,WProcess,Papi1, addr hacker ,sizeof SEH ;调用完后再改回来
.endif
mov eax,TRUE
ret
MyAPI endp
End DllEntry
============================hookdll.def=========================
LIBRARY hookdll
EXPORTS InstallHook
EXPORTS UninstallHook
=================================================
注意;连接时要加上"/SECTION:.bss[S]"的开关,用来设置共享段
能力值:
( LV2,RANK:10 )
10 楼
的确,这小代码出自29A-7,而且在我的机子上工作不正常,
原因是跳转的地址计算不正确(但我认为它计算得对,而跟踪
调试的结果证明错误,我不知其因),29A的大师出现此问题,
让人难以置信。
;=================================================
原文本讲述在RING3下HOOK API的方法。即:
1. 通过ImgeDirectoryEntryToData取得IAT表地址;
2. 再在IAT表中找出sleep的地址,将其改为new_sleep的地址,
3. 在new_sleep的最后跳转系统真正的sleep的地址。
在执行系统Sleep时,先执行HOOK 代码。
API正常的执行:
call api--->IAT--|->SYSTEM api--->
next code <------|---------------|
user region | system region
API的HOOK执行:
call api--->IAT--->HOOK CODE--|->SYSTEM api--->
next code <-------------------|---------------|
user region | system region
;=================================================
然而,精悍的小代码却演示在RING3下HOOK API的另一方法。
即:废掉系统的API,直接执行HOOK CODE。
1. 取得系统API的地址;
2. 废掉系统代码区的禁写保护;
3. 计算系统API的地址与HOOK CODE的距离;
4. 修改系统API的地址处的指令,使其指向HOOK CODE;
5. 恢复系统代码区的禁写保护。
该代码中的HOOK CODE是空HOOK,即立即返回。第一次CALL Sleep
是正常的API,要阻塞5秒,经过API HOOK后,第二次CALL Sleep时
立即返回。如不计代码的执行时间,该进程只阻塞5秒,此时系统中
的其它进程要CALL Sleep,将立即返回(不阻塞)。如不作API HOOK,
该进程要阻塞10秒。
说明系统API的地址与HOOK CODE的距离计算(即求跳转的距离)
下列代码将EDI地址处的指令改为:JMP new_sleep,
(共5个字节,JMP=E9h,new_sleep=004010bbH)
mov byte ptr[edi],0E9h ;to write relative jump
mov eax,offset new_sleep
sub eax,edi ;地址间的距离
sbb eax,5 ;除去JMP new_sleep指令占的5个字节
inc edi
stosd ;在EDI处保存跳转的距离
edi=系统API Sleep的地址=7C802444
EAX=OFFSET new_Sleep(HOOK code)=004010bb
第一次CALL Sleep时,7C802444的代码为:
7C802444: mov edi,edi
push ebp
mov ebp,esp
push 0
push dword ptr ss.[ebp+8]
call kernel.SleepEx
第二次CALL Sleep时,7C802444的代码为:
7C802444: jmp new_sleep
push 0
push dword ptr ss.[ebp+8]
call kernel.SleepEx
能力值:
( LV2,RANK:10 )
13 楼
mov byte ptr[edi],0E9h ;to write relative jump
mov eax,offset new_sleep
inc eax ;******************
sub eax,edi
sbb eax,5
inc edi
stosd ;this is relative address for jump
;============================================
.486
.model flat, stdcall
option casemap : none
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
includelib \masm32\lib\kernel32.lib
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
Beep PROTO :DWORD,:DWORD
Sleep PROTO :DWORD
GetModuleHandleA PROTO :DWORD
GetProcAddress PROTO :DWORD,:DWORD
VirtualQuery PROTO :DWORD,:DWORD,:DWORD
VirtualProtect PROTO :DWORD,:DWORD,:DWORD,:DWORD
VirtualAlloc PROTO :DWORD,:DWORD,:DWORD,:DWORD
VirtualFree PROTO :DWORD,:DWORD,:DWORD
FlushInstructionCache PROTO :DWORD,:DWORD,:DWORD
GetCurrentProcess PROTO
ExitProcess PROTO :DWORD
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
.const
TIMER_FREQUENCY equ 1193167 ; 1,193,167 Hz
OCTAVE equ 4 ; octave multiplier
PITCH_F2 equ 698
TONE_30 equ TIMER_FREQUENCY/(PITCH_F2*OCTAVE)
MEMORY_BASIC_INFORMATION_SIZE EQU 28
PAGE_READWRITE DD 04H
PAGE_EXECUTE_READWRITE DD 040H
MEM_COMMIT DD 01000H
MEM_RELEASE DD 08000H
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
.data
kernel_name DB "kernel32.dll",0
sleep_name DB "Sleep",0
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
.data?
old_protect DD ?
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
.code
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
start:
push 1000
call Sleep ;(Sleep.kernel32.dll)
do_hook:
push offset kernel_name
call GetModuleHandleA
push offset sleep_name
push eax
Call GetProcAddress
mov edi,eax ;finally got Sleep address
push PAGE_READWRITE
push MEM_COMMIT
push MEMORY_BASIC_INFORMATION_SIZE
push 0
call VirtualAlloc
test eax,eax
jz do_sleep
mov esi,eax ;allocation for MBI
push MEMORY_BASIC_INFORMATION_SIZE
push esi
push edi
call VirtualQuery
test eax,eax
jz free_mem
call GetCurrentProcess
push 5 ;5 bytes
push edi ;addr
push eax ;is a pseudohandle to the current process.
call FlushInstructionCache ;just to be sure
lea eax,[esi+014h]
push eax
push PAGE_EXECUTE_READWRITE
lea eax,[esi+0Ch]
push [eax]
push [esi]
call VirtualProtect
test eax,eax
jz free_mem
mov byte ptr[edi],0E9h ;to write relative jump
mov eax,offset new_sleep
inc eax
sub eax,edi
sbb eax,5
inc edi
stosd ;this is relative address for jump
push offset old_protect
lea eax,[esi+014h]
push [eax]
lea eax,[esi+0Ch]
push [eax]
push [esi]
call VirtualProtect ;return back the protection of page
free_mem:
push MEM_RELEASE
push 0
push esi
call VirtualFree ;free memory
do_sleep:
push 1000
call Sleep ;(jmp new_sleep)
push 0
call ExitProcess
new_sleep:
push 2000
push TONE_30
call Beep
retn
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
end start