Detours x64

来源:互联网 发布:编辑网络大赛 编辑:程序博客网 时间:2024/04/30 17:26
发信人: flier (小海 [渴望并不存在的完美]), 信区: MSDN
标  题: Detours x64 [Draft]
发信站: 水木社区 (Fri Aug  3 01:01:07 2007), 站内

该死的路径依赖,为了折腾另外一个问题,不得不先把这个搞定 :S

Detours我就不介绍了,MSR放出的2.1 Express版本不支持64位
而据某人发邮件问,要10000刀才给授权,基本也不用想了 -_-b

于是乎在此基础上修修补补,基本能在x64下跑起来
因为还有些bug,暂时不放完整版本出来,大概说说流程

API Hook 基本已经是大白菜级技术,无非就是找到函数入口点
替换前面几个字节为jmp,重定向到一个跳板,完成工作再跳回去
详细的流程请参考detours的代码,下面捡x64下不一样的说

首先是在DetourAttachEx时找到原始函数和Hook函数的真实代码入口点
可能需要跳过import表,或者调试用间接跳转指令啥的,
detours.cpp里detour_skip_jmp函数就是干这个的,
不过在x64下需要做一些调整,因为某些指令的数据长度跟x86不同
这块代码我基本照抄mhook的实现,比detours增加了嵌套检查



inline PBYTE detour_skip_jmp(PBYTE pbCode, PVOID *ppGlobals)

{

  if (pbCode == NULL) {

    return NULL;

  }

  if (ppGlobals != NULL) {

    *ppGlobals = NULL;

  }

  if (pbCode[0] == 0xff && pbCode[1] == 0x25) {   // jmp [+imm32]

    // Looks like an import alias jump, then get the code it points to.

    // on x64 we have a 32-bit offset...

    PBYTE pbTarget = *(PBYTE*)(pbCode + 6 + *(INT32 *)&pbCode[2]);

    if (detour_is_imported(pbCode, pbTarget)) {

      PBYTE pbNew = *(PBYTE *)pbTarget;

      DETOUR_TRACE(("%p->%p: skipped over import table./n", pbCode, pbNew));


      return pbNew;

    }

    return detour_skip_jmp(pbTarget, ppGlobals);

  }

  else if (pbCode[0] == 0xe9) {   // jmp + rel32, Near jump with the target

    /*

    SEH64!ILT+15(?CallThatFunctionYAHXZ):

    00000000`00401014 e957000000      jmp     SEH64!CallThatFunction (000000
00`00401070)

    SEH64!CallThatFunction [d:/study/win64/seh64/seh64.cpp @ 11]:

    00000000`00401070 4057            push    rdi

    00000000`00401072 4883ec40        sub     rsp,40h

    00000000`00401076 488bfc          mov     rdi,rsp

    */

    PBYTE pbNew = pbCode + 5 + *(INT32 *)&pbCode[1];

    return detour_skip_jmp(pbNew, ppGlobals);

  }

  else if (pbCode[0] == 0xeb) {   // jmp +imm8

    // These just started appearing with CL13.

    PBYTE pbNew = pbCode + 2 + *(CHAR *)&pbCode[1];

    return detour_skip_jmp(pbNew, ppGlobals);

  }

  return pbCode;

}

知道入口后,detours会调用DetourCopyInstructionEx复制入口处代码
其根据字节可能代表的指令,把相关信息放到s_rceCopyTable表中
x64下需要修改的是从0x40到0x4f这几个入口,x64指令集中用他们
作为REX前缀,详细说明参见AMD architecture programmer manual volume 3
1.2.7 REX Prefixes 小节中有详细讨论,这儿全部当成单字节前缀即可

#ifdef DETOURS_X64 // For Rex Prefix
    { 0x40, ENTRY_CopyBytesPrefix },                    // REX Prefixes
    { 0x41, ENTRY_CopyBytesPrefix },                    // REX Prefixes
    { 0x42, ENTRY_CopyBytesPrefix },                    // REX Prefixes

    { 0x43, ENTRY_CopyBytesPrefix },                    // REX Prefixes
    { 0x44, ENTRY_CopyBytesPrefix },                    // REX Prefixes
    { 0x45, ENTRY_CopyBytesPrefix },                    // REX Prefixes
    { 0x46, ENTRY_CopyBytesPrefix },                    // REX Prefixes
    { 0x47, ENTRY_CopyBytesPrefix },                    // REX Prefixes
    { 0x48, ENTRY_CopyBytesPrefix },                    // REX Prefixes
    { 0x49, ENTRY_CopyBytesPrefix },                    // REX Prefixes
    { 0x4A, ENTRY_CopyBytesPrefix },                    // REX Prefixes
    { 0x4B, ENTRY_CopyBytesPrefix },                    // REX Prefixes
    { 0x4C, ENTRY_CopyBytesPrefix },                    // REX Prefixes
    { 0x4D, ENTRY_CopyBytesPrefix },                    // REX Prefixes
    { 0x4E, ENTRY_CopyBytesPrefix },                    // REX Prefixes
    { 0x4F, ENTRY_CopyBytesPrefix },                    // REX Prefixes
#else

而对FF开始的far indirect jmp/call 指令,x64也跟x86不同

PBYTE CDetourDis::CopyFF(REFCOPYENTRY pEntry, PBYTE pbDst, PBYTE pbSrc)

{   // CALL /2

    // CALL /3

    // INC /0

    // JMP /4

    // JMP /5

    // PUSH /6

    (void)pEntry;

    if (0x15 == pbSrc[1] || 0x25 == pbSrc[1]) {         // CALL [], JMP []

#ifdef DETOURS_X64

        DWORD dwOffset = *((PDWORD)&pbSrc[2]);

        *m_ppbTarget = (PBYTE)*((PDWORD_PTR)(pbSrc + 6 + dwOffset));

#else

        PBYTE *ppbTarget = *(PBYTE**)&pbSrc[2];

        *m_ppbTarget = *ppbTarget;

#endif

    }

    else if (0x10 == (0x38 & pbSrc[1]) || // CALL /2 --> reg(bits 543) of Mo
dR/M == 010

             0x18 == (0x38 & pbSrc[1]) || // CALL /3 --> reg(bits 543) of Mo
dR/M == 011

             0x20 == (0x38 & pbSrc[1]) || // JMP /4 --> reg(bits 543) of Mod
R/M == 100

             0x28 == (0x38 & pbSrc[1])    // JMP /5 --> reg(bits 543) of Mod
R/M == 101

            ) {

        *m_ppbTarget = (PBYTE)DETOUR_INSTRUCTION_TARGET_DYNAMIC;

    }

    const COPYENTRY ce = { 0xff, ENTRY_CopyBytes2Mod };

    return (this->*ce.pfCopy)(&ce, pbDst, pbSrc);

}

拷贝了原始指令到跳板后,需要在后面增加跳回剩余指令的jmp
x86下面detours直接用detour_gen_jmp_immediate函数生成指令
但在x64下面需要修改,因为x64下面指针是64位的,
如果目标地址在当前地址前后2G范围内,可以用32位偏移跳转
否则必须把地址放到内存中,然后在jmp指令指定保存地址的位置

detours在通过detour_alloc_trampoline函数分配跳板内存时
会尽量尝试把内存分配在目标函数2G范围内,避免长跳转指令
这样可以确保目标函数大于5字节(near jmp) 时都能工作
但这样一来就无法确保跳板跟hook函数的位置在2G内,
所以x64下面必须处理这些情况,同理照抄mhook代码如下

inline PBYTE detour_gen_jmp(PBYTE pbCode, PBYTE pbJumpTo)

{

  PBYTE pbJumpFrom = pbCode + 5;

  SIZE_T cbDiff = pbJumpFrom > pbJumpTo ? pbJumpFrom - pbJumpTo : pbJumpTo -
 pbJumpFrom;

  if (cbDiff <= 0x7fff0000) {

    *pbCode++ = 0xe9;

    *((PDWORD)pbCode) = (DWORD)(DWORD_PTR)(pbJumpTo - pbJumpFrom);

    pbCode += sizeof(DWORD);

  } else {

    *pbCode++ = 0xff;

    *pbCode++ = 0x25;

    // on x64 we write the relative address of the same location

    *((PDWORD)pbCode) = (DWORD)0;

    pbCode += sizeof(DWORD);

    

    *((PDWORD_PTR)pbCode) = (DWORD_PTR)(pbJumpTo);

    pbCode += sizeof(DWORD_PTR);

  }

  return pbCode;

}

除此之外,还有一些异常情况的处理,例如暂停线程时,
其RIP刚好在跳板或者目标函数入口处,理论上可以使用
与x86相同的机制,不过暂时没法构造环境测试

#ifdef DETOURS_X64

#define DETOURS_EIP         Rip
#define DETOURS_EIP_TYPE    DWORD64

#endif // DETOURS_X64

最后还有一些跟细节的处理,例如对ModRm下RIP的处理
回头加上再一起放出完整可用的代码吧

Reference

1. Microsoft Research Detours Package
   http://research.microsoft.com/research/downloads/Details/d36340fb-4d3c-4ddd-bf5b-1db25d03713d/Details.aspx

2. Mhook, an API hooking library, V2.0
   http://codefromthe70s.org/mhook2.asp

3. AMD64 Architecture Programmer’s Manual Volume 3: General-Purpose and System Instructions

4. Everything You Need To Know To Start Programming 64-Bit Windows Systems, Matt Pietrek
   http://msdn.microsoft.com/msdnmag/issues/06/05/x64/default.aspx?print=true&loc=null
 .    生命的意义在于   //   ____/ //_ /   //_/     http://flier_lu.blogcn.com .                          
 .        希望         / /  /___/_/// /   //_/__     __    _ _★              .
 .        工作          / /   ____// / /    //  /  /'__`/ //`'_/              .
 .      爱你的人         / /  /___/ / / /___/ /  /// __// / / //              .
 .     和你爱的人         / /___/    / /_____/ /__/ /____/ / /_/              .
 .        ……             //___/     //_____///__///____/  //_/.lu@gmail.com .


※ 修改:·flier 于 Aug  3 01:01:35 修改本文·[FROM: 221.226.232.*]
※ 来源:·水木社区 newsmth.net·[FROM: 221.226.232.*]

 

