[그림 1] 문제

OEP를 찾고 Stolenbyte까지 찾는 문제이다.

OEP를 찾는 문제이므로 패킹되어있을 가능성이 아주 높다.

 

[그림 2] PEiD로 확인

PEiD로 확인해본 결과, UPX로 패킹이 되어있다. UPX로 패킹되어 있는 실행파일은 간단하게 upx 툴을 이용하여 언패킹이 가능하다.

 

[그림 3] upx -d 옵션으로 언패킹
[그림 4] 언패킹 된 11.exe를 OllyDBG로 실행

언패킹된 실행 파일을 다시 OllyDBG에 올렸더니 

MessageBox 함수에 들어갈 인자가 모자름을 단번에 알 수 있었다.

 

[그림 5] MessageBox

결과는 예상대로 깨진 문자열이 나온다.

이는 unpacking시 문제가 됐을 가능성이 있으므로 unpacking 되지 않은 파일의 POPAD 명령어 부분을 확인해보았다.

 

[그림 6] 패킹되어있는 11.exe의 POPAD 부분

POPAD 이후 스택에 적재되는 세 개의 값을 확인할 수 있었다.

 

OEP로 점프하는 구간에 BP를 걸고 실행시켰더니

MessageBoxA 함수 호출에 필요한 인자들이 스택에 PUSH 됨을 알 수 있고,

이를 통해 PUSH 되는 인자들이 StolenByte 임을 확인했다.

 

 

[그림 7] 코드 수정

Unpacking 했던 실행 파일에서 Ctrl+E를 통해 코드 수정을 하였다.

 

 

[그림 8] 정상적 실행 확인

부족한 인자를 완성 시키고 실행시켰더니 그림8과 같이 정상적으로 실행됨을 확인할 수 있다

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

CodeEngn Challenge : Basic RCE L14  (0) 2021.05.11
[HackCTF] Reversing Me 풀이  (0) 2021.05.11
CodeEngn Challenge : Basic RCE L10  (0) 2021.05.06
CodeEngn Challenge : Advance RCE L09  (0) 2021.04.28
CodeEngn Challenge : Advance RCE L03  (0) 2021.04.28

[그림 1] 문제
[그림 2] 10.exe

10.exe는 Name에 알맞는 Serial을 적는 실행파일이다.

[그림 3] PEiD로 분석

OEP 관련 문제들은 패킹과 연관이 되어있을 가능성이 높기 때문에 PEiD에 10.exe를 올려보니 Aspack으로 패킹되어있는 것을 알 수 있다.  

Aspack은 UPX와 비슷하게 처음에 PUSHAD를 통해 레지스터의 값을 넣고 디코딩 한 후 POPAD를 한다고 한다.

 

UPX로 패킹되어 있는 실행파일의 OEP 구하는 방법은 아래 글 참고!

https://these-dayss.tistory.com/53?category=957855

 

 

[그림 4] 처음 실행코드

처음에 예상대로 PUSHAD 명령어가 있다. 

 

[그림 5] Hardware BP

PUSH 명령어 실행 후 스택에 Break Point를 건다.

 

 

[그림 6] [F9] 실행

BreakPoint를 건 곳까지 실행하면 [그림 6]과 같이 POPAD 후, JNZ 구문에 의해 분기가 일어난 후 특정주소(00445834)를 PUSH 하는것을 알 수 있다. 이 주소가 바로 OEP 주소라고 할 수 있다.

 

 

[그림 7] 00445834로 이동

OEP 주소로 이동해보니 디버거가 OPCODE를 제대로 인식하지 못하고 있다. 이런 경우, 덤프를 해줘야한다고 한다.

 

 

[그림 8] OllyDump

OllyDump 툴을 사용하여 OEP를 수정한 후 덤프를 떠준다.

 

(Immunity Debugger는 따로 덤프 툴이 없어서 OllyDBG로 변경)

 

[그림 9] 덤프 뜬 실행 파일
[그림 10] text string 으로 찾은 well done 문자열
[그림 11] well done으로 가는 분기문

해당 주소를 찾아가보면 OPCODE는 75 55 임을 확인할 수 있다.

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

