stxxp

C언어 코드 분석 본문

Hacking

C언어 코드 분석

stxxp 2020. 7. 2. 23:04

참고하는 사이트1 : https://modoocode.com/23

 

씹어먹는 C 언어 - <12 - 1. 포인터는 영희이다! (포인터)>

 

modoocode.com

참고하는 사이트2 : https://modoocode.com/24

 

씹어먹는 C 언어 - <12 - 2. 포인터는 영희이다! (포인터)>

 

modoocode.com

 


 

#과제 1-1

=> * 연산자와 & 연산자의 역할이 무엇인지 말해보세요.

 

피연산자가 1개인 & 연산자는 피연산자의 주소값을 불러오는 역할을 하고

피연산자가 1개인 *  연산자는 & 연산자가 가져온 주소값에  대응되는 데이터를 가져오는 역할을 합니다.

 

#include <stdio.h>
#include <stdlib.h>

int main() // &연산자의 예
{
    int num=7;

    printf("%p", &num);
    return 0;
}

 

결과화면 - 아하 어떤 '값'이 출력되어 나오는구나! 하고 이해하면 됩니다

 

#include <stdio.h>
#include <stdlib.h>

int main() // * 연산자의 예
{
    int *p;
    int num;

    p = &num;
    num = 7;

    printf("num의 값 : %d\n*p의 값 : %d", num, *p);
    return 0;
}

 

결과화면 - 포인터p는 num의 메모리 주소를 받아 num의 값인 7을 출력합니다.

 

 

 

 

#과제 1-2

=> int **; 와 같은 이중 포인터(double-pointer)에 대해 생각해 보세요.

 

포인터를 여러 번 겹쳐 무한대로 쓰는 것은 이론상으로 가능한 이야기라고 생각합니다.

어떤 변수의 주소값을 가리키는 주소값의 주소값의 주소값 ... 은 중첩이 되도 실행되는데 문제는 없기 때문입니다.

 

#include <stdio.h>
#include <stdlib.h>

int main() // 이중 포인터
{
    int *p1;
    int **p2;
    int num=17;

    p1 = &num;

    p2 = &p1;

    printf("p2의 값 : %d", **p2);
    return 0;
}

 

결과화면

위의 코드에서 포인터 p1은 num의 주소값을 가리키고 포인터  p2는 포인터 p1의 주소값을 가리킵니다.

결과적으로 포인터를 두 번 사용해 num의 메모리 주소에 접근했고 num 안에 입력돼 값인 17을 화면에 출력하게 됩니다.

 

이러한 이중 포인터는 main() 함수에서 포인터를 함수의 인자 값으로 쓸 때 이중 포인터는 사용하고

그 이유는 이중 포인터를 사용해야  그 함수 내에서의 변경 사항이 main() 함수에서도 적용되기 때문입니다.

 

 

 


 

 

#과제 2-1

=> int arr [3][3]과 같은 배열은 내부적으로 어떻게 처리되는지 생각해보세요.

 

만약 int arr [3][3] 을 2차원 배열이라고 생각하면

arr는 가로의 크기와 세로의 크기가 각각 3인 int형 이차원 배열로 해석할 수 있습니다. 이 이차원 배열은 아래와 같이 그려볼 수 있습니다.

 

int arr[3][3] = {
    {10, 11, 12},
    {13, 14, 15},
    {16, 17, 18}
};

 

 

▼표로 나타낸 arr[3][3]

10 arr[0][0] 11 arr[0][1] 12 arr[0][2]
13 arr[1][0] 14 arr[1][1] 15 arr[1][2]
16 arr[2][0] 17 arr[2][1] 18 arr[2][2]

int arr [3][3]에서 앞에 [3]은 세로로 3개의 배열이 있다는 것이고 뒤에 [3]은 그 3개의 배열이 각각 3개의 원소를 가진다(=가로)는 뜻이 됩니다.

 

따라서 원소를 출력할 때, 2번째 배열 마지막 원소를 가리켜 출력하고 싶다면 arr [1][2]의 형태로 쓰면 됩니다.

 

(참고 : arr [1][2]의 값을 출력하면 15가 나옴)

 

 

 

 

 

 

#과제 2-2

=> int* arr [3]과 같은 배열이 가지는 의미는 무엇일까요?

 

int* arr [3] 은 포인터 배열이라고 생각합니다. 그냥 int arr[3] 이 원소가 3개인 배열을 뜻한다면 int* arr[3] 은 원소 3개의 주소값을 가진 배열, 즉 int형 원소를 3개 가지고 있는 배열을 가리키는 포인터일 것입니다.

 

  • 0번 원소 ==> 주소 "0x~~~~"
  • 1번 원소 ==> 주소 "0x~~~~ + 4" 
  • 2번 원소 ==> 주소 "0x~~~~ + 8"

 

#include <stdio.h>
#include <stdlib.h>

int main()
{
    int* arr[3];

    arr[0] = 3;
    arr[1] = 4;
    arr[2] = 5;

    for(int i=0; i<3; i++){
        printf("arr[%d] : %p\n", i, &arr[i]);
    }

    return 0;
}

 

결과화면 - int형이므로 4씩 커지는 것을 볼 수 있습니다.

'Hacking' 카테고리의 다른 글

Codegate 2018, BaskinRobbins31  (0) 2020.09.01
NX-bit 예제 풀기 (with ASLR ON)  (0) 2020.08.27
NX-bit 예제 풀기  (0) 2020.08.25
간단한 바이너리 분석하기  (0) 2020.07.12
C pointer 보고서  (1) 2020.06.24