U E D R , A S I H C RSS

새싹교실/2012/세싹

1. 새싹교실

  • 임시명 세싹반입니다.
  • 수업시간: 매주 화 15:00~16:00
    금 12:00~13:00
  • 이 외에 원할때 언제든 찾아오면 됩니다.
  • 수업과목: everything you want

2. 구성인원

선생님 정의정
새싹 권영기
김희성
  • 메일 : pkccr1@gmail.com
  • 네이트온 : pkccr@nate.com

3. feedback

  • 새싹교실이 ZeroPage에서 시행되는만큼 4F(ThreeFs + Future Action Plan)에 맞게 feedback을 작성합니다.
    • Facts, Feelings, Findings, Future Action Plan. 즉, 사실, 느낀 점, 깨달은 점, 앞으로의 계획.
    • 예를 들어 지난주에 돈가스를 먹은 것에 대해 후기를 쓴다면 : "지난주에 강남에 가서 하나에 5만원하는 돈가스를 먹었다.(사실) 기대를 뜩 했는데 별로 맛이 없었다.(느낌) 강남은 땅값이 비싸서 값만 보고 엄청 맛있을거라 기대하면 안된다는 것을 알았다.(깨달은점) 다음에는 미리 인터넷에서 평을 찾아보고 별점이 높은 돈가스집을 찾아서 가봐야겠다.(앞으로의 계획)"
      • 설마 이것보다 더 짧게 쓰진 않겠죠? 믿을게요
  • feedback은 최대한 성의있게 써주세요.
    • 반드시 ZeroWiki에 작성해주세요. 하위 페이지를 만드는 것도 허용합니다.
    • 여러분들이 배운 내용을 정리해주세요. 학습효과가 더 커집니다.

  • 참고로 ZeroWikiMoniWiki Engine을 사용하며 Google Chrome이나 Mozila Firefox, Safari보다는 Internet Explorer에서 가장 잘 돌아가는 것 같습니다.

4. 수업

4.1. 1회차(2012년 3월 16일)

4.1.1. 출석

선생님 정의정 O
학생 권영기 O
김희성 O

4.1.2. 수업내용

  • wiki를 왜 쓰는지, 어떻게 사용하는지에 대해 배웠습니다.
  • gcc 개발환경을 구축하는 법을 알아보았습니다.
    1) https://www.virtualbox.org 에서 자신의 운영 체제에 맞는 VirtualBux를 설치
    2) http://ftp.daum.net -> Ubuntu-releases -> 11.10 -> ubuntu-11.10-deskto-amd64.iso 다운
    3) Virtualbox실행 -> 새로 만들기 -> 운영체제 : Linux 버전 : Ubuntu -> 메모리1024MB로 설정하고 나머지 디폴트 설치
    4) 만들어진 ubuntu 실행 -> 설치 미디어로 ISO파일 마운트 -> 설치
    (설치 도중에 설정해줘야되는 것 : 글자판 배치를 한국어(101/104키 호환)으로 해야됨!)
  • gcc로 hello world를 컴파일 해보았습니다.
    1) 우분투 소프트웨어 센터에서 gcc 검색 & 설치
    2) 원하는 경로에 빈 문서 만들기 (확장자는 .c로 해주세요)
    3) 해당 문서에 코드 작성
    4) terminal 실행 -> .c 파일이 있는 경로로 이동 (ls와 cd를 이용합니다.)
    5) gcc로 컴파일을 합니다. (gcc 파일명.c -o 원하는파일명 -std=c99) 해당 예제외에 추가로 여러 옵션을 줄수 있습니다.
    6) 컴파일된 파일을 실행합니다. (./파일명)
  • w3schools를 소개했습니다. (www.w3schools.com)
  • 협업의 중요성에 대해 이야기했습니다.
    • 문서작성, 버전관리, 주석처리 등 아직은 실감이 안나겠지만 처음부터 습관을 들이는것이 중요합니다.

4.1.3. 숙제

  • wiki 사용법 익히기
    1) 자기 페이지 만들기 - 로그인후 자신의 이름으로 검색하여 페이지를 작성하시면 됩니다. 기본적인 프로필과 하고싶은말을 적어주세요.
    2) 후기 작성 - 아래 회고란에 편집을 눌러 후기를 남겨주시면됩니다. 위의 feedback 항목을 참고하세요.
  • gcc 개발환경 구축하기
    1) virtual box로 linux 설치 후 hello world 작성하고 컴파일하여 스크린샷을 강사 메일로 보내주세요.

4.1.4. 권장사항

  • 숙제는 아니지만 해봤으면 합니다:D
    1) w3schools에서 html파트 읽고 실습해보기
    2) linux의 다양한 명령어 검색해보기
    3) gcc의 옵션 검색해보기

4.1.5. 후기

  • 새싹 첫시간을 가졌습니다. 다른 새싹반들과는 다른 커리큘럼으로 진행을 해야해서, 무엇을 수업해야할지 고민이 많습니다(멘붕 일보직전). 학교수업 듣는것처럼 하지말고 자유로운 분위기에서 진행되면 좋겠습니다. - 정의정
  • 새싹 첫시간을 가졌습니다. 캡스톤실도 처음 들어가봐서 많이 신기했습니다. 처음 듣는 용어, 처음 보는 화면들 생소한게 많지만 재미있을 것 같아서 기대가 됩니다. 숙제도 권장사항도 열심히 해보겠습니다. 앞으로 잘 부탁드립니다. - 권영기
  • 새싹 첫시간을 가졌습니다. 이곳 Wiki가 매우 흥미로웠고, 캡스톤실에 대해서도 궁금점을 해소하여 좋았습니다. 이름만 들어보고 좀처럼 볼 일이 없던 것들을 보게되어 좋았습니다. 앞으로 잘 부탁드립니다. - 김희성
  • 숙제를 수행하기 위해 버추얼 박스를 설치하였습니다. 설치파일이 정상적으로 실행 않는 문제가 있었는데 인터넷으로 강제 압축해제하는 방법을 듣고 7z으로 압축을 해제하는 방법으로 해결하였습니다. 데몬이 없어 iso파일도 7z으로 풀었습니다. - 김희성
    • 어... iso파일을 풀필요없이 버추얼박스에서 바로 마운트시키는건데.. 제대로 설치됬어? - 정의정
    • 그리고 실패하였습니다. 7z 젠장... 여러단계를 한번에 풀어주는거 같군요. 메뉴얼을 읽어보니 cmd로 풀라고 합니다. 시키는데로 하니 msi 파일이 나오는군요. -김희성-
    • amd64버전을 쓰려고 했더니 cpu문제로 가상머신에서 설치되지 않는군요. i386버전으로 깔았습니다. -김희성