[本篇全文] [本篇作者:FreeWizard] [进入讨论区] [返回顶部]
2
发信人: FreeWizard (  ), 信区: MSDN
标  题: Re: Detours x64 [Draft]
发信站: 水木社区 (Fri Aug  3 01:02:58 2007), 站内

orz
先re再看

【 在 flier (小海 [渴望并不存在的完美]) 的大作中提到: 】
: 该死的路径依赖,为了折腾另外一个问题,不得不先把这个搞定 :S
: Detours我就不介绍了,MSR放出的2.1 Express版本不支持64位
: 而据某人发邮件问,要10000刀才给授权,基本也不用想了 -_-b
: ...................

--

※ 来源:·水木社区 newsmth.net·[FROM: 221.221.18.159]

 

[本篇全文] [本篇作者:flier] [进入讨论区] [返回顶部]
3
发信人: flier (小海 [渴望并不存在的完美]), 信区: MSDN
标  题: Re: Detours x64 [Draft]
发信站: 水木社区 (Fri Aug  3 01:11:16 2007), 站内

编译了一下 detours 那个 dtest 例子,代码完全不受影响,设置一下库就行
这个是vs2005编译后的调试版本,可以用windbg看看,呵呵,xp pro x64 下测试通过

【 在 flier (小海 [渴望并不存在的完美]) 的大作中提到: 】
: 该死的路径依赖,为了折腾另外一个问题,不得不先把这个搞定 :S
: Detours我就不介绍了,MSR放出的2.1 Express版本不支持64位
: 而据某人发邮件问,要10000刀才给授权,基本也不用想了 -_-b
: ...................



--
 .    生命的意义在于   //   ____/ //_ /   //_/     http://flier_lu.blogcn.com .                          
 .        希望         / /  /___/_/// /   //_/__     __    _ _★              .
 .        工作          / /   ____// / /    //  /  /'__`/ //`'_/              .
 .      爱你的人         / /  /___/ / / /___/ /  /// __// / / //              .
 .     和你爱的人         / /___/    / /_____/ /__/ /____/ / /_/              .
 .        ……             //___/     //_____///__///____/  //_/.lu@gmail.com .


※ 来源:·水木社区 http://newsmth.net·[FROM: 221.226.232.*]


附件: Debug64.rar (237KB)

附件: pdb.rar (634KB)

 

[本篇全文] [本篇作者:peach] [进入讨论区] [返回顶部]
4
发信人: peach (换台机器挂站), 信区: MSDN
标  题: Re: Detours x64 [Draft]
发信站: 水木社区 (Fri Aug  3 08:32:21 2007), 站内

最近也折腾了一些这方面的东西,但不是64位的

有些想法,正好拿出来

API HOOK 还可以用另外一种方法,虽然也会用到 detours 相关的技术,不过性能上有不少折扣

这种方法的核心思想就是使用 SEH,在需要 HOOK 的 API 入口处,改成一个  user break point 即可,这时候只要接管 SEH 处理函数即可,在 SEH 处理函数中,你可以修改 CONTEXT::Eip 以及其他寄存器来达到改变程序的流程的目的。

这时候有两个问题,
1、API入口的第一条指令。
   a) 绝对跳转之类的指令(jmp, call)。将 user break point 移至跳转到的地址处。
   b) 条件跳转。这种情况似乎很少见
   c) 其他指令。移走,在其他地方执行。

2、如何接管 SEH 处理函数。
   Detours 中有 DetourFirstChanceExceptionFilter,可以让你在第一时间处理所发生的异常。

如果需要 HOOK 的 API 不是很多,user break point 都不用加,用硬件调试寄存器就可以完成了。


【 在 flier (小海 [渴望并不存在的完美]) 的大作中提到: 】
: 标  题: Detours x64 [Draft]
: 发信站: 水木社区 (Fri Aug  3 01:01:07 2007), 站内
:
: 该死的路径依赖,为了折腾另外一个问题,不得不先把这个搞定 :S
:
: Detours我就不介绍了,MSR放出的2.1 Express版本不支持64位
: 而据某人发邮件问,要10000刀才给授权,基本也不用想了 -_-b
:
: 于是乎在此基础上修修补补,基本能在x64下跑起来
: 因为还有些bug,暂时不放完整版本出来,大概说说流程
:
: API Hook 基本已经是大白菜级技术,无非就是找到函数入口点
: 替换前面几个字节为jmp,重定向到一个跳板,完成工作再跳回去
: 详细的流程请参考detours的代码,下面捡x64下不一样的说
:
: 首先是在DetourAttachEx时找到原始函数和Hook函数的真实代码入口点
: 可能需要跳过import表,或者调试用间接跳转指令啥的,
: detours.cpp里detour_skip_jmp函数就是干这个的,
: 不过在x64下需要做一些调整,因为某些指令的数据长度跟x86不同
: 这块代码我基本照抄mhook的实现,比detours增加了嵌套检查
:
:
:
: inline PBYTE detour_skip_jmp(PBYTE pbCode, PVOID *ppGlobals)
:
: {
:
:   if (pbCode == NULL) {
:
:     return NULL;
:
:   }
:
:   if (ppGlobals != NULL) {
:
:     *ppGlobals = NULL;
:
:   }
:
:   if (pbCode[0] == 0xff && pbCode[1] == 0x25) {   // jmp [+imm32]
:
:     // Looks like an import alias jump, then get the code it points to.
:
:     // on x64 we have a 32-bit offset...
:
:     PBYTE pbTarget = *(PBYTE*)(pbCode + 6 + *(INT32 *)&pbCode[2]);
:
:     if (detour_is_imported(pbCode, pbTarget)) {
:
:       PBYTE pbNew = *(PBYTE *)pbTarget;
:
:       DETOUR_TRACE(("%p->%p: skipped over import table./n", pbCode, pbNew));
:
:
:       return pbNew;
:
:     }
:
:     return detour_skip_jmp(pbTarget, ppGlobals);
:
:   }
:
:   else if (pbCode[0] == 0xe9) {   // jmp + rel32, Near jump with the target
:
:     /*
:
:     SEH64!ILT+15(?CallThatFunctionYAHXZ):
:
:     00000000`00401014 e957000000      jmp     SEH64!CallThatFunction (000000
: 00`00401070)
:
:     SEH64!CallThatFunction [d:/study/win64/seh64/seh64.cpp @ 11]:
:
:     00000000`00401070 4057            push    rdi
:
:     00000000`00401072 4883ec40        sub     rsp,40h
:
:     00000000`00401076 488bfc          mov     rdi,rsp
:
:     */
:
:     PBYTE pbNew = pbCode + 5 + *(INT32 *)&pbCode[1];
:
:     return detour_skip_jmp(pbNew, ppGlobals);
:
:   }
:
:   else if (pbCode[0] == 0xeb) {   // jmp +imm8
:
:     // These just started appearing with CL13.
:
:     PBYTE pbNew = pbCode + 2 + *(CHAR *)&pbCode[1];
:
:     return detour_skip_jmp(pbNew, ppGlobals);
:
:   }
:
:   return pbCode;
:
: }
:
: 知道入口后,detours会调用DetourCopyInstructionEx复制入口处代码
: 其根据字节可能代表的指令,把相关信息放到s_rceCopyTable表中
: x64下需要修改的是从0x40到0x4f这几个入口,x64指令集中用他们
: 作为REX前缀,详细说明参见AMD architecture programmer manual volume 3
: 1.2.7 REX Prefixes 小节中有详细讨论,这儿全部当成单字节前缀即可
:
: #ifdef DETOURS_X64 // For Rex Prefix
:     { 0x40, ENTRY_CopyBytesPrefix },                    // REX Prefixes
:     { 0x41, ENTRY_CopyBytesPrefix },                    // REX Prefixes
:     { 0x42, ENTRY_CopyBytesPrefix },                    // REX Prefixes
:
:     { 0x43, ENTRY_CopyBytesPrefix },                    // REX Prefixes
:     { 0x44, ENTRY_CopyBytesPrefix },                    // REX Prefixes
:     { 0x45, ENTRY_CopyBytesPrefix },                    // REX Prefixes
:     { 0x46, ENTRY_CopyBytesPrefix },                    // REX Prefixes
:     { 0x47, ENTRY_CopyBytesPrefix },                    // REX Prefixes
:     { 0x48, ENTRY_CopyBytesPrefix },                    // REX Prefixes
:     { 0x49, ENTRY_CopyBytesPrefix },                    // REX Prefixes
:     { 0x4A, ENTRY_CopyBytesPrefix },                    // REX Prefixes
:     { 0x4B, ENTRY_CopyBytesPrefix },                    // REX Prefixes
:     { 0x4C, ENTRY_CopyBytesPrefix },                    // REX Prefixes
:     { 0x4D, ENTRY_CopyBytesPrefix },                    // REX Prefixes
:     { 0x4E, ENTRY_CopyBytesPrefix },                    // REX Prefixes
:     { 0x4F, ENTRY_CopyBytesPrefix },                    // REX Prefixes
: #else
:
: 而对FF开始的far indirect jmp/call 指令,x64也跟x86不同
:
: PBYTE CDetourDis::CopyFF(REFCOPYENTRY pEntry, PBYTE pbDst, PBYTE pbSrc)
:
: {   // CALL /2
:
:     // CALL /3
:
:     // INC /0
:
:     // JMP /4
:
:     // JMP /5
:
:     // PUSH /6
:
:     (void)pEntry;
:
:     if (0x15 == pbSrc[1] || 0x25 == pbSrc[1]) {         // CALL [], JMP []
:
: #ifdef DETOURS_X64
:
:         DWORD dwOffset = *((PDWORD)&pbSrc[2]);
:
:         *m_ppbTarget = (PBYTE)*((PDWORD_PTR)(pbSrc + 6 + dwOffset));
:
: #else
:
:         PBYTE *ppbTarget = *(PBYTE**)&pbSrc[2];
:
:         *m_ppbTarget = *ppbTarget;
:
: #endif
:
:     }
:
:     else if (0x10 == (0x38 & pbSrc[1]) || // CALL /2 --> reg(bits 543) of Mo
: dR/M == 010
:
:              0x18 == (0x38 & pbSrc[1]) || // CALL /3 --> reg(bits 543) of Mo
: dR/M == 011
:
:              0x20 == (0x38 & pbSrc[1]) || // JMP /4 --> reg(bits 543) of Mod
: R/M == 100
:
:              0x28 == (0x38 & pbSrc[1])    // JMP /5 --> reg(bits 543) of Mod
: R/M == 101
:
:             ) {
:
:         *m_ppbTarget = (PBYTE)DETOUR_INSTRUCTION_TARGET_DYNAMIC;
:
:     }
:
:     const COPYENTRY ce = { 0xff, ENTRY_CopyBytes2Mod };
:
:     return (this->*ce.pfCopy)(&ce, pbDst, pbSrc);
:
: }
:
: 拷贝了原始指令到跳板后,需要在后面增加跳回剩余指令的jmp
: x86下面detours直接用detour_gen_jmp_immediate函数生成指令
: 但在x64下面需要修改,因为x64下面指针是64位的,
: 如果目标地址在当前地址前后2G范围内,可以用32位偏移跳转
: 否则必须把地址放到内存中,然后在jmp指令指定保存地址的位置
:
: detours在通过detour_alloc_trampoline函数分配跳板内存时
: 会尽量尝试把内存分配在目标函数2G范围内,避免长跳转指令
: 这样可以确保目标函数大于5字节(near jmp) 时都能工作
: 但这样一来就无法确保跳板跟hook函数的位置在2G内,
: 所以x64下面必须处理这些情况,同理照抄mhook代码如下
:
: inline PBYTE detour_gen_jmp(PBYTE pbCode, PBYTE pbJumpTo)
:
: {
:
:   PBYTE pbJumpFrom = pbCode + 5;
:
:   SIZE_T cbDiff = pbJumpFrom > pbJumpTo ? pbJumpFrom - pbJumpTo : pbJumpTo -
:  pbJumpFrom;
:
:   if (cbDiff <= 0x7fff0000) {
:
:     *pbCode++ = 0xe9;
:
:     *((PDWORD)pbCode) = (DWORD)(DWORD_PTR)(pbJumpTo - pbJumpFrom);
:
:     pbCode += sizeof(DWORD);
:
:   } else {
:
:     *pbCode++ = 0xff;
:
:     *pbCode++ = 0x25;
:
:     // on x64 we write the relative address of the same location
:
:     *((PDWORD)pbCode) = (DWORD)0;
:
:     pbCode += sizeof(DWORD);
:
:    
:
:     *((PDWORD_PTR)pbCode) = (DWORD_PTR)(pbJumpTo);
:
:     pbCode += sizeof(DWORD_PTR);
:
:   }
:
:   return pbCode;
:
: }
:
: 除此之外,还有一些异常情况的处理,例如暂停线程时,
: 其RIP刚好在跳板或者目标函数入口处,理论上可以使用
: 与x86相同的机制,不过暂时没法构造环境测试
:
: #ifdef DETOURS_X64
:
: #define DETOURS_EIP         Rip
: #define DETOURS_EIP_TYPE    DWORD64
:
: #endif // DETOURS_X64
:
: 最后还有一些跟细节的处理,例如对ModRm下RIP的处理
: 回头加上再一起放出完整可用的代码吧
:
: Reference
:
: 1. Microsoft Research Detours Package
:    http://research.microsoft.com/research/downloads/Details/d36340fb-4d3c-4ddd-bf5b-1db25d03713d/Details.aspx
:
: 2. Mhook, an API hooking library, V2.0
:    http://codefromthe70s.org/mhook2.asp
:
: 3. AMD64 Architecture Programmer’s Manual Volume 3: General-Purpose and System Instructions
:
: 4. Everything You Need To Know To Start Programming 64-Bit Windows Systems, Matt Pietrek
:    http://msdn.microsoft.com/msdnmag/issues/06/05/x64/default.aspx?print=true&loc=null
:  .    生命的意义在于   //   ____/ //_ /   //_/     http://flier_lu.blogcn.com .                          
:  .        希望         / /  /___/_/// /   //_/__     __    _ _★              .
:  .        工作          / /   ____// / /    //  /  /'__`/ //`'_/              .
:  .      爱你的人         / /  /___/ / / /___/ /  /// __// / / //              .
:  .     和你爱的人         / /___/    / /_____/ /__/ /____/ / /_/              .
:  .        ……             //___/     //_____///__///____/  //_/.lu@gmail.com .
:
:
: ※ 修改:·flier 于 Aug  3 01:01:35 修改本文·[FROM: 221.226.232.*]
: ※ 来源:·水木社区 newsmth.net·[FROM: 221.226.232.*]


