/dev/hda 또는 /dev/fd 를 raw read할경우...

you의 이미지

아까
fopen()시 세그멘테이션 에러
질문올린 사람입니다만...
그문제는 여러분 덕에 잘 해결이 났구요^^

또다른 문제가...
어제도 계속 이문제로 질문을 했었는데...
(raw device read 어쩌고...하는 질문)
아래 소스코드에서
cc_dump() 함수에서
인자를 /dev/hda 나 /dev/fd로 했더니
무조건 같은값이 파싱되더군요
즉,
cc_dump()에서 raw device read한 뒤에
write한 cc_dump_bi 파일을
parse_dump()에서 파싱해서 cc_dump 파일로 write했습니다만
cc_dump 파일의 각 필드부분의 값이
하드디스크 파티션을 읽었을때와(ext2 FS)
플로피를 읽었을때가 같고
게다가 모든 필드의 값이 다 똑같네요...
3221223776이네요
그래서 ext2나 floppy나 앞부분은 부트영역이라 그렁가?싶어서
오프셋을 4096바이트 이동한 뒤에
다시 반복해봤습니다만
역시나 마찬가지더군요...

역시 raw device read는
저같은 방법으로 하면 안되는 건가요?
제가 원하는건
디스크 파티션을 포맷한 뒤에 raw device read로 읽어서
파일시스템 정보를 읽어들이고자 하는건데요
예를 들어 수퍼블락 정보 - 파일시스템id, 블락수, 프리블락의 수, 매직넘버, inode수, 등등...
(제가 테스트할 FS는 부트영역 없이 맨 앞부분이 수퍼블락이라...맨 앞부분부터 읽어들인 겁니다)

정말 어떻게 해야할지 모르겠네요
아시는분 부탁드립니다.
감사합니다.

deisys의 이미지

음.. fopen 으로 여는걸 실패하고 그 다음에 실패한 포인터로(0x0=NULL) 읽기나 쓰기를 하려고 하기 때문이 아닐까요...? 그냥 fopen 만 했는데 Seg. Fault가 뜰 것 같지는 않은데요.. 아니라면 소스코드를 봐야 알 수 있을것 같네요.

혹시

    FILE * fp;
    fprintf(fp=fopen("mm", "r"), "merong\n");

이런식의 코드가 있는 라인에서인가요...? ...

익명 사용자의 이미지

파일 열면서 죽는 이유는 없을듯 합니다.

어디 다른 코드에서 할당된 메모리를 침범하여 다른 영역까지
건드리는 코드가 있는지 중점적으로 보는것이 낳을거 같은데요.
다른곳에서 메모리 침범하는 부분이 있어서 엉뚱한곳에서
그로인한 영향을 받아 에러가 나는듯 합니다.

you의 이미지

위의 님 deisys 말씀대로는 아닙니다.
아래 소스를 올렸습니다만...
(정말 허접해서 올리기 창피하다만...)
제생각에도
어디 다른부분에서
침범하는 코드부분이 있어서 그런것 같긴한데...
도저히 모르겠네요
약간의 힌트라도 주실순 없을런지요>?

세그멘테이션 에러가 나는부분은
parse_dump() 에서 fopen()첫번째 부분입니다.
근데 이상한건
처음 이걸 실행했을때는
그 다음 루틴인
comp_cc_dump() 함수의 fopen()부분에서 세그멘테이션에러가 났다는 것입니다.
그 뒤로는 계속실행해도
똑같이 parse_dump()에서 에러가 나더군요
제발 조금이라도 도와주세요
그럼 부탁드립니다.

#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<sys/types.h>
#include<sys/stat.h>
#include<fcntl.h>
#include<string.h>
#include"errcode.h"

/*#define _OPTION_*/  /* if options are determined */

#define BUFSIZE 4096   /*number of byte to be read to cc_dump_bi file by raw device read*/

int ccfs_init();  /*CCFS initialization test*/
/*int run_cc_mkfs(char *);*/   /*run cc_mkfs utility*/
int cc_dump(char *);   /*dump the disk partition after formatting*/
int parse_dump();   /*parse the dumped file*/
int comp_cc_dump();   /*analize if cc_mkfs run well*/
char *scomp(char *, char *);   /*string compare routine*/

main()
{
  ccfs_init();
}

int ccfs_init()
{
  int ret;
  char *dev;
  printf("Device name : ");
  scanf("%s", dev);

  /*  if(run_cc_mkfs(dev)!=0){
    fprintf(stderr, "error: run_cc_mkfs\n");
    return MKFSERR;
    }*/
  if(cc_dump(dev)!=0){
    fprintf(stderr, "error: cc_dump\n");
    return DUMPERR;
  }

  if(parse_dump()!=0){
    fprintf(stderr, "error: parse_dump\n");
    return PARSERR;
  }

  if((ret=comp_cc_dump())<0){
    fprintf(stderr, "error: comp_cc_dump\n");
    return INITERR;
  }
  else if(ret>0){
    fprintf(stderr, "error: comp_cc_dump\n");
    return CMPERR;
  }
  else{
    fprintf(stdout, "Congratulations! cc_mkfs utility successes!\n");
    return 0;
  }
}