4.2. 2회차(2012년 3월 20일)

4.2.1. 출석

선생님 정의정 O
학생 권영기 O
김희성 O

4.2.2. 수업내용

  • 숙제에 대해서 이야기 나누었습니다.
    1) gcc 컴파일 옵션이 어려웠습니다. - gcc 컴파일 옵션의 대부분은 컴파일에 크리티컬한 것이 아니라 사용자에게 정보를 제공하는 것이 목적입니다. 그냥 안써도 되요 :D
  • 네트워크에 대하여 간단히 알아보았습니다.
    1) 우리가 사용하는 인터넷은 패킷 스위치 방식으로 소포에 주소를 써서 목적지에 보내는 것 처럼 작동하는 네트워크 입니다.
    2) 인터넷 프로토콜의 계층도에 대해 알아보았습니다.
    - app : 우리가 실제로 사용하는 서비스를 제공하는 계층입니다. http, smtp, ftp등이 있습니다.
    - transport : 데이터를 어떻게 보낼지 결정하는 계층입니다. 데이터를 어떻게 묶어서 보낼지, 오류처리는 어떻게 할지에 대해 결정합니다. TCP/UDP등이 있습니다.
    - ip : 호스트와 호스트, 즉 출발지에서 목적지까지 데이터 묶음(패킷)을 전달하는 역할을 합니다. 라우터가 있습니다.
    - link : 노드와 노드간에 데이터를 주고받는 역할을 합니다. 스위치, 브릿지등이 포함됩니다.
    - physical : 비트들을 물리적으로 이동시키는 역할을 합니다. 유선의 경우 다양한 케이블, 무선일 경우 공기가 매체가 되겠네요.
    3) 하지만 우리가 이 모든것을 반드시 알아야 통신 프로그램을 할 수 있는것은 아닙니다.
    - 이런 기능들을 단계별로 나눈 이유는, 자신의 하위 계층의 구현내용이 어떤지 잘 몰라도 그 기능을 사용할 수 있도록 하기 위해서입니다.
    - 즉, 소켓 프로그래밍도 해당 함수와 하위 함수들의 작동원리를 잘 모르더라도 어떤 기능을 하는지만 알면 쉽게 통신 프로그래밍을 할 수 있습니다.
    4) 그럼 소켓은 무엇인가요?
    - 인터넷 소켓(Internet socket, socket' 혹은 network socket 라고 부르기도 한다)은 네트워크로 연결되어 있는 컴퓨터의 통신의 접점에 위치한 통신 객체다.
    네트워크 통신을 위한 프로그램들은 소켓을 생성하고, 이 소켓을 통해서 서로 데이터를 교환한다. - wikipedia
    - 는 훼이크고 :P 간단히 설명하면 서버와 클라이언트가 byte stream을 주고 받는 것을 마치 파일 입출력을 하듯 해주는 것입니다.
    파일입출력 소켓
    파일구조체생성 소켓 생성
    fopen() connect()
    read()/write() read()/write()
    close() close()
    5) 자세한 사항은 http://forum.falinux.com/zbxe/?document_srl=441104 를 참고하세요.

4.2.3. 숙제

  • c로 소켓짜기
    1) 위 참조 페이지의 소스를 참고하여 서버와 클라이언트 코드를 직접 짜봅시다.
    2) 요구사항은 클라이언트에서 보내온 메시지를 서버측에서 대문자로 바꿔서 다시 클라이언트에게 보내주는 것입니다.
    3) 난이도가 다소 높을 수 있으므로 완성을 요구하지 않습니다. 한번 해보고 금요일날 다시 이야기 나눠보겠습니다.
    4) 리눅스 환경에서 gcc를 사용해 봅시다.
    5) 어려운 점은 카톡이나 위키 댓글을 이용해 주세요.

4.2.4. 권장사항

  • 숙제는 아니지만 해봤으면 합니다:D
    1) w3schools는 계속 조금씩 해보길 바랍니다.

