找回密码
 立即注册→加入我们

QQ登录

只需一步,快速开始

搜索
热搜: 下载 VB C 实现 编写
查看: 3063|回复: 1

【调试】学习调试

[复制链接]

307

主题

228

回帖

7335

积分

用户组: 真·技术宅

UID
2
精华
76
威望
291 点
宅币
5585 个
贡献
253 次
宅之契约
0 份
在线时间
947 小时
注册时间
2014-1-25
发表于 2014-8-8 12:05:08 | 显示全部楼层 |阅读模式

欢迎访问技术宅的结界,请注册或者登录吧。

您需要 登录 才可以下载或查看,没有账号?立即注册→加入我们

×
本帖最后由 元始天尊 于 2014-8-8 12:11 编辑

bpx function_name
拦截keyfile.key的CreateFile       bpx CreateFileA if(*(esp->4)=='keyf')

对于不从API第一个字节执行的保护机制,需要在中断和内核API上下断。
中断大全http://www.cs.cmu.edu/~ralf/files.html
内核API大全http://undocumented.ntinternals.net

ollydbg条件断点:EAX=="mypswd"
Delphi,Builder,MFC,VB库函数断点

消息断点:BMSG 句柄 WM_COMMAND
数据断点:对用户输入的判断、程序修改校验的破解

bpx CreateFileA DO "D esp->4 L 20;x;"
bpx CreateFileA if byte (*esp->4)=='a' DO xxx

反调试法:PUSHFD/POP REG读取FLAGS寄存器,检查TF位

跟踪:捕获特定指令

下面这些出于自己的研究:
IsDebuggerPresent()检查是否处于调试状态

  1. #include <Windows.h>
  2. void main()
  3. {
  4. if(IsDebuggerPresent())
  5.   printf("Being debugged\n");
  6. else
  7.   printf("Not Being debugged\n");
  8. }
复制代码


我在vs中使用了以后,单步调试,得到:
IsDebuggerPresent();
                  003513A0 call dword ptr [__imp__IsDebuggerPresent@0 (358198h)]
跟进以后:761EAFB3 jmp 761EAFA8  
再跟进:    761EAFA8 jmp dword ptr ds:[761A1D8Ch]
再跟进:    75D67AAC mov eax,dword ptr fs:[00000018h]
                  75D67AB2 mov eax,dword ptr [eax+30h]   
                  75D67AB5 movzx eax,byte ptr [eax+2]   
                  75D67AB9 ret  
fs中存的是TEB线程结构:
偏移  说明
000  指向SEH链指针
004  线程堆栈顶部
008  线程堆栈底部
00C  SubSystemTib
010  FiberData
014  ArbitraryUserPointer
018  FS段寄存器在内存中的镜像地址
020  进程PID
024  线程ID
02C  指向线程局部存储指针
030  PEB结构地址(进程结构)
034  上个错误号

PEB结构:
  1. /*000*/ UCHAR InheritedAddressSpace;
  2. /*001*/ UCHAR ReadImageFileExecOptions;
  3. /*002*/ UCHAR BeingDebugged;
  4. /*003*/ UCHAR SpareBool; // Allocation size
  5. /*004*/ HANDLE Mutant;
  6. /*008*/ HINSTANCE ImageBaseAddress; // Instance
  7. /*00C*/ VOID *DllList;
  8. /*010*/ PPROCESS_PARAMETERS *ProcessParameters;
  9. /*014*/ ULONG SubSystemData;
  10. /*018*/ HANDLE DefaultHeap;
  11. /*01C*/ KSPIN_LOCK FastPebLock;
  12. /*020*/ ULONG FastPebLockRoutine;
  13. /*024*/ ULONG FastPebUnlockRoutine;
  14. /*028*/ ULONG EnvironmentUpdateCount;
  15. /*02C*/ ULONG KernelCallbackTable;
  16. /*030*/ LARGE_INTEGER SystemReserved;
  17. /*038*/ ULONG FreeList;
  18. /*03C*/ ULONG TlsExpansionCounter;
  19. /*040*/ ULONG TlsBitmap;
  20. /*044*/ LARGE_INTEGER TlsBitmapBits;
  21. /*04C*/ ULONG ReadOnlySharedMemoryBase;
  22. /*050*/ ULONG ReadOnlySharedMemoryHeap;
  23. /*054*/ ULONG ReadOnlyStaticServerData;
  24. /*058*/ ULONG AnsiCodePageData;
  25. /*05C*/ ULONG OemCodePageData;
  26. /*060*/ ULONG UnicodeCaseTableData;
  27. /*064*/ ULONG NumberOfProcessors;
  28. /*068*/ LARGE_INTEGER NtGlobalFlag; // Address of a local copy
  29. /*070*/ LARGE_INTEGER CriticalSectionTimeout;
  30. /*078*/ ULONG HeapSegmentReserve;
  31. /*07C*/ ULONG HeapSegmentCommit;
  32. /*080*/ ULONG HeapDeCommitTotalFreeThreshold;
  33. /*084*/ ULONG HeapDeCommitFreeBlockThreshold;
  34. /*088*/ ULONG NumberOfHeaps;
  35. /*08C*/ ULONG MaximumNumberOfHeaps;
  36. /*090*/ ULONG ProcessHeaps;
  37. /*094*/ ULONG GdiSharedHandleTable;
  38. /*098*/ ULONG ProcessStarterHelper;
  39. /*09C*/ ULONG GdiDCAttributeList;
  40. /*0A0*/ KSPIN_LOCK LoaderLock;
  41. /*0A4*/ ULONG OSMajorVersion;
  42. /*0A8*/ ULONG OSMinorVersion;
  43. /*0AC*/ USHORT OSBuildNumber;
  44. /*0AE*/ USHORT OSCSDVersion;
  45. /*0B0*/ ULONG OSPlatformId;
  46. /*0B4*/ ULONG ImageSubsystem;
  47. /*0B8*/ ULONG ImageSubsystemMajorVersion;
  48. /*0BC*/ ULONG ImageSubsystemMinorVersion;
  49. /*0C0*/ ULONG ImageProcessAffinityMask;
  50. /*0C4*/ ULONG GdiHandleBuffer[0x22];
  51. /*14C*/ ULONG PostProcessInitRoutine;
  52. /*150*/ ULONG TlsExpansionBitmap;
  53. /*154*/ UCHAR TlsExpansionBitmapBits[0x80];
  54. /*1D4*/ ULONG SessionId;
