首页
社区
课程
招聘
跪求用汇编写的APIHOOK的小例子!
发表于: 2006-5-13 13:48 8358

跪求用汇编写的APIHOOK的小例子!

2006-5-13 13:48
8358
收藏
免费 0
支持
分享
最新回复 (15)
雪    币: 201
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
2
masm32里面有这样的例子,去下载一个masm32 安装包,icztutes\TUTE24有一例子.BTY,男儿膝下有黄金啊,别动不动就跪的.
2006-5-13 17:58
0
雪    币: 201
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
3
现在动不动就跪的人真多
2006-5-13 19:35
0
雪    币: 248
活跃值: (1141)
能力值: ( 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

;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
2006-5-13 20:57
0
雪    币: 12
活跃值: (620)
能力值: ( LV6,RANK:90 )
在线值:
发帖
回帖
粉丝
5
去看看29A#7吧
里面有篇文章很详细的写了RING3下的API HOOK
2006-5-14 11:23
0
雪    币: 201
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
6
汗!

那位老大能为4楼的代码加下注释呀?
2006-6-5 21:49
0
雪    币: 201
活跃值: (10)
能力值: ( 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

这里计算地址有问题。

大家测试是否成功呢?
2006-7-8 11:03
0
雪    币: 750
活跃值: (227)
能力值: ( 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]"的开关,用来设置共享段
2006-7-8 18:47
0
雪    币: 248
活跃值: (1141)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
9
最初由 ninja 发布
在使用win XP的电脑上试了一下



sleep_name DB "sleep",0
........

拦截API就是用自己的代码替换系统的某些功能代码。
1.在运行前拦截;
2.在运行中拦截。
;====================================
上面的HOOK Sleep的代码资料我目前找不到,过一阵子再解释。
2006-7-8 22:19
0
雪    币: 248
活跃值: (1141)
能力值: ( 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
2006-7-11 23:38
0
雪    币: 201
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
11
最初由 sixL 发布
stosd ;在EDI处保存跳转的距离


必须传送32位的地址吗?
2006-7-14 17:16
0
雪    币: 248
活跃值: (1141)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
12
最初由 ninja 发布
必须传送32位的地址吗?

我认为:
关于修改Sleep入口处指令的部分正常。在第二次
Call Sleep,sleep入口处指令变化:
原:
mov edi,edi
push ebp
mov ebp,esp
push 0
push dword ptr ss.[ebp+8]
call kernel.SleepEx
pop ebp
retn 4
;==============================
现:
jmp new_sleep
push 0
push dword ptr ss.[ebp+8]
call kernel.SleepEx
pop ebp
retn 4
;===============================
而在new_sleep:
RETN
此处后eip不正常。
2006-7-14 22:05
0
雪    币: 248
活跃值: (1141)
能力值: ( 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
2006-7-15 16:35
0
雪    币: 446
活跃值: (808)
能力值: ( LV7,RANK:100 )
在线值:
发帖
回帖
粉丝
14
把跪求用[求助]代替是不是比较好?
2006-7-15 16:52
0
雪    币: 201
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
15
最初由 sixL 发布
mov byte ptr[edi],0E9h ;to write relative jump
mov eax,offset new_sleep
inc eax ;******************
sub eax,edi
sbb eax,5
........


eax为什么要加1呢?
2006-7-17 22:02
0
雪    币: 248
活跃值: (1141)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
16
最初由 ninja 发布
eax为什么要加1呢?

这是调试的结果。
如果不加1就到不了new_sleep。
请问在你那这代码不运行?
2006-7-17 22:12
0
游客
登录 | 注册 方可回帖
返回