[HackCTF] Reversing Me 풀이  (0) 2021.05.11
CodeEngn Challenge : Basic RCE L11  (0) 2021.05.06
CodeEngn Challenge : Advance RCE L09  (0) 2021.04.28
CodeEngn Challenge : Advance RCE L03  (0) 2021.04.28
CodeEngn Challenge : Basic RCE L09  (0) 2021.04.07

문제

다짜고짜 password를 묻는다

 

 

실행화면

처음에 그냥 실행해봤고

예상대로 Sorry~ 문자열이 나왔다.

 

 

실행파일에 쓰인 텍스트 확인

실행하자마자 텍스트를 확인해봤다

[마우스 오른쪽]-[Search For]-[All referenced text strings]를 통해 확인이 가능하다

 

DonaldDuck이라는 문자열이 눈에 띄어서 Username이라고 짐작했다

 

DonaldDuck이 있던 곳의 맨 처음으로 가서 BP를 건 후 한줄씩 실행

BP를 건 후 [F9]키로 실행해주었다

Username과 Password를 입력하라고 하여서 

Username에 DonaldDuck, Password 자리에 1234를 적어주었다

 

그러고 나니 003E1008 위치에 DonaldDuck이 뜨는 것을 확인할 수 있었다

 

 

CMP 구문 확인

우리가 만난 첫 번째 분기문에선

우리가 입력한 Username의 첫 번째 자리와 0x00(NULL값)을 비교한다는 것을 알 수 있다

우리는 Username에 값을 입력했기 때문에 

JNE 명령어로 인해 003E1030 주소로 바로 이동하게 된다

 

두 번째 CMP

다음으로 만난 CMP 문이다

CMP EAX, DWORD PTR DS:[ECX] 부분에서 우리가 입력한 password값과 ecx값을 비교하고 있다

 

ECX 값 확인

HEX 창에서 ECX 주소로 가보니 0088228F라는 값이 적혀있다

이는 16진수이므로

10진수로 바꿔주면 8,921,743이 된다

password가 8921743일 것이라고 예상할 수 있다

 

 

Username과 DonaldDuck을 비교하는 구문

앞에서 예상은 했지만 입력한 Username과 'DonaldDuck' 문자열을 비교하는 구문이 있는 것을 확인할 수 있다.

따라서 Username이 DonaldDuck이라는 것이 확실해졌다

 

 

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

CodeEngn Challenge : Basic RCE L11  (0) 2021.05.06
CodeEngn Challenge : Basic RCE L10  (0) 2021.05.06
CodeEngn Challenge : Advance RCE L03  (0) 2021.04.28
CodeEngn Challenge : Basic RCE L09  (0) 2021.04.07
CodeEngn Challenge : Basic RCE L06  (0) 2021.04.07

문제

Name이 CodeEngn 일때 Serial이 무엇인지 맞추는 것이다

 

 

PEiD로 패킹 여부 판단

EP Section이 올바르게 나오고 컴파일 환경도 나오는 것을 보니 패킹이 되어있지 않은 실행파일이라고 판단했다

 

 

실행파일 실행 결과

아직 아무것도 모르는 상태이기에 

Hello 라는 문자열을 적었고

예상대로 Fail 창이 떴다

 

 

 

결정적 힌트

코드를 쭉 내려보다가 lstrcmpA라는 함수가 보였다.

 

lstrcmpA 함수는 Window32 API로, 두 문자열의 대소 관계를 비교하나
일반적으로 두 문자열이 같은지 다른지를 비교할 목적으로 많이 사용한다.
단순히 문자열의 동등성 여부만 판단할 경우는 리턴값이 0인지 아닌지만 점검하며 대소 관계를 판단할 때는 리턴값의 부호를 점검하면 된다.
영문자를 비교하는 경우 대소문자도 비교하므로 대소문자 구분없이 비교하려면
CharUpper 등의 함수로 모두 대문자로 바꾼 후 비교하거나 아니면 lstrcmpi 함수를 사용해야 한다.

 

여기에 내가 입력했던 Hello 문자열과 어떤 숫자를 비교하는 걸 확인했고

 

 