4.2.5. 후기

  • 이 반의 수업내용을 보니 저도 참여하고 싶어지는군요 =_=ㅋ 재밌겠네요 ㅋㅋ - 김태진
  • 소켓 프로그래밍을 시작하였습니다. 네트워크에 대해 전혀 지식이 없는 친구들에게 짧은 시간안에 어떻게 개념을 알려주나 많이 고민했고 결과는 역시 fail이었던 것 같습니다. 짧은 시간에 이론적인 부분을 하는건 강사나 새싹이나 멘탈이 찢어지는 일인 것 같습니다..... 그리고 화요일 시간을 조정해야될 것 같네요.. 새싹 수업이 선대 끝나고 바로 있어서 희성이가 꾸벅꾸벅 졸았습니다. 선대를 안들은자만이 돌을 던지라. - 정의정
  • 오 C로 소켓 프로그래밍은 처음 보네요 재미있을듯ㅋㅋ - 신기호
  • 이 반 빡세네요 ㅋㅋㅋㅋ 네트워크 가르치기 힘들겠다… 난감할땐 맨땅에 헤딩하는 것 그것이 진정한 공돌이의 길이라고 둘러대는 게 좋을듯… - 김수경
  • 졸면서 들어도 이해가 가능할 정도로 요점이 잘 정리된 수업이었습니다. - 김희성
    • 희성아...솔직해져도 되... - 정의정
      • 참고사이트 접속 2시간만에 과제 완료를 할 정도로 좋은 설명이었습니다.(음?) - 김희성
  • 소켓 프로그래밍에 대해서 배웠습니다. 수업 내용을 잘 따라가지 못할 것이 두려워 걱정을 많이 했는데 선생님이 설명을 잘 해주셔서 수업 내용을 이해 할 수 있었습니다. 옛날에 자격증 딸 때 보았던 단어들이 막 나오니까 신기했습니다. 다음 수업까지 복습을 열심히 해야될 것 같습니다. 아 그리고 선생님의 강의 노트가 굉장히 탐이 났습니다. - 권영기
    • 공감... - 김희성
    • 오피에서 숙제를 했습니다. VS로 하려니까 뭔가 막 오류가 나는데 고치지는 못하겠고 그래서 우분투를 깔아서 시도를 했네요. 용어가 익숙하지 않아서 그런지 함수 설명을 봐도 한번에 와닿지 않아서 힘들었습니다. 아 그리고 숙제를 하다가 생긴 문제인데요. 서버 프로그램을 처음 실행했을 때는 괜찮은데 두 번째로 실행했을 때는 Bind에러가 나네요. 그래서 매번 실행할 때마다 포트값을 수정해야했습니다. 왜 이런 문제가 생긴걸까요? - 권영기
      • 권영기 학생이 맞닥트린 bind 오류는, 해당 포트에 내가 가서 눌러앉으려고(bind하려고) 가 보니까 다른 놈이 이미 차지하고 있어서 bind하지 못했다는 오류입니다. 프로그램에서 bind한 후 다 쓰고 나서 bind를 해제하지 않으면 이런 일이 발생합니다. bind 해제 코드를 꼭 넣도록 하세요. - 황현
      • 잠깐 사이에 답글이 올라오다니! 감사합니다. :) - 권영기
        • 자세한 해결 방법입니다. 소켓을 생성하고나서 바로 setsockopt(mySocket, SOL_SOCKET, SO_REUSEADDR, &anyIntegerVariableThatContainsNonZero, sizeof(anyIntegerVariableThatContainsNonZero)); 함수를 호출하면 이 소켓의 생명이 다하는 순간 해당 포트에 자리가 나게 됩니다. - 황현


4.3. 3회차(2012년 3월 23일)

4.3.1. 출석

선생님 정의정 O
학생 권영기 O
김희성 O

4.3.2. 수업내용

  • 지난 시간에 수업한 내용에 대해 이야기 했습니다.
    1) 포트의 중복을 어떻게 해결하나요?
    - 서버소켓의 경우 창구의 역할을 하기때문에 클라이언트에서 서버로 요청이 올 경우 별도의
    포트를 열어 통신 서비스를 제공합니다.
    - 위와 같이하면 하나의 서버에 다수의 클라이언트가 연결하는 상황에 충분히 대처할 수 있습니다.
    2) 하나의 클라이언트가 다수의 서버에 연결을 요청하는 경우에는 어떻게 될까요?
    - 숙제입니다. 실험해보세요 :D
    3) 서버와 클라이언트를 따로두니 너무 불편합니다. 어떻게 방법이 없을까요?
    - thread를 이용하여 서버와 클라이언트를 한 어플리케이션 안에서 사용하는
    concurrent 프로그래밍을 다음시간부터 하겠습니다.
    4) 서버나 클라이언트 양쪽 다 연결되있기에는 제약사항이 너무 큽니다.
    - 양방향 통신중 한쪽이 off-line상태인 경우에도 메시지의 전송과 수령이 가능하도록
    서버를 두어 push형식으로 메시지를 주고 받습니다. 이를 C2DM이라고 합니다.
  • Thread에 대해서 알아보았습니다.
    - thread가 어떤 것인지 왜사용하는지 어떻게 사용하는지 간단히 소개하였습니다.
    다음시간에 어떻게 프로그래밍 할 것인지 같이 알아보겠습니다.

4.3.3. 숙제

  • 다수의 클라이언트가 하나의 서버에 연결 요청하는 시뮬레이션
    - terminal을 여러개 실행시켜 실험을 진행해 보세요.
  • 하나의 클라이언트가 다수의 서버에 연결 요청하는 경우도 해봅시다.
  • 지난 숙제에서는 클라이언트가 한번만 메시지를 전송하고 받았는데, 지속적으로 전송하도록 구현해봅시다.
    - 클라이언트에 while문만 추가하면 간단할 것 같습니다.

4.3.4. 권장사항


