首页
社区
课程
招聘
veh求助
2014-5-30 21:02 3894

veh求助

2014-5-30 21:02
3894
今天看到论坛里一篇文章:http://bbs.pediy.com/showthread.php?t=143432
  我也想试试,就写了一段奇丑无比的代码,尝试用veh进行hook一个函数:(4楼有C写的代码)
    .386
    .model flat,stdcall
    option casemap:none

include    \masm32\include\windows.inc
include    \masm32\include\user32.inc
includelib \masm32\lib\user32.lib
include    \masm32\include\kernel32.inc
includelib \masm32\lib\kernel32.lib

;数据段
    .data
    ctx CONTEXT <0>
    hcurrentthread dd 0h
    szkernel32 db "kernel32.dll",0h
    hkernel32 dd 0h
    szExitProcess db "ExitProcess",0h
    hExitProcess dd 0h
    sztext db "breakpoint occured!",0h
    sztitle db "qqand360",0h
;数据段?
    .data?
       

;代码段
    .code
    sethwbreakpoint proc address:dword
        pushad
        mov ctx.ContextFlags,CONTEXT_ALL
        invoke GetCurrentThread
        mov hcurrentthread,eax
        invoke GetThreadContext,eax,addr ctx
        mov eax,address
        mov ctx.iDr0,eax
        invoke SetThreadContext,hcurrentthread,addr ctx
        popad
        ret
    sethwbreakpoint endp
    exceptionhandler proc exceptioninfo:dword
        local @dwret:dword
        pushad
        mov ebx,exceptioninfo
        assume ebx:ptr EXCEPTION_POINTERS
        mov eax,[ebx].pExceptionRecord
        assume eax:ptr EXCEPTION_RECORD
        mov eax,[eax].ExceptionAddress
        assume eax:nothing
        mov edx,hExitProcess
        .if eax == edx
                invoke MessageBoxA,NULL,addr sztext,addr sztitle,MB_OK
                invoke GetThreadContext,hcurrentthread,addr ctx
                mov ctx.iDr0,0h
                invoke SetThreadContext,hcurrentthread,addr ctx
                invoke Sleep,3000
        .endif
        popad
        mov eax,EXCEPTION_CONTINUE_EXECUTION
        ret
    exceptionhandler endp
start:
        main proc
        invoke GetModuleHandle,addr szkernel32
        mov hkernel32,eax
        invoke GetProcAddress,eax,addr szExitProcess
        mov hExitProcess,eax
        invoke sethwbreakpoint,eax
        invoke AddVectoredExceptionHandler,1,addr exceptionhandler
        invoke ExitProcess,NULL
        ret
        main endp
end start
我用od调试的时候在sethwbreakpoint里的setthreadcontext返回的值显示已经设置成功,但是调用ExitProcess的时候并没有被断下来,exceptionhandler也没有被调用。请问各位坛子里的兄弟,我的代码在哪里错了,或者是我对那篇文章的理解有问题?