/*
int run_cc_mkfs(char *dev)
{
  char *path, *option;
  printf("Path name of cc_mkfs : ");
  scanf("%s", path);

#ifdef _OPTION_
  printf("Option : ");
  scanf("%s", option);
#endif

#ifdef _OPTION_
  if(execl(path, "cc_mkfs", option, dev, 0)<0){
    fprintf(stderr, "exec error\n");
    exit(1);
  }
#else
  if(execl(path, "cc_mkfs", dev, 0)<0){
    fprintf(stderr, "exec error\n");
    exit(1);
  }
#endif

  return(0);
}
*/

int cc_dump(char *dev)
{
  int fdin, fdout, n;
  char buf[BUFSIZE];


  if((fdin=open(dev, O_RDONLY))<0){
    fprintf(stderr, "open error - read\n");
    exit(3);
  }
  if((fdout=open("./cc_dump_bi", O_WRONLY | O_CREAT))<0){
    fprintf(stderr, "open error - write\n");
    exit(4);
  }

  if((n=read(fdin, buf, BUFSIZE))>0)
    if(write(fdout, buf, n)!=n){
      fprintf(stderr, "write error\n");
      exit(1);
    }
  if(n<0){
    fprintf(stderr, "read error\n");
    exit(2);
  }
  close(fdin);
  close(fdout);

  return(0);
}


int parse_dump()
{
  char *buf;
  FILE *fpin, *fpout;

  if((fpin=fopen("cc_dump_bi", "rb"))==NULL){
    fprintf(stderr, "fopen error - read\n");
    exit(1);
  }
  printf("here0!\n");

  if((fpout=fopen("cc_dump", "a"))==NULL){
    fprintf(stderr, "fopen  error - write\n");
    exit(2);
  } 

  printf("here1!\n");

  if(fread(buf, sizeof(long), 1, fpin)>0)
    fprintf(fpout, "file system unique id : %u\n", buf);
  else{
    fprintf(stderr, "fread error\n");
    return -1;
  }

  ......

  fclose(fpin);
  fclose(fpout);

  return 0;
}


#define LEN 80+1

int comp_cc_dump()
{
  int i;
  char *buf1, *buf2;
  FILE *fpin1, *fpin2;


  if((fpin1=fopen("cc_meta", "r"))==NULL){
    fprintf(stderr, "fopen error - read\n");
    exit(1);
  }
  if((fpin2=fopen("cc_dump", "r"))==NULL){
    fprintf(stderr, "fopen  error - write\n");
    exit(2);
  } 

  if(fgets(buf1, LEN, fpin1)!=NULL)
    if(fgets(buf2, LEN, fpin2)!=NULL){
      if(scomp(buf1, buf2)==NULL){
	fprintf(stderr, "file system unique id is wrong\n");
	return -1;
      }
      else
	fprintf(stdout, "file system unique id is %s\n", buf2);
    }

	......

    fclose(fpin1);
    fclose(fpin2);

    return 0;
}

char *scomp(char *s1, char *s2)
{
  for(; *s1!=':'; s1++);
  for(; *s2!=':'; s2++);
  if(strcmp(s1, s2)==0)
    return s1;
  return NULL;
}
afsadfsaf의 이미지

char *scomp(char *s1, char *s2)
{
  for(; *s1!=':'; s1++);
  for(; *s2!=':'; s2++);
  if(strcmp(s1, s2)==0)
    return s1;
  return NULL;
}

가 수상하군요.

수정 -
가 아니라 -_-

  int ret;
  char *dev;
  printf("Device name : ");
  scanf("%s", dev);

dev가 어딜 가리키고 있을까요? :wink:
그런데 scanf가 메모리를 자동으로 생성해 주는거였나?;;
그럼 이것도 아닐지도 -_-a

어셈을 잘 모르지만 "경험" -_-상 세그먼트 폴트는
에러 나는 위치와는 그다지 관련이없는 듯 하더군요,

만약 윈도98이었으면 다른프로그램이 낸 에러일수도 :wink: 있었겠지만..-_

L-System

jemiro의 이미지

정확한 지적이십니다.
dev에 메모리를 할당해주던가,
적당한 사이즈의 배열로 잡아주던가 해야 할것입니다.

yubgipenguin wrote:
char *scomp(char *s1, char *s2)
{
  for(; *s1!=':'; s1++);
  for(; *s2!=':'; s2++);
  if(strcmp(s1, s2)==0)
    return s1;
  return NULL;
}

가 수상하군요.

수정 -
가 아니라 -_-

  int ret;
  char *dev;
  printf("Device name : ");
  scanf("%s", dev);

dev가 어딜 가리키고 있을까요? :wink:
그런데 scanf가 메모리를 자동으로 생성해 주는거였나?;;
그럼 이것도 아닐지도 -_-a