결과

이를 그대로 넣어주니 succeeded 메시지가 떴다

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

CodeEngn Challenge : Basic RCE L10  (0) 2021.05.06
CodeEngn Challenge : Advance RCE L09  (0) 2021.04.28
CodeEngn Challenge : Basic RCE L09  (0) 2021.04.07
CodeEngn Challenge : Basic RCE L06  (0) 2021.04.07
CodeEngn Challenge : Basic RCE L16  (0) 2021.03.30

[그림1] stolenbyte를 구하는 문제
[그림2] 실행창1
[그림3] 실행창2

 

StolenByte

 패킹된 바이너리를 언패킹할 때의 과정을 방해하기 위한 방법으로, 프로그램의 일부 바이트를 별도의

영역에서 실행되게 하여 OEP를 다른 위치로 가장하고 덤프를 쉽게 하지 못하도록 구현한 기법

 

 패커가 패킹을 진행할 때, 원본 코드 중 일부를 다른 곳으로 이동 시킨 코드로써, 주로 EP 위의 몇 줄의 코드이다

 

  올바른 프로그램을 얻기 위해서는 패킹 과정에서 떼어진 StolenByte를 함께 복원해야 덤프가 성공적으로 이루어진다

 

[그림4] 프로그램의 시작 코드가 PUSHAD로 되어 있다. 패킹된 파일임을 짐작할 수 있다.

 

[그림5] PEiD로 확인한 결과. 역시 UPX 로 패킹이 되어있다.

 

[그림6] upx -d 옵션을 활용해 unpacking

 

[그림7] unpacking 후 확인한 코드
[그림8] 0040100E 주소의 MessageBox함수 호출 결과

unpacking 후 디버거로 열었을 때, 처음에 NOP로 덮어진 부분이 눈에 띄었다.

첫 번째로 실행되는 MessageBoxA 함수에 전달할 인자가 부족함을 알 수 있었고

이를 실행했을 때, 온전하지 못한 글자들과 함께 결과가 보여짐을 확인할 수 있었다.

 

이를 통해 부족한 인자들이 문제와 연관있음을 예측했다.

 

 

[그림9] unpacking 하지 않은 실행파일의 POPAD 부분 확인

unpacking 시 stolenbyte 문제가 생긴다는 것을 깨달은 후,

다시 원본 실행 파일에서 POPAD 부분을 찾아갔다.

(POPAD 찾는 방법은 아래를 확인)

2021.04.07 - [Study/Reversing] - CodeEngn Challenge : Basic RCE L06

 

그리고 POPAD 이후 스택에 적재되는 세 개의 값을 확인할 수 있었다.

 

OEP로 점프하는 구간에 BP를 걸고 실행시켰더니

MessageBoxA 함수 호출에 필요한 인자들이 스택에 PUSH 됨을 알 수 있고,

이를 통해 PUSH 되는 인자들이 StolenByte 임을 확인했다.

 

 

[그림10] NOP로 덮여진 부분

 

[그림11] [Ctrl+E] 로 코드 변경

 

[그림12] 정상적 unpacking 성공

 

따라서 stolenbyte는 6A0068002040006812204000 이다.

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

CodeEngn Challenge : Advance RCE L09  (0) 2021.04.28
CodeEngn Challenge : Advance RCE L03  (0) 2021.04.28
CodeEngn Challenge : Basic RCE L06  (0) 2021.04.07
CodeEngn Challenge : Basic RCE L16  (0) 2021.03.30
CodeEngn Challenge : Basic RCE L15  (0) 2021.03.30

[그림1] 문제

문제에서 packing이 된 실행파일이라는 것을 알려주고 있다.

 

[그림2] 첫 실행화면

 

[그림3] 값 입력 후 뜨는 결과창

 

[그림4] PEiD로 확인한 실행파일

+) PEiD는 파일의 PE 정보로 패킹, 암호화, 컴파일에 사용된 프로그램을 찾아준다.

실행파일을 올려 확인해 보니 UPX 프로그램으로 패킹됐음을 유추할 수 있다.

 

 

<Packing & UnPacking 설명 참고>

