[TECH] 비동기 문맥 점프

minzkn의 이미지

먼저 이글은 제 목적에 의해서 다시 지워질수 있겠습니다.
예전에 그냥 지웠는데 분명 그것은 제 잘못임을 인정합니다.
이번에는 먼저 이런 조건을 남기고 글 남기겠습니다.

설명은 않겠습니다. 한번 해보세요. 그리고 이것의 문제점에 대해 생각해보세요.

이것은 비동기 문맥 점프라고 이름지어 봤습니다.
일종의 Buffer overflow기법에 속한다고 해야 겠지요?
재귀적인 호출처럼 보이지만 실체는 핑퐁함수입니다.

이 소스에서 제가 말하고 싶은것은
Buffer overflow에 대한 이해를 돕자는 것이고
모든 개발자는 이러한 Buffer overflow기법을 막을수 있는 방법을
모색할수 있도록 생각해볼수 있는 예를 든것입니다.

부디 좋은 개발자가 되십시요.

아! 깜박했는데 이 프로그램을 실행해보시면 그리 오래가지는 않고 죽어버립니다.
그렇다면 이것은 죽지 않고 계속 핑퐁시킬수 있는 방법은 어떤게 있을까요?

#include <stdio.h>

void MyJumpAdjust(void);

void MyStackAdjust(void)
{
 fprintf(stdout, "Oh~ jump done.\n");
 MyJumpAdjust();
}

void MyJumpAdjust(void)
{
 int s_JumpLabel;
 *(((int *)(&s_JumpLabel)) + 1 + 1)  = ((int)(&MyStackAdjust));
 fprintf(stdout, "Jump to 0x%08x\n", (int)(&MyStackAdjust));
}

int main(void)
{
 MyJumpAdjust();
 return(0);
}
Forums: 
girneter의 이미지

세상엔 이런 사람도 있고 저런 사람도 있습니다.

저같은 초보의 경우에는 그냥 고수분들이 올려주시는
code 와 설명 하나하나가 놀라울 따름입니다.
물론...
엉터리 소스가 올라와서 그걸 보고 제가 엉터리로 배울 수도
있는거지만
누구나 다 그렇게 크는거 아니겠습니까?

소스에 문제가 있으면 더 나은 방법을 다른 분들이 제시하면 되는거고.

또 제가 제시할 수도 있는거고. 흠흠~~~

부디 kldp 에서만큼은 모두 즐겁게 웃으면서
리눅스를 다루고 프로그래밍을 했으면 합니다.

개념없는 초딩들은 좋은 말로 할때 DC나 웃대가서 놀아라. 응?

kuma의 이미지

*(((int *)(&s_JumpLabel)) + 1 + 1) = ((int)(&MyStackAdjust));
여기서 1+1 의 의미를 설명 부탁합니다. 도저히 어셈으로 풀어서 봐도 잘 모르겠네요... ㅠㅠ

ddoman의 이미지

이 프로그램 코드 분석과 해석 해주실분 없으신가요...
도대체 코드를 읽어봐도 모르겠네요..

그냥 봐선 int형 변수 주소값에 +2를 해준후, 그 공간에..
MyStackAdjust함수의 주소값을 넣어주고..
fprintf로 그 주소 값을 출력해주는거밖에 안보이는데..

어떻게 MyStackAdjust가 호출되는지 모르겠네요..

아...무식이 죄인가..........

조언조언 좀..글구 핑퐁함수가 뭐죠??

bugiii의 이미지

함수가 리턴되는 주소를 스택에 만들어지는 변수를 가지고 위치를 구해서 (int 포인터형 1 + 1) 바꿔치기 했으니까 당연히 main으로 돌아가지 않고 다시... 냠...

근데, 좀... 뭐하시려구요? 포터블하지 못한 문제도 있고... (스택이 자라는 방향이 다 똑같은 것도 아니고 주소 크기가 int 포인터 크기가 아닐 경우도...) 리턴값 있는 함수일 경우에는 레지스터로 리턴될지 스택에서 리턴될지도 그렇고...

:roll:

bugiii의 이미지

어궁.. 근데 왜 지우실려구요?
답변 붙으면 제글은 안지워지는 것 맞죠? -_-;

권순선의 이미지

