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

분석 툴 : Immunity Debugger

 

 

 

먼저 exe 파일을 실행해보니 비밀번호를 입력해야 하는 것 같다.

hello 를 입력해보았다.

 

 

[Search for] - [All referenced text strings] 를 이용해 이 프로그램의 모든 스트링을 확인해본다.

 

 

 

정답일 때 나오는 듯한 문자열 "Congratulation !!"이 눈에 띄므로 더블클릭하여 해당 위치로 간다.

 

해당 함수의 시작점으로 가 bp를 걸고 한 줄씩 실행하며 어셈블리어를 쓰윽 분석해본다.

 

보통 CMP 구문에서 비교한 후, JNZ 구문을 실행할 지 말지를 결정하는 경우가 많다.

CMP A B 비교 구문. A와 B가 같은지 판단
(같을 경우 ZE는 1이 되고 다를 경우 ZE는 0이 된다.)
JNZ(Zump if not Zero)  Address 연산 결과가 0이 아니면(ZF=0)이동하고,
0이면 (ZE=1) 다음 명령을 실행

 

CMP 구문에서 [ESP+5] 자리의 값과 61을 비교하고 있다.

 

ESP+5 자리를 가보니 내가 입력한 hello 중에 e 가 자리잡고 있는 것을 확인할 수 있다.

 

즉, 내가 입력한 문자열의 두번째 자리와 61을 비교하여

두 문자가 같을 경우 ZF가 1이 되고, 나머지 경우에는 ZF가 0이 되어

00401135 주소로 갈지(ZF=0) 말지(ZF=1)를 결정한다는 것이다.

 

JNZ문이 실행되면 함수가 종료되어 "Incorrect Password"가 뜨므로 JNZ문이 실행되면 안된다.

 

61을 아스키 값으로 변경하면 a 이다.

따라서 비밀번호의 두번째 자리가 a라는 것을 알게된 셈이다.

 

 

 

이번엔 입력에 hallo 를 입력한 후 실행해본다.

 

JNZ 구문이 실행되지 않고 (ZF=1 이므로) 

밑의 명령어로 넘어온다.

 

 

LEA ECX, ~~[ESP+A] = "ECX에 ESP+A 값을 옮긴다"

 

 

 

ECX 값을 확인해보니

내가 입력했던 세번째 문자열부터 끝까지의 문자열("llo")이 담겨져 있다.

 

 

 

이후 CALL 함수를 실행하면 ZF가 0이 되어 

JNZ 구문에 걸린다.

 

따라서 ■a5y■ 임을 예상한다.

 

 

 

 

 

이제 ha5yllo를 입력한 후 실행을 해보았다.

 

0040606C 값("R3versing")을 ESI로 옮긴 후, 

ESP+10을 EAX에 옮기고 있다.

 

 

[ESP+10] 의 값을 확인하니 내가 입력했던 다섯번째 이후의 문자열("llo")이 보인다.

 

 

그리고 반복문이 나오는데,

반복문을 살펴보니

 

EAX 값과 ESI 값을 각각 DL, BL 레지스터에 넣고

그 둘을 CMP 구문으로 비교하고 있다.

 

즉, llo 와 R3versing을 비교하고 있는 것.

 

따라서 ■a5yR3versing 임을 예상한다.

 

 

다시 ha5yR3versing을 입력한 후 

 

반복문까지 거친 후 

CMP 구문을 또 만났다.

 

[ESP+4] 값과 45를 비교한다.

[ESP+4]에는 내가 입력했던 첫번째 문자열("h")가 있다.

45는 아스키 값으로 "E"이므로

 

 

최종 비밀번호를 유추할 수 있게되었다.

 

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

CodeEngn Challenge : Basic RCE L16  (0) 2021.03.30
CodeEngn Challenge : Basic RCE L15  (0) 2021.03.30
main 함수 찾기  (0) 2021.03.23
OllyDBG, 어셈블리어  (0) 2021.02.04
IAT & EAT  (0) 2021.01.25

리버싱

:: 소프트웨어 공학의 한 분야로, 이미 만들어진 시스템을 역으로 추적하여

처음의 문서나 설계기법 등의 자료를 얻어내는 일

 

즉, 사람이 인식하기 어려운 기계어를 재번역하고, 재번역된 코드를 읽어서 기능과 역할을 알아낸다고 보면 된다.

 

 

소스코드

 

Visual Studio 와 같은 개발 툴을 이용해서 코드를 작성하고 컴파일을 하면 실행 파일이 만들어진다.

TEST.exe 파일 확인

 

실행파일이 만들어졌다는 것은 우리가 작성한 코드가 기계어로 변환되었음을 의미한다.

 

기계어로 번역된 main()코드의 일부

 

그리고 이 기계어를 CPU가 읽어서 문자열을 출력시킨다.

TEST.exe 파일 실행

------------------------------------------------------------------------------------------------------------------------------

 

이제 실행 파일을 리버싱해보자

앞서 언급했듯이 실행 파일에는 기계어로 번역된 main() 함수 코드가 있다.

하지만 우리는 기계어를 읽을 수 없다.

 

따라서 리버싱 작업은 보통 WinDBG나 IDA, OllyDBG와 같은 디버깅(디컴파일러) 툴을 사용해서 이루어진다.

이러한 툴들은 사람이 인식하기 어려운 기계어를 재번역하는 데 일차적인 목적이 있다.

 

OllyDBG.exe와 같은 툴로 TEST.exe 파일을 확인하면 

기계어에서 어셈블리어로 재번역된 main()함수 코드를 확인할 수 있다.

 

TEST.exe 메인코드

 

리버싱은 한 마디로, "디버거에서 재번역해 준 어셈블리 코드를 잘 읽고, 기능과 역할을 도출하는 것"이다.

 

------------------------------------------------------------------------------------------------------------------------------

 

리버싱(분석) 방법

 

ⓐ 정적 분석(Static Analysis)

:: 파일을 실행하지 않고 파일의 겉모습을 관찰하여 분석하는 방법

  -- 파일의 종류, 크기, 헤더 정보(PE), Import/Export API, 내부 문자열, 실행 압축 여부, 등록 정보, 디버깅 정보, 디지털인증서 등의 다양한 내용을 확인할 수 있다.

  -- 디스어셈블러(ex; IDA)를 이용해 내부 코드와 구조를 확인할 수 있다.

 

==> 실행 파일을 구성하는 모든 요소, 대상 실행 파일이 실제로 동작할 CPU 아키텍처에 해당하는 어셈블리 코드를 이해하는 것이 필요

 

ⓑ 동적 분석(Dynamic Analysis)

: 파일을 실행시켜 행위를 분석하고, 디버깅하여 코드 흐름과 메모리 상태를 살펴보는 방법

  -- 파일, 레지스트리, 네트워크 등을 관찰하면서 프로그램의 행위를 분석한다.

  -- 디버거(ex; OllyDBG)를 이용하여 프로그램 내부 구조와 동작 원리를 분석한다.

 

==> 실행 단계별로 자세한 동작 과정을 살펴봐야 하므로, 환경에 맞는 디버거를 이용해 단계별로 분석하는 기술을 익혀야함

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

main 함수 찾기  (0) 2021.03.23
OllyDBG, 어셈블리어  (0) 2021.02.04
IAT & EAT  (0) 2021.01.25
PE 헤더  (0) 2021.01.24
PE File Format 이해  (0) 2021.01.23

+ Recent posts