Break,Break BreakPoint!! 1)Software Breakpoint softice¿¡¼­ bpx·Î ¾²ÀδÙ. Opcode·Î´Â 0xCCÀÇ 1¹ÙÀÌÆ®·Î ÀÌ·ç¾îÁ® ÀÖ´Ù. Àç¹Õ´Â Á¡Àº ÀÌ°Ô ÇÔ¼ö·Îµµ Á¸ÀçÇÑ´Ù´Â Á¡Àε¥, ¹«¾ùÀ» À§ÇÑ °ÍÀÎÁö´Â ¸ð¸£°ÚÁö¸¸ Á¸ÀçÇÑ´Ù. °ú¿¬ DebugBreak()¶ó´Â ÇÔ¼ö´Â ´ëü ¹«½¼ Äڵ带 °¡Áö°í Àִ°¡? ¶ó´Â È£±â½É¿¡ DisassembleÇØº¸´Ï ´ÙÀ½°ú °°ÀÌ ³ª¿Â´Ù. 7C931230 > CC INT3 7C931231 C3 RETN Á¤¸» °£´ÜÇÏ´Ù -_-; ±×³É INT3 È£Ãâ ÇØÁÖ°í ³ª¿À´Â °ÍÀ̾ú´Ù.. MSDN¿¡´Â ´ÙÀ½°ú °°ÀÌ ³ª¿Í ÀÖ´Ù. void DebugBreak(void); Causes a breakpoint exception to occur in the current process. This allows the calling thread to signal the debugger to handle the exception. To cause a breakpoint exception in another process, use the DebugBreakProcess function ¿ÀÈ£ :) Àç¹Ì³­ °É º¼ ¼ö ÀÖ´Ù. DebugBreak()´Â ÇØ´ç ÇÁ·Î¼¼½º ³»¿¡¼­ ºê·¹ÀÌÅ© Æ÷ÀÎÆ®¸¦ ¹ß»ý ½Ã۱â À§ÇÑ °ÍÀε¥, DebugBreakProcess()¶ó´Â API´Â ´Ù¸¥ ÇÁ·Î¼¼½º¿¡¼­ ºê·¹ÀÌÅ© Æ÷ÀÎÆ®¸¦ ¹ß»ý½ÃÄÑ Áشٰí ÇÑ´Ù. INT3 ÀÌ ½ÇÇàµÇ¸é IDT¿¡ ÁöÁ¤µÇ¾î ÀÖ´Â Interrupt3 Handler°¡ È£Ã⠵ȴÙ. º» ½Ã½ºÅÛ¿¡´Â ´ÙÀ½°ú °°ÀÌ ÁöÁ¤µÇ¾î ÀÖ¾ú´Ù. [º» È­¸éÀº ¿©¸®´ÔÀÇ kc¸¦ ÀÌ¿ëÇÏ¿© ¾ò¾ú´Ù. :)] -------------------------------------------------------- vector number__________ : 3 (0x03) - type________________ : INTERRUPT GATE - description_________ : Breakpoint Exception - DPL_________________ : 3 - segment_____________ : 0x0008 - offset______________ : 0x804E189D + module information__ - name_____________ : ntoskrnl.exe - base address_____ : 0x804D9000 - path_____________ : WINDOWSsystem32ntoskrnl.exe ---------------------------------------------------- DPLÀÌ 3À¸·Î ÁöÁ¤µÇ¾î ÀÖÀ½À¸·Î Usermode Process ¿¡¼­µµ È£ÃâÀÌ °¡´ÉÇÑ ÀÎÅÍ·´Æ® À̸ç, 󸮴 0x804E189D¿¡¼­ Çϰí ÀÖÀ½À» º¼ ¼ö ÀÖ´Ù. Disassemblme ÇØº¸¸é, ----------------------------------------------------- 804E189D | 6A 00 | PUSH 0 804E189F | 66:C74424 02 0000 | MOV WORD PTR [ESP+2], 0 804E18A6 | 55 | PUSH EBP 804E18A7 | 53 | PUSH EBX 804E18A8 | 56 | PUSH ESI 804E18A9 | 57 | PUSH EDI 804E18AA | 0FA0 | PUSH FS 804E18AC | BB 30000000 | MOV EBX, 30 804E18B1 | 8EE3 | MOV FS, BX ................... ------------------------------------------------------ Àú ÄÚµåÀÇ ³»¿ëÀº MSDN¿¡¼­ ã¾Ò´ø DebugBreak()ÀÇ Remarks°¡ ¼³¸íÇØ ÁÖ°í ÀÖ´Ù. If the process is not being debugged, the function uses the search logic of a standard exception handler. In most cases, this causes the calling process to terminate because of an unhandled breakpoint exception. 2)Hardware Breakpoint softice¿¡¼­ bpmÀ̶ó´Â ¸í·É¾î·Î ¾Ë·ÁÁ® ÀÖ´Ù. Hardware Breakpoint´Â CPU¿¡ ÀÖ´Â Debug Register¸¦ ÀÌ¿ëÇÏ¿© ºê·¹ÀÌÅ© Æ÷ÀÎÆ®¸¦ °Å´Â ¹æ¹ýÀÌ´Ù. Software Breakpoint´Â ½ÇÇàÀ» Àâ¾Æ³¾ ¼ö ¹Û¿¡ ¾øÁö¸¸, Hardware Breakpoint´Â ½ÇÇà/Àбâ/¾²±â¸¦ Àâ¾Æ³»´Â °ÍÀÌ °¡´ÉÇÏ´Ù. ÇÏÁö¸¸ Hardware Breakpoint¸¦ »ç¿ëÇÒ‹š¿¡, Breakpoint°É ÁÖ¼Ò¸¦ ÁöÁ¤ÇÒ ¼ö ÀÖ´Â °ø°£Àº DR0,DR1,DR2,DR3 ÀÌ·¸°Ô 4°³ ¹Û¿¡ ¾ø´Ù. Áï Hardware BreakpointÀÇ Á¦ÇÑÀº 4°³ ÀΰÍÀÌ´Ù. Hardware Breakpoint¸¦ ÁöÁ¤ÇÏ´Â ¼ø¼­´Â ´ÙÀ½°ú °°´Ù. (DR0À» »ç¿ëÇÑ´Ù°í °¡Á¤Çß´Ù.) 1. DR0¿¡ ´ÙÀ½°ú °°Àº ¹æ¹ýÀ¸·Î ÁÖ¼Ò¸¦ ³Ö´Â´Ù. __asm { mov eax,Break_Address mov DR0,eax } 2. DR7¿¡ Breakpoint¸¦ ó¸®ÇÒ ¹æ¹ýÀ» ÁöÁ¤ÇØÁÖ¾î¾ß ÇÑ´Ù. DR7À» C¾ð¾î ±¸Á¶Ã¼·Î Ç¥±âÇØº¸¸é ´ÙÀ½°ú °°´Ù. typedef struct tagDebugReg7 { unsigned L0 :1; // unsigned G0 :1; // unsigned L1 :1; // unsigned G1 :1; // unsigned L2 :1; // unsigned G2 :1; // unsigned L3 :1; // unsigned G3 :1; // unsigned GL :1; // unsigned GE :1; // unsigned undefined1 :3; // 001 unsigned GD :1; // unsigned undefined2 :2; // 00 unsigned RW0 :2; unsigned LEN0 :2; unsigned RW1 :2; unsigned LEN1 :2; unsigned RW2 :2; unsigned LEN2 :2; unsigned RW3 :2; unsigned LEN3 :2; } DebugReg7; L0 : ƯÁ¤ Task¸¸À» ¸ñÀûÀ¸·Î Breakpoint¸¦ ÁöÁ¤ÇÒ‹š setÇÑ´Ù. TaskÀüȯÀÌ ÀϾ¸é ¸ðµç LºñÆ®´Â 0À¸·Î resetµÈ´Ù. G0 : ¸ðµç Task¸¦ ´ë»óÀ¸·Î Breakpoint¸¦ ÁöÁ¤ÇÒ‹š setÇÑ´Ù. GD : ÀÌ ºñÆ®°¡ setµÇ¾î ÀÖÀ¸¸é DebugRegister¿¡ Á¢±ÙÀÌ ¹ß»ýÇÏ¿´À»‹š, ÀÎÅÍ·´Æ® 1¹øÀÌ ¹ß»ýÇÑ´Ù. ÀÎÅÍ·´Æ®1¹ø ¹ß»ý ÈÄ GDºñÆ®´Â 0À¸·Î resetµÈ´Ù. RW0 : ºê·¹ÀÌÅ© Æ÷ÀÎÆ® ·¹Áö½ºÅÍÀÇ ¹ß»ý Á¶°ÇÀ» ÁöÁ¤ÇÑ´Ù. 00 : ¸í·ÉÀÌ ½ÇÇà(excute) µÇ¾úÀ» ‹š ÀÎÅÍ·´Æ®1 ¹ß»ý. 01 : µ¥ÀÌÅͰ¡ ±â·Ï(write)µÉ ‹š ÀÎÅÍ·´Æ® 1 ¹ß»ý. 10 : Do not use 11 : Àаųª(read) ¾µ ¶§(write) ÀÎÅÍ·´Æ® 1 ¹ß»ý. LEN0 : ºê·¹ÀÌÅ© Æ÷ÀÎÆ®ÀÇ ÀÎ½Ä ¹üÀ§¸¦ ÁöÁ¤ÇÑ´Ù. 00 : 1¹ÙÀÌÆ® = BYTE 01 : 2¹ÙÀÌÆ® = WORD 10 : Do not use 11 : 4¹ÙÀÌÆ® = DWORD DR0¿¡ ÀÖ´Â ÁÖ¼Ò¿¡ RW0°ú LEN0¿¡ ¸¸Á·ÇÏ´Â Á¢±ÙÀÌ ¹ß»ýÇÑ´Ù¸é, ÀÎÅÍ·´Æ® 1¹øÀÌ È£ÃâµÇ°í, ÇØ´ç ¹ß»ý ¿äÀÎÀÌ DR6¿¡ ÀúÀåµÇ¾î ÀÖ´Ù. DR6¸¦ C¾ð¾î ±¸Á¶Ã¼·Î Ç¥±âÇØº¸¸é ´ÙÀ½°ú °°´Ù. typedef struct DebugReg6 { unsigned B0 :1; unsigned B1 :1; unsigned B2 :1; unsigned B3 :1; unsigned undefined1 :9; // 011111111 unsigned BD :1; unsigned BS :1; unsigned BT :1; unsigned undefined2 :16; // 1111111111111111 } DebugReg6; B0 : Breakpoint,R/W,LENÀÌ ÃæÁ·µÇ¾î¼­ ¹ß»ýÇÑ ÀÎÅÍ·´Æ® 1ÀÇ °æ¿ì ÀÌ ºñÆ®°¡ 1·Î setµÈ´Ù. BD : GD ºñÆ®°¡ 1·Î ¼³Á¤µÇ¾î ÀÖ´Â »óÅ¿¡¼­ Debug Register¿¡ Á¢±ÙÀÌ ¹ß»ýÇϸé ÀÌ ºñÆ®°¡ 1·Î setµÈ´Ù. BS : Flag RegisterÀÇ TFºñÆ®°¡ 1·Î ¼³Á¤µÇ¾î ÀÖÀ» ‹š ÀÌ ºñÆ®°¡ 1·Î setµÈ´Ù. BT : Task SwitchingÀÌ ¹ß»ýÇßÀ» ‹š »õ·Î¿î TSSÀÇ TºñÆ®°¡ 1·Î setµÇ¾î ÀÖ´Ù¸é BTºñÆ®°¡ 1·Î setµÈ´Ù. (»õ·Î¿î ŽºÅ©ÀÇ ¸í·ÉÀ» ½ÇÇàÇϱâ Àü¿¡ ÀÎÅÍ·´Æ®1ÀÌ ¹ß»ýÇÑ´Ù.) ¾î¶»°Ô ÇÏ¸é ¿ì¸®°¡ Á÷Á¢ Hardware Breakpoint¸¦ ´Ù·ç¾î ÁÙ¼ö Àִ°¡? Interrupt1À» HookingÇÔÀ¸·Î½á °¡´ÉÇÏ´Ù. 1. HookingÇÏ¿© ¿¬°áÇÒ ÇÔ¼ö¸¦ ¸¸µç´Ù. _declspec( naked ) void interrupt1( void ) { __asm{ cmp [DebuggedProcessID],0 //µð¹ö±ë ÁßÀΰ¡? jz Original //¾Æ´Ï¶ó¸é ±âº» Çڵ鷯 È£Ãâ PUSHAD //32 push ds //4 push es //4 push gs //4 push fs //4 mov ax,0x23 mov ds,ax mov es,ax mov gs,ax mov ax,0x30 mov fs,ax mov eax,esp add eax,48 push eax //ProcessÀÇ ½ºÅÃÁÖ¼Ò¸¦ ³Ö´Â´Ù. CALL PesudoINT1Handler // cmp eax,1 //¸®ÅÏ º§·ù°¡ 1ÀÌ¸é ±âº» Çڵ鷯¸¦ È£ÃâÇÏÁö ¾Ê´Â´Ù. je Exit pop fs pop gs pop es pop ds POPAD Original: JMP [Int1Address] Exit: pop fs pop gs pop es pop ds POPAD IRETD }; } PesudoINTHandlerÀÇ ÄÚµå´Â ´ÙÀ½°ú °°´Ù. ULONG __stdcall PesudoINT1Handler(IN PULONG Stacklocation ) { ULONG result=2; //2ÀÏ‹ž ±âº» Çڵ鷯°¡ È£ÃâµÇÁö ¾Ê´Â´Ù. if ((ULONG)PsGetCurrentProcessId()==DebuggedProcessID) { //Áö±Ý ÀÌ ÇÁ·Î¼¼½º°¡ µð¹ö±ë ´çÇÏ´Â ´ë»ó ÇÁ·Î¼¼½ºÀΰ¡? ULONG DR_0,DR_1,DR_2,DR_3; DebugReg6 DR_6; DebugReg7 DR_7; DbgPrint("Welcome to my INT1 Handler"); __asm{ mov eax,dr0 mov DR_0,eax mov eax,dr1 mov DR_1,eax mov eax,dr2 mov DR_2,eax mov eax,dr3 mov DR_3,eax mov eax,dr6 mov DR_6,eax mov eax,dr7 mov DR_7,eax }; //·¹Áö½ºÅ͵éÀÇ ³»¿ë Ãâ·Â DbgPrint("Hello from int1n"); DbgPrint("eax=%xn",Stacklocation[-1]); DbgPrint("ebx=%xn",Stacklocation[-4]); DbgPrint("ecx=%xn",Stacklocation[-2]); DbgPrint("edx=%xn",Stacklocation[-3]); DbgPrint("esi=%xn",Stacklocation[-7]); DbgPrint("edi=%xn",Stacklocation[-8]); DbgPrint("ebp=%xn",Stacklocation[-6]); DbgPrint("esp=%xn",Stacklocation[3]); DbgPrint("eip=%xn",Stacklocation[0]); DbgPrint("DR0=%xn",DR_0); DbgPrint("DR1=%xn",DR_1); DbgPrint("DR2=%xn",DR_2); DbgPrint("DR3=%xn",DR_3); DbgPrint("DR6=%xn",DR_6); DbgPrint("DR7=%xn",DR_7); DbgPrint("DR_7.L3=%dnDR_6.B3=%dnDR_3=%xn",DR_7.L3,DR_6.B3,DR_3); DbgPrint("-3=%xn",Stacklocation[-1]); DbgPrint("-2=%xn",Stacklocation[-1]); DbgPrint("-1=%xn",Stacklocation[-1]); DbgPrint("0=%xn",Stacklocation[0]); DbgPrint("1=%xn",Stacklocation[1]); DbgPrint("2=%xn",Stacklocation[2]); DbgPrint("3=%xn",Stacklocation[3]); DbgPrint("4=%xn",Stacklocation[4]); DbgPrint("5=%xn",Stacklocation[5]); DbgPrint("6=%xn",Stacklocation[6]); DbgPrint("7=%xn",Stacklocation[7]); DbgPrint("8=%xn",Stacklocation[8]); DbgPrint("9=%xn",Stacklocation[9]); DbgPrint("10=%xn",Stacklocation[10]); DbgPrint("11=%xn",Stacklocation[11]); DbgPrint("12=%xn",Stacklocation[12]); if ( ((DR_7.L0) && (DR_6.B0) && (DR_0>=DebuggedAddress) && (DR_0<=DebuggedAddress+DebuggedAddressLength)) || ((DR_7.L1) && (DR_6.B1) && (DR_1>=DebuggedAddress) && (DR_1<=DebuggedAddress+DebuggedAddressLength)) || ((DR_7.L2) && (DR_6.B2) && (DR_2>=DebuggedAddress) && (DR_2<=DebuggedAddress+DebuggedAddressLength)) || ((DR_7.L3) && (DR_6.B3) && (DR_3>=DebuggedAddress) && (DR_3<=DebuggedAddress+DebuggedAddressLength)) ) { //DbgPrint("Handled by my selfn"); result=1; DR_6.B0=0; DR_6.B1=0; DR_6.B2=0; DR_6.B3=0; __asm { mov eax,DR_6 mov dr6,eax } if (BufferSize<50) { int spot; spot=BufferSize; BufferSize++; DebugEvents[spot].EAX=Stacklocation[-1]; DebugEvents[spot].EBX=Stacklocation[-4]; DebugEvents[spot].ECX=Stacklocation[-2]; DebugEvents[spot].EDX=Stacklocation[-3]; DebugEvents[spot].ESI=Stacklocation[-7]; DebugEvents[spot].EDI=Stacklocation[-8]; DebugEvents[spot].EBP=Stacklocation[-6]; DebugEvents[spot].ESP=Stacklocation[3]; DebugEvents[spot].EIP=Stacklocation[0]; } } else { DbgPrint("Unexpected!!!n"); } if (DR_6.BS) { single step } if (DR_6.BD) { //the debugregs got accesses //save the current debugregs //set the ownprocessdebugregs back to the debugregs //do a single step (set the step flag in eflags //set the debugregs back to what the program put them to DbgPrint("The debugregs got accessedn"); } } } return result; } 2. IDT¿¡¼­ 1¹øÀÇ ÁÖ¼Ò¸¦ ÀÌÀü¿¡ ¸¸µç ÇÔ¼ö ÁÖ¼Ò·Î ¹Ù²Û´Ù. int HookInterrupts() { IDTINFO idt_info; IDTENTRY* idt_entries; IDTENTRY* int1_entry; __asm{ sidt idt_info; } idt_entries = (IDTENTRY*) MAKELONG(idt_info.LowIDTbase,idt_info.HiIDTbase); Int1Address = MAKELONG(idt_entries[1].LowOffset,idt_entries[1].HiOffset); int1_entry = &(idt_entries[1]); __asm{ cli; lea eax,interrupt1; mov ebx, int1_entry; mov [ebx],ax; shr eax,16 mov [ebx+6],ax; lidt idt_info; sti; } return 0; } À§¿¡¼­ »ç¿ëµÈ ±¸Á¶Ã¼µéÀ» C¾ð¾î ±¸Á¶Ã¼·Î Ç¥±âÇØº¸¸é ´ÙÀ½°ú °°´Ù. typedef struct { WORD LowOffset; WORD selector; BYTE unused_lo; unsigned char unused_hi:5; /* stored TYPE ? */ unsigned char DPL:2; unsigned char P:1; /* present */ WORD HiOffset; } IDTENTRY; /* sidt returns idt in this format */ typedef struct { WORD IDTLimit; WORD LowIDTbase; WORD HiIDTbase; } IDTINFO; /* from undoc nt */ typedef struct { unsigned short limit_0_15; unsigned short base_0_15; unsigned char base_16_23; unsigned char accessed : 1; unsigned char readable : 1; unsigned char conforming : 1; unsigned char code_data : 1; unsigned char app_system : 1; unsigned char dpl : 2; unsigned char present : 1; unsigned char limit_16_19 : 4; unsigned char unused : 1; unsigned char always_0 : 1; unsigned char seg_16_32 : 1; unsigned char granularity : 1; unsigned char base_24_31; } CODE_SEG_DESCRIPTOR; /* from undoc nt */ typedef struct { unsigned short offset_0_15; unsigned short selector; unsigned char param_count : 4; unsigned char some_bits : 4; unsigned char type : 4; unsigned char app_system : 1; unsigned char dpl : 2; unsigned char present : 1; unsigned short offset_16_31; } CALLGATE_DESCRIPTOR; ÇÙ½É ³»¿ëÀº ¾Æ´ÏÁö¸¸ ¾î¶»°Ô Çϸé ÀÚ½ÅÀÇ Thread¿¡ HardwareBreakpoint°¡ ¼³Ä¡µÇ¾î ÀÖ´ÂÁö ¾Æ´ÑÁö¸¦ ¾Ë¾Æ³»´Â °£´ÜÇÑ Äڵ带 ÀÛ¼ºÇØ º¸¾Ò´Ù. // GetHBP.cpp : Defines the entry point for the console application. // #include "stdafx.h" #include "windows.h" typedef struct tagDebugReg7 { unsigned L0 :1; // unsigned G0 :1; // unsigned L1 :1; // unsigned G1 :1; // unsigned L2 :1; // unsigned G2 :1; // unsigned L3 :1; // unsigned G3 :1; // unsigned GL :1; // unsigned GE :1; // unsigned undefined1 :3; // 001 unsigned GD :1; // unsigned undefined2 :2; // 00 unsigned RW0 :2; unsigned LEN0 :2; unsigned RW1 :2; unsigned LEN1 :2; unsigned RW2 :2; unsigned LEN2 :2; unsigned RW3 :2; unsigned LEN3 :2; } DebugReg7; DebugReg7 *DR_7; int main(int argc, char* argv[]) { int i = 0; CONTEXT z; z.ContextFlags = CONTEXT_DEBUG_REGISTERS; //Coded by Dual(http://dualpage.muz.ro) while(1) { GetThreadContext(GetCurrentThread(),&z); if(!z.Dr0 && !z.Dr1 && !z.Dr2 && !z.Dr3) { printf("There is no Debuggern"); } else { printf("There is Debugger!!n"); DR_7 = (DebugReg7 *)&z.Dr7; printf("GD : %Xn",DR_7->GD); if(z.Dr0) { printf("HardwareBreakpoint at : 0x%X",z.Dr0); if(DR_7->LEN0 == 0) printf(" Len : 1byte"); else if(DR_7->LEN0 == 1) printf(" Len : 2byte"); else if(DR_7->LEN0 == 2) printf(" Len : Not Active"); else if(DR_7->LEN0 == 3) printf(" Len : 4byte"); if(DR_7->RW0 == 0) printf(" condition : excuten"); else if(DR_7->RW0 == 1) printf(" condition : writen"); else if(DR_7->RW0 == 2) printf(" condtion : Not Activen"); else if(DR_7->RW0 == 3) printf(" condition : read/writen"); } if(z.Dr1) { printf("HardwareBreakpoint at : 0x%X",z.Dr1); if(DR_7->LEN1 == 0) printf(" Len : 1byte"); else if(DR_7->LEN1 == 1) printf(" Len : 2byte"); else if(DR_7->LEN1 == 2) printf(" Len : Not Active"); else if(DR_7->LEN1 == 3) printf(" Len : 4byte"); if(DR_7->RW1 == 0) printf(" condition : excuten"); else if(DR_7->RW1 == 1) printf(" condition : writen"); else if(DR_7->RW1 == 2) printf(" condtion : Not Activen"); else if(DR_7->RW1 == 3) printf(" condition : read/writen"); } if(z.Dr2) { printf("HardwareBreakpoint at : 0x%X",z.Dr2); if(DR_7->LEN2 == 0) printf(" Len : 1byte"); else if(DR_7->LEN2 == 1) printf(" Len : 2byte"); else if(DR_7->LEN2 == 2) printf(" Len : Not Active"); else if(DR_7->LEN2 == 3) printf(" Len : 4byte"); if(DR_7->RW2 == 0) printf(" condition : excuten"); else if(DR_7->RW2 == 1) printf(" condition : writen"); else if(DR_7->RW2 == 2) printf(" condtion : Not Activen"); else if(DR_7->RW2 == 3) printf(" condition : read/writen"); } if(z.Dr3) { printf("HardwareBreakpoint at : 0x%X",z.Dr3); if(DR_7->LEN3 == 0) printf(" Len : 1byte"); else if(DR_7->LEN3 == 1) printf(" Len : 2byte"); else if(DR_7->LEN3 == 2) printf(" Len : Not Active"); else if(DR_7->LEN3 == 3) printf(" Len : 4byte"); if(DR_7->RW3 == 0) printf(" condition : excuten"); else if(DR_7->RW3 == 1) printf(" condition : writen"); else if(DR_7->RW3 == 2) printf(" condtion : Not Activen"); else if(DR_7->RW3 == 3) printf(" condition : read/writen"); } } Sleep(100); } return 0; } ½ÇÇà È­¸éÀº ÀÌ·¸´Ù : 1. µð¹ö°Å¿¡ ÀÇÇØ HardwareBreakPoint°¡ ÁöÁ¤µÇ¾î ÀÖÁö¾ÊÀ» ‹š: 2. R/W¸¦ °É¾î µÎ¾úÀ» ¶§ : 3. excute¸¦ °É¾î µÎ¾úÀ» ¶§; 4. write¸¦ °É¾î µÎ¾úÀ» ¶§ : ------------------------------------------------------- ±×·¸´Ù¸é ÀÌ·¯ÇÑ Detection Code°¡ Á¸ÀçÇÏ´Â ÇÁ·Î±×·¥¿¡ Hardware Breakpoint¸¦ °Å´Â °ÍÀº ºÒ°¡´ÉÇѰ¡? ¹°·± ¾Æ´Ï´Ù. GetThreadContext()·Î °¨ÁöÇØ³¿À¸·Î, ÀÌ ÇÔ¼ö¸¦ Global HookingÇÏ¸é µÈ´Ù. WinAPIÀÇ GetThreadContext()´Â NTAPIÀÇ ZwGetContextThread() ·Î ¿¬°áµÇ´Âµ¥, À̸¦ SSDT HookingÀ̳ª, Inline HookingÇÏ¿©, ¾Æ·¡¿Í °°ÀÌ Ã³¸®ÇÏ¿© ÁÖ¸é µÉ°ÍÀÌ´Ù. NTSTATUS NewZwGetContextThread(HANDLE hThread,PCONTEXT pContext) { NTSTATUS rc; rc = OldZwGetContextThread(hThread,pContext); if(PsGetCurrentProcess() != MyProcess) { pContext->DR0 = 0; pContext->DR1 = 0; pContext->DR2 = 0; pContext->DR3 = 0; pContext->DR6 = 0; pContext->DR7 = 0; } return rc; }; ±Û ³»¿ë¿¡ À߸øµÈ ³»¿ëÀÌ ÀÖÀ¸¸é ¸ÞÀÏ ÁÖ¼¼¿ä :) Dual5651@hotmail.com # dualpage.muz.ro [2008-01-26]