[CTF] PICOCTF2019

picoCTF 2019 - asm2

レ(゚∀゚;)ヘ=З=З=З 2023. 12. 29. 15:40
728x90

asm2는 0x4, 0x21을 넣었을 때 return 값을 구하는 문제였다.

<주어진 코드>

asm2:
	<+0>:	push   ebp
	<+1>:	mov    ebp,esp
	<+3>:	sub    esp,0x10
	<+6>:	mov    eax,DWORD PTR [ebp+0xc]
	<+9>:	mov    DWORD PTR [ebp-0x4],eax
	<+12>:	mov    eax,DWORD PTR [ebp+0x8]
	<+15>:	mov    DWORD PTR [ebp-0x8],eax
	<+18>:	jmp    0x509 <asm2+28>
	<+20>:	add    DWORD PTR [ebp-0x4],0x1
	<+24>:	add    DWORD PTR [ebp-0x8],0x74
	<+28>:	cmp    DWORD PTR [ebp-0x8],0xfb46
	<+35>:	jle    0x501 <asm2+20>
	<+37>:	mov    eax,DWORD PTR [ebp-0x4]
	<+40>:	leave  
	<+41>:	ret

 <+0>:           push           ebp 
 <+1>:           mov            ebp, esp           까지 스택의 모양을 그려보았다.

push를 통해 0x4와 0x21이 스택에 들어간 것을 확인할 수 있다.

<+3>:                      sub           esp, 0x10

esp의 값에서 0x10를 뺀 다음에 esp에 넣는 것을 볼 수 있다. 16진수 10은 10진수로 16이므로 16byte만큼 공간을 얻은 것을 확인할 수 있다.

<+6>:             mov            eax, DWORD PTR [ebp+0xc]
<+9>:             mov            DWORD PTR [ebp-0x4], eax
<+12>:           mov            eax, DWORD PTR [ebp+0x8]
<+15>:           mov            DWORD PTR [ebp-0x8], eax

→ 이 코드들에서 [ebp-0x4], [ebp-0x8]이 사용되는 것을 보아 ebp보다 위쪽에 공간을 얻은 것 같았다.

→  그리고 mov를 통해 1. [ebp+0xc]를 eax에 저장 2. eax를 [ebp-0x4]에 저장 3. [ebp+0x8]를 eax에 저장 4. eax를 [ebp-0x8]에 저장 한다. 즉, [ebp+0xc]에 있는 0x21이 [ebp-0x4]에 저장되고, [ebp+0x8]에 있는 0x4가 [ebp-0x8]에 저장된다. 

<+18>:           jmp           0x509 

 28번째 줄로 점프한다.

<+28>:           cmp           DWORD PTR [ebp-0x8], 0xfb46

 [ebp-0x8]에 있는 값인 0x4와 0xfb46을 비교한다.


<+35>:           jle           0x501 
-> 위 코드에서 비교했을 때 앞의 값이 더 작으므로 20번째 줄로 점프한다.

더보기

jle : 점프 부호 있는 값 중 앞의 값이 작거나 같을 때(<=) 점프

<+20>:           add           DWORD PTR [ebp-0x4], 0x1

 [ebp-0x4]에 있는 값에 0x1을 더한 값인 0x22를 [ebp-0x4]에 넣어준다. 

더보기

 add : [add 인자1인자2]일 때 인자1+인자2 값을 인자1에 대입

<+24>:           add           DWORD PTR [ebp-0x8], 0x74

 [ebp-0x8]에 있는 값에 0x74를 더한 값인 0x78을 [ebp-0x8]에 넣어준다.

<+28>:           cmp           DWORD PTR [ebp-0x8], 0xfb46

→  cmp를 통해 [ebp-0x8]의 값인 0x78과 0xfb46을 비교한다.

<+35>           jle           0x501 

→  위 코드에서 앞의 값이 더 작았기 때문에 20번째 줄로 점프한다.

이를 통해서 [ebp-0x8]의 값이 0xfb46보다 커질 때까지 <+20>, <+24>, <+28>, <+35>를 반복하는 것을 알 수 있다. 계산하려면 오래 걸릴 것 같아서 c언어로 코드를 짜보았다.

#include <stdio.h>

int main() {
	int x = 0x4;
    int y = 0x21;
    
    while(1) {
    	x += 0x74;
        y += 0x1;
        
        if(x > 0xfb46) {
        	printf("[ebp-0x8] : 0x%x\n ", x);
            printf("[ebp-0x4] : 0x%x\n ", y);
            break;
        }
    }
    return 0;
}

계속해서 0x74와 0x1을 더하도록 코드를 생성하였다.

위와 같은 결과가 나왔다. 

<+28>:           cmp           DWORD PTR [ebp-0x8], 0xfb46
<+35>:           jle           0x501 

→  [ebp-0x8]이 0xfb46보다 크므로 점프를 하지 않고 아래 코드를 실행한다.

<+37>:           mov           eax, DWORD PTR [ebp-0x4]

→  함수의 반환값이 저장되는 eax에 [ebp-0x4]의 값인 0x24c를 저장한다.

<+40>:           leave
<+41>:           ret

 eax가 반환된다. 

flag의 값은 picoCTF{0x24c}이다.

'[CTF] PICOCTF2019' 카테고리의 다른 글

picoCTF 2019 – asm3  (0) 2023.12.29
picoCTF 2019 - asm1  (0) 2023.12.29