--

※ 来源:·水木社区 newsmth.net·[FROM: 166.111.8.*]

 

[本篇全文] [本篇作者:bbinn] [进入讨论区] [返回顶部]
5
发信人: bbinn (明天的明天), 信区: MSDN
标  题: Re: Detours x64 [Draft]
发信站: 水木社区 (Fri Aug  3 08:55:39 2007), 站内




【 在 flier (小海 [渴望并不存在的完美]) 的大作中提到: 】
: 标  题: Detours x64 [Draft]
: 发信站: 水木社区 (Fri Aug  3 01:01:07 2007), 站内
:
: 该死的路径依赖,为了折腾另外一个问题,不得不先把这个搞定 :S
:
: Detours我就不介绍了,MSR放出的2.1 Express版本不支持64位
: 而据某人发邮件问,要10000刀才给授权,基本也不用想了 -_-b
:
: 于是乎在此基础上修修补补,基本能在x64下跑起来
: 因为还有些bug,暂时不放完整版本出来,大概说说流程
:
: API Hook 基本已经是大白菜级技术,无非就是找到函数入口点
: 替换前面几个字节为jmp,重定向到一个跳板,完成工作再跳回去
: 详细的流程请参考detours的代码,下面捡x64下不一样的说
:
: 首先是在DetourAttachEx时找到原始函数和Hook函数的真实代码入口点
: 可能需要跳过import表,或者调试用间接跳转指令啥的,
: detours.cpp里detour_skip_jmp函数就是干这个的,
: 不过在x64下需要做一些调整,因为某些指令的数据长度跟x86不同
: 这块代码我基本照抄mhook的实现,比detours增加了嵌套检查
:
:
:
: inline PBYTE detour_skip_jmp(PBYTE pbCode, PVOID *ppGlobals)
:
: {
:
:   if (pbCode == NULL) {
:
:     return NULL;
:
:   }
:
:   if (ppGlobals != NULL) {
:
:     *ppGlobals = NULL;
:
:   }
:
:   if (pbCode[0] == 0xff && pbCode[1] == 0x25) {   // jmp [+imm32]
:
:     // Looks like an import alias jump, then get the code it points to.
:
:     // on x64 we have a 32-bit offset...
:
:     PBYTE pbTarget = *(PBYTE*)(pbCode + 6 + *(INT32 *)&pbCode[2]);
:
:     if (detour_is_imported(pbCode, pbTarget)) {
:
:       PBYTE pbNew = *(PBYTE *)pbTarget;
:
:       DETOUR_TRACE(("%p->%p: skipped over import table./n", pbCode, pbNew));
:
:
:       return pbNew;
:
:     }
:
:     return detour_skip_jmp(pbTarget, ppGlobals);
:
:   }
:
:   else if (pbCode[0] == 0xe9) {   // jmp + rel32, Near jump with the target
:
:     /*
:
:     SEH64!ILT+15(?CallThatFunctionYAHXZ):
:
:     00000000`00401014 e957000000      jmp     SEH64!CallThatFunction (000000
: 00`00401070)
:
:     SEH64!CallThatFunction [d:/study/win64/seh64/seh64.cpp @ 11]:
:
:     00000000`00401070 4057            push    rdi
:
:     00000000`00401072 4883ec40        sub     rsp,40h
:
:     00000000`00401076 488bfc          mov     rdi,rsp
:
:     */
:
:     PBYTE pbNew = pbCode + 5 + *(INT32 *)&pbCode[1];
:
:     return detour_skip_jmp(pbNew, ppGlobals);
:
:   }
:
:   else if (pbCode[0] == 0xeb) {   // jmp +imm8
:
:     // These just started appearing with CL13.
:
:     PBYTE pbNew = pbCode + 2 + *(CHAR *)&pbCode[1];
:
:     return detour_skip_jmp(pbNew, ppGlobals);
:
:   }
:
:   return pbCode;
:
: }
:
: 知道入口后,detours会调用DetourCopyInstructionEx复制入口处代码
: 其根据字节可能代表的指令,把相关信息放到s_rceCopyTable表中
: x64下需要修改的是从0x40到0x4f这几个入口,x64指令集中用他们
: 作为REX前缀,详细说明参见AMD architecture programmer manual volume 3
: 1.2.7 REX Prefixes 小节中有详细讨论,这儿全部当成单字节前缀即可
:
: #ifdef DETOURS_X64 // For Rex Prefix
:     { 0x40, ENTRY_CopyBytesPrefix },                    // REX Prefixes
:     { 0x41, ENTRY_CopyBytesPrefix },                    // REX Prefixes
:     { 0x42, ENTRY_CopyBytesPrefix },                    // REX Prefixes
:
:     { 0x43, ENTRY_CopyBytesPrefix },                    // REX Prefixes
:     { 0x44, ENTRY_CopyBytesPrefix },                    // REX Prefixes
:     { 0x45, ENTRY_CopyBytesPrefix },                    // REX Prefixes
:     { 0x46, ENTRY_CopyBytesPrefix },                    // REX Prefixes
:     { 0x47, ENTRY_CopyBytesPrefix },                    // REX Prefixes
:     { 0x48, ENTRY_CopyBytesPrefix },                    // REX Prefixes
:     { 0x49, ENTRY_CopyBytesPrefix },                    // REX Prefixes
:     { 0x4A, ENTRY_CopyBytesPrefix },                    // REX Prefixes
:     { 0x4B, ENTRY_CopyBytesPrefix },                    // REX Prefixes
:     { 0x4C, ENTRY_CopyBytesPrefix },                    // REX Prefixes
:     { 0x4D, ENTRY_CopyBytesPrefix },                    // REX Prefixes
:     { 0x4E, ENTRY_CopyBytesPrefix },                    // REX Prefixes
:     { 0x4F, ENTRY_CopyBytesPrefix },                    // REX Prefixes
: #else
:
: 而对FF开始的far indirect jmp/call 指令,x64也跟x86不同
:
: PBYTE CDetourDis::CopyFF(REFCOPYENTRY pEntry, PBYTE pbDst, PBYTE pbSrc)
:
: {   // CALL /2
:
:     // CALL /3
:
:     // INC /0
:
:     // JMP /4
:
:     // JMP /5
:
:     // PUSH /6
:
:     (void)pEntry;
:
:     if (0x15 == pbSrc[1] || 0x25 == pbSrc[1]) {         // CALL [], JMP []
:
: #ifdef DETOURS_X64
:
:         DWORD dwOffset = *((PDWORD)&pbSrc[2]);
:
:         *m_ppbTarget = (PBYTE)*((PDWORD_PTR)(pbSrc + 6 + dwOffset));
:
: #else
:
:         PBYTE *ppbTarget = *(PBYTE**)&pbSrc[2];
:
:         *m_ppbTarget = *ppbTarget;
:
: #endif
:
:     }
:
:     else if (0x10 == (0x38 & pbSrc[1]) || // CALL /2 --> reg(bits 543) of Mo
: dR/M == 010
:
:              0x18 == (0x38 & pbSrc[1]) || // CALL /3 --> reg(bits 543) of Mo
: dR/M == 011
:
:              0x20 == (0x38 & pbSrc[1]) || // JMP /4 --> reg(bits 543) of Mod
: R/M == 100
:
:              0x28 == (0x38 & pbSrc[1])    // JMP /5 --> reg(bits 543) of Mod
: R/M == 101
:
:             ) {
:
:         *m_ppbTarget = (PBYTE)DETOUR_INSTRUCTION_TARGET_DYNAMIC;
:
:     }
:
:     const COPYENTRY ce = { 0xff, ENTRY_CopyBytes2Mod };
:
:     return (this->*ce.pfCopy)(&ce, pbDst, pbSrc);
:
: }
:
: 拷贝了原始指令到跳板后,需要在后面增加跳回剩余指令的jmp
: x86下面detours直接用detour_gen_jmp_immediate函数生成指令
: 但在x64下面需要修改,因为x64下面指针是64位的,
: 如果目标地址在当前地址前后2G范围内,可以用32位偏移跳转
: 否则必须把地址放到内存中,然后在jmp指令指定保存地址的位置
:
: detours在通过detour_alloc_trampoline函数分配跳板内存时
: 会尽量尝试把内存分配在目标函数2G范围内,避免长跳转指令
: 这样可以确保目标函数大于5字节(near jmp) 时都能工作
: 但这样一来就无法确保跳板跟hook函数的位置在2G内,
: 所以x64下面必须处理这些情况,同理照抄mhook代码如下
:
: inline PBYTE detour_gen_jmp(PBYTE pbCode, PBYTE pbJumpTo)
:
: {
:
:   PBYTE pbJumpFrom = pbCode + 5;
:
:   SIZE_T cbDiff = pbJumpFrom > pbJumpTo ? pbJumpFrom - pbJumpTo : pbJumpTo -
:  pbJumpFrom;
:
:   if (cbDiff <= 0x7fff0000) {
:
:     *pbCode++ = 0xe9;
:
:     *((PDWORD)pbCode) = (DWORD)(DWORD_PTR)(pbJumpTo - pbJumpFrom);
:
:     pbCode += sizeof(DWORD);
:
:   } else {
:
:     *pbCode++ = 0xff;
:
:     *pbCode++ = 0x25;
:
:     // on x64 we write the relative address of the same location
:
:     *((PDWORD)pbCode) = (DWORD)0;
:
:     pbCode += sizeof(DWORD);
:
:    
:
:     *((PDWORD_PTR)pbCode) = (DWORD_PTR)(pbJumpTo);
:
:     pbCode += sizeof(DWORD_PTR);
:
:   }
:
:   return pbCode;
:
: }
:
: 除此之外,还有一些异常情况的处理,例如暂停线程时,
: 其RIP刚好在跳板或者目标函数入口处,理论上可以使用
: 与x86相同的机制,不过暂时没法构造环境测试
:
: #ifdef DETOURS_X64
:
: #define DETOURS_EIP         Rip
: #define DETOURS_EIP_TYPE    DWORD64
:
: #endif // DETOURS_X64
:
: 最后还有一些跟细节的处理,例如对ModRm下RIP的处理
: 回头加上再一起放出完整可用的代码吧
:
: Reference
:
: 1. Microsoft Research Detours Package
:    http://research.microsoft.com/research/downloads/Details/d36340fb-4d3c-4ddd-bf5b-1db25d03713d/Details.aspx
:
: 2. Mhook, an API hooking library, V2.0
:    http://codefromthe70s.org/mhook2.asp
:
: 3. AMD64 Architecture Programmer’s Manual Volume 3: General-Purpose and System Instructions
:
: 4. Everything You Need To Know To Start Programming 64-Bit Windows Systems, Matt Pietrek
:    http://msdn.microsoft.com/msdnmag/issues/06/05/x64/default.aspx?print=true&loc=null
:  .    生命的意义在于   //   ____/ //_ /   //_/     http://flier_lu.blogcn.com .                          
:  .        希望         / /  /___/_/// /   //_/__     __    _ _★              .
:  .        工作          / /   ____// / /    //  /  /'__`/ //`'_/              .
:  .      爱你的人         / /  /___/ / / /___/ /  /// __// / / //              .
:  .     和你爱的人         / /___/    / /_____/ /__/ /____/ / /_/              .
:  .        ……             //___/     //_____///__///____/  //_/.lu@gmail.com .
:
:
: ※ 修改:·flier 于 Aug  3 01:01:35 修改本文·[FROM: 221.226.232.*]
: ※ 来源:·水木社区 newsmth.net·[FROM: 221.226.232.*]


