
1. CrackMe란?
리버스 엔지니어링을 배우기 위해 만들어진 연습용 프로그램으로 프로그램을 리버스 엔지니어링해서 비밀번호를 밝혀 풀어낸다.
5장에서는 멀웨어에서 자주 사용되는 인코딩 방법을 다루는 4문제를 푼다.
2. level1 crackme(xor)
level 1 크랙미 디스어셈블 결과
undefined8 main(void)
{
char *pcVar1;
size_t sVar2;
undefined8 uVar3;
long in_FS_OFFSET;
int local_6c;
int local_68 [12];
byte local_38 [40];
long local_10;
local_10 = *(long *)(in_FS_OFFSET + 0x28);
local_68[0] = 0x29;
local_68[1] = 0x4b;
local_68[2] = 0x17;
local_68[3] = 10;
local_68[4] = 0x4b;
local_68[5] = 0x49;
local_68[6] = 0x25;
local_68[7] = 2;
local_68[8] = 0x4a;
local_68[9] = 8;
printf("Enter password: ");
pcVar1 = fgets((char *)local_38,0x20,stdin);
if ((pcVar1 == (char *)0x0) || (sVar2 = strlen((char *)local_38), sVar2 != 0xb)) {
LAB_001008b1:
puts("Wrong...");
uVar3 = 1;
}
else {
for (local_6c = 0; local_6c < 10; local_6c = local_6c + 1) {
if ((int)(char)(local_38[local_6c] ^ 0x7a) != local_68[local_6c]) goto LAB_001008b1;
}
puts("Correct!!");
uVar3 = 0;
}
if (local_10 == *(long *)(in_FS_OFFSET + 0x28)) {
return uVar3;
}
/* WARNING: Subroutine does not return */
__stack_chk_fail();
}
디스어셈블 결과코드는 loacl_38 배열의 원소들을 0x7a값과 xor해서 local_68 배열의 값과 비교한다.
XOR 연산은 A ^ B = C일 때, C ^ B = A가 되는 대칭적인 성질이 있어, 암호화된 값에 키값을 다시 XOR 하면 원래 값을 복구할 수 있다.
local_68을 xor 0x7a와 xor한 값을 찾으면 local_38에 들어갈 값을 찾을 수 있다.
3. PyGhidra를 사용한 풀이

toAddr은 주소 객체를 얻고 getInstructionAt은 지정한 주소의 명령 객체를 얻는다.
메인 함수 내에서 배열(local_68)에 값을 넣기 시작하는 어셈블리 코드의 시작 주소가 0x1007e1이므로 addr을 얻어온다.
inst.getDefaultOperandRepresentation(1)를 통해 오퍼랜드를 얻을 수 있다.

getNext()메소드를 사용하면 다음 주소로 스택에 쌓여있는 값을 읽는다.
inst.getNext().getDefaultOperandRepresentation(1)처럼 사용할 수 있다.
파이썬 스크립트로 아래와 같이 짜면
addr = toAddr(0x1007e1)
enc =[]
inst = getInstructionAt(addr)
for _ in range(0, 10):
e = inst.getDefaultOperandRepresentation(1)
enc.append(int(e,16))
inst = inst.getNext()
print(''.join([chr(e^0x7a) for e in enc]))

S1mp13_x0r 가 나오고
cyberChef에서 검증하면 S1mp13_x0r이 나온다.

4. 3줄 요약
- CrackMe Level 1은 사용자 입력값을 0x7a와 XOR 연산하여 하드코딩된 배열과 비교하는 로직임을 확인했다.
- PyGhidra 스크립트를 작성해 0x1007e1 주소의 배열 값을 추출하고, XOR 역연산을 통해 비밀번호를 복구했다.
- 복호화 결과 플래그는 S1mp13_x0r이며, CyberChef를 통해 해당 값이 정확함을 검증했다
'Security > 리버싱' 카테고리의 다른 글
| [Ghidra] 리버스 엔지니어링 기드라 실전 가이드 스터디 - chapter 5(level4-GO바이너리) (0) | 2026.01.24 |
|---|---|
| [Ghidra] 리버스 엔지니어링 기드라 실전 가이드 스터디 - chapter 5(level3) (0) | 2026.01.24 |
| [Ghidra] 리버스 엔지니어링 기드라 실전 가이드 스터디 - 기드라 취약점 3 (0) | 2026.01.23 |
| [Ghidra] 리버스 엔지니어링 기드라 실전 가이드 스터디 - chapter 5(level2) (0) | 2026.01.22 |
| [Ghidra] 리버스 엔지니어링 기드라 실전 가이드 스터디 - 00 (0) | 2026.01.04 |