C ----컴파일----> CPU가 읽을 수 있는 언어(기계어) 11010011 ----디스어셈블 ----> 어셈블리어

 

어셈블리어

- 한 가지 동작까지 세세하게 지정

- 주로 IA-32 를 사용(Intel)

- 기본형태 : 명령어(opcode) + 인자(operand 1~2)

 


CPU가 사용하는 변수, 저장공간 (레지스터)

:: EAX (연산 Accumulator, 리턴 값 저장)

:: EBX, EDX (목적이 없는 레지스터, 공간 필요시 사용)

:: ECX (for문에서 i의 역할 Count, 변수로 사용해도 무방)

:: ESI, EDI (source index, destination index. 문자열이나 반복데이터 처리, 메모리 옮기는데 사용)

:: ESP (스택포인터)

:: EBP (베이스포인터)

:: EIP (인스트럭션 포인터, CPU가 실행할 명령어를 가리킴)


어셈블리 명령어

- PUSH, POP (PUSHAD, POPAD) : 모든 레지스터에 있는 값들을 스택에 push, pop

- MOV : source를 가져옴

- LEA : source의 주소를 가져옴

- ADD : +

- SUB : -

- INT : 잠깐 정지

- CALL : 함수 호출

- INC, DEC : i++, i--

- AND, OR, XOR : bit 연산

- NOP : 실행하지 않고 다음 단계로 넘어감

- CMP, JMP : 비교, 점프

 


리버스 엔지니어링에 필요한 스택

> 함수 프롤로그 & 함수 에필로그

함수 프롤로그는 스택을 만드는 역할, 에필로그는 스택을 지우는 역할을 한다.

 

ex) main함수에서 plus라는 함수를 또 호출하는 상황 = 프롤로그

push ebp          이전 함수의 ebp를 스택에 저장하기 위해

mov ebp, esp     esp 값을 ebp에 저장. 같은 곳을 가리키게 됨

sub esp, 50h      esp에서 50h 위치만큼 값을 줄임(esp가 위로 상승) 

                        --> 그 결과, 새로운 plus 함수를 위한 스택 공간이 할당됨

 

.....

 

plus 함수에서 main 함수로 돌아가는 상황 = 에필로그

mov esp, ebp     돌아가기 위해(스택 정리) ebp를 esp에 할당해줌

pop ebp            ebp를 스택에서 빼면 main 함수의 다음행 주소가 스택에 있고 

retn                  main 함수로 돌아간다.

 

 


<reverseMe.exe 분석>

 

만료일이 다 됐으니 라이선스를 구매하라는 문구가 뜨고 확인을 누르면 그대로 꺼진다

 

이 파일을 제대로 동작하게 만들어 보겠다

 

실행파일의 전체적 코드

코드를 보다보니 CreateFileA 함수가 눈에 띈다.

MSDN에서 찾아봤다.

 

CreateFile 함수는 파일을 생성하는 것뿐만 아니라 파일을 읽어오기도 한다고 한다.

그리고 코드 내에서 dwShareMode가 OPEN_EXISTING 값을 가지는데 이것은 무슨 의미인지 확인해보았다.

 

CreateFile이라고 해서 단순히 File을 생성하는 것인줄 알았으나 

제대로 알아보니 file 또는 장치가 있다면 이를 열어주는 작업을 하고 있다.

 

CreateFile 함수 이후

EAX와 -1을 비교하고 있다. EAX에 FFFFFFFF가 들어있으므로 둘은 같다.

따라서 CMP 문을 지나면 ZF가 1(참)이 되고, JNZ 명령어를 따를 필요가 없으므로 

처음에 봤던 문장 "Evaluarion period out,,,," 을 띄우는 MessageBox 함수 부분을 실행한다.

 

 

그래서 일단 

ZF를 0으로 임시로 바꿔준 후 ReadFile 함수를 실행하도록 한다.
ReadFile 함수 이후

TEST EAX, EAX 명령어를 실행한다.

EAX는 0 이므로 ZF는 1이 되어

JNZ를 따르지 않고 그 밑의 JMP 명령어를 실행한다.

 

JMP 명령어 이후

파일이 존재하지 않는다는 오류와 함께 프로세스가 종료된다.

 

그렇다면 이 파일이 존재할 때는 어떨까?

 

Keyfile.dat 파일 생성
저장

 

ReadFile 함수 결과

그 결과 EAX가 1의 값을 가지는 것을 알 수 있고

 

원하던 위치로 오게 되었다.

XOR 명령어로 EBX와 ESI를 각각 0으로 만들어준 후

CMP DWORD PTR DS:[412173], 10 명령어로 402173에 있는 값과 10을 비교하고 있다.

밑에 나와있듯이 DS:[00402173]값은 4이므로 

JL 명령어를 따라 004010F7 위치로 점프하게 된다.

 

 

그러면 00402173에 있는 값이 10보다 크면 될까?

(이 값이 무엇을 의미하는지 나중에 알게 됐다)

 

00402173 값을 a로 변경하여 HEX 값이 10보다는 크게 만든다
40211A에 있는 값을 AL로 MOV 한다

0040211A부터는 우리가 적었던 내용인 test가 있고 여기서부터 파일의 내용을 다루는 것 같다.

 

MOV 명령어 이후 AL = 74('t') 이므로 

CMP AL, 0 결과는 1 

같지 않기 때문에 JE 명령어를 건너뛰고 

CMP AL, 47 명령어로 AL과 47('G')을 비교한다.

 

비교 결과 같지 않기 때문에 

INC ESI를 건너뛰고

INC EBX로 바로 간다.

이것을 4번 반복하고 (입력한 내용만큼 반복)

CMP ESI, 8 명령어를 실행한다.

ESI는 0이기 때문에 JL 명령어를 실행하지 않고 바로 아래 명령어를 실행하고 ,,

 

그 결과 

성공

 

따라서 유추해보면 Keyfile.dat에 들어있는

글자수는 16 이상이어야 하고, 8개 이상의 G 문자가 필요한 것이다. 

 

 

 

 

 

Keyfile.dat 수정

 

성공

'Study > Reversing' 카테고리의 다른 글

Lena 2번 풀이/Rena's Reversing Tutorial 02  (0) 2021.10.27
윈도우 실행 파일과 패커  (0) 2021.10.06
악성코드 유형  (0) 2021.09.18
Suninatas_11번 문제 풀이  (0) 2021.05.19
Reversing.kr _Easy Unpack 풀이  (0) 2021.05.18

+ Recent posts