자기가 올린 글을 지우거나 수정하는 것은 개개인의 자유입니다만 그것이 다른 사람들을 불쾌하게 만드는 일이 되어서는 곤란합니다. 이미 아시겠지만, minzkn님의 그 "목적"때문에 불미스러운 일이 한번 있었습니다.

http://bbs.kldp.org/viewtopic.php?t=22728

저는 사이트 관리자로서 여전히 자기자신의 글에 대한 삭제/수정의 자유는 인정하겠다는 의사를 위에서도 밝혔습니다만, 그러한 행위가 반복적이고 의도적으로 이루어져도 괜찮다는 뜻은 아닙니다.

그러므로 지난번과 같은 식으로 또다시 물의를 일으킬 뜻이 조금이라도 있으시다면(자기가 올린 글을 지난번처럼 마음대로 수정하거나 삭제할 생각이 있으시다면) 이곳에 더이상 글을 올리지 말아 주실 것을 부탁드리며 지금 탈퇴 요청을 해 주시기 바랍니다. 탈퇴처리해 드리도록 하겠습니다. 개개인의 자유는 인정하지만, minzkn님의 행위로 인해 많은 사람들이 또다시 반목하게 되는 일이 발생하는 것은 원치 않습니다.

bugiii의 이미지

어구구... 괜히 꼬리 달아서... 두분에게 다 죄송합니다...

이글이 더 괜한 글이 될지도 모릅니다만 이젠 더 그런 일이 없겠죠!!!

자자... 살기도 힘든데 우리끼리라도 다들 웃고 삽시다.

:lol:

lsj0713의 이미지

minzkn wrote:
먼저 이글은 제 목적에 의해서 다시 지워질수 있겠습니다.
예전에 그냥 지웠는데 분명 그것은 제 잘못임을 인정합니다.
이번에는 먼저 이런 조건을 남기고 글 남기겠습니다.

설명은 않겠습니다. 한번 해보세요. 그리고 이것의 문제점에 대해 생각해보세요.

이것은 비동기 문맥 점프라고 이름지어 봤습니다.
일종의 Buffer overflow기법에 속한다고 해야 겠지요?
재귀적인 호출처럼 보이지만 실체는 핑퐁함수입니다.

이 소스에서 제가 말하고 싶은것은
Buffer overflow에 대한 이해를 돕자는 것이고
모든 개발자는 이러한 Buffer overflow기법을 막을수 있는 방법을
모색할수 있도록 생각해볼수 있는 예를 든것입니다.

부디 좋은 개발자가 되십시요.

아! 깜박했는데 이 프로그램을 실행해보시면 그리 오래가지는 않고 죽어버립니다.
그렇다면 이것은 죽지 않고 계속 핑퐁시킬수 있는 방법은 어떤게 있을까요?

#include <stdio.h>

void MyJumpAdjust(void);

void MyStackAdjust(void)
{
 fprintf(stdout, "Oh~ jump done.\n");
 MyJumpAdjust();
}

void MyJumpAdjust(void)
{
 int s_JumpLabel;
 *(((int *)(&s_JumpLabel)) + 1 + 1)  = ((int)(&MyStackAdjust));
 fprintf(stdout, "Jump to 0x%08x\n", (int)(&MyStackAdjust));
}

int main(void)
{
 MyJumpAdjust();
 return(0);
}

*(((int *)(&s_JumpLabel)) + 1 + 1) = ((int)(&MyStackAdjust));

이런 식의 기법은 무슨 용도에 쓰는 건지 알고 싶습니다. 이식성을 생각하면 별로 바람직한 코드가 아닌데, 그런데도 적으신 것을 보면 뭔가 특별히 유용한 용도가 있을 것 같습니다만...

한가지 더, 위의 코드랑
*(&s_JumpLabel + 2) = (int)(&MyStackAdjust);
이거랑 차이점이 뭐지요?

bugiii의 이미지

저같은 경우는 자체 쓰레드 같은 것을 구현할 때, 리턴 주소를 교묘히 이용해서 이러저리 왔다갔다 하는 곳에 사용했습니다.
물론 os에서 제공하는 setjmp 계열을 많이 씁니다만 (이것도 이식성이 많이 떨어져서...), 직접적이라면 이식성 때문에 os별 기종별 #if 가 훨씬 더 난무하겠죠...

