동적 디 버 깅 기술 총화
#include "stdio.h"
#include "windows.h"
#include "tchar.h"
void AD_BreakPoint()
{
printf("SEH : BreakPoint
");
__asm {
// install SEH
push handler
push DWORD ptr fs:[0]
mov DWORD ptr fs:[0], esp
//INT 3 CPU , ( ntdll.dll KiUserExceptionDispatcher)。
// generating exception
int 3
// 1) debugging
// go to terminating code
mov eax, 0xFFFFFFFF
jmp eax // process terminating!!!
// 2) not debugging
// go to normal code
handler:
mov eax, dword ptr ss:[esp+0xc]
mov ebx, normal_code
mov dword ptr ds:[eax+0xb8], ebx
xor eax, eax
retn
normal_code:
// remove SEH
pop dword ptr fs:[0]
add esp, 4
}
printf(" => Not debugging...
");
}
int _tmain(int argc, TCHAR* argv[])
{
AD_BreakPoint();
return 0;
}
메모: OD 의 이상 옵션 은 int 3 인 터 럽 트 를 무시 합 니 다. 선택 하지 않 아야 합 니 다. strongOD 플러그 인 옵션 은 사용 하지 않 는 것 이 좋 습 니 다. 명령 에 들 어 갈 수 있 습 니 다.
mov eax, 0xFFFFFFFF
jmp eax
OD 는 int 3 에서 끊 을 수 없습니다 (F2). 그렇지 않 으 면 이상 주소 int 3 로 순환 합 니 다.
2. 이상 - setUnhandled 예외 필터
#include "stdio.h"
#include "windows.h"
#include "tchar.h"
LPVOID g_pOrgFilter = 0;
LONG WINAPI ExceptionFilter(PEXCEPTION_POINTERS pExcept)
{
SetUnhandledExceptionFilter((LPTOP_LEVEL_EXCEPTION_FILTER)g_pOrgFilter);
// 8900 MOV DWORD PTR DS:[EAX], EAX
// FFE0 JMP EAX
pExcept->ContextRecord->Eip += 4;
return EXCEPTION_CONTINUE_EXECUTION;
}
void AD_SetUnhandledExceptionFilter()
{
printf("SEH : SetUnhandledExceptionFilter()
");
//SetUnhandledExceptionFilter() Top Level Exception Filter 。
// , , Kernel32.dll
//UnhandledExceptionFilter() 。UnhandledExceptionFilter()
//ntdll.dll NtQueryInformationProcess() ,
// , ( , )。
// , Top Level Exception Filter 。
g_pOrgFilter = (LPVOID)SetUnhandledExceptionFilter(
(LPTOP_LEVEL_EXCEPTION_FILTER)ExceptionFilter);
__asm {
xor eax, eax;
mov dword ptr [eax], eax
jmp eax
}
printf(" => Not debugging...
");
}
int _tmain(int argc, TCHAR* argv[])
{
AD_SetUnhandledExceptionFilter();
return 0;
}
3.Timing Check
#include "stdio.h"
#include "windows.h"
#include "tchar.h"
void DynAD_RDTSC()
{
//Timing Check , 。
//1.Counter based method
// RDTSC (RD==READ TSC == Time Stamp Counter)
// x86 CPU TSC(Time Stamp Counter, ) 64 。
// CPU Clock Cycle( ) , TSC.RDTSC ,
// TSC EDX:EAX )。
// OD Olly Advanced->options 2 Anti-RDSTC( ), 。
// kernel32!QueryPerformanceCounter()/ntdll!NtQueryPerformanceCounter()
// kernel32!GetTickCount()
//2.Time based method
// timeGetTime()
// _ftime()
DWORD dwDelta = 0;
printf("Timing Check (RDTSC method)");
__asm {
pushad
//0F31 rdtsc
rdtsc
push edx
push eax
// ( )
xor eax, eax
mov ecx, 0x3e8
_LOOP_START:
inc eax
loop _LOOP_START
rdtsc
pop esi // eax
pop edi // edx
// check high order bits
cmp edx, edi
ja _DEBUGGER_FOUND
// check low order bits
sub eax, esi
mov dwDelta, eax
cmp eax, 0xffffff
jb _DEBUGGER_NOT_FOUND
// debugger found -> crash!!!
_DEBUGGER_FOUND:
xor eax, eax
mov [eax], eax
// debugger not found
_DEBUGGER_NOT_FOUND:
popad
}
printf(" : delta = %X (ticks)
", dwDelta);
printf(" => Not debugging...
");
}
int _tmain(int argc, TCHAR* argv[])
{
DynAD_RDTSC();
return 0;
}
4. 함정 표식
#include "stdio.h"
#include "windows.h"
#include "tchar.h"
void DynAD_SingleStep()
{
// EFLAGS 9 (Index8) 。
//TF 1 ,CPU (Single Step) 。 ,CPU 1
// EXCEPTION_SINGLE_STEP(0x80000004) , 。
// 。
printf("Trap Flag (Single Step)
");
__asm {
// install SEH
push handler
push DWORD ptr fs:[0]
mov DWORD ptr fs:[0], esp
// EFLAGS,
pushfd
or dword ptr ss:[esp], 0x100
popfd
// nop , EXCEPTION_SINGLE_STEP ,OD nop F7,F8,F9 。
// KiUserExceptionDispatcher mov eax,0xFFFFFFFF
//1) , SEH
//2) , , F7,F8,F9 mov eax,0xFFFFFFFF
nop
// 1) debugging
// go to terminating code
mov eax, 0xFFFFFFFF
jmp eax // process terminating!!!
// 2) not debugging
// go to normal code
handler:
mov eax, dword ptr ss:[esp+0xc]
mov ebx, normal_code
mov dword ptr ds:[eax+0xb8], ebx
xor eax, eax
retn
normal_code:
// remove SEH
pop dword ptr fs:[0]
add esp, 4
}
printf(" => Not debugging...
");
}
int _tmain(int argc, TCHAR* argv[])
{
DynAD_SingleStep();
return 0;
}
#include "stdio.h"
#include "windows.h"
#include "tchar.h"
void DynAD_INT2D()
{
//INT 2D , 。
// , 。
//INT 2D
//1. INT2D (F7,F8), , 。 , 。
//2. INT2D (F7,F8), , , ( ,OD BUG)。
BOOL bDebugging = FALSE;
__asm {
// install SEH
push handler
push DWORD ptr fs:[0]
mov DWORD ptr fs:[0], esp
// , EFlags TF=1, SEH
int 0x2d
nop
mov bDebugging, 1
jmp normal_code
handler:
mov eax, dword ptr ss:[esp+0xc]
mov dword ptr ds:[eax+0xb8], offset normal_code
mov bDebugging, 0
xor eax, eax
retn
normal_code:
// remove SEH
pop dword ptr fs:[0]
add esp, 4
}
printf("Trap Flag (INT 2D)
");
if( bDebugging ) printf(" => Debugging!!!
");
else printf(" => Not debugging...
");
}
int _tmain(int argc, TCHAR* argv[])
{
DynAD_INT2D();
return 0;
}
5.0 xcC 탐지
#include "stdio.h"
#include "windows.h"
#include "tchar.h"
DWORD g_dwOrgChecksum = 0xF5934986;
int _tmain(int argc, TCHAR* argv[]);
void DynAD_Checksum()
{
BOOL bDebugging = FALSE;
DWORD dwSize = 0;
printf("Checksum
");
__asm {
mov ecx, offset _tmain
mov esi, offset DynAD_Checksum
sub ecx, esi // ecx : loop count (buf size)
xor eax, eax // eax : checksum
xor ebx, ebx
_CALC_CHECKSUM:
movzx ebx, byte ptr ds:[esi]
add eax, ebx
rol eax, 1
inc esi
loop _CALC_CHECKSUM
cmp eax, g_dwOrgChecksum
je _NOT_DEBUGGING
mov bDebugging, 1
_NOT_DEBUGGING:
}
if( bDebugging ) printf(" => Debugging!!!
");
else printf(" => Not debugging...
");
}
int _tmain(int argc, TCHAR* argv[])
{
DynAD_Checksum();
return 0;
}
요약:
1. CC int 3 명령 (둘 사이 에 빈 칸 이 없 음 을 주의 하 세 요).
2. CD 2D int 2d 명령
3.
pushfd
or [esp],100
popfd
EFlags 레지스터 TF = 1.
이 세 가지 방법 은 모두 디 버 거 특유 의 성질 을 이용 한 것 입 니 다. (1. 무시 2. 정지점 까지 계속 실행 합 니 다. 3. 명령 을 실행 한 후에 끊 긴 명령 은 ntdll! KiUserException Dispatcher () 를 실행 하지 않 았 습 니 다.
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
다양한 언어의 JSONJSON은 Javascript 표기법을 사용하여 데이터 구조를 레이아웃하는 데이터 형식입니다. 그러나 Javascript가 코드에서 이러한 구조를 나타낼 수 있는 유일한 언어는 아닙니다. 저는 일반적으로 '객체'{}...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.