--
-                     不谈金钱,不谈妇女,不谈琐事


※ 来源:·水木社区 newsmth.net·[FROM: 219.232.52.*]

 

[本篇全文] [本篇作者:bbinn] [进入讨论区] [返回顶部]
6
发信人: bbinn (明天的明天), 信区: MSDN
标  题: Re: Detours x64 [Draft]
发信站: 水木社区 (Fri Aug  3 08:58:20 2007), 站内

太赞了,我现在就在折腾这个。
不过OLE嵌入的时候你这招就不管用了,debug break会先被csrss.exe捕获到,
然后就直接认为嵌入失败,然后进程就suspend了。


【 在 peach (换台机器挂站) 的大作中提到: 】
: 标  题: Re: Detours x64 [Draft]
: 发信站: 水木社区 (Fri Aug  3 08:32:21 2007), 站内
:
: 最近也折腾了一些这方面的东西,但不是64位的
:
: 有些想法,正好拿出来
:
: API HOOK 还可以用另外一种方法,虽然也会用到 detours 相关的技术,不过性能上有不少折扣
:
: 这种方法的核心思想就是使用 SEH,在需要 HOOK 的 API 入口处,改成一个  user break point 即可,这时候只要接管 SEH 处理函数即可,在 SEH 处理函数中,你可以修改 CONTEXT::Eip 以及其他寄存器来达到改变程序的流程的目的。
:
: 这时候有两个问题,
: 1、API入口的第一条指令。
:    a) 绝对跳转之类的指令(jmp, call)。将 user break point 移至跳转到的地址处。
:    b) 条件跳转。这种情况似乎很少见
:    c) 其他指令。移走,在其他地方执行。
:
: 2、如何接管 SEH 处理函数。
:    Detours 中有 DetourFirstChanceExceptionFilter,可以让你在第一时间处理所发生的异常。
:
: 如果需要 HOOK 的 API 不是很多,user break point 都不用加,用硬件调试寄存器就可以完成了。
:
:
: 【 在 flier (小海 [渴望并不存在的完美]) 的大作中提到: 】
: : 标  题: Detours x64 [Draft]
: : 发信站: 水木社区 (Fri Aug  3 01:01:07 2007), 站内
: :
: : 该死的路径依赖,为了折腾另外一个问题,不得不先把这个搞定 :S
: :
: : Detours我就不介绍了,MSR放出的2.1 Express版本不支持64位
: : 而据某人发邮件问,要10000刀才给授权,基本也不用想了 -_-b
: :
: : 于是乎在此基础上修修补补,基本能在x64下跑起来
: : 因为还有些bug,暂时不放完整版本出来,大概说说流程
: :
: : API Hook 基本已经是大白菜级技术,无非就是找到函数入口点
: : 替换前面几个字节为jmp,重定向到一个跳板,完成工作再跳回去
: : 详细的流程请参考detours的代码,下面捡x64下不一样的说
: :
: : 首先是在DetourAttachEx时找到原始函数和Hook函数的真实代码入口点
: : 可能需要跳过import表,或者调试用间接跳转指令啥的,
: : detours.cpp里detour_skip_jmp函数就是干这个的,
: : 不过在x64下需要做一些调整,因为某些指令的数据长度跟x86不同
: : 这块代码我基本照抄mhook的实现,比detours增加了嵌套检查
: :
: :
: :
: : inline PBYTE detour_skip_jmp(PBYTE pbCode, PVOID *ppGlobals)
: :
: : {
: :
: :   if (pbCode == NULL) {
: :
: :     return NULL;
: :
: :   }
: :
: :   if (ppGlobals != NULL) {
: :
: :     *ppGlobals = NULL;
: :
: :   }
: :
: :   if (pbCode[0] == 0xff && pbCode[1] == 0x25) {   // jmp [+imm32]
: :
: :     // Looks like an import alias jump, then get the code it points to.
: :
: :     // on x64 we have a 32-bit offset...
: :
: :     PBYTE pbTarget = *(PBYTE*)(pbCode + 6 + *(INT32 *)&pbCode[2]);
: :
: :     if (detour_is_imported(pbCode, pbTarget)) {
: :
: :       PBYTE pbNew = *(PBYTE *)pbTarget;
: :
: :       DETOUR_TRACE(("%p->%p: skipped over import table./n", pbCode, pbNew));
: :
: :
: :       return pbNew;
: :
: :     }
: :
: :     return detour_skip_jmp(pbTarget, ppGlobals);
: :
: :   }
: :
: :   else if (pbCode[0] == 0xe9) {   // jmp + rel32, Near jump with the target
: :
: :     /*
: :
: :     SEH64!ILT+15(?CallThatFunctionYAHXZ):
: :
: :     00000000`00401014 e957000000      jmp     SEH64!CallThatFunction (000000
: : 00`00401070)
: :
: :     SEH64!CallThatFunction [d:/study/win64/seh64/seh64.cpp @ 11]:
: :
: :     00000000`00401070 4057            push    rdi
: :
: :     00000000`00401072 4883ec40        sub     rsp,40h
: :
: :     00000000`00401076 488bfc          mov     rdi,rsp
: :
: :     */
: :
: :     PBYTE pbNew = pbCode + 5 + *(INT32 *)&pbCode[1];
: :
: :     return detour_skip_jmp(pbNew, ppGlobals);
: :
: :   }
: :
: :   else if (pbCode[0] == 0xeb) {   // jmp +imm8
: :
: :     // These just started appearing with CL13.
: :
: :     PBYTE pbNew = pbCode + 2 + *(CHAR *)&pbCode[1];
: :
: :     return detour_skip_jmp(pbNew, ppGlobals);
: :
: :   }
: :
: :   return pbCode;
: :
: : }
: :
: : 知道入口后,detours会调用DetourCopyInstructionEx复制入口处代码
: : 其根据字节可能代表的指令,把相关信息放到s_rceCopyTable表中
: : x64下需要修改的是从0x40到0x4f这几个入口,x64指令集中用他们
: : 作为REX前缀,详细说明参见AMD architecture programmer manual volume 3
: : 1.2.7 REX Prefixes 小节中有详细讨论,这儿全部当成单字节前缀即可
: :
: : #ifdef DETOURS_X64 // For Rex Prefix
: :     { 0x40, ENTRY_CopyBytesPrefix },                    // REX Prefixes
: :     { 0x41, ENTRY_CopyBytesPrefix },                    // REX Prefixes
: :     { 0x42, ENTRY_CopyBytesPrefix },                    // REX Prefixes
: :
: :     { 0x43, ENTRY_CopyBytesPrefix },                    // REX Prefixes
: :     { 0x44, ENTRY_CopyBytesPrefix },                    // REX Prefixes
: :     { 0x45, ENTRY_CopyBytesPrefix },                    // REX Prefixes
: :     { 0x46, ENTRY_CopyBytesPrefix },                    // REX Prefixes
: :     { 0x47, ENTRY_CopyBytesPrefix },                    // REX Prefixes
: :     { 0x48, ENTRY_CopyBytesPrefix },                    // REX Prefixes
: :     { 0x49, ENTRY_CopyBytesPrefix },                    // REX Prefixes
: :     { 0x4A, ENTRY_CopyBytesPrefix },                    // REX Prefixes
: :     { 0x4B, ENTRY_CopyBytesPrefix },                    // REX Prefixes
: :     { 0x4C, ENTRY_CopyBytesPrefix },                    // REX Prefixes
: :     { 0x4D, ENTRY_CopyBytesPrefix },                    // REX Prefixes
: :     { 0x4E, ENTRY_CopyBytesPrefix },                    // REX Prefixes
: :     { 0x4F, ENTRY_CopyBytesPrefix },                    // REX Prefixes
: : #else
: :
: : 而对FF开始的far indirect jmp/call 指令,x64也跟x86不同
: :
: : PBYTE CDetourDis::CopyFF(REFCOPYENTRY pEntry, PBYTE pbDst, PBYTE pbSrc)
: :
: : {   // CALL /2
: :
: :     // CALL /3
: :
: :     // INC /0
: :
: :     // JMP /4
: :
: :     // JMP /5
: :
: :     // PUSH /6
: :
: :     (void)pEntry;
: :
: :     if (0x15 == pbSrc[1] || 0x25 == pbSrc[1]) {         // CALL [], JMP []
: :
: : #ifdef DETOURS_X64
: :
: :         DWORD dwOffset = *((PDWORD)&pbSrc[2]);
: :
: :         *m_ppbTarget = (PBYTE)*((PDWORD_PTR)(pbSrc + 6 + dwOffset));
: :
: : #else
: :
: :         PBYTE *ppbTarget = *(PBYTE**)&pbSrc[2];
: :
: :         *m_ppbTarget = *ppbTarget;
: :
: : #endif
: :
: :     }
: :
: :     else if (0x10 == (0x38 & pbSrc[1]) || // CALL /2 --> reg(bits 543) of Mo
: : dR/M == 010
: :
: :              0x18 == (0x38 & pbSrc[1]) || // CALL /3 --> reg(bits 543) of Mo
: : dR/M == 011
: :
: :              0x20 == (0x38 & pbSrc[1]) || // JMP /4 --> reg(bits 543) of Mod
: : R/M == 100
: :
: :              0x28 == (0x38 & pbSrc[1])    // JMP /5 --> reg(bits 543) of Mod
: : R/M == 101
: :
: :             ) {
: :
: :         *m_ppbTarget = (PBYTE)DETOUR_INSTRUCTION_TARGET_DYNAMIC;
: :
: :     }
: :
: :     const COPYENTRY ce = { 0xff, ENTRY_CopyBytes2Mod };
: :
: :     return (this->*ce.pfCopy)(&ce, pbDst, pbSrc);
: :
: : }
: :
: : 拷贝了原始指令到跳板后,需要在后面增加跳回剩余指令的jmp
: : x86下面detours直接用detour_gen_jmp_immediate函数生成指令
: : 但在x64下面需要修改,因为x64下面指针是64位的,
: : 如果目标地址在当前地址前后2G范围内,可以用32位偏移跳转
: : 否则必须把地址放到内存中,然后在jmp指令指定保存地址的位置
: :
: : detours在通过detour_alloc_trampoline函数分配跳板内存时
: : 会尽量尝试把内存分配在目标函数2G范围内,避免长跳转指令
: : 这样可以确保目标函数大于5字节(near jmp) 时都能工作
: : 但这样一来就无法确保跳板跟hook函数的位置在2G内,
: : 所以x64下面必须处理这些情况,同理照抄mhook代码如下
: :
: : inline PBYTE detour_gen_jmp(PBYTE pbCode, PBYTE pbJumpTo)
: :
: : {
: :
: :   PBYTE pbJumpFrom = pbCode + 5;
: :
: :   SIZE_T cbDiff = pbJumpFrom > pbJumpTo ? pbJumpFrom - pbJumpTo : pbJumpTo -
: :  pbJumpFrom;
: :
: :   if (cbDiff <= 0x7fff0000) {
: :
: :     *pbCode++ = 0xe9;
: :
: :     *((PDWORD)pbCode) = (DWORD)(DWORD_PTR)(pbJumpTo - pbJumpFrom);
: :
: :     pbCode += sizeof(DWORD);
: :
: :   } else {
: :
: :     *pbCode++ = 0xff;
: :
: :     *pbCode++ = 0x25;
: :
: :     // on x64 we write the relative address of the same location
: :
: :     *((PDWORD)pbCode) = (DWORD)0;
: :
: :     pbCode += sizeof(DWORD);
: :
: :    
: :
: :     *((PDWORD_PTR)pbCode) = (DWORD_PTR)(pbJumpTo);
: :
: :     pbCode += sizeof(DWORD_PTR);
: :
: :   }
: :
: :   return pbCode;
: :
: : }
: :
: : 除此之外,还有一些异常情况的处理,例如暂停线程时,
: : 其RIP刚好在跳板或者目标函数入口处,理论上可以使用
: : 与x86相同的机制,不过暂时没法构造环境测试
: :
: : #ifdef DETOURS_X64
: :
: : #define DETOURS_EIP         Rip
: : #define DETOURS_EIP_TYPE    DWORD64
: :
: : #endif // DETOURS_X64
: :
: : 最后还有一些跟细节的处理,例如对ModRm下RIP的处理
: : 回头加上再一起放出完整可用的代码吧
: :
: : Reference
: :
: : 1. Microsoft Research Detours Package
: :    http://research.microsoft.com/research/downloads/Details/d36340fb-4d3c-4ddd-bf5b-1db25d03713d/Details.aspx
: :
: : 2. Mhook, an API hooking library, V2.0
: :    http://codefromthe70s.org/mhook2.asp
: :
: : 3. AMD64 Architecture Programmer’s Manual Volume 3: General-Purpose and System Instructions
: :
: : 4. Everything You Need To Know To Start Programming 64-Bit Windows Systems, Matt Pietrek
: :    http://msdn.microsoft.com/msdnmag/issues/06/05/x64/default.aspx?print=true&loc=null
: :  .    生命的意义在于   //   ____/ //_ /   //_/     http://flier_lu.blogcn.com .                          
: :  .        希望         / /  /___/_/// /   //_/__     __    _ _★              .
: :  .        工作          / /   ____// / /    //  /  /'__`/ //`'_/              .
: :  .      爱你的人         / /  /___/ / / /___/ /  /// __// / / //              .
: :  .     和你爱的人         / /___/    / /_____/ /__/ /____/ / /_/              .
: :  .        ……             //___/     //_____///__///____/  //_/.lu@gmail.com .
: :
: :
: : ※ 修改:·flier 于 Aug  3 01:01:35 修改本文·[FROM: 221.226.232.*]
: : ※ 来源:·水木社区 newsmth.net·[FROM: 221.226.232.*]
:
:
: --
:
: ※ 来源:·水木社区 newsmth.net·[FROM: 166.111.8.*]