4.3.5. 후기

  • 컴파일이 안되서 인터넷으로 확인해보니 다중 스레드를 쓰려면 gcc에 옵션 -lpthread를 주어야하는군요. - 김희성
  • 데이터 처리에 대하여 좀 더 검색하였는데 기본적으로 send된 정보는 버퍼에 계속 쌓이며, recv가 큐처럼 버퍼를 지우면서 읽는다고 되어있었습니다. 반면 read와 같은 파일포인터 함수로 읽으면 버퍼를 지우지않고 파일포인터만 이동하는 것 같더군요. recv도 옵션을 변경하면 버퍼에 계속 누적해서 보관할 수 있는거 같습니다.
  • 참고 사이트 :
  • 소캣 옵션 참고 사이트 (close시 bind 해제 설정)
  • 예제가 이미지인 줄 알았는데 박스였군요. - 김희성
  • 스레드 실행 시점이 그때그때 달라서 값이 변하는 변수의 포인터를 인자로 주면 안되는군요. 그것 때문에 고생했습니다. - 김희성
  • 숙제 완료 - 김희성
    • 숙제가 정확히 뭐였지? 좀 올려줘 - 권영기
      • 다중접속 가능한 클라이언트랑 서버 (스레드를 이용한 일 대 다수 연결 구현)- 김희성
      • 하지만 버츄얼 박스가 너무 느려서 시간관계상 다중접속은 서버만 구현했다는...<- 퍽 - 김희성
      • 아 우리 숙제가 이런거였나. 금요일 기억이 어째선지 머리 속에 없다. 아무튼 일단은 선대 숙제부터 하고나서.. - 권영기
      • 동시 채팅 완성 20명까지 된다구!. 그리고 과제는 토요일 저녁 상태 그대로... 으으아아악 운지! - 김희성
  • 주말간 바빠서 위키접속을 못하는 동안 엄청난 일이 벌어졌군.. 절대 저런 숙제를 내준 기억은 없는데.... - 정의정
    • 채팅은 그냥 해본거긴한데 여러개의 클라이언트와 동시 접속하는 서버랑, 여러개의 서버에 접속하는 클라이언트는 숙제 아니였나요? - 김희성
      p.s. 한국사 레포트랑 선대 숙제만 아니었어도 음성 인식에 쓸 학습형 문장 인식 코딩 하고 있었을지도...
    • 그래 근데 스레드를 이용하는 건 다음시간에 하기로 했었다고 ㅋㅋㅋㅋ 그래서 나 멘붕하는 줄 알았음 ㅋㅋㅋ - 권영기
      • 그럼 나 한시간치 과제 쉬어도 되는건가... 안그래도 선대과제 쌓인데다가 시험 크리 - 김희성
      • 가만보니 예제가 사라졌다. - 김희성
  • 할 줄 아는 거라고 생각했는데 막상 하려니까 되질 않네요. 좀 더 열심히 해야될 것 같네요. - 권영기


4.4. 4회차(2012년 3월 27일)

4.4.1. 출석

선생님 정의정 지각
학생 권영기 O
김희성 O

4.4.2. 수업내용

  • 숙제에 대해 이야기 했습니다.
    1) 권영기 학생이 클라이언트 쪽에서 메시지가 한번만 보내지는 현상때문에 멘붕
    -> 서버측에서 메시지를 한번만 받고 close해버려서 생긴 결과였습니다.
    2) 하나의 클라이언트가 다수의 서버에 연결을 요청하는 경우
    -> 직접 해보는게 숙제였는데 다들 당연히 될 것으로 예상하고 해보지 않았네요. :(
    3) 위키의 늦은 업데이트로 인한 숙제 착오
    -> 주말간 강사가 너무 바빠서 위키 업데이트를 못하는동안 참사가 발생
    잠깐 소개했던 thread프로그래밍을 김희성 학생이 thread로 소켓을 짜는 것인줄 알고 채팅 프로그래밍을 완성시켰네요. 강사 멘붕
  • concurrent 프로그래밍에 대해 배웠습니다.
    1) thread 프로그래밍
    - thread의 동작 원리와 thread를 어떻게 생성하는지, 종료를 어떻게 시키는지에 대해 배웠습니다.
    - 자세한 내용은 링크를 참조. http://www.joinc.co.kr/modules/moniwiki/wiki.php/Site/Thread/Beginning/WhatThread

4.4.3. 숙제

  • socket과 thread를 이용하여 메시지를 주고 받을 수 있는 채팅 프로그램을 작성하시오.

4.4.4. 권장사항


4.4.5. 후기

  • 이번에도 위키 업데이트가 좀 늦었습니다. 새싹 시간도 깜빡해서 지각하고.. 점점 바빠지는 것 같네요. 시간을 좀 더 아껴써야겠다는 생각이 들었습니다. 그리고 정해진 커리큘럼대로 하는 수업이 아니라서 그냥 손에 잡히는대로 필요한 지식을 전수하기로 했습니다. 물론 코딩은 지속적으로 할 수 있게 숙제가 나갈 예정입니다. - 정의정

4.5. 5회차(2012년 3월 30일)

4.5.1. 출석

선생님 정의정 O
학생 권영기 O
김희성 O

4.5.2. 수업내용


4.5.3. 숙제


4.5.4. 권장사항


4.5.5. 후기

4.6. 6회차(2012년 4월 3일)

4.6.1. 출석

선생님 정의정 O
학생 권영기 O
김희성 O