더보기

패킹(packing)은 "실행 압축"이라고 표현할 수 있다.

실행 파일 내부에 있는 코드를 압축하여 평소에는 코드를 압축한 상태로 저장하고 있다가

파일을 실행하면 메모리에서 압축을 해제 시킨 후 파일을 실행시키는 기술이다.

 

장점

1. 파일의 크기를 줄일 수 있다.(전 후 3~4배의 차이가 있다)

2. 크래커의 리버싱으로부터 보호할 수 있다.

 


언패킹(unpacking)은 말 그대로 패킹을 푸는 것이다.

특히 UPX Compressor를 사용하는 경우는 아래의 상황이다.

- UPX 기준 설명

1. 운영체제의 Loader가 실행파일을 메모리에 올린다

2. Packing된 파일은 Unpacking Code 시작부분이 Entry Point이다.

3. EP에서 프로그램이 시작된다.

4. Packing된 파일은 Unpacking Code 영역에 들어있다.

5. Unpacking Code는 패킹된 데이터를 하나씩 읽어 압축을 풀고 Empty Space(빈 공간)에 원래 데이터를 저장한다.

6. 모든 코드가 Unpacking 되었다면 Original Entry Point(OEP)에서 프로그램이 다시 시작된다.

 

즉, OEP는 Unpacking 되기 이전 실행파일의 시작점이다

 

<UPX로 패킹된 실행파일을 unpacking 하는 방법>

1. upx 프로그램의 -d 옵션 사용

[그림5] upx 프로그램으로 unpacking 하는 과정

-d 옵션을 사용하면 패킹된 파일을 언패킹한 후 덮어 씌울 수 있다.

 

그 후 디버거에 올려서 실행하면 바로 OEP를 알 수 있다.

 

 

2. PUSHAD/POPAD 명령어 찾기

- UPX는 실행 파일 압축 프로그램으로 함수를 계속 진행하면 OEP에 도달할 수 있다.

UPX는 PUSHAD와 POPAD를 활용해 언패킹한다.

 

PUSHAD는 범용 레지스터의 값들을 스택에 저장하며, POPAD와 짝을 이루어서 사용된다.

코드의 PUSHAD가 진행되면 범용 레지스터의 값들을 EAX, ECX, EDX, EBX, ESP, EBP, ESI, EDI 순서로 스택에 저장한다.

POPAD는 스택에 저장된 레지스터 값들을 다시 레지스터에 입력한다.

보통 POPAD 밑에 점프문이 있으며 이 점프문 주소에 해당하는게 OEP인 경우가 많다.

 

① PUSHAD를 지나 마지막 레지스터 값(EDI)이 스택에 저장되었을 때,

② 그 스택부분에 BP(Break Point)를 걸면

③ POPAD에서 마지막 레지스터(EDI)를 복구시킨 후 정지된다. (스택 BP 사용시 해당 스택의 데이터가 접근 되는 시점에 브레이크가 잡히게 된다.)

④ 마지막으로 , POPAD가 끝난 후 진행되는 코드를 진행하면 원본 시작 코드로 진입할 수 있다.

 

[그림7] packing된 실행파일 처음 화면

 

[그림8] PUSHAD 작동 후 상황

각 레지스터에 값이 저장되어 있고 마지막으로 PUSH 되었던 EDI의 주소로 가 스택에 저장된 값을 확인한다.

 

[그림9] 마지막으로 PUSH 된 레지스터 값에 접근

 

[그림10] 스택에 BP 걸기

 

[그림11] [F9]키 실행 결과

이 점프문 주소(00401360)에 해당하는 게 OEP 이다.

 


문제는 OEP 뿐만이 아니라 Serial 값을 찾도록 요구하고 있다.

따라서 이 실행파일을 unpacking 한 후 다시 분석해보았다.

 

[그림12] 프로그램에 사용된 문자열들을 확인

잘못된 값을 입력했을 때 GUI 모드로 'Wrong serial!'이라는 문자열이 떴기 때문에 

프로그램에 사용된 문자열들을 확인한다.

 

[그림13] 선택한 문자열 주변 코드