--
-                     不谈金钱,不谈妇女,不谈琐事


※ 来源:·水木社区 newsmth.net·[FROM: 219.232.52.*]

 

[本篇全文] [本篇作者:bbinn] [进入讨论区] [返回顶部]
7
发信人: bbinn (明天的明天), 信区: MSDN
标  题: Re: Detours x64 [Draft]
发信站: 水木社区 (Fri Aug  3 09:03:59 2007), 站内

可能这样要好一点,就是把user break point改成 divide by 0,
就不会有别的机制抢着去处理这个异常了,就是字节多一点。



【 在 peach (换台机器挂站) 的大作中提到: 】
: 标  题: Re: Detours x64 [Draft]
: 发信站: 水木社区 (Fri Aug  3 08:32:21 2007), 站内
:
: 最近也折腾了一些这方面的东西,但不是64位的
:
: 有些想法,正好拿出来
:
: API HOOK 还可以用另外一种方法,虽然也会用到 detours 相关的技术,不过性能上有不少折扣
:
: 这种方法的核心思想就是使用 SEH,在需要 HOOK 的 API 入口处,改成一个  user break point 即可,这时候只要接管 SEH 处理函数即可,在 SEH 处理函数中,你可以修改 CONTEXT::Eip 以及其他寄存器来达到改变程序的流程的目的。
:
: 这时候有两个问题,
: 1、API入口的第一条指令。
:    a) 绝对跳转之类的指令(jmp, call)。将 user break point 移至跳转到的地址处。
:    b) 条件跳转。这种情况似乎很少见
:    c) 其他指令。移走,在其他地方执行。
:
: 2、如何接管 SEH 处理函数。
:    Detours 中有 DetourFirstChanceExceptionFilter,可以让你在第一时间处理所发生的异常。
:
: 如果需要 HOOK 的 API 不是很多,user break point 都不用加,用硬件调试寄存器就可以完成了。
:
:
: 【 在 flier (小海 [渴望并不存在的完美]) 的大作中提到: 】
: : 标  题: Detours x64 [Draft]
: : 发信站: 水木社区 (Fri Aug  3 01:01:07 2007), 站内
: :
: : 该死的路径依赖,为了折腾另外一个问题,不得不先把这个搞定 :S
: :
: : Detours我就不介绍了,MSR放出的2.1 Express版本不支持64位
: : 而据某人发邮件问,要10000刀才给授权,基本也不用想了 -_-b
: :
: : 于是乎在此基础上修修补补,基本能在x64下跑起来
: : 因为还有些bug,暂时不放完整版本出来,大概说说流程
: :
: : API Hook 基本已经是大白菜级技术,无非就是找到函数入口点
: : 替换前面几个字节为jmp,重定向到一个跳板,完成工作再跳回去
: : 详细的流程请参考detours的代码,下面捡x64下不一样的说
: :
: : 首先是在DetourAttachEx时找到原始函数和Hook函数的真实代码入口点
: : 可能需要跳过import表,或者调试用间接跳转指令啥的,
: : detours.cpp里detour_skip_jmp函数就是干这个的,
: : 不过在x64下需要做一些调整,因为某些指令的数据长度跟x86不同
: : 这块代码我基本照抄mhook的实现,比detours增加了嵌套检查
: :
: :
: :
: : inline PBYTE detour_skip_jmp(PBYTE pbCode, PVOID *ppGlobals)
: :
: : {
: :
: :   if (pbCode == NULL) {
: :
: :     return NULL;
: :
: :   }
: :
: :   if (ppGlobals != NULL) {
: :
: :     *ppGlobals = NULL;
: :
: :   }
: :
: :   if (pbCode[0] == 0xff && pbCode[1] == 0x25) {   // jmp [+imm32]
: :
: :     // Looks like an import alias jump, then get the code it points to.
: :
: :     // on x64 we have a 32-bit offset...
: :
: :     PBYTE pbTarget = *(PBYTE*)(pbCode + 6 + *(INT32 *)&pbCode[2]);
: :
: :     if (detour_is_imported(pbCode, pbTarget)) {
: :
: :       PBYTE pbNew = *(PBYTE *)pbTarget;
: :
: :       DETOUR_TRACE(("%p->%p: skipped over import table./n", pbCode, pbNew));
: :
: :
: :       return pbNew;
: :
: :     }
: :
: :     return detour_skip_jmp(pbTarget, ppGlobals);
: :
: :   }
: :
: :   else if (pbCode[0] == 0xe9) {   // jmp + rel32, Near jump with the target
: :
: :     /*
: :
: :     SEH64!ILT+15(?CallThatFunctionYAHXZ):
: :
: :     00000000`00401014 e957000000      jmp     SEH64!CallThatFunction (000000
: : 00`00401070)
: :
: :     SEH64!CallThatFunction [d:/study/win64/seh64/seh64.cpp @ 11]:
: :
: :     00000000`00401070 4057            push    rdi
: :
: :     00000000`00401072 4883ec40        sub     rsp,40h
: :
: :     00000000`00401076 488bfc          mov     rdi,rsp
: :
: :     */
: :
: :     PBYTE pbNew = pbCode + 5 + *(INT32 *)&pbCode[1];
: :
: :     return detour_skip_jmp(pbNew, ppGlobals);
: :
: :   }
: :
: :   else if (pbCode[0] == 0xeb) {   // jmp +imm8
: :
: :     // These just started appearing with CL13.
: :
: :     PBYTE pbNew = pbCode + 2 + *(CHAR *)&pbCode[1];
: :
: :     return detour_skip_jmp(pbNew, ppGlobals);
: :
: :   }
: :
: :   return pbCode;
: :
: : }
: :
: : 知道入口后,detours会调用DetourCopyInstructionEx复制入口处代码
: : 其根据字节可能代表的指令,把相关信息放到s_rceCopyTable表中
: : x64下需要修改的是从0x40到0x4f这几个入口,x64指令集中用他们
: : 作为REX前缀,详细说明参见AMD architecture programmer manual volume 3
: : 1.2.7 REX Prefixes 小节中有详细讨论,这儿全部当成单字节前缀即可
: :
: : #ifdef DETOURS_X64 // For Rex Prefix
: :     { 0x40, ENTRY_CopyBytesPrefix },                    // REX Prefixes
: :     { 0x41, ENTRY_CopyBytesPrefix },                    // REX Prefixes
: :     { 0x42, ENTRY_CopyBytesPrefix },                    // REX Prefixes
: :
: :     { 0x43, ENTRY_CopyBytesPrefix },                    // REX Prefixes
: :     { 0x44, ENTRY_CopyBytesPrefix },                    // REX Prefixes
: :     { 0x45, ENTRY_CopyBytesPrefix },                    // REX Prefixes
: :     { 0x46, ENTRY_CopyBytesPrefix },                    // REX Prefixes
: :     { 0x47, ENTRY_CopyBytesPrefix },                    // REX Prefixes
: :     { 0x48, ENTRY_CopyBytesPrefix },                    // REX Prefixes
: :     { 0x49, ENTRY_CopyBytesPrefix },                    // REX Prefixes
: :     { 0x4A, ENTRY_CopyBytesPrefix },                    // REX Prefixes
: :     { 0x4B, ENTRY_CopyBytesPrefix },                    // REX Prefixes
: :     { 0x4C, ENTRY_CopyBytesPrefix },                    // REX Prefixes
: :     { 0x4D, ENTRY_CopyBytesPrefix },                    // REX Prefixes
: :     { 0x4E, ENTRY_CopyBytesPrefix },                    // REX Prefixes
: :     { 0x4F, ENTRY_CopyBytesPrefix },                    // REX Prefixes
: : #else
: :
: : 而对FF开始的far indirect jmp/call 指令,x64也跟x86不同
: :
: : PBYTE CDetourDis::CopyFF(REFCOPYENTRY pEntry, PBYTE pbDst, PBYTE pbSrc)
: :
: : {   // CALL /2
: :
: :     // CALL /3
: :
: :     // INC /0
: :
: :     // JMP /4
: :
: :     // JMP /5
: :
: :     // PUSH /6
: :
: :     (void)pEntry;
: :
: :     if (0x15 == pbSrc[1] || 0x25 == pbSrc[1]) {         // CALL [], JMP []
: :
: : #ifdef DETOURS_X64
: :
: :         DWORD dwOffset = *((PDWORD)&pbSrc[2]);
: :
: :         *m_ppbTarget = (PBYTE)*((PDWORD_PTR)(pbSrc + 6 + dwOffset));
: :
: : #else
: :
: :         PBYTE *ppbTarget = *(PBYTE**)&pbSrc[2];
: :
: :         *m_ppbTarget = *ppbTarget;
: :
: : #endif
: :
: :     }
: :
: :     else if (0x10 == (0x38 & pbSrc[1]) || // CALL /2 --> reg(bits 543) of Mo
: : dR/M == 010
: :
: :              0x18 == (0x38 & pbSrc[1]) || // CALL /3 --> reg(bits 543) of Mo
: : dR/M == 011
: :
: :              0x20 == (0x38 & pbSrc[1]) || // JMP /4 --> reg(bits 543) of Mod
: : R/M == 100
: :
: :              0x28 == (0x38 & pbSrc[1])    // JMP /5 --> reg(bits 543) of Mod
: : R/M == 101
: :
: :             ) {
: :
: :         *m_ppbTarget = (PBYTE)DETOUR_INSTRUCTION_TARGET_DYNAMIC;
: :
: :     }
: :
: :     const COPYENTRY ce = { 0xff, ENTRY_CopyBytes2Mod };
: :
: :     return (this->*ce.pfCopy)(&ce, pbDst, pbSrc);
: :
: : }
: :
: : 拷贝了原始指令到跳板后,需要在后面增加跳回剩余指令的jmp
: : x86下面detours直接用detour_gen_jmp_immediate函数生成指令
: : 但在x64下面需要修改,因为x64下面指针是64位的,
: : 如果目标地址在当前地址前后2G范围内,可以用32位偏移跳转
: : 否则必须把地址放到内存中,然后在jmp指令指定保存地址的位置
: :
: : detours在通过detour_alloc_trampoline函数分配跳板内存时
: : 会尽量尝试把内存分配在目标函数2G范围内,避免长跳转指令
: : 这样可以确保目标函数大于5字节(near jmp) 时都能工作
: : 但这样一来就无法确保跳板跟hook函数的位置在2G内,
: : 所以x64下面必须处理这些情况,同理照抄mhook代码如下
: :
: : inline PBYTE detour_gen_jmp(PBYTE pbCode, PBYTE pbJumpTo)
: :
: : {
: :
: :   PBYTE pbJumpFrom = pbCode + 5;
: :
: :   SIZE_T cbDiff = pbJumpFrom > pbJumpTo ? pbJumpFrom - pbJumpTo : pbJumpTo -
: :  pbJumpFrom;
: :
: :   if (cbDiff <= 0x7fff0000) {
: :
: :     *pbCode++ = 0xe9;
: :
: :     *((PDWORD)pbCode) = (DWORD)(DWORD_PTR)(pbJumpTo - pbJumpFrom);
: :
: :     pbCode += sizeof(DWORD);
: :
: :   } else {
: :
: :     *pbCode++ = 0xff;
: :
: :     *pbCode++ = 0x25;
: :
: :     // on x64 we write the relative address of the same location
: :
: :     *((PDWORD)pbCode) = (DWORD)0;
: :
: :     pbCode += sizeof(DWORD);
: :
: :    
: :
: :     *((PDWORD_PTR)pbCode) = (DWORD_PTR)(pbJumpTo);
: :
: :     pbCode += sizeof(DWORD_PTR);
: :
: :   }
: :
: :   return pbCode;
: :
: : }
: :
: : 除此之外,还有一些异常情况的处理,例如暂停线程时,
: : 其RIP刚好在跳板或者目标函数入口处,理论上可以使用
: : 与x86相同的机制,不过暂时没法构造环境测试
: :
: : #ifdef DETOURS_X64
: :
: : #define DETOURS_EIP         Rip
: : #define DETOURS_EIP_TYPE    DWORD64
: :
: : #endif // DETOURS_X64
: :
: : 最后还有一些跟细节的处理,例如对ModRm下RIP的处理
: : 回头加上再一起放出完整可用的代码吧
: :
: : Reference
: :
: : 1. Microsoft Research Detours Package
: :    http://research.microsoft.com/research/downloads/Details/d36340fb-4d3c-4ddd-bf5b-1db25d03713d/Details.aspx
: :
: : 2. Mhook, an API hooking library, V2.0
: :    http://codefromthe70s.org/mhook2.asp
: :
: : 3. AMD64 Architecture Programmer’s Manual Volume 3: General-Purpose and System Instructions
: :
: : 4. Everything You Need To Know To Start Programming 64-Bit Windows Systems, Matt Pietrek
: :    http://msdn.microsoft.com/msdnmag/issues/06/05/x64/default.aspx?print=true&loc=null
: :  .    生命的意义在于   //   ____/ //_ /   //_/     http://flier_lu.blogcn.com .                          
: :  .        希望         / /  /___/_/// /   //_/__     __    _ _★              .
: :  .        工作          / /   ____// / /    //  /  /'__`/ //`'_/              .
: :  .      爱你的人         / /  /___/ / / /___/ /  /// __// / / //              .
: :  .     和你爱的人         / /___/    / /_____/ /__/ /____/ / /_/              .
: :  .        ……             //___/     //_____///__///____/  //_/.lu@gmail.com .
: :
: :
: : ※ 修改:·flier 于 Aug  3 01:01:35 修改本文·[FROM: 221.226.232.*]
: : ※ 来源:·水木社区 newsmth.net·[FROM: 221.226.232.*]
:
:
: --
:
: ※ 来源:·水木社区 newsmth.net·[FROM: 166.111.8.*]


