元始天尊 发表于 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()检查是否处于调试状态

#include <Windows.h>
void main()
{
if(IsDebuggerPresent())
printf("Being debugged\n");
else
printf("Not Being debugged\n");
}

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

PEB结构:
/*000*/ UCHAR InheritedAddressSpace;
/*001*/ UCHAR ReadImageFileExecOptions;
/*002*/ UCHAR BeingDebugged;
/*003*/ UCHAR SpareBool; // Allocation size
/*004*/ HANDLE Mutant;
/*008*/ HINSTANCE ImageBaseAddress; // Instance
/*00C*/ VOID *DllList;
/*010*/ PPROCESS_PARAMETERS *ProcessParameters;
/*014*/ ULONG SubSystemData;
/*018*/ HANDLE DefaultHeap;
/*01C*/ KSPIN_LOCK FastPebLock;
/*020*/ ULONG FastPebLockRoutine;
/*024*/ ULONG FastPebUnlockRoutine;
/*028*/ ULONG EnvironmentUpdateCount;
/*02C*/ ULONG KernelCallbackTable;
/*030*/ LARGE_INTEGER SystemReserved;
/*038*/ ULONG FreeList;
/*03C*/ ULONG TlsExpansionCounter;
/*040*/ ULONG TlsBitmap;
/*044*/ LARGE_INTEGER TlsBitmapBits;
/*04C*/ ULONG ReadOnlySharedMemoryBase;
/*050*/ ULONG ReadOnlySharedMemoryHeap;
/*054*/ ULONG ReadOnlyStaticServerData;
/*058*/ ULONG AnsiCodePageData;
/*05C*/ ULONG OemCodePageData;
/*060*/ ULONG UnicodeCaseTableData;
/*064*/ ULONG NumberOfProcessors;
/*068*/ LARGE_INTEGER NtGlobalFlag; // Address of a local copy
/*070*/ LARGE_INTEGER CriticalSectionTimeout;
/*078*/ ULONG HeapSegmentReserve;
/*07C*/ ULONG HeapSegmentCommit;
/*080*/ ULONG HeapDeCommitTotalFreeThreshold;
/*084*/ ULONG HeapDeCommitFreeBlockThreshold;
/*088*/ ULONG NumberOfHeaps;
/*08C*/ ULONG MaximumNumberOfHeaps;
/*090*/ ULONG ProcessHeaps;
/*094*/ ULONG GdiSharedHandleTable;
/*098*/ ULONG ProcessStarterHelper;
/*09C*/ ULONG GdiDCAttributeList;
/*0A0*/ KSPIN_LOCK LoaderLock;
/*0A4*/ ULONG OSMajorVersion;
/*0A8*/ ULONG OSMinorVersion;
/*0AC*/ USHORT OSBuildNumber;
/*0AE*/ USHORT OSCSDVersion;
/*0B0*/ ULONG OSPlatformId;
/*0B4*/ ULONG ImageSubsystem;
/*0B8*/ ULONG ImageSubsystemMajorVersion;
/*0BC*/ ULONG ImageSubsystemMinorVersion;
/*0C0*/ ULONG ImageProcessAffinityMask;
/*0C4*/ ULONG GdiHandleBuffer;
/*14C*/ ULONG PostProcessInitRoutine;
/*150*/ ULONG TlsExpansionBitmap;
/*154*/ UCHAR TlsExpansionBitmapBits;
/*1D4*/ ULONG SessionId;mov eax,dword ptr fs:TEB偏移0x18处取出的值是镜像,所以EAX仍然指向TEB//见过很多次了,现在还不明白为什么不能直接用,而是先取镜像,,,难道为了某种兼容目的?
mov eax,dword ptr TEB偏移0x30处取出的是TEB结构
movzx eax,byte ptr    PEB偏移0x02处为BeingDebugged,作为返回

对于反检测方式,只需要在调试器中手工将该位改动回来即可
测试:程序中加入
_asm
{
mov eax,dword ptr fs:;
mov eax,dword ptr ;
mov byte ptr ,0;
}debug状态消除


下面这些代码检测TF位检测调试器
#include <stdio.h>
int _tmain(int argc, _TCHAR* argv[])
{
_asm PUSHFD;
//在这里调试
_asm
{
POP EAX;
AND EAX,100h;
JNZ BEINGDEBUGGED;
}
printf("Not being debugged");
getchar();
return 0;
BEINGDEBUGGED:
printf("Being debugged");
getchar();
return 0;
}对于这种方式的检测,只需要在调试器执行入口时改动eflags即可
测试:程序中加入
_asm
{
PUSHFD;
POP EAX;
AND EAX,~100h;
POPFD;
}debug状态消除

元始天尊 发表于 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
任何调试寄存器(DR0:DR7)
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

=="password"      UNICODE =="password"      * + - > <
CALL CONST
TEST EAX,EAX
Jx CONST
|||||||||
条件断点:
(==0E8)&(==0C085)&((==74)|(==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();
}
页: [1]
查看完整版本: 【调试】学习调试