4.6.2. 수업내용

  • NTFS에 대하여 간략하게 설명하였습니다.
  • 코 드 분 석
      // 헤더 : ntfs.h
    #pragma once
    #define _WIN32_WINNT 0x0500
    
    #include <windows.h>
    #include <winioctl.h>
    #include <stdio.h>
    
    typedef BOOLEAN TF;
    typedef	UCHAR U8;
    typedef USHORT U16;
    typedef ULONG U32;
    typedef ULONGLONG U64;
    
    typedef struct {
    	U32 Type;
    	U16 UsaOffset;
    	U16 UsaCount;
    	U64 Usn;
    } NTFS_RECORD_HEADER, *PNTFS_RECORD_HEADER;
    
    typedef struct {
    	NTFS_RECORD_HEADER Ntfs;
    	U16 SequenceNumber;
    	U16 LinkCount;
    	U16 AttributeOffset;
    	U16 Flags;		// inUse 0x0001 Directory 0x0002
    	U32 BytesInUse;
    	U32 BytesAllocated;
    	U64 BaseFileRecord;
    	U16 NextAttributeNumber;
    } FILE_RECORD_HEADR, *PFILE_RECORD_HEADER;
    
    // Standard Attribute
    
    typedef enum {
    	AttributeStandardInformation = 0x10,
    	AttributeAttributeList = 0x20,
    	AttributeFileName = 0x30,
    	AttributeObjectId = 0x40,
    	AttributeSecurityDesciptor = 0x50,
    	AttributeVolumeName = 0x60,
    	AttributeVolumeInformation = 0x70,
    	AttributeData = 0x80,
    	AttributeIndexRoot = 0x90,
    	AttributeIndexAllocation = 0xA0,
    	AttributeBitmap = 0xB0,
    	AttributeReparsePoint = 0xC0,
    	AttributeEAInformation = 0xD0,
    	AttributeEA = 0xE0,
    	AttributePropertySet = 0xF0,
    	AttributeLoggedUtilityStream = 0x100
    } ATTRIBUTE_TYPE, *PATTRIBUTE_TYPE;
    
    typedef struct {
    	ATTRIBUTE_TYPE AttributeType;
    	U32 Length;
    	TF Nonresident;
    	U8 NameLength;
    	U16 NameOffset;
    	U16 Flags;
    	U16 AttributeNumber;
    } ATTRIBUTE, *PATTRIBUTE;
    
    typedef struct {
    	ATTRIBUTE Attribute;
    	U32 ValueLength;
    	U16 ValueOffset;
    	U16 Flags;
    } RESIDENT_ATTRIBUTE,*PRESIDENT_ATTRIBUTE;
    
    
    
    #pragma pack(push, 1)
    typedef struct {
    	U8 Jump[3];
    	U8 Format[8];
    	U16 BytesPerSector;	//섹터당 바이트 수
    	U8 SectorsPerCluster;	//섹터당 클러스터수
    	U16 BootSectors;
    	U8 Mbz1;
    	U16 Mbz2;
    	U16 Reserved1;
    	U8 MediaType;
    	U16 Mbz3;
    	U16 SectorsPerTrack;
    	U16 NumberOfHeads;
    	U32 PartitionOffset;
    	U32 Reserved2[2];
    	U64 TotalSectors;	//디스크의 총 섹터수.
    	U64 MftStartLcn;	//MFT가 시작되는 주소.
    	U64 Mft2StartLcn;	// MFT Mirror 부분이 시작되는 주소
    	U32 ClustersPerFileRecord;	// 파일 레코드당 클러스터수
    	U32 ClustersPerIndexBlock;	//	인덱스 블럭당 클러스터수
    	U64 VolumeSerialNumber;
    	U8 Code[0x1AE];
    	U16 BootSignature;
    } BOOT_BLOCK, *PBOOT_BLOCK;
    #pragma pack(pop)
    
    - main.cpp

#include "ntfs.h"

U32 BytesPerFileRecord;
BOOT_BLOCK boot_block;
HANDLE hVolume;
U32 cnt;
CHAR drive[] = "\\\\.\\C:";
PFILE_RECORD_HEADER MFT;


void ReadSector(U64 sector, U32 count, void* buffer);
void LoadMFT();

void main()
{

	hVolume = CreateFile(drive, GENERIC_READ,FILE_SHARE_READ | FILE_SHARE_WRITE, 0,OPEN_EXISTING, 0, 0);
	ReadFile(hVolume, &boot_block, sizeof(boot_block), &cnt, 0);
	
	printf("======My FILE SYSTEM INFO==========\n");
	printf("File System : %s \n",boot_block.Format);
	printf("Total Sectors : %u \n",boot_block.TotalSectors);
	printf("Sector per Bytes : %u \n",boot_block.BytesPerSector);
	printf("Cluster per Sectors : %u\n",boot_block.SectorsPerCluster);
	printf("Clusters Per FileRecord : %u\n",boot_block.ClustersPerFileRecord);
	printf("Clusters Per IndexBlock : %u\n",boot_block.ClustersPerIndexBlock);

}

void LoadMFT()
{
	BytesPerFileRecord = boot_block.ClustersPerFileRecord < 0x80? boot_block.ClustersPerFileRecord* boot_block.SectorsPerCluster* boot_block.BytesPerSector : 1 << (0x100 - boot_block.ClustersPerFileRecord);
	MFT = PFILE_RECORD_HEADER(new U8[BytesPerFileRecord]);
	ReadSector(boot_block.MftStartLcn * boot_block.SectorsPerCluster,	BytesPerFileRecord / boot_block.BytesPerSector, MFT);
	printf("buffer : %s\n", MFT+0x27);
}

void ReadSector(U64 sector, U32 count, void* buffer)
{
	ULARGE_INTEGER offset;
	OVERLAPPED overlap = {0};
	U32 n;
	
	offset.QuadPart = sector * boot_block.BytesPerSector;
	overlap.Offset = offset.LowPart; 
	overlap.OffsetHigh = offset.HighPart;
	ReadFile(hVolume, buffer, count * boot_block.BytesPerSector, &n, &overlap);
	
}

4.6.3. 숙제

4.6.4. 권장사항

  • 채팅 코드를 보기 좋게 수정해봅시다. 힌트 - cpp 분할, 함수화

4.6.5. 후기

  • 강사께서 과제로 멘붕한 것으로 추측되어 대신 페이지를 작성하였습니다. - 김희성
  • 저도 과제 누적으로 멘붕할듯 합니다. 뒤는 너에게 맡긴다 영기야. - 김희성

4.7. 7회차(2012년 4월 6일)

4.7.1. 출석

선생님 정의정 O
학생 권영기 O
김희성 X

4.7.2. 수업내용

  • NTFS 분석하는 방법
  • 소스코드 분석

4.7.3. 숙제

  • 소스코드 또는 기존 분석기를 이용하여 MFT 분석하기

4.7.5. 후기

  • 새싹교실이 URP프로젝트 팀으로 넘어가게 되었습니다. 김희성 내가 어제 창설하라고 할때는 안하고 오늘은 새싹을 째고 창설을 하는구나 :D - 정의정
    • 그리고 배때지에 F빵을 맞았죠.ㅠㅜ - 김희성
  • NTFS에 대해서 배웠습니다. 생소한 용어들이 좀 있어서 걱정입니다. 그래도 새로운 것을 배우는 것은 정말 즐거운 일이네요.
    요즘 갑자기 과제가 늘어서 채팅 프로그램에 손을 대지 못했습니다. 시간을 현명하게 써야할 것 같습니다. - 권영기

4.8. 8회차(2012년 4월 10일)

4.8.1. 출석

선생님 정의정 O
학생 권영기 O
김희성 O

4.8.2. 수업내용


4.8.3. 숙제


4.8.4. 권장사항

  • NTFS에 대해 틈틈히 공부해봅시다.