--
-                     不谈金钱,不谈妇女,不谈琐事


※ 来源:·水木社区 newsmth.net·[FROM: 219.232.52.*]

 

[本篇全文] [本篇作者:Quaful] [进入讨论区] [返回顶部]
8
发信人: Quaful (夸父|嗯), 信区: MSDN
标  题: Re: Detours x64 [Draft]
发信站: 水木社区 (Fri Aug  3 09:17:44 2007), 站内

问一下,这种方法有什么好处吗?呵呵
可以不修改入口代码(如果用hardware breakpoint?)

【 在 peach (换台机器挂站) 的大作中提到: 】
: 最近也折腾了一些这方面的东西,但不是64位的
: 有些想法,正好拿出来
: API HOOK 还可以用另外一种方法,虽然也会用到 detours 相关的技术,不过性能上有不少折扣
: ...................

--

※ 来源:·水木社区 newsmth.net·[FROM: 202.165.107.*]

 

[本篇全文] [本篇作者:peach] [进入讨论区] [返回顶部]
9
发信人: peach (换台机器挂站), 信区: MSDN
标  题: Re: Detours x64 [Draft]
发信站: 水木社区 (Fri Aug  3 09:26:12 2007), 站内

好处不多,只是一种方法而已,可能会有它的适用场合。
但使用 hardware breakpoint 的时候会好处多多的