'You got it' 이라는 문자열 코드가 있는 부분을 선택해 주변을 살펴보았다.

CMP 문과 JMP문이 사용된 것으로 보아 내가 입력한 값과 정답 serial 값을 비교해 

성공인지 실패인지를 가려내어 결과를 보여주는 것으로 보인다.

 

JMP문에 [F2]키를 사용해 BP를 걸고 [F9]키를 사용해 실행한다.

 

[그림14] 그러면 이러한 실행창이 뜬다.

 

[그림15] 값을 입력하고 Check Serial 버튼을 누른 결과

 

내가 입력한 값이 어디론가 PUSH 되고 있다.

아마 그 다음에 나오는 "AD46DFS547"이라는 값과 비교하여 결과가 나뉘는 것 같다.

 

따라서 정답 serial 은 "AD46DFS547" 이라고 유추 가능하다.

 

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

CodeEngn Challenge : Advance RCE L03  (0) 2021.04.28
CodeEngn Challenge : Basic RCE L09  (0) 2021.04.07
CodeEngn Challenge : Basic RCE L16  (0) 2021.03.30
CodeEngn Challenge : Basic RCE L15  (0) 2021.03.30
Reversing.kr 1번 풀이  (0) 2021.03.24

분석 도구 : Immunity Debugger

 

저번 게시물에 올렸던 CodeEngn 15번 문제와 아주 유사하다

 

2021.03.30 - [Study/Reversing] - CodeEngn Challenge : Basic RCE L15

참고하면 이해하는 데 아주 도움이 될 것이다!!!!!!!

 

이번엔 CUI 모드로 작동하는 듯 싶다.

 

잘못된 password를 입력하면 'Wrong password!' 문자열이 뜨고

해당 exe 파일이 있는 곳에 null 이라는 파일이 생긴다.

 

[Search for] - [All referenced text strings] 를 통해 힌트 구간을 얻어본다.

 

'Good job!' 이 있는 곳을 더블클릭하여

해당 코드가 있는 곳으로 이동한다.

 

 

이번에도 역시 분기문이 보인다. (CMP)

 

EAX 값과 SS 값(EBP-3C 주소 기준 4byte) 를 비교한 후,

두 값이 같지 않으면 

'wrong password!' 문자열이 출력되는 주소로 점프해버린다.

 

따라서 우리는 EAX 값에 어떤 값이 들어가는지EBP-3C에 들어가있는 값을 확인해야 한다.

 

 

4015A2 에 BP를 건 후 실행하였고, password(serial)에는 1234를 입력해 주었다.

EAX에 들어가는 것은 우리가 입력했던 1234(10진수)가 000004D2(16진수)로 바뀐 형태의 값인 것을 알 수 있다.

 

 

EBP-3C에 있는 값은 E4C60D97 이다.

따라서 우리가 원하는 serial 값을 찾을 수 있다.

 

 

 

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

CodeEngn Challenge : Basic RCE L09  (0) 2021.04.07
CodeEngn Challenge : Basic RCE L06  (0) 2021.04.07
CodeEngn Challenge : Basic RCE L15  (0) 2021.03.30
Reversing.kr 1번 풀이  (0) 2021.03.24
main 함수 찾기  (0) 2021.03.23

분석 도구 : Immunity Debbuger

 

문제는 Name이 CodeEngn일 때 Serial을 구하라는 것

 

해당 exe 파일을 실행해보니 실제로 Name과 Serial을 적는 칸이 있다.

 

애초에 문자는 입력할 수 없는 것 같고

 

맞지 않는 Serial 숫자를 적으면 'Try Again !' 이라는 문자열이 뜨는 것 같다.

 

 

디버거에 실행 파일을 올린 후 분석 시작

 

먼저 'Try Again !' 등 문자열이 있는 곳에 문제의 해답이 있을 수 있으므로

[Search for] - [All referenced text strings] 로 실행 파일에 담겨진 모든 문자열을 확인한다.

 

 

crack이 목적이므로

'CRACKED' 가 있는 곳으로 더블클릭하여 이동한다.

 

 

+) CMP Dest, Src