4.8.5. 후기


4.9. 9회차(2012년 4월 13일)

4.9.1. 출석

선생님 정의정 O
학생 권영기 O
김희성 O

4.9.2. 수업내용

#include "ntfs.h"

U32 BytesPerFileRecord;
BOOT_BLOCK boot_block;
HANDLE hVolume;
U32 cnt;
CHAR drive[] = "\\\\.\\C:";
//WCHAR drive[] = TEXT("\\\\.\\C:");
PFILE_RECORD_HEADER MFT;


void ReadSector(U64 sector, U32 count, void* buffer);
void LoadMFT();

void main()
{

	hVolume = CreateFile(drive, GENERIC_READ,FILE_SHARE_READ | FILE_SHARE_WRITE, 0,OPEN_EXISTING, 0, 0);
	ReadFile(hVolume, &boot_block, sizeof(boot_block), &cnt, 0);
//	FILE *fp=fopen(drive,"rb");
//	fread((void*)&boot_block,sizeof(boot_block),1,fp);

	printf("======My FILE SYSTEM INFO==========\n");
	printf("File System : %s \n",boot_block.Format);
	printf("Total Sectors : %u \n",boot_block.TotalSectors);
	printf("Sector per Bytes : %u \n",boot_block.BytesPerSector);
	printf("Cluster per Sectors : %u\n",boot_block.SectorsPerCluster);
	printf("Clusters Per FileRecord : %u\n",boot_block.ClustersPerFileRecord);
	printf("Clusters Per IndexBlock : %u\n",boot_block.ClustersPerIndexBlock);
	printf("\n\n");
	LoadMFT();
}

void LoadMFT()
{
	int i;
	BytesPerFileRecord = boot_block.ClustersPerFileRecord < 0x80? boot_block.ClustersPerFileRecord* boot_block.SectorsPerCluster* boot_block.BytesPerSector : 1 << (0x100 - boot_block.ClustersPerFileRecord);
	MFT = PFILE_RECORD_HEADER(new U8[BytesPerFileRecord]);

	ReadSector(boot_block.MftStartLcn * boot_block.SectorsPerCluster,	BytesPerFileRecord / boot_block.BytesPerSector, MFT);

	printf("$MFT's Signaturer : %s\n", MFT);//+0x27);
	printf("Offset to fixup array : 0x%02x%02x\n", *((unsigned char*)MFT+5),*((unsigned char*)MFT+4));
	printf("Number of this MFT Entry : 0x%02x%02x%02x%02x\n"
		, *((unsigned char*)MFT+47),*((unsigned char*)MFT+46),*((unsigned char*)MFT+45),*((unsigned char*)MFT+44));

	
	printf("Offset to first attribute : 0x%02x%02x \n"
		, *((unsigned char*)MFT+21),*((unsigned char*)MFT+20));



	i=((int)(*((unsigned char*)MFT+21))<<8)+*((unsigned char*)MFT+20);//Offset으로 포인터 이동
	printf("First Attribute : 0x%02x%02x%02x%02x\n",*((unsigned char*)MFT+i+3),*((unsigned char*)MFT+i+2),*((unsigned char*)MFT+i+1),*((unsigned char*)MFT+i));
	i+=4;//속성값의 4바이트 이동
	printf("First Attribute Size : 0x%02x%02x%02x%02x\n",*((unsigned char*)MFT+i+3),*((unsigned char*)MFT+i+2),*((unsigned char*)MFT+i+1),*((unsigned char*)MFT+i));
	printf("\n");

	

	i=	i+
		((int)(*((unsigned char*)MFT+i+3))<<24)+
		((int)(*((unsigned char*)MFT+i+2))<<16)+
		((int)(*((unsigned char*)MFT+i+1))<<8)+
		*((unsigned char*)MFT+i)
		-4;//사이즈를 읽기위해 사용한 4바이트를 제외한다.

	printf("Second Attribute : 0x%02x%02x%02x%02x\n",*((unsigned char*)MFT+i+3),*((unsigned char*)MFT+i+2),*((unsigned char*)MFT+i+1),*((unsigned char*)MFT+i));
	i+=4;//속성값의 4바이트 이동
	printf("Second Attribute Size : 0x%02x%02x%02x%02x\n",*((unsigned char*)MFT+i+3),*((unsigned char*)MFT+i+2),*((unsigned char*)MFT+i+1),*((unsigned char*)MFT+i));
	printf("\n");


	i=	i+
		((int)(*((unsigned char*)MFT+i+3))<<24)+
		((int)(*((unsigned char*)MFT+i+2))<<16)+
		((int)(*((unsigned char*)MFT+i+1))<<8)+
		*((unsigned char*)MFT+i)
		-4;//사이즈를 읽기위해 사용한 4바이트를 제외한다.

	printf("Third Attribute : 0x%02x%02x%02x%02x\n",*((unsigned char*)MFT+i+3),*((unsigned char*)MFT+i+2),*((unsigned char*)MFT+i+1),*((unsigned char*)MFT+i));
	i+=4;//속성값의 4바이트 이동
	printf("Third Attribute Size : 0x%02x%02x%02x%02x\n",*((unsigned char*)MFT+i+3),*((unsigned char*)MFT+i+2),*((unsigned char*)MFT+i+1),*((unsigned char*)MFT+i));
	printf("\n");
	
/*
	ReadSector(boot_block.Mft2StartLcn * boot_block.SectorsPerCluster,	BytesPerFileRecord / boot_block.BytesPerSector, MFT);

	printf("$MFT Mirr's Signaturer : %s\n", MFT);//+0x27);
	printf("Offset to fixup array : 0x%02x%02x\n", *((unsigned char*)MFT+5),*((unsigned char*)MFT+4));
	printf("Number of this MFT Entry : 0x%02x%02x%02x%02x\n"
		, *((unsigned char*)MFT+47),*((unsigned char*)MFT+46),*((unsigned char*)MFT+45),*((unsigned char*)MFT+44));
	printf("\n");
//*/

	printf("MftStartLcn : %d\n",boot_block.MftStartLcn);
	printf("Mft2StartLcn : %d\n",boot_block.Mft2StartLcn);
}


