분류 전체보기(36)
-
TCP/IP 소켓 프로그래밍 (with C언어)
소켓 프로그래밍이란 양 끝 단의 프로세스들, 즉 응용 프로그램들이 서로 데이터를 주고받고 통신하는 것이다. 소켓은 통신을 하기 위한 하나의 방이라고 할 수 있고, 연결이 설정되면 클라이언트(서비스를 요청하는 측, 즉 이용자)와 서버(서비스를 제공하는 측, 즉 운영자)가 서로 데이터를 주고받는 통신을 할 수 있게 된다. 소켓 프로그래밍은 아주 간단한 것들(서버에 접속해서 로그를 남긴다거나 등)부터 아주 복잡한 게임들까지 널리 사용된다. 소켓 프로그래밍의 특징 양방향 통신을 지원한다. 주로 웹을 이용할 때 사용하는 HTTP 프로토콜에서는 클라이언트가 서버에게 요청하여 서버는 응답만 해주고 연결을 끊는 것과는 달리 소켓에서는 클라이언트와 서버 모두 통신을 할 수 있다. 서버와 연결을 맺은 후 연결이 지속되는 ..
2021.06.11 -
ELF 파일 포맷
ELF 파일이란 보통 실행파일은 .exe로 많이 보았을 것이다. 우리가 윈도우를 많이 사용하기 때문에 .exe 실행파일을 볼 일이 많다. 그러나 .exe는 리눅스에서 실행이 불가능하다. 그러면 리눅스에서 사용되는 실행파일은 어떤 것이 있을까? 이것이 바로 ELF 파일이다. ELF는 Executable and Linkable Format의 약자이며, 이는 실행이 가능하고 링킹이 가능하다는 의미이다. 리눅스에서 사용되는 .exe 파일이라고 생각하면 편하다. ELF 파일의 구조 ELF Header : ELF 파일의 구성을 나타낸다. 파일의 첫 부분을 차지하여 파일의 특성에 대해서 알 수 있다. File Data : ELF Header를 제외한 모든 내용으로, 이 곳에 실제 데이터가 담긴다. 프로그램 헤더 테이..
2021.05.31 -
리버싱 실습
gdb에서 실행파일을 실행시켰다. main 함수가 없기 때문에 다른 방법을 이용해야 한다. 실행을 하면 문자열이 출력되는데, 이를 통해 프로그램 내에서 printf, 또는 write 등의 함수들이 있다는 것을 알 수 있다. b write로 write 함수에 브레이크 포인트를 건 다음, finish로 write에서 빠져나와 write가 실행되었던 main 함수로 돌아간다. 이를 통해 write가 호출되었던 위치를 얻을 수 있게 된다. 0x55555555481d main을 디스어셈블 한 결과이다. 입력한 값은 "helloworld"이다. (엔터까지 포함해 helloworld\n이다.) ►0x55555555481d mov edx, 0x31 edx = 0x31 0x555555554822 lea rsi, [rip..
2021.05.27 -
어셈블리 동적 분석 실습
어셈블리어와 x64 아키텍처에 관해서 잘 모른다면 어셈블리 - Assembly x64 글을 참고하기 바란다. main 함수를 disassemble 한 결과이다. 각 영역이 나눠진 대로 하나하나씩 살펴보자. 첫 번째 구간 push rbp 스택의 가장 위(rsp의 값)에 rbp의 값을 넣는 것이다. 그다음 rsp는 한 칸 올라간다. 현재 rbp에는 0x0이라는 값이 담겨 있다. rbp가 rsp의 위치에 rbp를 넣고 난 뒤를 보니, rsp의 위치에 0x0이 들어갔다. 이것은 SFP를 스택 프레임에 넣기 위한 것이다. mov rbp, rsp 맨 밑에 있었던 rbp에 rsp가 있는 주소를 복사함으로써 rbp를 rsp와 같은 위치를 가리키게 끌어올린다. 아래 사진에서 rbp가 rsp가 있는 위치로 올라온 것을 확..
2021.05.24 -
어셈블리 - Assembly x64
이 글은 어셈블리에 관한 글이다. 어셈블리가 무엇인지 정확히 모른다면 실행파일이 만들어지는 과정 글을 참고하기 바란다. 어셈블리 어셈블리어는 기계어와 1대 1 대응되는 컴퓨터 친화적(저수준) 언어이다. 사람이 작성하는 C언어와 CPU가 처리하는 기계어 사이의 중간 단계라 할 수 있다. 오로지 0과 1만으로 구성된 기계어 그대로를 사람이 읽고 이해하기 쉽게 문자로 바꾸어 표현하는 언어이다. 각 CPU 제조사마다 ISA(명령어 구조)가 다를 수 있기 때문에 당연히 기계어도 제조사마다 다를 것이고, 이에 따라 자연스럽게 어셈블리도 달라질 수밖에 없다. ISA는 대표적으로 CISC와 RISC로 구분할 수 있고, CISC에는 x64, x86, RISC에는 ARM, MIPS 등이 있다. 이 글에서는 CISC에 속하..
2021.05.18 -
Pwndbg 명령어
Pwndbg는 GDB(GNU Debugger)의 한 플러그인이다. 리눅스 환경에서 간편하게 동적 분석을 할 수 있도록 해주는 디버거 도구이다. 리버싱 할 프로그램을 디버거에서 실행 gdb ./[프로그램명] Pwndbg 종료 q quit Ctrl+D 실행 중단 Ctrl+C 프로세스가 멈추어있는 상태에서 프로세스를 이어서 실행 c continue 브레이크 포인트 설정 b b 10 //10행에 브레이크 포인트 설정 b main b *[주소값] 설정한 브레이크 포인트 보기 i b info b info breakpoints 브레이크 포인트 삭제 d del [번호] 프로그램 시작 start 프로그램 실행 r run 프로그램 종료 k kill 현재 행 실행 (함수의 경우 함수 내부로 진입) / 줄 단위 s step ..
2021.05.16 -
실행파일이 만들어지는 과정
프로그램이 만들어지는 과정 우리가 만든 프로그램을 실행할 수 있도록 하려면 여러 가지 작업을 거쳐야 한다. 우리가 손수 C언어로 작성한 소스 코드는 바로 실행할 수 없다. C언어는 고수준 언어(High-level Language)이므로 사람이 이해하기에는 쉽지만, 0과 1 밖에 구분하지 못하는 CPU는 이 C언어 코드를 가지고 어떻게 할 수가 없다. 그래서 고수준 언어를 컴퓨터 친화적인 저수준 언어(Low-level Language)로 바꾸면 드디어 우리가 만든 프로그램을 컴퓨터가 실행할 수 있게 된다. 우리가 VS에서 Ctrl+F5, 또는 Dev-C++에서 F11을 누르는 순간 우리가 작성한 C언어 코드를 기반으로 빌드가 만들어지고 실행이 된다. 그러나 우리는 빌드되는 과정에서 정확히 어떤 일이 일어나..
2021.05.13 -
포인터에 대하여
포인터, 주소를 저장하는 변수 포인터는 변수의 주소를 저장하는 역할을 수행한다. 우리가 프로그램에서 사용하는 변수들은 모두 메모리 상에 저장되게 되는데, 이때 메모리는 기나 긴 도로라고 생각하고, 각 집의 번지수를 메모리 주소라고 비유할 수 있다. 위와 같이 메모리에 변수가 담기게 되는데, 각 변수의 시작 주소를 주소값이라 한다. 즉, 위에서 변수는 0x11, 0x12, 0x13까지 공간을 차지함에도 불구하고 변수의 주소값은 항상 데이터가 시작되는 부분이다. (0x10). 포인터는 이러한 주소값을 저장하기 위한 자료형이다. 다만, 이는 또한 주소값을 저장하는 것이기에 포인터 또한 변수이다. 주소 연산자(&)와 역참조 연산자(*)의 등장 주소 연산자와 역참조 연산자는 포인터를 사용하기 위한 필수적인 연산자..
2021.05.10 -
임베디드 구조
UART 핀 찾기 위에 빨간색으로 표시한 부분이 UART 핀으로 보입니다. UART란, 병렬 전송을 직렬로 변환하는 통신 방법입니다. TX: 송신자 핀 RX: 수신자 핀 GND: 그라운드 UART 통신에서는 송신자 측이 TX이고 수신자 측이 RX이므로 위의 포트들 중에서 TX와 RX가 써져 있는 포트를 찾았습니다. 보드에 적혀 있는 것은 특별히 신경 써야 할 사항은 아닌 것 같고... #0BA440 WINBOND 25032JVS10 검색해본 결과 정확히 이 제품은 나오지 않았지만 W25Q32JV라는 제품과 생긴 것도 대충 비슷하고 이름도 비슷해서... (대충 맞겠지 하는 마인드로) 후자에 대해서 알아봅시다. W25Q32JV는 32Mbit (약 4MB) 크기의 NOR 플래시 메모리입니다. 플래시 메모리란,..
2021.04.20 -
CPU의 명령어 처리
중앙처리장치의 개요 중앙처리장치(CPU)는 사람에 비유하면 두뇌에 해당하는 역할을 합니다. 주기억장치에서 데이터를 가져와 해석하고, 실행하고 데이터를 돌려주는 작업을 합니다. 중앙처리장치의 구조 연산장치 제어장치 레지스터 연산장치(ALU)는 산술 연산과 논리 연산을 담당하는 장치입니다. 산술 연산이란, 덧셈, 뺄셈, 곱셈, 나눗셈 등이 있으며, 논리 연산으로는 논리합, 논리곱, 부정 등이 있습니다. 데이터를 레지스터에서 가져와 연산을 수행한 뒤 레지스터에 다시 덮어쓰기 합니다. 제어장치는 지휘자의 역할을 합니다. 주기억장치에서 데이터를 인출해(Fetch) 해독(Decode), 실행(Execute) 그리고 다시 데이터를 되돌려주는 (Write-Back)의 과정을 수행합니다. 즉, 명령어를 순서대로 실행할 ..
2021.04.15 -
컴퓨터의 부팅 과정
컴퓨터를 많은 사람들이 사용하고 있으나 부팅할 때 어떤 일이 이루어지는 지에 대해 아는 사람은 소수입니다. 부팅이란, 컴퓨터 용어로서 컴퓨터를 시작할 때, 자기 자신(컴퓨터)을 구동시킬 프로그램을 컴퓨터 스스로 불러내는 동작. (나무위키) 컴퓨터에 있는 파워 버튼을 누르게 되면 먼저 전류를 조정하는 장치인 파워 서플라이(PSU)에 전기가 들어옵니다. 파워 서플라이는 보통 가정집에서 사용하는 교류(AC)를 컴퓨터가 사용할 수 있는 직류(DC)로 바꿔주는 역할을 담당합니다. 직류란, 곧을 直과 흐를 流, 영어로는 Direct Current이며, 전자가 시간에 따라서 한쪽 방향으로만 흐르고 크기가 일정한 전류입니다. 교류는 주고받을 交와 흐를 流, 영어로는 Alternating Current이며, 시간에 따라..
2021.04.06 -
Flash, ROM, RAM에 대하여
컴퓨터의 뇌라고 할 수 있는 중앙처리장치(CPU)는 데이터를 읽고 쓰는 작업을 주로 합니다. 이를 위해 데이터를 일시적으로 또는 영구적으로 저장할 수 있는 저장장치가 필요합니다. 저장장치의 종류는 크게 세 종류로 나눌 수 있습니다. 첫 번째, 주기억 장치 비유하자면 책상 또는 작업대라 할 수 있고, 클수록 더 많은 서류를 올려놓을 수 있습니다. 두 번째, 보조 기억 장치 수납장에 비유할 수 있으며, 수납장에서 물건을 가져오는데 시간은 좀 걸리지만 많은 물건을 보관할 수 있습니다. 세 번째, 특수 기억 장치 이는 캐시 메모리와 가상 기억 장치로 나뉩니다. 캐시 메모리는 우리가 평소에 간단한 계산을 외우고 있는 구구단에 비유할 수 있고, 가상 기억 장치는 작업대가 작아서 수납장과 작업대를 함께 사용하는 것과..
2021.04.05