设为首页收藏本站
查看: 3108|回复: 0

[原创] [翻译]反调试:定时

[复制链接]
  • TA的每日心情
    开心
    2022-1-9 18:41
  • 签到天数: 5 天

    [LV.2]偶尔看看I

    发表于 2021-9-12 15:31:09 | 显示全部楼层 |阅读模式
    备注
    原文地址:https://anti-debug.checkpoint.com/techniques/timing.html
    原文标题:Anti-Debug: Timing
    更新日期:2021年6月15日
    此文后期:根据自身所学进行内容扩充
    因自身技术有限,只能尽自身所能翻译国外技术文章,供大家学习,若有不当或可完善的地方,希望可以指出,用于共同完善这篇文章。



    目录
    • 定时
    • 1. RDPMC/RDTSC
    • 2. GetLocalTime()
    • 3. GetSystemTime()
    • 4. GetTickCount()
    • 5. ZwGetTickCount() / KiGetTickCount()
    • 6. QueryPerformanceCounter()
    • 7. timeGetTime()
    • 反制措施

    定时
    当一个进程在调试器中被追踪时,在指令和执行之间会有巨大的延迟。代码的某些部分之间的 "本地 "延迟可以用几种方法测量并与实际延迟进行比较。
    1. RDPMC/RDTSC
    这些指令要求在CR4寄存器中设置PCE标志寄存器。
    RDPMC指令只能在内核模式下使用。
    C/C++ 代码:
    1. bool IsDebugged(DWORD64 qwNativeElapsed)
    2. {
    3.     ULARGE_INTEGER Start, End;
    4.     __asm
    5.     {
    6.         xor  ecx, ecx
    7.         rdpmc
    8.         mov  Start.LowPart, eax
    9.         mov  Start.HighPart, edx
    10.     }
    11.     // ... some work
    12.     __asm
    13.     {
    14.         xor  ecx, ecx
    15.         rdpmc
    16.         mov  End.LowPart, eax
    17.         mov  End.HighPart, edx
    18.     }
    19.     return (End.QuadPart - Start.QuadPart) > qwNativeElapsed;
    20. }
    复制代码

    RDTSC是一个用户模式指令。
    C/C++ 代码:
    1. bool IsDebugged(DWORD64 qwNativeElapsed)
    2. {
    3.     ULARGE_INTEGER Start, End;
    4.     __asm
    5.     {
    6.         xor  ecx, ecx
    7.         rdtsc
    8.         mov  Start.LowPart, eax
    9.         mov  Start.HighPart, edx
    10.     }
    11.     // ... some work
    12.     __asm
    13.     {
    14.         xor  ecx, ecx
    15.         rdtsc
    16.         mov  End.LowPart, eax
    17.         mov  End.HighPart, edx
    18.     }
    19.     return (End.QuadPart - Start.QuadPart) > qwNativeElapsed;
    20. }
    复制代码

    2. GetLocalTime()
    C/C++ 代码:
    1. bool IsDebugged(DWORD64 qwNativeElapsed)
    2. {
    3.     SYSTEMTIME stStart, stEnd;
    4.     FILETIME ftStart, ftEnd;
    5.     ULARGE_INTEGER uiStart, uiEnd;

    6.     GetLocalTime(&stStart);
    7.     // ... some work
    8.     GetLocalTime(&stEnd);

    9.     if (!SystemTimeToFileTime(&stStart, &ftStart))
    10.         return false;
    11.     if (!SystemTimeToFileTime(&stEnd, &ftEnd))
    12.         return false;

    13.     uiStart.LowPart  = ftStart.dwLowDateTime;
    14.     uiStart.HighPart = ftStart.dwHighDateTime;
    15.     uiEnd.LowPart  = ftEnd.dwLowDateTime;
    16.     uiEnd.HighPart = ftEnd.dwHighDateTime;
    17.     return (uiEnd.QuadPart - uiStart.QuadPart) > qwNativeElapsed;
    18. }
    复制代码

    3. GetSystemTime()
    C/C++ 代码:
    1. bool IsDebugged(DWORD64 qwNativeElapsed)
    2. {
    3.     SYSTEMTIME stStart, stEnd;
    4.     FILETIME ftStart, ftEnd;
    5.     ULARGE_INTEGER uiStart, uiEnd;

    6.     GetSystemTime(&stStart);
    7.     // ... some work
    8.     GetSystemTime(&stEnd);

    9.     if (!SystemTimeToFileTime(&stStart, &ftStart))
    10.         return false;
    11.     if (!SystemTimeToFileTime(&stEnd, &ftEnd))
    12.         return false;

    13.     uiStart.LowPart  = ftStart.dwLowDateTime;
    14.     uiStart.HighPart = ftStart.dwHighDateTime;
    15.     uiEnd.LowPart  = ftEnd.dwLowDateTime;
    16.     uiEnd.HighPart = ftEnd.dwHighDateTime;
    17.     return (uiEnd.QuadPart - uiStart.QuadPart) > qwNativeElapsed;
    18. }
    复制代码

    4. GetTickCount()
    C/C++ 代码:
    1. bool IsDebugged(DWORD dwNativeElapsed)
    2. {
    3.     DWORD dwStart = GetTickCount();
    4.     // ... some work
    5.     return (GetTickCount() - dwStart) > dwNativeElapsed;
    6. }
    复制代码

    5. ZwGetTickCount() / KiGetTickCount()
    这两个函数只在内核模式下使用。

    就像用户模式的GetTickCount()或GetSystemTime()一样,内核模式的ZwGetTickCount()从KUSER_SHARED_DATA页面读取。这个页面在虚拟地址的用户模式范围内被映射为只读,在内核范围内被映射为读写。系统时钟的滴答声更新了系统时间,它直接存储在这个页面中。

    ZwGetTickCount()的使用方法与GetTickCount()相同。使用KiGetTickCount()比调用ZwGetTickCount()要快,但比直接从KUSER_SHARED_DATA页面读取稍慢一些。
    C/C++ 代码:
    1. bool IsDebugged(DWORD64 qwNativeElapsed)
    2. {
    3.     ULARGE_INTEGER Start, End;
    4.     __asm
    5.     {
    6.         int  2ah
    7.         mov  Start.LowPart, eax
    8.         mov  Start.HighPart, edx
    9.     }
    10.     // ... some work
    11.     __asm
    12.     {
    13.         int  2ah
    14.         mov  End.LowPart, eax
    15.         mov  End.HighPart, edx
    16.     }
    17.     return (End.QuadPart - Start.QuadPart) > qwNativeElapsed;
    18. }
    复制代码

    6. QueryPerformanceCounter()
    C/C++ 代码:
    1. bool IsDebugged(DWORD64 qwNativeElapsed)
    2. {
    3.     LARGE_INTEGER liStart, liEnd;
    4.     QueryPerformanceCounter(&liStart);
    5.     // ... some work
    6.     QueryPerformanceCounter(&liEnd);
    7.     return (liEnd.QuadPart - liStart.QuadPart) > qwNativeElapsed;
    8. }
    复制代码

    7. timeGetTime()
    C/C++ 代码:
    1. bool IsDebugged(DWORD dwNativeElapsed)
    2. {
    3.     DWORD dwStart = timeGetTime();
    4.     // ... some work
    5.     return (timeGetTime() - dwStart) > dwNativeElapsed;
    6. }
    复制代码

    反制措施
    调试期间:只需用NOP填充定时检查,并将这些检查的结果设置为适当的值。
    对于反调试绕过方案的开发:没有很大的必要去做什么,因为所有的定时检查都不是很可靠。你仍然可以拦截定时函数,加快调用之间的时间。
    您需要登录后才可以回帖 登录 | 注册

    本版积分规则

    红盟社区--红客联盟 

    Processed in 0.055461 second(s), 21 queries.

    站点统计| 举报| Archiver| 手机版| 黑屋 |   

    备案号:冀ICP备20006029号-1 Powered by HUC © 2001-2021 Comsenz Inc.

    手机扫我进入移动触屏客户端

    关注我们可获取更多热点资讯

    Honor accompaniments. theme macfee

    快速回复 返回顶部 返回列表