[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课

收藏
点赞0
打赏
分享
最新回复 (8)
雪    币: 7074
活跃值: (3463)
能力值: ( LV12,RANK:340 )
在线值:
发帖
回帖
粉丝
bxc 6 2014-5-30 22:33
2
0
你还是用c或c++写吧,汇编看得头晕
雪    币: 185
活跃值: (25)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
whnet 2014-5-30 22:37
3
0
me too ... 真心不会汇编。

感觉有必要的地方用inline asm 这种方式更好。
雪    币: 90
活跃值: (87)
能力值: ( LV5,RANK:60 )
在线值:
发帖
回帖
粉丝
张jialin 1 2014-5-30 22:57
4
0
不好意思,主要觉得汇编不需要用强制转换方便,确实不方便阅读,我把代码用C写了一下,希望大牛帮忙看下,
#include <iostream>
#include <windows.h>
using namespace std;
DWORD ExitProcessAddress = 0;
int sethwbreakpoint()
{
        CONTEXT ctx;
        ctx.ContextFlags = CONTEXT_ALL;
        GetThreadContext(GetCurrentThread(),&ctx);
        ctx.Dr0 = ExitProcessAddress;
        SetThreadContext(GetCurrentThread(),&ctx);
        return 0;
}
DWORD ExceptionHandler(EXCEPTION_POINTERS *p)
{
        if(p->ExceptionRecord->ExceptionAddress = (PVOID)ExitProcessAddress)
        {
                MessageBoxA(NULL,"hardware breakpoint","bp",MB_OK);
                CONTEXT ctx;
                ctx.ContextFlags = CONTEXT_ALL;
                GetThreadContext(GetCurrentThread(),&ctx);
                ctx.Dr0 = 0;
                SetThreadContext(GetCurrentThread(),&ctx);
                return EXCEPTION_CONTINUE_EXECUTION;
        }
        else
                return EXCEPTION_CONTINUE_SEARCH;
}
int main ()
{
        HMODULE hkernel32 = GetModuleHandle("kernel32.dll");
        DWORD addr = (DWORD)GetProcAddress(hkernel32,"ExitProcess");
        ExitProcessAddress = addr;
        sethwbreakpoint();
        AddVectoredExceptionHandler(1,(PVECTORED_EXCEPTION_HANDLER)ExceptionHandler);
        ExitProcess(NULL);
        return 0;
}
雪    币: 7074
活跃值: (3463)
能力值: ( LV12,RANK:340 )
在线值:
发帖
回帖
粉丝
bxc 6 2014-5-30 23:43
5
0
LZ看下 【总结】调试寄存器 原理与使用:DR0-DR7
调试寄存器 DR0-DR3
这四个寄存器是用来设置 断点地址的。断点的比对在物理地址转换前(异常产生时,还没有将线性地址转换成物理地址)。由于只有0-3四个保存地址的寄存器,所以,硬件断点,在物理上最多只能有4个。
调试寄存器DR4-DR5
这两个调试寄存器有CR4的DE标记控制。如果DE置位,那么对这两个寄存器的访问会导致#UD异常。如果DE置0,那么他们就被化名为DR6-DR7(你一定会问原来的DR6-DR7怎么办?这个…… 我也不知道。如果你搞明白了,一定记得告诉我)
调试寄存器DR7(控制寄存器)
(先介绍DR7对DR6的理解有好处。)

DR7是调试控制寄存器。控制方式嘛!继续看:
1. L0-L3(由第0,2,4,6位控制):对应DR0-DR3,设置断点作用范围,如果被置位,那么将只对当前任务有效。每次异常后,Lx都被清零。
2. G0-G3(由第1,3,5,7位控制):对应DR0-DR3,如果置位,那么所有的任务都有效。每次异常后不会被清零。以确保对所有任务有效。


还有一点,我不知道对不对,如果我记得没错的话。
MessageBox如果父窗口设置为NULL,这个函数就直接返回了(消息框还在,如果退出进程好像就没了)。
LZ自己测试下吧~
雪    币: 239
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
封心锁爱 2014-5-31 00:05
6
0
要设置Dr7的, sethwbreakpoint中加上ctx.Dr7 |= 1; 表示启用Dr0
还有, 你这个异常处理函数写错了, 系统从异常处理函数返回加载的是参数ExceptionPoint->ContextRecord中的内容, 你调用SetContextThread没用, 要修改ExceptionPoint->ContextRecord它中的值
雪    币: 2122
活跃值: (358)
能力值: ( LV9,RANK:200 )
在线值:
发帖
回帖
粉丝
疯子 4 2014-5-31 00:40
7
0
槽点太多了,不会参考文档,就参考别人的代码吧。

link:http://bbs.pediy.com/showthread.php?t=159449
雪    币: 90
活跃值: (87)
能力值: ( LV5,RANK:60 )
在线值:
发帖
回帖
粉丝
张jialin 1 2014-5-31 12:45
8
0
看了这篇文章我才发现我是在对调试寄存器完全不了解的情况下乱用啊。。。我还以为Dr0到Dr7全部是直接给地址就算下断了。
雪    币: 90
活跃值: (87)
能力值: ( LV5,RANK:60 )
在线值:
发帖
回帖
粉丝
张jialin 1 2014-5-31 12:49
9
0
谢谢,谢谢,正在学习调试寄存器的使用,我写代码的时候还以为Dr0到Dr7只要给个地址就会下断,刚刚去看了下调试寄存器的科普贴,我都不好意思看原来的代码。。。非常感谢,还有你指出的异常处理函数里的那个错误,看来我对异常处理机制理解还是不行。
游客
登录 | 注册 方可回帖
返回