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 |