그리고, 두번째는... 경고 피하기 아닌가요?

총총...

kuma의 이미지

일단 Debug 모드로 컴파일해서 돌렸을때는 위에 본문을 쓰신분의 말 처럼 결과가 나오지만 Size 모드로 최적화를 거친 결과는 MyJumpAdjust 함수를 한번 수행하고 프로그램을 종료합니다.

아래와 같이 바꾸었는데도 s_JumpLabel 의 주소가 실행중 계속 증가를 하는군요.( 즉 Stack 이 계속 자란다는 결과가.... ), 왜 이런지가 알고 싶습니다.

#include <stdio.h>

void MyJumpAdjust();

void MyStackAdjust( )
{

int s_JumpLabel;
*( ((int *)(&s_JumpLabel)) + 1 + 1) = ((int)(&MyJumpAdjust));
fprintf(stdout, "Oh~ jump done.\n");
}

void MyJumpAdjust()
{
int s_JumpLabel;
*( ((int *)(&s_JumpLabel)) + 2 ) = ((int)(&MyStackAdjust));
fprintf(stdout, "Jump to 0x%08x\n", (int)(&MyStackAdjust));
}

int main(void)
{
MyJumpAdjust();
return(0);
}

minzkn의 이미지

권순선 wrote:
자기가 올린 글을 지우거나 수정하는 것은 개개인의 자유입니다만 그것이 다른 사람들을 불쾌하게 만드는 일이 되어서는 곤란합니다. 이미 아시겠지만, minzkn님의 그 "목적"때문에 불미스러운 일이 한번 있었습니다.

http://bbs.kldp.org/viewtopic.php?t=22728

저는 사이트 관리자로서 여전히 자기자신의 글에 대한 삭제/수정의 자유는 인정하겠다는 의사를 위에서도 밝혔습니다만, 그러한 행위가 반복적이고 의도적으로 이루어져도 괜찮다는 뜻은 아닙니다.

그러므로 지난번과 같은 식으로 또다시 물의를 일으킬 뜻이 조금이라도 있으시다면(자기가 올린 글을 지난번처럼 마음대로 수정하거나 삭제할 생각이 있으시다면) 이곳에 더이상 글을 올리지 말아 주실 것을 부탁드리며 지금 탈퇴 요청을 해 주시기 바랍니다. 탈퇴처리해 드리도록 하겠습니다. 개개인의 자유는 인정하지만, minzkn님의 행위로 인해 많은 사람들이 또다시 반목하게 되는 일이 발생하는 것은 원치 않습니다.

존경하는 순선님의 말씀 새겨 듣겠습니다. 이 쓰레드의 글은 삭제않할께요.
다만 많은 분들이 제가 목적하는 바에 다가오지 못하고 있는것이 섭섭할뿐이군요.
아무튼 순선님의 뜻을 거역할 생각은 전혀 없습니다.

도구의 결함은 장인의 손으로 극복한다.

bugiii의 이미지

목적하시는 바를 말씀하세요.
저같은 바보는 말씀을 해주셔야 압니다.

p.s. 역시 안끼는게 나은 건지...

kuma의 이미지

아둔해서 도저히 모르겠네요. ㅡㅜ

*(&s_JumpLabel + 2) 로 쓰지 않고 *( ((int *)(&s_JumpLabel)) + 1 + 1 ) 게 쓰신 목적도......,

그리고 최적화 방법에 따라 작동 할 수도 또는 아닐수도...., 또는 컴파일러에 따라 순서도 조금 틀리는것 같은데......,

정확한 목적하는 바를 알려주세요, 그리고 오버플로나는걸 막는방법도......, 요렇게, 저렇게 짱돌 굴려봐두 나이를 먹어서 그런지 돌굴러가는 소리만 나지 답을 모르겠네여.... ㅡㅜ

김희상의 이미지

목적하시는 바가 뭔지는 잘 모르겠지만.......

#include <stdio.h>

int     g_nCount = 0;

void MyJumpAdjust(void);

