가변인자함수에 대하여 공부하면서 가변함수의 대표예시인 printf를 구현해보았습니다.

출력하는 부분은 printf 내부쪽을 알아야되기에 일단 printf함수를 이용했습니다.

 

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
#include<stdio.h>
#include<stdarg.h>
int my_printf(char* str,...)
{
    int len=0;
    int i;
    char buf[256];
    va_list ap;
    va_start(ap,str);
    
    for(;*str;str++,len++)
    {
        if(*str=='%'
        {
            switch(*(str+1))
            {
                case 'c' : //문자 
                    printf("%c",va_arg(ap,int));
                    break;
                case 's' : //문자열
                    printf("%s",ap);
                    va_arg(ap,int);
                    break;
                case 'd' : //정수 
                    printf("%d",va_arg(ap,int));
                    break;
                case 'x' : //16진수  
                    printf("%x",va_arg(ap,int));
                    break;
                case 'f' : //실수  
                    printf("%f",va_arg(ap,double));
                    break;
                default :
                    str--;
                    len--
                    break;
            }
            str++;
            len++;
        }
        else if(*str==92//92는 역슬래쉬
        {
            switch(*(str+1))
            {
                case 'n' : //줄넘김 
                    printf("\n");
                    str++;
                    len++;
                    break;
                default :
                    break;
            }
        }
        else
        {
            printf("%c",*str);
        }
    }
    va_end(ap);
    return len;
}
 
int main()
{
    my_printf("  %d\n",my_printf("%d %d %c %s %c %f",1,2,'c','test','c',0.1));
    my_printf("%d %x %x %x",3);
    printf("%d",printf("asdf%d",1));
}
cs

 

하면서 의문이 들었던게 va_arg()매크로함수의 2번째인자값에 char을 넣을 수 없다는 것이였습니다.

[va_arg는 ap의 포인터를 다음 인자로 옮겨주는 역할을 합니다.]

스택이 무조건 4byte씩 쌓인다면 모를까 char형은 1byte씩 쌓인다고 생각했기 때문에 char형이 필요하지 않냐고 생각했는데

알아보니 char이나 short는 인자로 전달될때 스택에서 int 형으로 확장되어서 전달되기 때문에 두번째 인자의 값이 int, double만 사용되는 것이였습니다. 또 va_list 는 char형인데 이는 포인터를 이동시킬때 1byte씩 이동시키기 위함이라고 하네요.

'『프로그래밍』 > C' 카테고리의 다른 글

뱀게임  (1) 2017.12.27
전역변수명과 지역변수명이 같을때  (0) 2017.12.21
조건부 컴파일  (0) 2017.12.20

 

 

wormgame.c

 

몇달전에 만들었던 뱀게임입니다.

그땐 아직 프로그래밍에서 함수란 개념이 정립이 안되있어서 돌아가기만 하면 된다는 생각에 아무렇게나 코딩했네요. 코드가 좀 난잡합니다.

그래도 한번 예시로 써보실 분들은 써보시길...

 

 

 

 

 

 

'『프로그래밍』 > C' 카테고리의 다른 글

printf함수 구현해보기  (0) 2017.12.29
전역변수명과 지역변수명이 같을때  (0) 2017.12.21
조건부 컴파일  (0) 2017.12.20

-PE구조 정리 : http://kaekpiteoseu.tistory.com/category/%E3%80%8E%EB%A6%AC%EB%B2%84%EC%8B%B1%E3%80%8F -

PE구조에 대해서 공부했으니 메모장.exe파일을 이용해 확인해 보겠습니다.

 

 

DOS Header


 

 

DOS Header부분은 색칠된 부분입니다.

 

 

PE파일이 exe파일인것을 알 수 있으며

 

 

NT Header의 시작주소가 0x000000E8[리틀엔디언방식]인것을 알 수 있습니다.

 

DOS Stub


 

 

NT Header의 시작주소가 000000E8인것으로 보아 이곳까지가 DOS Stub 영역인것을 알 수 있습니다. 내용을 보면 "이 프로그램은 도스모드로 실행할 수 없다" 라고 적혀있습니다. DOS모드[16bit]로 실행할시 저 문장이 출력됩니다.

 

NT Header


 

 

NT Header의 첫번째 멤버입니다. PE파일인 경우 50450000[PE00]으로 고정되어 있습니다.

 

 

NT Header의 두번째 멤버입니다.

i386 즉 32bit 에서 동작하며[EC-ED], 섹션이 5개가 존재합니다.[EE-EF] 속성값 부분은 0102인데 32bit 기반이며 실행가능한 파일이라고 해석됩니다.[FE-FF]

 

 

NT Header의 3번째 멤버입니다. 값이 좀 많은데 여기는 주소관련 내용이 들어있습니다.

프로그램의 시작주소 : 0001B550

파일로딩시작주소 : 00400000

메모리에서 섹션 최소 단위 : 00001000

파일에서 섹션 최소 단위 : 00000200

메모리에 로딩됬을때 파일 크기 : 0003F000

PE헤더의 크기 : 00000400

 

 

Section Table[Section Header]


 

 

섹션이름 : .text[1E0-1E7]

메모리에서의 섹션크기 : 0001B0DC

메모리에서의 섹션시작주소 : 00001000

파일에서의 섹션크기 : 0001B200

파일에서의 섹션시작주소 : 00000400

파일속성 :  60000020 = 실행가능하고 읽기가능한 섹션코드를 포함하고 있다라는 의미를 가집니다.

 

종류가 많으니 .text만 하겠습니다.

 

Section


 

 

Section Table의 정보로 보아 400부터 1B200까지가 .text 섹션의 영역입니다. 안에는 기계어로 된 코드가 담겨있습니다.

 

DOS Header[메모리 할당시]


 

Immunity Debugger를 이용했습니다. Memory map에 들어가 Dump를 보면 됩니다.

 

 

주소가 바뀌긴 했지만 내용의 변화는 없습니다. 크기도 40 그대롭니다.

 

DOS Stub[메모리 할당시]


 

 

Hex 에디터로 열었을때와 같습니다. 길어서 다출력은 못했지만요.

 

NT Header[메모리 할당시]


 

 

이곳도 똑같습니다.

 

Section Table[메모리 할당시]


 

 

여기도 똑같습니다.

 

Section[메모리 할당시]


 

 

메모리가 할당됬을시에 NT Header의 설정대로 메모리에 올라갔을땐 .text의 시작주소가 400[파일상태일때 .text섹션이 위치한 번호]번이아닌 1000번인걸 확인할 수 있습니다. 그리고 사이즈가 1B0DC[메모리에 올라갔을때 크기]가아닌 1C000인데 이유는 NT Header의 값중 메모리에서 섹션의 최소단위가 1000단위로 끊어지게 셋팅되어 있기 때문입니다.

'『리버싱』' 카테고리의 다른 글

PE구조 정리  (0) 2017.12.25

ID : natas5   

PW : iX6IOfmpN7AYOQGPwtn3fXpbaJVJcHfq

 

 

로그인해서 들어가면 엑세스가 안됬다. 로그인되지 않았다. 라고 나옵니다.

또 패킷을 확인해 봅시다.

 

 

쿠키에 loggedin이라는 값이 있는걸 확인할 수 있는데 값이 0입니다.

쿠키는 조그마한 정보를 전달하는 용도로 사용하는데 이걸 보고 추측한다면 필요없는 정보를 전달할리는 없고 변수이름도 로그인이니 이값에 따라서 로그인이 될것이라는 것을 생각해볼 수 있습니다.

패킷을 잡아서 loggedin의 값을 1로 바꿔서 전송해봅시다.

 

 

그 결과 natas6의 비밀번호를 얻을 수 있었습니다.

'『워게임』 > NATAS' 카테고리의 다른 글

NATAS4-문제풀이  (0) 2017.12.26
NATAS3-문제풀이  (0) 2017.12.25
NATAS2-문제풀이  (0) 2017.12.22
NATAS1-문제풀이  (0) 2017.12.22
NATAS0-문제풀이  (0) 2017.12.22

ID : natas4

PW : Z9tkRkWmpt9Qr7XrR5jWRkgOU901swEZ

 

들어가보면 엑세스가 허용되지 않았다. 접근하려면 natas5홈페이지에서 접근해야 한다고 적혀있습니다. [참고로 코드에는 힌트가 없습니다.]

이 홈페이지는 http프로토콜로 통신을 하는데 http 요청 헤더에 요청할때의 홈페이지 주소를 전달하는 옵션이 있습니다.

바로 Referer이라는 옵션인데 이 홈페이지의 패킷을 잡아서 보면[fiddler를 이용했습니다.]

 

 

요렇게 보내는걸 확인할 수 있습니다.

natas5홈페이지에서 접근하여야 된다고 했으니 Referer값을 natas4에서 natas5로 바꿔주고 잡았던 패킷을 전송해 보겠습니다.

 

 

응답으로 natas5의 비밀번호를 보내주는것을 확인할 수 있습니다.

 

'『워게임』 > NATAS' 카테고리의 다른 글

NATAS5-문제풀이  (0) 2017.12.26
NATAS3-문제풀이  (0) 2017.12.25
NATAS2-문제풀이  (0) 2017.12.22
NATAS1-문제풀이  (0) 2017.12.22
NATAS0-문제풀이  (0) 2017.12.22

+ Recent posts