首页
社区
课程
招聘
[求助]Veh 可以补货c05异常吗?eip应改在哪里
发表于: 2016-2-18 02:55 4512

[求助]Veh 可以补货c05异常吗?eip应改在哪里

2016-2-18 02:55
4512
比如 -0400000 mov eax,【0500000】 当设置0500000为不可读时,veh可以捕获到异常吗? 如果捕获到了,eip 应该是0400000还是0400000所处的内存段首

[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!

收藏
免费 0
支持
分享
最新回复 (6)
雪    币: 6124
活跃值: (4666)
能力值: ( LV6,RANK:80 )
在线值:
发帖
回帖
粉丝
2
如果你设置了异常的话是可以捕获的,哪里发生异常eip就是哪里,代码段而不是数据段
2016-2-18 05:07
0
雪    币: 14
活跃值: (13)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
3
了解了 大牛 我发现一个问题 我在一个地址内存属性设置禁止运行的时候 异常的eip竟然是这个地址所在内存段段首
2016-2-19 02:04
0
雪    币: 78
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
4
因为VirtualProtect设置的是整个内存页的属性,执行到该页头部的代码时就会产生异常,通常并不是你想Hook的点。
2016-2-20 14:26
0
雪    币: 245
活跃值: (294)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
5
首先在这个问题之前先要了解一个调试器的基础知识-内存断点实现原理
也就是ZChameleon所说的VirtualProtect问题
内存断点工作原理是通过VirtualProtect设置一个地址为不可读时,他其实是设置你这个地址所在的一整个内存页的属性都是不可读的,这个范围如果我没记错是4K也就是说内存断点是断的一个范围
内存断点 这种断点不同于硬件断点或CC断点,硬件断点或CC断点他们只会让异常捕获一次就能实现就是你所要断下的位置,而内存断点会触发多次,然后有你的异常处理函数来过滤哪次断点是你所要的

下面附上代码举例说明一下
添加一个内存断点地址是0050020
  ProcessHandle := OpenProcess(PROCESS_ALL_ACCESS,False,GetCurrentProcessId());
  if (ProcessHandle = 0) or (ProcessHandle = INVALID_HANDLE_VALUE) then Exit;
  VEHInstall();
  MemoryBreakPoint:=TMemoryBreakPoint.Create(ProcessHandle);
  MemoryBreakPoint.AddMBP($0050020);

假如所在的代码页有这两行指令访问到了
0400100: mov eax,[0050024]<--因为是在同一内存页所以这里也会断到通过过滤把他去除
0400200: mov eax,[0050020]<--要断的位置

type
  PExceptionRecord = ^TExceptionRecord;
  _EXCEPTION_RECORD = record
    ExceptionCode: DWORD;
    ExceptionFlags: DWORD;
    ExceptionRecord: PExceptionRecord;
    ExceptionAddress: Pointer;<-----内存断点触发时访问你VirtualProtect所设置的内存页的汇编指令地址就是EIP
    NumberParameters: DWORD;
    ExceptionInformation: array[0..EXCEPTION_MAXIMUM_PARAMETERS - 1] of DWORD;<-----ExceptionInformation[1]中是当前在内存页中所被访问到的地址
  end;

function ExceptionHandler(const exce: TExceptionPointers): LongInt; stdcall;
const
  EXCEPTION_CONTINUE_SEARCH = 0;
  EXCEPTION_EXECUTE_HANDLER = 1;
  EXCEPTION_CONTINUE_EXECUTION = -1;
var
  per: PExceptionRecord;
begin
  per := exce.ExceptionRecord;
  case per.ExceptionCode of
    EXCEPTION_ACCESS_VIOLATION:  //内存断点异常
    begin
      if per.ExceptionInformation[1] = $0050020 then
      begin
        TTLog.Log(Format('内存断点异常 汇编地址:%.8x 访问地址:%.8x', [Cardinal(per.ExceptionAddress),per.ExceptionInformation[1]]));
        //这里就只会断到0400200所在的汇编指令了做你的处理
        MemoryBreakPoint.DelMBP($0050020);//删除掉断点
        Result:=EXCEPTION_CONTINUE_EXECUTION;//正常运行
        Exit;
      end;
    end;   
  end;
  Result := EXCEPTION_CONTINUE_SEARCH;//下一次搜索
end;

VEH是个非常不错的东西用他同样可以实现调试器的功能
2016-2-20 16:41
0
雪    币: 14
活跃值: (13)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
6
谢谢大牛 很详细啊 受教了
2016-2-20 21:19
0
雪    币: 129
活跃值: (333)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
xed
7
进来学习
2016-2-22 15:45
0
游客
登录 | 注册 方可回帖
返回
//