리눅스 커널에서 스택의 값을 어떻게 바꾸나요?

dragon01254의 이미지

최근에 리눅스 커널을 공부해보고 있는 학생입니다.

리눅스 커널 내부구조 라는 책을 보며 공부하고 있는데요.

실습문제 중에
"함수가 호출될 때는 스택에 어떤 값을 저장할까? 이때 스택에 저장되는 값을 변경함으로써
함수가 종료된 후, 함수를 호출한 원래 위치가 아닌 다른 곳으로 복귀되도록 스택의 내용을
변경해보자"

라고 문제가 있습니다.

그런데 스택에 어떻게 접근해야 하는지, 변경은 또 어떻게 하는지 잘 알지를 못하겠습니다.

shint의 이미지

함수 주소로 직접 접근은 안되는거 같네요.
함수 포인터로는 다른 주소로 보이기는 하는데. 원하시는 내용인지는 모르겠습니다.

여기서 리눅스 커널도 알려주니. 참고해보세요.
http://olc.kr/main/index.jsp

네이버 책
http://book.naver.com/

검색해보니. 여러가지 내용이 보였습니다.

리눅스 커널에서 스택의 값을 어떻게 바꾸나요?
http://search.naver.com/search.naver?ie=utf8&sm=stp_hty&where=se&query=%EB%A6%AC%EB%88%85%EC%8A%A4+%EC%BB%A4%EB%84%90%EC%97%90%EC%84%9C+%EC%8A%A4%ED%83%9D%EC%9D%98+%EA%B0%92%EC%9D%84+%EC%96%B4%EB%96%BB%EA%B2%8C+%EB%B0%94%EA%BE%B8%EB%82%98%EC%9A%94%3F

http://www.google.co.kr/search?q=%EB%A6%AC%EB%88%85%EC%8A%A4+%EC%BB%A4%EB%84%90%EC%97%90%EC%84%9C+%EC%8A%A4%ED%83%9D%EC%9D%98+%EA%B0%92%EC%9D%84+%EC%96%B4%EB%96%BB%EA%B2%8C+%EB%B0%94%EA%BE%B8%EB%82%98%EC%9A%94%3F&hl=ko&biw=&bih=&gbv=2&oq=%EB%A6%AC%EB%88%85%EC%8A%A4+%EC%BB%A4%EB%84%90%EC%97%90%EC%84%9C+%EC%8A%A4%ED%83%9D%EC%9D%98+%EA%B0%92%EC%9D%84+%EC%96%B4%EB%96%BB%EA%B2%8C+%EB%B0%94%EA%BE%B8%EB%82%98%EC%9A%94%3F&gs_l=heirloom-serp.12...96531.96531.0.97150.1.1.0.0.0.0.158.158.0j1.1.0....0...1ac.1.34.heirloom-serp..1.0.0.48GCFUDZvls

리눅스 커널에서 스택의 값 변경
http://search.naver.com/search.naver?sm=stb_hty&where=se&ie=utf8&query=%EB%A6%AC%EB%88%85%EC%8A%A4+%EC%BB%A4%EB%84%90%EC%97%90%EC%84%9C+%EC%8A%A4%ED%83%9D%EC%9D%98+%EA%B0%92+%EB%B3%80%EA%B2%BD

http://www.google.co.kr/search?q=%EB%A6%AC%EB%88%85%EC%8A%A4+%EC%BB%A4%EB%84%90%EC%97%90%EC%84%9C+%EC%8A%A4%ED%83%9D%EC%9D%98+%EA%B0%92+%EB%B3%80%EA%B2%BD&btnG=%EA%B2%80%EC%83%89&hl=ko&biw=&bih=&gbv=2

void fn2()
{
    printf("                                      fn2\n");
}
 
void fn()
{
    printf("                       fn PREV \n");
    fn2();
    printf("                       fn NEXT \n");
}
 
 
 
int CALLBACK fnCallBack()
{
    return 2;
}
 
int __cdecl fnCdecl()
{
    return 3;
}
 
 
 
void (*pfn)();
 
int main(int argc, char** argv) 
{
    //함수가 호출될 때는 스택에 어떤 값을 저장할까?
    pfn = fn;
    printf("fn             %x\n", fn);
    printf("pfn            %x\n", pfn);
    printf("fnCallBack     %x\n", fnCallBack);
    printf("fnCdecl        %x\n", fnCdecl);
 
 
    //이때 스택에 저장되는 값을 변경
    printf("-------------\n");
//    *(int*)0x401529 = *(int*)pfn;
 
    printf("fn();\n");
    fn();
 
    printf("pfn            %x\n", pfn);
    printf("pfn = (void(*)())fn;\n");
    pfn = (void(*)())fn;
    printf("pfn();\n");
    pfn();
 
    printf("pfn            %x\n", pfn);
 
    printf("pfn = (void(*)())fn2;\n");
    pfn = (void(*)())fn2;
    printf("pfn();\n");
    pfn();
 
    printf("pfn            %x\n", pfn);
    printf("fn             %x\n", fn);
    printf("-------------\n");
 
 
	return 0;
}
 
 
 
 
출력 결과
 
fn             40153d
pfn            40153d
fnCallBack     401562
fnCdecl        40156c
-------------
fn();
                       fn PREV
                                      fn2
                       fn NEXT
pfn            40153d
pfn = (void(*)())fn;
pfn();
                       fn PREV
                                      fn2
                       fn NEXT
pfn            40153d
pfn = (void(*)())fn2;
pfn();
                                      fn2
pfn            401529
fn             40153d
-------------

----------------------------------------------------------------------------
젊음'은 모든것을 가능하게 만든다.

매일 1억명이 사용하는 프로그램을 함께 만들어보고 싶습니다.
정규 근로 시간을 지키는. 야근 없는 회사와 거래합니다.

각 분야별. 좋은 책'이나 사이트' 블로그' 링크 소개 받습니다. shintx@naver.com

dragon01254의 이미지

좋은 답변 감사합니다.
그런데 이 코드는 실행해보니, 리턴 주소를 바꾸는게 아니라 어떤 빈 함수를 만들어서 다른 함수의 시작주소를 넘겨주는 코드네요.
그래서 그 빈 함수를 다른 함수들처럼 쓸 수 있게 해주는 코드요.
리턴 주소를 건드리기 위해서는, 다른 분들 말처럼 어셈블리얼르 배워서 opcode를 건드려야 하는 것 같습니다.
덕분에 참고하는데 도움이 됬습니다.

익명 사용자의 이미지

악성 코드의 입장으로 저걸 실행하면 흔히 Stack overflow라고 부르는 보안 취약점이 되죠. 현대적인 컴파일러는 저걸 막기 위해서 여러 가지 방법을 사용합니다.

gilgil의 이미지

stack pointer의 변경은 관련된 op code의 사용에 의해 변경이 됩니다(mov, push, pop, call, ret 등). OS와는 무관합니다.
stack의 기본 작동 원리를 이해하시고, 관련 op code를 공부해 보시기 바랍니다.

dragon01254의 이미지

답변들 감사합니다. 일단 해보고 다시 댓글 올리도록 하겠습니다.

댓글 달기

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