复制代码
mov eax,dword ptr fs:[00000018h]  TEB偏移0x18处取出的值是镜像,所以EAX仍然指向TEB//见过很多次了,现在还不明白为什么不能直接用,而是先取镜像,,,难道为了某种兼容目的?
mov eax,dword ptr [eax+30h]  TEB偏移0x30处取出的是TEB结构
movzx eax,byte ptr [eax+2]   PEB偏移0x02处为BeingDebugged,作为返回

对于反检测方式,只需要在调试器中手工将该位改动回来即可
测试:程序中加入
  1. _asm
  2. {
  3.   mov eax,dword ptr fs:[00000018h];
  4.   mov eax,dword ptr [eax+30h];
  5.   mov byte ptr [eax+2],0;
  6. }
复制代码
debug状态消除


下面这些代码检测TF位检测调试器
  1. #include <stdio.h>
  2. int _tmain(int argc, _TCHAR* argv[])
  3. {
  4. _asm PUSHFD;
  5. //在这里调试
  6. _asm
  7. {
  8.   POP EAX;
  9.   AND EAX,100h;
  10.   JNZ BEINGDEBUGGED;
  11. }
  12. printf("Not being debugged");
  13. getchar();
  14. return 0;
  15. BEINGDEBUGGED:
  16. printf("Being debugged");
  17. getchar();
  18. return 0;
  19. }
复制代码
对于这种方式的检测,只需要在调试器执行入口时改动eflags即可
测试:程序中加入
  1. _asm
  2. {
  3.   PUSHFD;
  4.   POP EAX;
  5.   AND EAX,~100h;
  6.   POPFD;
  7. }
复制代码
debug状态消除
回复

使用道具 举报

307

主题

228

回帖

7335

积分

用户组: 真·技术宅

UID
2
精华
76
威望
291 点
宅币
5585 个
贡献
253 次
宅之契约
0 份
在线时间
947 小时
注册时间
2014-1-25
 楼主| 发表于 2014-8-8 23:13:03 | 显示全部楼层
OllyDbg支持的用于指定断点的关键字

关键字
描述
R8
任意8位寄存器(AL BL CL DL AH BH CH DL)
R16
任意16位寄存器(AX BX CX DX SP BP SI DI)
R32
任意32位寄存器(EAX EBX ECX EDX ESP EBP ESI EDI)
FPU
任意数字协处理器寄存器(ST0:ST7)
MMX
任何MMX寄存器(MM0:MM7)

CRX
任何控制寄存器(CR0:CR7)
DRX
任何调试寄存器(DR0R7)
CONST
任何常量
OFFSET
任何偏移量(类似于常量)
JCC
任意条件跳转(JE JC JNGE....)
SETCC
任何设置字节的条件跳转指令(SETE SETC SETNGE...)
CMOVCC                        任何条件移动(CMOVE CMOVC CMOVNGE

Ollydbg Search for Sequence of commands        CALL CONST
ANY n 跳过0条到n条机器指令
CALL CONST
TEST EAX,EAX
ANY 3
JCC CONST

[ESI]=="password"        UNICODE [ESI]=="password"        * + - > <
CALL CONST
TEST EAX,EAX
Jx CONST
|||||||||
条件断点:
([BYTE EIP]==0E8)&([WORD EIP+5]==0C085)&(([BYTE EIP+7]==74)|([BYTE EIP+7]==75))

代码覆盖:找出2次运行指令序列不同


ring3设置硬件断点:
SetBreakPoint(void* p
{
    CONTEXT ctx;
    HANDLE h=GetCurrentThread();
    ctx.ContextFlags=CONTEXT_DEBUG_REGISTERS;
    GetThreadContext(h,&ctx);
    ctx.Dr0=p;
    ctx.Dr7=(ctx.Dr7&0xFFF0FFFF)|0x101;//地址p设置断点数
    SetThreadContext(h,&ctx);
}

UnSetBreakPoint()
{
    CONTEXT ctx;
    HANDLE h=GetCurrentThread();
    ctx.ContextFlags=CONTEXT_DEBUG_REGISTERS;
    GetThreadContext(h,&ctx);
    ctx.Dr7=(ctx.Dr7&0xFFFFFFFE);
    SetThreadContext(h,&ctx);
}

text(){printf("this is just a test\n")};

main()
{
    __try
    {
        test();
        SetBreakPoint(test);
        test();
    }
    __except(1)
    {
        printf("hello,breakpoint!\n");
        UnSetBreakPoint();
    }
    test();
}
回复 赞! 靠!

使用道具 举报

QQ|Archiver|小黑屋|技术宅的结界 ( 滇ICP备16008837号 )|网站地图

GMT+8, 2024-4-20 00:43 , Processed in 0.043981 second(s), 31 queries , Gzip On.

Powered by Discuz! X3.5

© 2001-2024 Discuz! Team.

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