1、可以不修改入口代码
2、可以灵活的控制Hook与否
3、再进一步,都可以使用单步执行中断,自己调试自己。

我之所以弄这些,是因为最近在写脱壳程序来自动脱 asprotect 的壳。脱壳代码是个 dll ,注入到远程进程后,自己调试自己进行脱壳,这些方法还是很方便实用的。


【 在 Quaful (夸父|嗯) 的大作中提到: 】
: 标  题: Re: Detours x64 [Draft]
: 发信站: 水木社区 (Fri Aug  3 09:17:44 2007), 站内
:
: 问一下,这种方法有什么好处吗?呵呵
: 可以不修改入口代码(如果用hardware breakpoint?)
:
: 【 在 peach (换台机器挂站) 的大作中提到: 】
: : 最近也折腾了一些这方面的东西,但不是64位的
: : 有些想法,正好拿出来
: : API HOOK 还可以用另外一种方法,虽然也会用到 detours 相关的技术,不过性能上有不少折扣
: : ...................
:
: --
:
: ※ 来源:·水木社区 newsmth.net·[FROM: 202.165.107.*]


--

※ 来源:·水木社区 newsmth.net·[FROM: 166.111.8.*]

 

[本篇全文] [本篇作者:bbinn] [进入讨论区] [返回顶部]
10
发信人: bbinn (明天的明天), 信区: MSDN
标  题: Re: Detours x64 [Draft]
发信站: 水木社区 (Fri Aug  3 09:41:02 2007), 站内

还是这个好啊,实现起来也容易。

【 在 Quaful (夸父|嗯) 的大作中提到: 】
: 标  题: Re: Detours x64 [Draft]
: 发信站: 水木社区 (Fri Aug  3 09:17:44 2007), 站内
:
: 问一下,这种方法有什么好处吗?呵呵
: 可以不修改入口代码(如果用hardware breakpoint?)
:
: 【 在 peach (换台机器挂站) 的大作中提到: 】
: : 最近也折腾了一些这方面的东西,但不是64位的
: : 有些想法,正好拿出来
: : API HOOK 还可以用另外一种方法,虽然也会用到 detours 相关的技术,不过性能上有不少折扣
: : ...................
:
: --
:
: ※ 来源:·水木社区 newsmth.net·[FROM: 202.165.107.*]


--
-                     不谈金钱,不谈妇女,不谈琐事


※ 来源:·水木社区 newsmth.net·[FROM: 219.232.52.*]

 

[本篇全文] [本篇作者:flier] [进入讨论区] [返回顶部]
11
发信人: flier (小海 [渴望并不存在的完美]), 信区: MSDN
标  题: Re: Detours x64 [Draft]
发信站: 水木社区 (Fri Aug  3 09:44:47 2007), 站内

硬件断点的话,同时支持数有限,只适用于小规模应用情况
我前段也写过一个进程内硬件断点抓指令和数据访问的,
效果不错但真要同时处理一堆入口,得切换来切换去挺麻烦

如果有类似需求,我考虑的另外一个解决方案是利用VM的支持
强制把os切换到VM guest模式下,通过注入特权指令
让目标进程跳回到VMM的VMExit处理模式下来获取控制权

优点是完全硬件支持理论上对被调试进程透明难以检测
缺点是实现较为复杂,需要有核心态驱动提供后台支持
不过技术上应该是完全可行的,有rootkit已经用上类似技术

就目前来说大部分应用程序还没有考虑到对硬件VM的检测
应该还是能工作一段时间的,呵呵,也就赶个早而已
等以后硬件VM大规模使用,到时候又是另外的头痛问题 :P

【 在 peach (换台机器挂站) 的大作中提到: 】
: 标  题: Re: Detours x64 [Draft]
: 发信站: 水木社区 (Fri Aug  3 09:26:12 2007), 站内
:
: 好处不多,只是一种方法而已,可能会有它的适用场合。
: 但使用 hardware breakpoint 的时候会好处多多的
:
: 1、可以不修改入口代码
: 2、可以灵活的控制Hook与否
: 3、再进一步,都可以使用单步执行中断,自己调试自己。
:
: 我之所以弄这些,是因为最近在写脱壳程序来自动脱 asprotect 的壳。脱壳代码是个 dll ,注入到远程进程后,自己调试自己进行脱壳,这些方法还是很方便实用的。
:
:
: 【 在 Quaful (夸父|嗯) 的大作中提到: 】
: : 标  题: Re: Detours x64 [Draft]
: : 发信站: 水木社区 (Fri Aug  3 09:17:44 2007), 站内
: :
: : 问一下,这种方法有什么好处吗?呵呵
: : 可以不修改入口代码(如果用hardware breakpoint?)
: :
: : 【 在 peach (换台机器挂站) 的大作中提到: 】
: : : 最近也折腾了一些这方面的东西,但不是64位的
: : : 有些想法,正好拿出来
: : : API HOOK 还可以用另外一种方法,虽然也会用到 detours 相关的技术,不过性能上有不少折扣
: : : ...................
: :
: : --
: :
: : ※ 来源:·水木社区 newsmth.net·[FROM: 202.165.107.*]
:
:
: --
:
: ※ 来源:·水木社区 newsmth.net·[FROM: 166.111.8.*]


--
 .    生命的意义在于   //   ____/ //_ /   //_/     http://flier_lu.blogcn.com .                          
 .        希望         / /  /___/_/// /   //_/__     __    _ _★              .
 .        工作          / /   ____// / /    //  /  /'__`/ //`'_/              .
 .      爱你的人         / /  /___/ / / /___/ /  /// __// / / //              .
 .     和你爱的人         / /___/    / /_____/ /__/ /____/ / /_/              .
 .        ……             //___/     //_____///__///____/  //_/.lu@gmail.com .


※ 来源:·水木社区 newsmth.net·[FROM: 218.104.127.*]

 

[本篇全文] [本篇作者:peach] [进入讨论区] [返回顶部]
12
发信人: peach (换台机器挂站), 信区: MSDN
标  题: Re: Detours x64 [Draft]
发信站: 水木社区 (Fri Aug  3 09:55:18 2007), 站内


