간단한 C언어 disassemble한 모습에서 질문이 있네요.. ecx관련

sungyunhwang의 이미지

안녕하세요
디어셈블한 것을 분석할 일이 있어서 진자 간단한 C프로그램을 짠뒤에 디스어셈블을 해봤습니다.
현재 gcc버전은

gcc version 4.3.3 ( ubuntu 4.3.3-5ubuntu4 )
이구요 stack guard는 disable로 컴파일했습니다.

C프로그램은 단순하게 char array[8]배열을 잡아서 gets(array) 하고 종료하는 것입니다.

0x080483c4 : lea 0x4(%esp),%ecx <------------------------
0x080483c8 : and $0xfffffff0,%esp
0x080483cb : pushl -0x4(%ecx)
0x080483ce : push %ebp
0x080483cf : mov %esp,%ebp
0x080483d1 : push %ecx <------------------------
0x080483d2 : sub $0x14,%esp
0x080483d5 : lea -0xc(%ebp),%eax
0x080483d8 : mov %eax,(%esp)
0x080483db : call 0x80482e4
0x080483e0 : mov $0x0,%eax
0x080483e5 : add $0x14,%esp
0x080483e8 : pop %ecx <------------------------
0x080483e9 : pop %ebp
0x080483ea : lea -0x4(%ecx),%esp <------------------------
0x080483ed : ret

main함수를 disassemble한 모습인데 여기서 궁금한것은 ecx의 역활이 궁금합니다.
디버깅을 다라가다보면 gets함수가 불린다음에 $ecx 에 보면 사용자가 입력한 값이 저장되어있고
$esp에는 사용자가 입력한값이 저장되어있는 주소가 저장이 되어있습니다.
그리고 처음에 저장되어있는 값은 00000001dl 저장되어있는데
확실하게 이해가 안가네요..
답변 주시면 감사하겠습니다~

pastime의 이미지

ecx는 caller-saved (scratch) register 입니다.
즉 해당 함수 안에서 임의의 용도로 자유롭게 사용할 수 있으며
원래의 값이 무엇이었지는 고려할 필요가 없습니다.
또한 해당 함수 안에서 다른 함수를 호출한 경우
호출 전과 후에 ecx 레지스터의 값이 바뀔 수 있으므로
(마찬가지로 호출된 함수에서 ecx를 자유롭게 사용할 수 있으니까요)
ecx에 중요한 정보가 들어있다면 호출 전에 미리 스택에 저장해 두어야 합니다.

따라서 함수가 실행된 당시의 값과 다른 함수를 호출하고 난 직후의 ecx 값은 의미가 없습니다.
여기서 ecx가 사용된 부분은 함수의 시작(prologue) 부분에서
esp를 16바이트 단위로 정렬하기 위해 andl 명령을 실행하는 과정에서
원래의 esp 값을 저장하기 위한 용도로 쓰인 것 같습니다.

스택을 16바이트로 정렬하는 이유는 혹시나 쓰일지 모를 SSE 관련 명령 때문입니다.
(SSE에서 사용되는 데이터들은 반드시 16바이트 단위로 정렬되어 있어야 합니다)
지금처럼 그러한 명령들을 사용하지 않는 경우 불필요한 스택 정렬을 막기위해
-mpreferred-stack-boundary=2 옵션을 추가하면 이러한 부분이 사라질 것이며
따라서 ecx도 사용되지 않을 것 같습니다.

ydwhoru의 이미지

대단하십니다!!

컴파일 옵션으로는 -mpreferred-stack-boundary=2 ... 같은..

옵션들은 어디서 참조 하셨나요?

또는 알게 되셨나요??

저는 그러한 여러 옵션들이 필요 함에도 불구하고 -_-;;

어디서 내가 원하는 걸 찾을것이며 어디서 구할지 참... 답답합니다...

단순히 컴파일 옵션이라고만 하면 너무나도 많은 것이 있더라구요...

sungyunhwang의 이미지

궁금한 점이 풀렸네요^^

또하나의 궁금증이 있어서 이렇게 질문을 올려봅니다.

제가 지금 버퍼오버플로우를 일으켜서 다른 함수를 호출해 보려고 하고 있는데

0x080483e8 : pop %ecx
0x080483e9 : pop %ebp
0x080483ea : lea -0x4(%ecx),%esp
0x080483ed : ret

이부분이 어떻게 해석을 해야할지 약간 좀 난감합니다.
pop ecx를 하면서 0000001이란 값이 ecx로 들어가게 되는데
0x080483ea : lea -0x4(%ecx),%esp
이 부분을 통해서 -0x4(%ecx) 를 하게 될 경우
%ecx 가 현재 가르치고 있는 주소값 즉 0000001이 저장되어있는 주소에서 -4를 해서 esp에 저장이 되며
그리고 ret 을 하면서 이제 main을 call 했던 곳으로 다시 돌아가는것을 확인을 하였습니다.

제가 여기서 오버플로우를 일으켜서 ecx 61616161(aaaa)로 덮어 씌우게 되었습니다.
그런데 esp에 올라가 있는 부분을 보니 6161615d로 변경이 되더라구요
그래서 이게 -0x4(%ecx)이부분과 관련이 있는 것 같은데 ecx가 가르치고있는 즉 61616161에서 -4를 하는지
아니면 61616161이 들어가 있는 주소값에 -4를 하는지 햇갈리더라구요..

질문이 약간 이상한 것 같은데 정확하게 -0x4(%ecx)가 어떻게 계산된느지 궁금해서 이렇게 올렸습니다.
만약 ecx가 가르치고있는값 즉 61616161에서 -4를 하는것이라면.. 정상적일때 0000001인데 여기서 -4를 하는것은 아닌것 같은데
의아해서 질문하게 되었습니다

질문이 약간 이상하네요 ... 제가쓰고도..
혹시 이해하시고 현상에 대해서 알고 계시다면 답변 한번 해주시면 감사하겠습니다~

댓글 달기

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