어셈을 잘 모르지만 "경험" -_-상 세그먼트 폴트는
에러 나는 위치와는 그다지 관련이없는 듯 하더군요,

만약 윈도98이었으면 다른프로그램이 낸 에러일수도 :wink: 있었겠지만..-_

you의 이미지

그렇군요 -_-;;
아까는 배열로 잡아주고
실행했을때 마찬가지로 에러가 났던것 같은데...
그래서 다시 고쳐서 다른데서 잡아보려 했건만...
어쨋든
이제는 세그멘테이션 에러는 안나네요
근데...
다시 다른질문좀 올릴께요...
(위에...)

익명 사용자의 이미지

하드디스크와 플로피는 서로 약간은 다른 로직으로 정보분석을 하셔야 된다고
강력히 주장합니다.

플로피는 파티션이 없기 때문에 첫번째 섹터는 Boot Sector입니다.

하드디스크는 첫번째 섹터에 파티션 정보가 있는 MBR 입니다.

님의 경우 2개의 첫번째 섹터를 읽어서 같게 나온다는 것은 이해할수 없는
결과군요.

그렇다면 확인할 방법이 저번에도 말씀드린거 같은데

Offset (512 - 2) 부분의 2바이트에 0xaa, 0x55가 나타나 보이는지

꼭 확인해주세요. 그것이 없다면 질문하신분의 코드는 잘못짜여진겁니다.

하드디스크는 MBR에서 파티션정보를 먼저 검색하고

해당 파티션중에서 부트플래그가 설정된 파티션을 먼저 읽어서

해당 파티션의 첫번째 섹터를 구한다음 다시 그 위치를 512바이트 읽어서

이때부터는 파일시스템의 타입에 따라서 정보가 전혀 다른 위치에 있기 때문에

파일시스템에 따른 분석루틴이 따로 호출되어야 합니다.

여기서 또한 LBA관련 확장 정보가 나타나는 경우도 있어 놓치면 안되는 정보입니다.

그 다음 해당 파일시스템의 첫 root entry를 찾거나 System 파일을 찾아야 됩니다.

그 다음의 절차부터는 파일시스템마다 다르므로 설명 않겠습니다.

예로 FAT16인 경우 ROOT 영역을 찾아 메모리에 올리고

ROOT(entry) 에 기술된 하부 디렉토리 구조를 재귀적으로 찾아가면 됩니다.

FAT32는 FAT16에서 Reserved되었던 부분이 확장되서 그부분을 추가적으로

분석하면 되고요...

아래는 제가 오래전에 MBR에 대한 내용을 조금 적어둔 메모입니다.

[url]http://linux.co.kr/tips/content.html?do=showall&msg_id=427&order=search&cur_page=1&keyword=파티션&search_option=msg_subject[/url]

you의 이미지

계속 답변해주셔서 감사드리구요^^
우선 질문을 원점으로 돌려서

제가 아까 테스트했던 파티션과
실제 테스트할 파티션은
MBR이 있는 주파티션이 아니라
아까는 /dev/hda8이었고(hda6이 리눅스 root 파티션),
실제 테스트는 두번째 파티션(부트영역없음)에 파일시스템을 포맷하고
파티션정보를 읽어들일 것입니다.
그렇다면
그 파티션의 처음 섹터부분은
파티션정보가 아니라
제가 테스트할 FS의 경우
수퍼블락이 위치한다고 layout에 나와있던데요..
ext2의 경우에도 그렇지 않나요?(첫번째 블락그룹에서의 ...)
그래서 저는
처음오프셋부분부터 읽어들였습니다만...
님의 말씀은
우선은 우선은 MBR에서 파티션 정보를 읽고나서
그 파티션의 첫째섹터위치를 구해서
그 위치부터 읽어들여야 한다는 말씀이신지요?
이게
/dev/hda8에서 read하는것과 무슨다른점이 있는지요?

과연 제가 짠 대로 하면 잘못된건가요?ㅠㅠ

댓글 달기

Filtered HTML

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

BBCode

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param>
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

Textile

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • You can use Textile markup to format text.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Markdown

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • Quick Tips:
    • Two or more spaces at a line's end = Line break
    • Double returns = Paragraph
    • *Single asterisks* or _single underscores_ = Emphasis
    • **Double** or __double__ = Strong
    • This is [a link](http://the.link.example.com "The optional title text")
    For complete details on the Markdown syntax, see the Markdown documentation and Markdown Extra documentation for tables, footnotes, and more.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Plain text

  • HTML 태그를 사용할 수 없습니다.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 줄과 단락은 자동으로 분리됩니다.
댓글 첨부 파일
이 댓글에 이미지나 파일을 업로드 합니다.
파일 크기는 8 MB보다 작아야 합니다.
허용할 파일 형식: txt pdf doc xls gif jpg jpeg mp3 png rar zip.
CAPTCHA
이것은 자동으로 스팸을 올리는 것을 막기 위해서 제공됩니다.