CMP 구문은 두 개의 피연산자를 비교한다.

Destination 피연산자에서 Source 연산자를 묵시적으로 빼서 값을 비교한다.

 

두 피연산자의 값이 같으면 결과는 0이 될 것이고, ZF(Zero Flag)는 1이 된다.

두 값이 다르면 결과는 0이 아닌 값, ZF는 0이 된다.

 

+) 명령어 DWORD PTR DS : [주소값]

DWORD 는 크기(BYTE : 1byte, WORD : 2bytes, DWORD : 4bytes),

PTR 은 기준을 의미한다.

 

즉, '주소값을 기준으로 4byte를 ~명령어~ 한다' 는 의미

 

 

따라서, CMP EAX, DWORD PTR DS:[45B844]의 의미는

EAX 값과 DS 값(45B844 주소 기준 4Byte 값)을 비교해서 

두 값이 같으면 ZF=1, 다르면 ZF=0 이 된다는 것

 

 

+) JNZ (Jump Not Zero) 주소 = JNE (Jump Not Equal) 주소

결과가 0이 아닐 때(ZF=0) 해당 주소로 이동하고,

0이 아닐 때(ZF=1) 바로 다음(아래) 명령어를 실행한다.

 

 

따라서, JNZ SHORT 00458854 의 의미는

위에서 비교했을 때 두 값이 같으면 바로 다음 명령어를 실행(성공 메시지),

두 값이 다르면 00458854(Try Again) 로 점프한다는 것

 

 

분기점 (00458837) 에 BP를 설정하고

두 개중 어떤것에 serial 값이 저장됐는지 확인하면 쉽게 serial 값을 얻을수 있을 것이다.

 

 

serial 값에 1234 를 입력했더니 

EAX 에 000004D2가 저장이 된다.

 

우리가 입력한 1234(10진수) → 4D2(16진수)로 바뀌어 저장된 것 !!!

 

 

CMP 명령어에서 DS 값 (45B844 주소 기준 4Byte)과 비교하므로

45B844 주소로 가서 들어있는 값을 확인하였다.

00006160(16진수)가 저장되어 있다. 

이제 이를 10진수로 변경하면 원하는 serial을 획득할 수 있다!

 

00006160 → ?????

 

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

CodeEngn Challenge : Basic RCE L06  (0) 2021.04.07
CodeEngn Challenge : Basic RCE L16  (0) 2021.03.30
Reversing.kr 1번 풀이  (0) 2021.03.24
main 함수 찾기  (0) 2021.03.23
OllyDBG, 어셈블리어  (0) 2021.02.04

분석 툴 : 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

우리가 Main 함수를 작성할 때, 딱히 정해진 방식이 있는 것은 아니다.

 

- 메인함수 선언 방식

1. int main()
2. int main(void)
3. int main(int argc, char *argv[], char *envp[])

 

main함수 원형은 3번과 같이 인자와 환경변수 전달을 같이 받는다.

 

 

-컴파일 과정에서의 메인 구성

int main(int argc, char *argv[], char *envp[])

사용자가 어떻게 작성하던 간에 컴파일 과정에서는 원형이 지켜지게 된다.

 

즉, main 호출은 인자를 3개 전달한다.

CALL 00401000이 이 실행파일의 main 함수이다.

main 함수를 찾지 못하겠을 때 이와 같은 방법이 조금 도움이 될 수 있겠다.

 

 

 


*참고 : Visual Studio 6.0 에서 작성된 실행파일의 Stub 코드

 

Stub 코드의 흐름을 보고 main() 호출이 어느 지점에서 일어날 지 예측할 수 있다.

 

ex:) main()함수가 GetCommandLineA() 호출보단 뒤에, exit() 호출보단 앞에 있을 것으로 예측하며 

main()함수의 위치를 대략 예상할 수 있다.

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

CodeEngn Challenge : Basic RCE L15  (0) 2021.03.30
Reversing.kr 1번 풀이  (0) 2021.03.24
OllyDBG, 어셈블리어  (0) 2021.02.04
IAT & EAT  (0) 2021.01.25
PE 헤더  (0) 2021.01.24

+ Recent posts