void MyStackAdjust(void)
{
//  register unsigned long ebp __asm__("ebp");
//  register unsigned long esp __asm__("esp");
//  printf("esp1=%#lx, ebp=%#lx\n", esp, ebp);


    if (g_nCount++ % 100000 == 0)
        fprintf(stdout, "Oh~ jump done.\n");

    __asm__ __volatile__ (
            "lea 0x4(%%ebp),%%esp\n\t"
            "call MyJumpAdjust"
            ::
    );
}

void MyJumpAdjust(void)
{
    volatile long s_JumpLabel;

    *(&s_JumpLabel + 1 + 1)  = ((long)(&MyStackAdjust));

    if (g_nCount % 100000 == 0)
        fprintf(stdout, "Jump to 0x%08lx\n", (long)(&MyStackAdjust));
}

int main(void)
{
    MyJumpAdjust();
    return(0);
}

일단 이렇게 하면 동작은 합니다. 의도하신대로 한건진 잘 모르겠지만..
뭐, 물론 위와같이 안하고도 다른 방법도 있을겁니다...

gcc의 최적화 옵션을 켜도 제대로 동작하도록 원 소스에서 좀 수정하였습니다.

단, 위의 소스는 함수진입시 스택프레임을 만드는 컴파일러에 한합니다.
보통의 경우 gcc는 위의 소스를 컴파일해도 별 문제(?) 없고...
어떤 컴파일러는 옵티마이즈한다고 스택프레임을 자기가 마음대로 만들지 않고
컴파일할 수도 있으므로 항상, 100% 동작한다고는 못해도 gcc로 컴파일하면
잘(?) 돌겁니다.....

뭐, 혹시 실수한게 있을지도 모르니 안되시는 분들은 알려주시거나 직접 수정하셔서 :lol: 올려주시면 고맙겠네요..

권순선의 이미지

minzkn wrote:
존경하는 순선님의 말씀 새겨 듣겠습니다. 이 쓰레드의 글은 삭제않할께요.
다만 많은 분들이 제가 목적하는 바에 다가오지 못하고 있는것이 섭섭할뿐이군요.
아무튼 순선님의 뜻을 거역할 생각은 전혀 없습니다.

이 스레드의 글을 포함해서 앞으로 올리시는 다른 글들도 지난번과 같은 식으로 삭제/수정하지 않겠다는 뜻인지요? 본인이 올리는 글에 대해서 지난번처럼 삭제/수정할 의도가 있는지를 정확히 밝혀 주십시오. 사실 이런 이야기를 하고 있는 것 자체가 말이 안되는 상황입니다만....이미 불행한 경험이 한번 있었기에 어쩔수 없군요.

글을 올리는 것도 자유이고 글을 지우고 고치는 것도 자유입니다만 그것이 상식에 어긋나고, 많은 사람들을 불쾌하게 만드는 식이 되어서는 곤란합니다. minzkn님의 양식과 상식을 믿겠습니다.

답변 부탁드립니다....

mastercho의 이미지

minzkn wrote:
먼저 이글은 제 목적에 의해서 다시 지워질수 있겠습니다.
예전에 그냥 지웠는데 분명 그것은 제 잘못임을 인정합니다.
이번에는 먼저 이런 조건을 남기고 글 남기겠습니다.

것참 성격이상한분이시네요

말을 안할려고 했지만 "제 목적에 의해서 다시 지워질수 있다?"을 하다뉘요...

분명이 탈퇴를 할때도 토론과 관계없는 글까지도 모조리 지움으로써

다른 사람들에게 피해를 이미 주어놓고 말도 안되는 저런 조건을

달고 다시 가입을 하고 글을 쓰네요

것참 불편합니다 불편해... 보는 사람으로 하여금....

저런 조건을 달고 글을 쓴다는거 자체가 님때문에 피해를 본

사람들에 대한 반성의 기미가 전혀 없다고도 보여지네요

탈퇴는 단지 쇼였나요?

넉살도 좋으십니다 것참

쩝 ,

이미 상식있는분이라면 저런 조건을 달고 글을 쓰진 않았을거라 봅니다
......

Quote:
이 쓰레드의 글은 지우지 않을께요

이 말의 의도가 참 의심스럽습니다
다른 쓰레드 글은 지운다는 이야기군요]

