[codeengn] basic #04

·2025년 6월 24일

CodeEngn 바로가기


문제

이 프로그램은 디버거 프로그램을 탐지하는 기능을 갖고 있다. 디버거를 탐지하는 함수의 이름은 무엇인가

1. 프로그램 실행

프로그램을 실행시킬 경우 프로그램이 종료될 때까지 "정상"이라는 문자열이 출력된다.

Ollydbg에서 04.exe 파일을 열어서 f8 단축키를 통해 한줄한줄 실행해보면 00408454 오프셋의 CALL 구문이 실행될 경우 터미널에 디버깅 유무 판단 결과가 print된다.


2. 흐름 파악

00408454     E8 B68BFFFF    CALL 04.0040100F
...

0040105E   . FF15 64B14300  CALL DWORD PTR DS:[<&KERNEL32.IsDebugger>; [IsDebuggerPresent
00401064   . 3BF4           CMP ESI,ESP
00401066   . E8 A5710000    CALL 04.00408210
0040106B   . 85C0           TEST EAX,EAX
0040106D   . 74 0F          JE SHORT 04.0040107E
0040106F   . 68 24104300    PUSH 04.00431024                         ; /Arg1 = 00431024
00401074   . E8 17710000    CALL 04.00408190                         ; \04.00408190
00401079   . 83C4 04        ADD ESP,4
0040107C   . EB 0D          JMP SHORT 04.0040108B
0040107E   > 68 1C104300    PUSH 04.0043101C                         ; /Arg1 = 0043101C
00401083   . E8 08710000    CALL 04.00408190                         ; \04.00408190
00401088   . 83C4 04        ADD ESP,4
0040108B   >^EB BB          JMP SHORT 04.00401048

오프셋 00408454에서 f7 단축키를 통해 함수 내부로 진입 후, 단축키 f8로 흐름를 따라가다보면 IsDbuggerPresent 함수가 호출되며, 리턴값을 TEST와 JE 구문을 이용해 비교하며 분기를 나누고 있다.

① TEST
TEST A BA & B AND 비트연산을 수행하는데, TEST EAX EAX 와 같이 두 인자에 동일한 값이 있을 경우에는, EAX에 값 존재 유무(0인지 아닌지)를 판별하기 위함이라고 한다. 만약 EAX가 0일 경우에는 ZF(ZeroFlag)가 1이 되고, EAX에 다른 값이 존재할 경우에는 ZF가 0이 된다.

② JE
JE 구문은 ZF가 0일 경우 인자의 주소로 이동한다. 즉, 이번 문제에서는 EAX에 값이 없을 경우, 오프셋 0040107E("정상" 출력")으로 점프한다.


IsDebuggerPresent 함수의 리턴값 EAX 값을 기준으로 출력에 대한 분기를 나누고 있으므로, 문제의 정답인 디버거를 탐지하는 함수의 이름은 IsDebuggerPresent으로 추측할 수 있다.

3. 코드 변조

"정상" 문자열을 출력하기 위해서는 ①EAX의 값을 0으로 변조하거나, ②JE문을 JNE로 변조하여 정상 문자열을 출력하는 주소로 점프시키는 방법, ③ZF 플래그를 변조하는 방법 등을 이용할 수 있을 것으로 보인다.

BreakPoint를 설정하고, EAX값을 0으로 변조하여 실행해보자.


"정상" 문자열을 확인할 수 있다.

그러나 EAX를 변조할 경우, 반복문 실행 중 한 번만 정상 문자열이 실행되기 때문에 반복적으로 "정상" 문자열을 출력하기 위해선 JE구문을 JNE구문으로 변조해야 할 것으로 생각된다. 🤔


기타

코드엔진 깃허브에 가면 다양한 방식의 풀이를 확인할 수 있다!

profile
🔥

0개의 댓글