2014年11月18日 星期二

array and pointer X global and local

我很想知道 g.c 和 g1.c 有什麼不同, source code 之前沒有秘密, 尤其是在組合語言之前。

先來四個問題 ...

Q1: g.c L3 可讀可寫, 為什麼?
Q2: g.c L4 read only, why?

g.c
1 int main(int argc, char *argv[])
2 {
3   char ch[]="abc";
4   const char *chp="abc";
5   return 0;
6 }

Q3: g1.c L1 可讀可寫, 為什麼?
Q4: g1.c L2 read only, why?

g1.c
1   char ch[]="abc";
2   const char *chp="abc";
3 int main(int argc, char *argv[])
4 {
5   ch[0] = '1';
6   return 0;
7 }

先來反組譯 g (source code g.c), L5 把 "abc" 複製到 ch, L6 把 chp 指到 "abc", 這個 "abc" 是為於 .rodata, 所以 chp 指到的內容不能改, chp 本身在 stack。

ch 本身位於 stack, 把 "abc" 複製到這裡自然是可以修改的。

objdump -d g
1 080483cd <main>:
2  80483cd:       55                      push   %ebp
3  80483ce:       89 e5                   mov    %esp,%ebp
4  80483d0:       83 ec 10                sub    $0x10,%esp
5  80483d3:       c7 45 f8 61 62 63 00    movl   $0x636261,-0x8(%ebp)
6  80483da:       c7 45 fc 80 84 04 08    movl   $0x8048480,-0x4(%ebp)
7  80483e1:       b8 00 00 00 00          mov    $0x0,%eax
8  80483e6:       c9                      leave  
9  80483e7:       c3                      ret   

g1呢? 不用反組譯, 看他的 .s 就可以了。ch 和 ch 所指到的 "abc" 在 .data section, 所以可讀寫。 chp 本身位於 .data, 可讀可寫, 但它指到的 "abc" 位於 .rodata, 只能讀取。

gcc -S g1.c
 1  .file "g1.c"
 2  .globl ch
 3  .data
 4  .type ch, @object
 5  .size ch, 4
 6 ch:
 7  .string "abc"
 8  .globl chp
 9  .section .rodata
10 .LC0:
11  .string "abc"
12  .data
13  .align 4
14  .type chp, @object
15  .size chp, 4
16 chp:
17  .long .LC0
18  .text
19  .globl main
20  .type main, @function
21 main:
22 .LFB0:
23  .cfi_startproc
24  pushl %ebp
25  .cfi_def_cfa_offset 8
26  .cfi_offset 5, -8
27  movl %esp, %ebp
28  .cfi_def_cfa_register 5
29  movb $49, ch
30  movl $0, %eax
31  popl %ebp
32  .cfi_restore 5
33  .cfi_def_cfa 4, 4
34  ret
35  .cfi_endproc
36 .LFE0:
37  .size main, .-main
38  .ident "GCC: (Debian 4.8.2-16) 4.8.2"
39  .section .note.GNU-stack,"",@progbits

.rodata section 為什麼會有 read only 的能力, 那是因為 mmu 的作用, 所以若沒有這種記憶體保護機制, 是可以直接修改值的。例如: dos。

就像蒙面魔術師破解魔術一樣, 了解之後, 就知道為什麼可以這樣, 不能那樣。

組合語言的聽說讀寫, 最好能有的能力, 這樣才能了解最底層的秘密。

沒有留言:

張貼留言

使用 google 的 reCAPTCHA 驗證碼, 總算可以輕鬆留言了。

我實在受不了 spam 了, 又不想讓大家的眼睛花掉, 只好放棄匿名留言。這是沒辦法中的辦法了。留言的朋友需要有 google 帳號。