7주차과제

조승현·2022년 11월 25일
0

EVI$ION_전체세션

목록 보기
6/6
post-thumbnail

Pwnable

소스코드 해석하기

간단한 코드를 짜봤습니다
사용자로부터 숫자 두개를 입력 받고 그 합을 반환하는 프로그램

#include <stdio.h>

int sum(int a, int b);

int main(void) {
00B41990  push        ebp  //기존 ebp 값을 스택에 쌓는다
00B41991  mov         ebp,esp  //esp값을 ebp에 할당
00B41993  sub         esp,0DCh  //스택의 공간은 224만큼 공간을 늘림
00B41999  push        ebx  //ebx를 스택에 push
00B4199A  push        esi  //esi를 스택에 push
00B4199B  push        edi  //edi를 스택에 push
00B4199C  lea         edi,[ebp-1Ch]  //ebp-1Ch를 edi에 대입
00B4199F  mov         ecx,7  
00B419A4  mov         eax,0CCCCCCCCh  
00B419A9  rep stos    dword ptr es:[edi]  
00B419AB  mov         eax,dword ptr [__security_cookie (0B4A004h)]  
00B419B0  xor         eax,ebp  
00B419B2  mov         dword ptr [ebp-4],eax  
00B419B5  mov         ecx,offset _8486901B_소스@cpp (0B4C008h)  
00B419BA  call        @__CheckForDebuggerJustMyCode@4 (0B4132Ah)  
	int a, b;
	scanf_s("%d", &a);
00B419BF  lea         eax,[a]  
00B419C2  push        eax  
00B419C3  push        offset string "%d" (0B47B30h)  //사용자가 입력한 값을 push
00B419C8  call        _scanf_s (0B41285h)  //scanf_s 함수 호출
00B419CD  add         esp,8  //push를 두번해서 디로 간 스택을 다시 앞으로
	scanf_s("%d", &b);
00B419D0  lea         eax,[b]  
00B419D3  push        eax  
00B419D4  push        offset string "%d" (0B47B30h)  
00B419D9  call        _scanf_s (0B41285h)  
00B419DE  add         esp,8  
	printf("%d", sum(a, b));
00B419E1  mov         eax,dword ptr [b] //eax 레지스터에 b의 주소에 저장된 데이터 복사 
00B419E4  push        eax  
00B419E5  mov         ecx,dword ptr [a]  //ecx 레지스터에 a의 주소에 저장된 데이터 복사 
00B419E8  push        ecx  
00B419E9  call        sum (0B41181h)  //sum 함수 호출
00B419EE  add         esp,8  
00B419F1  push        eax  
00B419F2  push        offset string "%d" (0B47B30h)  
00B419F7  call        _printf (0B410D7h)  
00B419FC  add         esp,8  
}
00B419FF  xor         eax,eax  
00B41A01  push        edx  
00B41A02  mov         ecx,ebp  
00B41A04  push        eax  
00B41A05  lea         edx,ds:[0B41A30h]  
00B41A0B  call        @_RTC_CheckStackVars@8 (0B411EFh)  
00B41A10  pop         eax  //스택 가장 위에 있는 값을 꺼내서 eax에 저장 (stack은 lifo)
00B41A11  pop         edx  
00B41A12  pop         edi  
00B41A13  pop         esi  
00B41A14  pop         ebx  
00B41A15  mov         ecx,dword ptr [ebp-4]  
00B41A18  xor         ecx,ebp  
00B41A1A  call        @__security_check_cookie@4 (0B4114Fh)  
00B41A1F  add         esp,0DCh  
00B41A25  cmp         ebp,esp  
00B41A27  call        __RTC_CheckEsp (0B4124Eh)  
00B41A2C  mov         esp,ebp  
00B41A2E  pop         ebp  
00B41A2F  ret  
00B41A30  add         al,byte ptr [eax]  
00B41A32  add         byte ptr [eax],al  
00B41A34  cmp         byte ptr [edx],bl  
00B41A36  mov         ah,0  
00B41A38  hlt   

주어진 어세블리어 코드 c언어로 변환하기

후.. 살펴봅시다

먼저 main 함수에서 메모리 할당을 하네요

변수를 선언하는 것으로 추정되는 부분

mov: 변수의 값을 저장
lea: 변수의 주소를 저장

이 둘의 차이로 보아 movl로 4byte의 변수(int 타입)를 선언했고
lea로 변수의 주소값을 하나 선언했습니다
그러고 다시 mov로 lea를 통해 주소값을 저장한 것을 0x10(%rbp)에 저장

sub 명령어가 있는것으로 보아 차이를 계산하고 다시 변수를 저장하는 것으로 판단됨
처음에 mov 했던 int 형 변수에서 1을 뻄
두번째 변수의 값을 rdx에 저장하고
위에서 계산했던 int형 변수의 값을 eax에 저장

마지막으로 rdx의 값을 rsi로 밀어넣고
eax의 값을 edi에 밀어넣는다

printName 함수 호출하고 main 함수 종료


역시나 printName 함수도 메모리 할당 후 시작

처음 두줄은 mov로 변수 2개 할당
마지막 mov는 2번째 줄에서 발생한 변수를 rax에 저장


주소값을 rdx에 저장함
위에서 저장한 rdx 값을 rsi로 옮기고
(위의 사진의 세번째 줄, 두번째 변수)rax에 저장한 값을 rdi에 옮겨서 저장


strcmp 함수 호출
변수 2개가 같은지 비교

jne: jump if not equal

즉 값이 다르다면 <+73>로 이동하는 것 같다 -> 밑에서 더 설명

값이 같다면 쭉쭉 실행

첫번째 변수에 0x77값 대입
eax에 두번째 변수 값 대입

rax에 0xe51(%rip)값 저장
rax 값 rdi 저장
eax에 0 저장 -> 함수가 끝나려는 듯 하다

마지막으로 printf 함수를 호출하고 끝!
여기서 <+73>이 나타나는 것을 알 수 있다

후..이제 c언어로 옮겨볼까요

#include <stdio.h>
#include <string.h>

void printName(int a, char* c);

int main(void) {
	int a = 24;
	char* c = "string_1";
	a = a - 1;
	printName(a, c);
	return 0;
}

void printName(int a, char* c) {
	if (strcmp(c, "string_2")) {
		int b = 119;
		printf("string_3", a);
	};
	return;
}

0개의 댓글