Ctrl + N
현재 실행파일에서 사용하겠다고 말한 함수들의 이름을 볼 수있다.
IsDebugger
원하는 문자를 입력해서 찾을 수 있다.
1. IsDebuggerPresent 를 검색해서 찾는다.
엔터를 누르면 그 함수위치를 볼 수있다.
즉 , 안티리버싱에 관한 함수를 알아내서 그 함수를 알고, 이름을 통해 그 분기를 찾아 가는 것이다.
이러한 안티리버싱에 관련된 함수를 구글에 검색해서 무슨 함수인지 알아본다.
https://docs.microsoft.com/en-us/windows/desktop/api/debugapi/nf-debugapi-isdebuggerpresent
IsDebuggerPresent function (debugapi.h)
Determines whether the calling process is being debugged by a user-mode debugger.
docs.microsoft.com
소스로 짜기위해서는
_WIN32_WINNT 매크로를 0x0400 이상을 정의해야한다.
StdAfx.h에 #define _WIN32_WINNT 0x0501 을 정의
소스.
F5는디버거로 실행
Ctrl+ F5는 디버거없이 실행
JE를 JMP 변경해 우회시킬 수 있다. TEST JE는 거짓이면 점프, 참이면 실행이다.
JMP로 변경하면 if문으로 우회를 해 No Debugger가 출력된다.
함수안에 코드 분석
MOV EAX,DWORD PTR FS:[18]
FS의 값에 18을 더한 값을 EAX에 넣는다.
MOV EAX,DWORD PTR DS:[EAX+30]
위의 값에 30을 넣은 값이 EAX에 저장
MOVZX EAX,BYTE PTR DS:[EAX+2]
이 값으로 디버깅을 구별. 1이면 디버깅이고, 0이면 디버깅이 아니라고 판별
이렇게 작성하면 isdebugger가 검색해도 안나오기때문에 분석을 하나하나 다해야하기 때문에 힘들다.
__asm은 어셈블리어를 사용하게 해주는 함수이다.
ntqueryinformationprocess 함수
함수에 대한 설명
https://docs.microsoft.com/en-us/windows/desktop/api/winternl/nf-winternl-ntqueryinformationprocess
NtQueryInformationProcess function (winternl.h)
Retrieves information about the specified process.
docs.microsoft.com
ntqueryinformationprocess를 사용하려면 LoadLibrary GetProcAddress함수를 사용해야한다.
GetProcAddress function (libloaderapi.h)
Retrieves the address of an exported function or variable from the specified dynamic-link library (DLL).
docs.microsoft.com
LoadLibraryA function (libloaderapi.h)
Loads the specified module into the address space of the calling process.
docs.microsoft.com
이 함수는 디버거 포트를 통해 판단한다.
두개의 프로세스는 디버거 포트를 통해 실행된다.
ntqueryinformationprocess
위의 함수에서 사용하는 GetProcAddress와 LoadLibrary를 통해 확인할 수 있다.
nt함수는 위의 2개함수를 사용한다.
LoadLibrary함수가 먼저실행되고, GetPorcAddress가 실행된다.
ntqueryinformationprocess는 바로 호출이 되지 않기 때문에 zwQueryinformationprocess먼저 호출하고 호출된다.
이함수의 인자값은 5개
-1은 자기자신 7번째 정보를 조회 실제데이터에 4바이트의 데이터 사이즈 0이니 필요없다.
0번부터 세는 것이다. 즉 , 7번째는 ProcessDebugPort
그냥 실행 시
0이면 디버깅을 사용하지 않고있다는 뜻이다.
디버깅 시 결과 값 FFFFFFFF로 디버깅포트가되어 안티디버깅이 실행된다.
즉, if문을 우회하면 된다.
JE를 JMP로 변경해 우회하면 No Debugger Detected가 뜬다.
CheckRemoteDebuggerPresent 함수
https://docs.microsoft.com/en-us/windows/desktop/api/debugapi/nf-debugapi-checkremotedebuggerpresent
CheckRemoteDebuggerPresent function (debugapi.h)
Determines whether the specified process is being debugged.
docs.microsoft.com
매개변수가 2개인 함수이다.
지정된 프로세스가 디버깅되고 있는지 여부를 결정하는 함수이다.
함수가 성공하면(디버깅중이면) 반환값이 0이아니고, 실패하면 반환값이 0이다.
똑같이 Ctrl+ N을 통해 위의 함수를 찾는다.
위의 주소를 break를 걸고 그 주소로 찾아간다.
매개변수가 2개라 2개를 넣는다.
값이 1 즉, 0이 아니면 디버깅중이라 판단.
JE를 JMP로 변경해 흐름분기를 우회한다.
SetLastError
GetLastError
OutPutDebugString
표시를 위해 문자열을 디버거에 보내는 함수
https://docs.microsoft.com/en-us/windows/desktop/api/debugapi/nf-debugapi-outputdebugstringw
OutputDebugStringW function (debugapi.h)
Sends a string to the debugger for display.
docs.microsoft.com
Ctrl + N 으로 OutPutString을 찾아 온다.
29A라는 값을 LastErr에 넣는다.
OutPutDebugStringW 디버거로 문자열을 출력하라는 의미이다.
이런식으로 random이란 값을 출
GetLastError 는 LastError의 값을 가져온다. EAX로 가져옴
디버거가 있으면 에러가 일어나지 않고, 디버거가 없으면 에러가난다. 이것으로 판별.
LastError -> 마지막 에러를 캐치함. 즉 , 에러가 있으면 디버거가 없다 판단.
에러가 없으면 디버거가 있다판단.
에러가 있으면 Last Error에 있는 값과 EAX의 있는 값이 다르므로 디버깅이 없다판단
즉 , 같으면 디버깅이 있다고 판단하므로 안티디버깅 활성화
따라서 JNZ를 JMP로 변경해 우회
findWindow
활성화 중인 창에서 OllyDbg를 찾는다.
Ctrl + n 을통해 들어간다. 이번에는 2군데라 2군데 전부 break Point 를 건다.
활성 중인 Title을 찾는다. 내부 클래스에 대한 값을 찾는다.
OLLYDBG라는 창을 찾으면(0이 아니면) EAX에 값이 담겨 점프가 되어 OllyDBG Detected가 뜨고
창을 찾지 못하면 EAX값은 0이되어 점프를 하지 않아, Not Detected가 뜬다.
따라서 JNZ를 NOP 으로 변경하면된다.
NOP으로 변경
AnitQuiz1
디버깅을 실행시켜 Strat를 누르면, 메모장이 뜨면 성공
Findwindow를 찾아 JE를 JMP로 변경해 OllyDbg를 우회
이모양이 뜨지만 실행은 안됌.
찾다보니 이함수가 notepad.exe 와 연관된 것을 확인 JE를 NOP으로 변경해 점프가 되지않고 그대로 실행되게 설정.
winexec는 응용프로그램을 실행시키는 함수.
https://docs.microsoft.com/en-us/windows/desktop/api/winbase/nf-winbase-winexec
WinExec function (winbase.h)
Runs the specified application.
docs.microsoft.com
잘 실행된다
프로그램을 강제종료하는 명령어 외워두면 좋다.
-1 나 자신
1E -> 30번 째 ProcessDebugObjectHandle을 의미
주소의 값이 다시 실행되는 곳에 브레이크포인트를 거는 방법이다. Hardware Break Point라 한다.