【 在 flier (小海 [渴望并不存在的完美]) 的大作中提到: 】
: 标  题: Re: Detours x64 [Draft]
: 发信站: 水木社区 (Fri Aug  3 09:44:47 2007), 站内
:
: 硬件断点的话,同时支持数有限,只适用于小规模应用情况
: 我前段也写过一个进程内硬件断点抓指令和数据访问的,
: 效果不错但真要同时处理一堆入口,得切换来切换去挺麻烦
没错,适用场合有限
:
: 如果有类似需求,我考虑的另外一个解决方案是利用VM的支持
: 强制把os切换到VM guest模式下,通过注入特权指令
: 让目标进程跳回到VMM的VMExit处理模式下来获取控制权
:
: 优点是完全硬件支持理论上对被调试进程透明难以检测
: 缺点是实现较为复杂,需要有核心态驱动提供后台支持
: 不过技术上应该是完全可行的,有rootkit已经用上类似技术
想法很好 :) 你若有时间给大家写一个吧
:
: 就目前来说大部分应用程序还没有考虑到对硬件VM的检测
: 应该还是能工作一段时间的,呵呵,也就赶个早而已
: 等以后硬件VM大规模使用,到时候又是另外的头痛问题 :P
不管什么东西,一旦流行,新的问题就会接踵而至啊
:
: 【 在 peach (换台机器挂站) 的大作中提到: 】
: : 标  题: Re: Detours x64 [Draft]
: : 发信站: 水木社区 (Fri Aug  3 09:26:12 2007), 站内
: :
: : 好处不多,只是一种方法而已,可能会有它的适用场合。
: : 但使用 hardware breakpoint 的时候会好处多多的
: :
: : 1、可以不修改入口代码
: : 2、可以灵活的控制Hook与否
: : 3、再进一步,都可以使用单步执行中断,自己调试自己。
: :
: : 我之所以弄这些,是因为最近在写脱壳程序来自动脱 asprotect 的壳。脱壳代码是个 dll ,注入到远程进程后,自己调试自己进行脱壳,这些方法还是很方便实用的。
: :
: :
: : 【 在 Quaful (夸父|嗯) 的大作中提到: 】
: : : 标  题: Re: Detours x64 [Draft]
: : : 发信站: 水木社区 (Fri Aug  3 09:17:44 2007), 站内
: : :
: : : 问一下,这种方法有什么好处吗?呵呵
: : : 可以不修改入口代码(如果用hardware breakpoint?)
: : :
: : : 【 在 peach (换台机器挂站) 的大作中提到: 】
: : : : 最近也折腾了一些这方面的东西,但不是64位的
: : : : 有些想法,正好拿出来
: : : : API HOOK 还可以用另外一种方法,虽然也会用到 detours 相关的技术,不过性能上有不少折扣
: : : : ...................
: : :
: : : --
: : :
: : : ※ 来源:·水木社区 newsmth.net·[FROM: 202.165.107.*]
: :
: :
: : --
: :
: : ※ 来源:·水木社区 newsmth.net·[FROM: 166.111.8.*]
:
:
: --
:  .    生命的意义在于   //   ____/ //_ /   //_/     http://flier_lu.blogcn.com .                          
:  .        希望         / /  /___/_/// /   //_/__     __    _ _★              .
:  .        工作          / /   ____// / /    //  /  /'__`/ //`'_/              .
:  .      爱你的人         / /  /___/ / / /___/ /  /// __// / / //              .
:  .     和你爱的人         / /___/    / /_____/ /__/ /____/ / /_/              .
:  .        ……             //___/     //_____///__///____/  //_/.lu@gmail.com .
:
:
: ※ 来源:·水木社区 newsmth.net·[FROM: 218.104.127.*]


--

※ 来源:·水木社区 newsmth.net·[FROM: 166.111.8.*]

 

[本篇全文] [本篇作者:flier] [进入讨论区] [返回顶部]
13
发信人: flier (小海 [渴望并不存在的完美]), 信区: MSDN
标  题: Re: Detours x64 [Draft]
发信站: 水木社区 (Fri Aug  3 10:11:05 2007), 站内


【 在 peach (换台机器挂站) 的大作中提到: 】
: 没错,适用场合有限
: 想法很好 :) 你若有时间给大家写一个吧
-_-b

这块内容前段倒是看过一些,
但从头弄一个出来太麻烦了,
回头找找有没有现成的改改 :S

: 不管什么东西,一旦流行,新的问题就会接踵而至啊
: ...................

--
 .    生命的意义在于   //   ____/ //_ /   //_/     http://flier_lu.blogcn.com .                          
 .        希望         / /  /___/_/// /   //_/__     __    _ _★              .
 .        工作          / /   ____// / /    //  /  /'__`/ //`'_/              .
 .      爱你的人         / /  /___/ / / /___/ /  /// __// / / //              .
 .     和你爱的人         / /___/    / /_____/ /__/ /____/ / /_/              .
 .        ……             //___/     //_____///__///____/  //_/.lu@gmail.com .


※ 来源:·水木社区 newsmth.net·[FROM: 218.104.127.*]

 

[本篇全文] [本篇作者:chice] [进入讨论区] [返回顶部]
14
发信人: chice (do the right thing), 信区: MSDN
标  题: Re: Detours x64 [Draft]
发信站: 水木社区 (Fri Aug 10 10:33:17 2007), 站内

赞啊!

不过vista里面搞钩子好像跟UAC总是不和谐……

【 在 flier (小海 [渴望并不存在的完美]) 的大作中提到: 】
: 该死的路径依赖,为了折腾另外一个问题,不得不先把这个搞定 :S
: Detours我就不介绍了,MSR放出的2.1 Express版本不支持64位
: 而据某人发邮件问,要10000刀才给授权,基本也不用想了 -_-b
: ...................

--
理论上,理论与实际没有差距
实际上,理论与实际差距很大……


※ 来源:·水木社区 newsmth.net·[FROM: 68.181.255.*]

 

[本篇全文] [本篇作者:laoduan] [进入讨论区] [返回顶部]
15
发信人: laoduan (铁鞋踏破也要找到你), 信区: MSDN
标  题: Re: Detours x64 [Draft]
发信站: 水木社区 (Sun Aug 12 20:45:38 2007), 站内

一点提醒:使用SEH机制,效率可能会有些折扣。。。

【 在 peach (换台机器挂站) 的大作中提到: 】
: 最近也折腾了一些这方面的东西,但不是64位的
: 有些想法,正好拿出来
: API HOOK 还可以用另外一种方法,虽然也会用到 detours 相关的技术,不过性能上有不少折扣
: ...................

--

     谨代表《金瓶梅》剧组感谢BTV和狐媚导演,是他们耗费了大量的
     人力、物力,帮我们选出了如此合适的李萍儿和潘金莲人选。。。


※ 来源:·水木社区 newsmth.net·[FROM: 123.113.203.*]

 

[本篇全文] [本篇作者:laoduan] [进入讨论区] [返回顶部]
16
发信人: laoduan (铁鞋踏破也要找到你), 信区: MSDN
标  题: Re: Detours x64 [Draft]
发信站: 水木社区 (Sun Aug 12 20:47:18 2007), 站内

用VM面临着一个大问题,那就是I家和A家的做法并不兼容。。。

【 在 flier (小海 [渴望并不存在的完美]) 的大作中提到: 】
: 硬件断点的话,同时支持数有限,只适用于小规模应用情况
: 我前段也写过一个进程内硬件断点抓指令和数据访问的,
: 效果不错但真要同时处理一堆入口,得切换来切换去挺麻烦
: ...................

--

     谨代表《金瓶梅》剧组感谢BTV和狐媚导演,是他们耗费了大量的
     人力、物力,帮我们选出了如此合适的李萍儿和潘金莲人选。。。


※ 修改:·laoduan 于 Aug 12 21:24:13 修改本文·[FROM: 123.113.203.*]
※ 来源:·水木社区 newsmth.net·[FROM: 123.113.203.*]

 

[本篇全文] [本篇作者:flier] [进入讨论区] [返回顶部]
17
发信人: flier (小海 [渴望并不存在的完美]), 信区: MSDN
标  题: Re: Detours x64 [Draft]
发信站: 水木社区 (Mon Aug 13 01:15:18 2007), 站内

其实还好了,虽然一些细节上有出入,
但大的功能方面基本能对应上就行
貌似xen里面已经做了个抽象层来封装

比较麻烦的是对I/O的处理,
这块貌似大家都还没太好办法

【 在 laoduan (铁鞋踏破也要找到你) 的大作中提到: 】
: 用VM面临着一个大问题,那就是I家和A家的做法并不兼容。。。


--
 .    生命的意义在于   //   ____/ //_ /   //_/     http://flier_lu.blogcn.com .                          
 .        希望         / /  /___/_/// /   //_/__     __    _ _★              .
 .        工作          / /   ____// / /    //  /  /'__`/ //`'_/              .
 .      爱你的人         / /  /___/ / / /___/ /  /// __// / / //              .
 .     和你爱的人         / /___/    / /_____/ /__/ /____/ / /_/              .
 .        ……             //___/     //_____///__///____/  //_/.lu@gmail.com .


※ 来源:·水木社区 newsmth.net·[FROM: 221.226.232.*]

 

[本篇全文] [本篇作者:laoduan] [进入讨论区] [返回顶部]
18
发信人: laoduan (铁鞋踏破也要找到你), 信区: MSDN
标  题: Re: Detours x64 [Draft]
发信站: 水木社区 (Mon Aug 13 23:06:17 2007), 站内

等VT-d和VMDq出来。。。

【 在 flier (小海 [渴望并不存在的完美]) 的大作中提到: 】
: 其实还好了,虽然一些细节上有出入,
: 但大的功能方面基本能对应上就行
: 貌似xen里面已经做了个抽象层来封装
: ...................

--

     谨代表《金瓶梅》剧组感谢BTV和狐媚导演,是他们耗费了大量的
     人力、物力,帮我们选出了如此合适的李萍儿和潘金莲人选。。。


※ 来源:·水木社区 newsmth.net·[FROM: 123.113.203.*]
原创粉丝点击