승자는 자기보다 우월한 사람을 보면 존경심을 갖고 그로부터 배울 점을 찾지만 패자는 자기보다 우월한 사람을 만나면 질투심을 갖고 어디 구멍난 곳이 없는지 찾는다.
- 하비스

cedar의 이미지

코더 자신만이 의미를 알 수 있는
전형적인 쓰기 전용 코드(Write-only code)로군요. :(
소프트웨어공학적으로 절대 피해야만 하는 좋지 않은 코딩스타일입니다.

wind772의 이미지

버퍼오버플로우...^^;;
리눅스에서 돌려보니깐 안 멈추던데요....(와우 7.1 - gcc 2.95)
방금 윈도우에서 해봤는데..역시 무한이네요...(윈98se - Dev-C++)
제가 사용한 소스입니다..(ㅋㅋ 아주 비슷하죠??)

#include <stdio.h>


void aa();
void bb()
{
    printf("BB : Call aa()\n");
    aa();
}

void aa() {
    int i;
    *((int*)(&i)+2) = (int)bb;
    printf("AA : Hello\n");
}


int main()
{
    aa();
    return 0;
}

꼭 "+1+1"이 아니어도 됩니다. 저는 "+2" 입니다..^^;;
이것이 의미하는게 특별한게 아니라 변수의 위치보다 8바이트 뒤에 BB함수의 주소를 써 넣음으로써 함수를 마치고 리턴될 위치를 BB함수로 바꿔주는 것이니까요..

[변수(4)] [SFP(4)] [RET(4)]
           ~~~~
           리턴될 주소..(여기다가 써 넣음)

근데 이건 리눅스쪽 자료라서..
윈도쪽 테스트는 오늘 처음 해보네요..

===================================================
중요한건 얼마나 아느냐가 아니라 그것에 대한 열정이다.

익명 사용자의 이미지

minzkn wrote:

다만 많은 분들이 제가 목적하는 바에 다가오지 못하고 있는것이 섭섭할뿐이군요.

다른 많은 분들도 minzkn 님처럼 글 올렸다가 심심하면 삭제해야 하나요?
아니면 나 잘났으니 좀 봐달라는 소위 "난 척" 입니까?

자꾸 두리뭉실하게 목적, 목적 하지 마시고, 그 목적이라는걸 공개하시지요.
공개해서 우매한 백성을 깨우쳐 주시길 바라마지않겠나이다.
제가 깨우침을 받으면 "난 척" 이라는 제 언행에 사과하겠습니다.

minzkn님. 자신의 신념을 가지고 사는 것은 좋은 것입니다.
그러나 그 신념이 네거티브하거나 다른 이에게 알게 모르게 피해를 주는 것이라면 그 신념을 계속 유지해야 하는지에 대해 고민해 보셔야 할 것 같습니다.

나중에 다시 지울 글이라면 이곳에 올리지 말고 자유게시판에 올리십시오.

-- 이 게시판은 토론게시판이 아니지만 보다못해 한마디 남깁니다.

maximus의 이미지

지금은 없어진 잡지지만..
예전에 Linux Magazine 에 올라 왔던 글이 있습니다..

Remote OverFlow 와 Local OverFlow 에 관한 내용이었는데..

그부분과 추가하여 함수 return Address를 수정해서 Root 권한을 얻는 방법이 소개 된적이 있습니다. (루트권한의 데몬에서)

대충 보아하니 비슷한 일을 하는 기본적인 함수 같아 보입니다..

=================================
:: how about a cup of tea ? ::
=================================

송지석의 이미지

예전에 kldp에서 secure programming howto를 봤었던 기억이 있는데 거기에 설명이 좀 되어있던 기억이 납니다.
버퍼 오버 플로 버그의 예로

int my_func( char* str)
{
    printf(str);
    return SUCCESS;
}

이런 코드가 있을 경우,
str에 "%x %x %x %x" 이런 식으로 넣어주고 호출하면 재밌는 결과가 나온다는 식으로 introduction한 예가 있었던 것 같네요.
역사적으로 최초의 버퍼 오버플로 버그 이용사례랄까 하는 게 sendmail 버그를 이용했던 것이라고 들은 적이있습니다.

댓글 달기

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
이것은 자동으로 스팸을 올리는 것을 막기 위해서 제공됩니다.