void ReadSector(U64 sector, U32 count, void* buffer)
{
	ULARGE_INTEGER offset;
	OVERLAPPED overlap = {0};
	U32 n;
	
	offset.QuadPart = sector * boot_block.BytesPerSector;
	overlap.Offset = offset.LowPart; 
	overlap.OffsetHigh = offset.HighPart;
	ReadFile(hVolume, buffer, count * boot_block.BytesPerSector, &n, &overlap);
}

4.9.3. 숙제


4.9.4. 권장사항

  • 리틀엔디언 출력방식 개선
  • 시험공부

4.9.5. 후기

  • 뒤집어 읽는 함수는 없고, 리틀엔디언을 빅엔디언으로 변환하는 함수는 있군요.
    소캣 라이브러리를 요구합니다.
    htons, htonl
  • HxD라는 헥스에디터가 있습니다. 4기가 바이트이상의 파일을 열수 있고 최대 8엑사 바이트까지 열 수 있다고 합니다. 그리고 가장 중요한 건 프리웨어네요.
    http://mh-nexus.de/en/hxd/ - 권영기
  • Code jam으로 불태웠더니 시간이... - 김희성
  • 공간을 절약해야하는 저장이라 자료형이 일정하지않습니다. 4bit unsigned 정수형부터 3byte,7byte unsigned 정수형까지 상상을 초월하네요.ㅠㅜ - 김희성


4.10. 10회차(2012년 4월 17일)

4.10.1. 출석

선생님 정의정 O
학생 권영기 O
김희성 O

4.10.2. 수업내용

#include "ntfs.h"

U32 BytesPerFileRecord;
BOOT_BLOCK boot_block;
HANDLE hVolume;
U32 cnt;
CHAR drive[] = "\\\\.\\C:";
//WCHAR drive[] = TEXT("\\\\.\\C:");
PFILE_RECORD_HEADER MFT;


void ReadSector(U64 sector, U32 count, void* buffer);
void LoadMFT();
unsigned int LoadAttribute(int i);

unsigned __int64 htonll(unsigned __int64);
unsigned int htonl(unsigned int);
//unsigned short htons(unsigned short);

void main()
{

	hVolume = CreateFile(drive, GENERIC_READ,FILE_SHARE_READ | FILE_SHARE_WRITE, 0,OPEN_EXISTING, 0, 0);
	ReadFile(hVolume, &boot_block, sizeof(boot_block), &cnt, 0);
//	FILE *fp=fopen(drive,"rb");
//	fread((void*)&boot_block,sizeof(boot_block),1,fp);

	printf("======My FILE SYSTEM INFO==========\n");
	printf("File System : %s \n",boot_block.Format);
	printf("Total Sectors : %u \n",boot_block.TotalSectors);
	printf("Sector per Bytes : %u \n",boot_block.BytesPerSector);
	printf("Cluster per Sectors : %u\n",boot_block.SectorsPerCluster);
	printf("Clusters Per FileRecord : %u\n",boot_block.ClustersPerFileRecord);
	printf("Clusters Per IndexBlock : %u\n",boot_block.ClustersPerIndexBlock);
	printf("\n\n");
	LoadMFT();
	system("pause");
}

void LoadMFT()
{
	int point;
	unsigned __int64 num;
	BytesPerFileRecord = boot_block.ClustersPerFileRecord < 0x80? boot_block.ClustersPerFileRecord* boot_block.SectorsPerCluster* boot_block.BytesPerSector : 1 << (0x100 - boot_block.ClustersPerFileRecord);
	MFT = PFILE_RECORD_HEADER(new U8[BytesPerFileRecord]);

	printf("MftStartLcn : %016x\n",boot_block.MftStartLcn);
	printf("Mft2StartLcn : %016x\n",boot_block.Mft2StartLcn);
	printf("\n");

	//0 대신 값을 대입하면 다른 MFT entry를 볼 수 있음.
	ReadSector((boot_block.MftStartLcn+0) * boot_block.SectorsPerCluster,	BytesPerFileRecord / boot_block.BytesPerSector, MFT);
	

	printf("MFT's Signaturer : %s\n", MFT);//+0x27);
	printf("Offset to fixup array : 0x%02x%02x\n", *((unsigned char*)MFT+5),*((unsigned char*)MFT+4));
	printf("Number of this MFT Entry : 0x%02x%02x%02x%02x\n"
		, *((unsigned char*)MFT+47),*((unsigned char*)MFT+46),*((unsigned char*)MFT+45),*((unsigned char*)MFT+44));

	printf("Offset to first attribute : 0x%02x%02x \n"
		, *((unsigned char*)MFT+21),*((unsigned char*)MFT+20));
	printf("\n");


	point=((int)(*((unsigned char*)MFT+21))<<8)+*((unsigned char*)MFT+20);//Offset으로 포인터 이동
	
	printf("Attribute List Start\n\n");
	while(htonl(*((unsigned int*)((unsigned char*)MFT+point)))!=0xFFFFFFFF)
		point+=LoadAttribute(point);
	printf("Attribute List End\n");

	printf("\n");

}

