Detours x64

    技术2022-05-11  7

    发信人: 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.*]

    最新回复(0)