unsigned int LoadAttribute(int point)
{
	int i=0,j=0,k=0;
	int HeaderSize;

	/*
		*((unsigned char*)MFT+i+9) = Attribute Name Size
		Resident=24 / Non-resident=64
	*/

	if(*((unsigned char*)MFT+point+8))
		HeaderSize=64+*((unsigned char*)MFT+point+9);
	else
		HeaderSize=24+*((unsigned char*)MFT+point+9);


	switch(htonl(*((unsigned int*)((unsigned char*)MFT+point))))
	{
	case 0x10://$STANDARD_INFORMATION
		printf("Attribute type : Standard Information\n");
		break;

	case 0x20://$ATTRIBUTE_LIST
		printf("Attribute type : Attribute List\n");
		break;

	case 0x30://$FILE_NAME
		printf("Attribute type : File Name\n");
		printf("File Name Size : %d\n",*((unsigned char*)MFT+point+HeaderSize+64));	
		printf("File NameSpace : ");
		switch(*((unsigned char*)MFT+point+HeaderSize+65))
		{
		case 0:
			printf("POSIX\n");
			break;
		case 1:
			printf("Win32\n");
			break;
		case 2:
			printf("DOS\n");
			break;
		case 3:
			printf("Win32 & DOS\n");
			break;
		}
		printf("File Name : ");
		for(j=0;j<2**((unsigned char*)MFT+point+HeaderSize+64);j++)
			printf("%c",*((unsigned char*)MFT+point+HeaderSize+66+j));
		printf("\n");
		break;

	case 0x40://$
		printf("Attribute type : \n");
		break;

	case 0x50://$SECURITY_DESCRIPTOR
		printf("Attribute type : Security Descriptor\n");
		break;

	case 0x60://$
		printf("Attribute type : \n");
		break;

	case 0x70://$
		printf("Attribute type : \n");
		break;

	case 0x80://$DATA
		printf("Attribute type : Data\n");

		//__int64는 메모리상에 little endian식으로 저장됨. 왜인지 이해가 안 가지만...
		printf("Run List  Start VCN : %I64d\n",*((unsigned __int64*)((unsigned char*)MFT+point+16)));
		printf("Run List   End  VCN : %I64d\n",*((unsigned __int64*)((unsigned char*)MFT+point+24)));
		printf("Run List Start Offset : 0x%02x%02x\n",*((unsigned char*)MFT+point+33),*((unsigned char*)MFT+point+32));

//		printf("Cluster Size : %I64d\n",*((unsigned __int64*)((unsigned char*)MFT+point+40)));
//		printf("Attribute Size : %I64d\n",*((unsigned __int64*)((unsigned char*)MFT+point+48)));
//		printf("real Size : %I64d\n",*((unsigned __int64*)((unsigned char*)MFT+point+56)));

		i=(int)*((unsigned char*)MFT+point+33)+*((unsigned char*)MFT+point+32);

		for(j=0;j<(*((unsigned char*)MFT+point+i)&0x0F);j++)//*((unsigned __int64*)((unsigned char*)MFT+point+24));j++)
		{
			printf("Cluster %d lenth : 0x",j);
			for(k=0;k<(*((unsigned char*)MFT+point+i)&0x0F);k++)
				printf("%02x",*((unsigned char*)MFT+point+i+(*((unsigned char*)MFT+point+i)&0x0F)-k));
			printf("\n");

			printf("Cluster %d offset : 0x",j);
			for(;k<(*((unsigned char*)MFT+point+i)&0x0F)+((*((unsigned char*)MFT+point+i)&0xF0)>>4);k++)
				printf("%02x",*((unsigned char*)MFT+point+i
					+(*((unsigned char*)MFT+point+i)&0x0F)+((*((unsigned char*)MFT+point+i)&0xF0)>>4)
					-k+(*((unsigned char*)MFT+point+i)&0x0F)));
			printf("\n");
			i+=(*((unsigned char*)MFT+point+i)&0x0F)+((*((unsigned char*)MFT+point+i)&0xF0)>>4)+1;
		}
		break;
	case 0xB0:
		printf("Attribute type : Bitmap\n");
		break;
	}

	printf("\n");

	return htonl(*((unsigned int*)((unsigned char*)MFT+point+4)));
}

void ReadSector(U64 sector, U32 count, void* buffer)
{
	ULARGE_INTEGER offset;
	OVERLAPPED overlap = {0};
	U32 n;
	
	offset.QuadPart = sector * boot_block.BytesPerSector;
	overlap.Offset = offset.LowPart; 
	overlap.OffsetHigh = offset.HighPart;
	ReadFile(hVolume, buffer, count * boot_block.BytesPerSector, &n, &overlap);
}



unsigned __int64 htonll(unsigned __int64 LittleEndian)
{
	unsigned __int64 BigEndian;
	int i;
	LittleEndian>>=16;
	BigEndian=0;
	BigEndian+=(unsigned __int64)(*((unsigned char*)&LittleEndian+7))<<54;
	BigEndian+=(unsigned __int64)(*((unsigned char*)&LittleEndian+6))<<48;
	BigEndian+=(unsigned __int64)(*((unsigned char*)&LittleEndian+5))<<40;
	BigEndian+=(unsigned __int64)(*((unsigned char*)&LittleEndian+4))<<32;
	BigEndian+=(unsigned __int64)(*((unsigned char*)&LittleEndian+3))<<24;
	BigEndian+=(unsigned __int64)(*((unsigned char*)&LittleEndian+2))<<16;
	BigEndian+=(unsigned __int64)(*((unsigned char*)&LittleEndian+1))<<8;
	BigEndian+=(unsigned __int64)(*((unsigned char*)&LittleEndian+0));
	return BigEndian;
}


unsigned int htonl(unsigned int LittleEndian)
{
	unsigned int BigEndian;
	BigEndian=
		((unsigned int)(*((unsigned char*)&LittleEndian+3))<<24)+
		((unsigned int)(*((unsigned char*)&LittleEndian+2))<<16)+
		((unsigned int)(*((unsigned char*)&LittleEndian+1))<<8)+
		*((unsigned char*)&LittleEndian)
		;
	return BigEndian;
}



/*
unsigned short htons(unsigned short LittleEndian)
{
	unsigned short BigEndian;
	BigEndian=
		((unsigned short)(*((unsigned char*)&LittleEndian+1))<<8)+
		*((unsigned char*)&LittleEndian)
		;
	return BigEndian;
}
/*/



4.10.3. 숙제


4.10.4. 권장사항


4.10.5. 후기


Valid XHTML 1.0! Valid CSS! powered by MoniWiki
last modified 2021-02-07 05:29:46
Processing time 0.0927 sec