Saturday, December 28, 2013

P2P communication across NAT

1. NAT concept
2. P2P communication
3. Types of NAT

Friday, December 27, 2013

Linux跟Windows對記憶體保護機制的不同

一樣的程式,分別用GCC-4.4/Linux, GCC-4.5/Cygwin, VC 9.0/Windows 7

  1 #include
  2 #include
  3
  4 int main (void)
  5 {
  6
  7     char *a  = "abcd";
  8     char b[] = "ABCD";
  9
 10     a[0] = 'x';
 11     b[0] = 'x';
 12
 13     printf ("a:%s\n", a);
 14     printf ("b:%s\n", b);
 15
 16     return (0);
 17 }

Linux會將上述第7行的資料保護著,設為唯讀。

LungSWuBlog:~/temp$ gcc a.c -o a
LungSWuBlog:~/temp$ ./a
程式記憶體區段錯誤
LungSWuBlog:~/temp$ gcc -c a.c -o a.o
LungSWuBlog:~/temp$ objdump -s a.o

a.o:     file format elf64-x86-64

Contents of section .text:
 0000 554889e5 4883ec20 48c745e8 00000000  UH..H.. H.E.....
 0010 c745f041 424344c6 45f40048 8b45e8c6  .E.ABCD.E..H.E..
 0020 0078c645 f078b800 00000048 8b55e848  .x.E.x.....H.U.H
 0030 89d64889 c7b80000 0000e800 000000b8  ..H.............
 0040 00000000 488d55f0 4889d648 89c7b800  ....H.U.H..H....
 0050 000000e8 00000000 b8000000 00c9c3    ...............
Contents of section .rodata:
 0000 61626364 00613a25 730a0062 3a25730a  abcd.a:%s..b:%s.
 0010 00                                   .
Contents of section .comment:
 0000 00474343 3a202855 62756e74 7520342e  .GCC: (Ubuntu 4.
 0010 342e332d 34756275 6e747535 2e312920  4.3-4ubuntu5.1)
 0020 342e342e 3300                        4.4.3.
Contents of section .eh_frame:
 0000 14000000 00000000 017a5200 01781001  .........zR..x..
 0010 1b0c0708 90010000 1c000000 1c000000  ................
 0020 00000000 5f000000 00410e10 4386020d  ...._....A..C...
 0030 06000000 00000000                    ........
LungSWuBlog:~/temp$

Windows 7不會將上述第7行的資料保護著,還是可以寫入。

[VC 9.0]
D:\LungSWuBlog>cl a.c

/out:a.exe
a.obj

D:\LungSWuBlog>a
a:xbcd
b:xBCD

D:\LungSWuBlog>

[Cygwin]

LungSWuBlog ~/tmp
$ gcc a.c -o a

LungSWuBlog ~/tmp
$ ./a.exe
a:xbcd
b:xBCD

LungSWuBlog ~/tmp
$ gcc -c a.c -o a.o

LungSWuBlog ~/tmp
$ objdump.exe -s a.o

a.o:     file format pe-i386

Contents of section .text:
 0000 5589e583 e4f083ec 20e80000 0000c744  U....... ......D
 0010 241c0000 0000c744 24174142 4344c644  $......D$.ABCD.D
 0020 241b008b 44241cc6 0078c644 2417788b  $...D$...x.D$.x.
 0030 44241c89 442404c7 04240500 0000e800  D$..D$...$......
 0040 0000008d 44241789 442404c7 04240b00  ....D$..D$...$..
 0050 0000e800 000000b8 00000000 c9c39090  ................
Contents of section .rdata:
 0000 61626364 00613a25 730a0062 3a25730a  abcd.a:%s..b:%s.
 0010 00000000                             ....

LungSWuBlog ~/tmp
$

最後,跟program loader也可能有關

GDB Server於Linux - LEON2 platform的設定

由於LEON2 CPU中有DSU,預設中會攔截所有的debugger所設的break point,目的是讓DSU當做debug monitor,直接由DSU跟debugger溝通。

但是Linux user mode application on LEON2 CPU的debug...
不需要使用到DSU的monotor,完全需要由gdbserver跟host的debugger溝通,

所以LEON2中DSU controller中有一個控制flags,使DSU放棄breakpoint的monitor,交由gdbserver來控制breakpoint。

0x90000000 DSU control register


Linux run time shared library path setting

此篇中,其目的是於corss platform中讓gdb找到正確的shared library path。
於native host環境中,執行程式時有時會有

error while loading shared libraries: ????????.so.?: cannot open
shared object file: No such file or directory

其可能的問題為不能找到需要的shared library,For examples...

$ pwd
/ImageMagick-6.5.7-10/utilities/.libs
$
$ ls
animate  composite  convert  identify  mogrify  stream
compare  conjure    display  import    montage
$
$ echo $LD_LIBRARY_PATH

$
$ ldd convert
 linux-gate.so.1 =>  (0xb7f23000)
 libMagickCore.so.2 => not found
 libMagickWand.so.2 => not found
 libpthread.so.0 => /lib/tls/i686/cmov/libpthread.so.0 (0xb7efa000)
 libdl.so.2 => /lib/tls/i686/cmov/libdl.so.2 (0xb7ef6000)
 libm.so.6 => /lib/tls/i686/cmov/libm.so.6 (0xb7ed0000)
 libc.so.6 => /lib/tls/i686/cmov/libc.so.6 (0xb7d6d000)
 /lib/ld-linux.so.2 (0xb7f24000)
$
$ ./convert
./convert: error while loading shared libraries: libMagickCore.so.2:
cannot open shared object file: No such file or directory
$

以上之中,由ldd command觀察convert所需要額外的library中,
沒找到libMagickCore.so.2,libMagickWand.so.2此兩的shared linary的所在位址,
所以會有"not found"的訊息出現。

若是以LD_LIBRARY_PATH來註冊額外shared library的路徑,即可解決...

$ export LD_LIBRARY_PATH=/ImageMagick-6.5.7-10/magick/.libs:/ImageMagick-6.5.7-10/wand/.libs
$
$ echo $LD_LIBRARY_PATH
/ImageMagick-6.5.7-10/magick/.libs:/ImageMagick-6.5.7-10/wand/.libs
$
$ ldd convert
 linux-gate.so.1 =>  (0xb7ee9000)
 libMagickCore.so.2 => /ImageMagick-6.5.7-10/magick/.libs/libMagickCore.so.2 (0xb7d66000)
 libMagickWand.so.2 => /ImageMagick-6.5.7-10/wand/.libs/libMagickWand.so.2 (0xb7c70000)
 libpthread.so.0 => /lib/tls/i686/cmov/libpthread.so.0 (0xb7c49000)
 libdl.so.2 => /lib/tls/i686/cmov/libdl.so.2 (0xb7c45000)
 libm.so.6 => /lib/tls/i686/cmov/libm.so.6 (0xb7c1f000)
 libc.so.6 => /lib/tls/i686/cmov/libc.so.6 (0xb7abc000)
 /lib/ld-linux.so.2 (0xb7eea000)
$

Linux GDB breakpoint at _start

寫一個Linux上user mode最簡單的AP
$ cat foo.s
.text
.globl _start

_start:
        movl    $0,%ebx         /* exit code */
        movl    $1,%eax         /* exit function */
        int     $0x80
這樣就可以正常的執行並結束。
但怪的事...

$ as foo.s -o foo.o
$ ld foo.o -o foo

這樣邊一之後再用GDB來debug...
(gdb) break _start
Breakpoint 1 at 0x8048054
(gdb) run
Starting program: /home/lungswu/Working/application/hello/foo 
(no debugging symbols found)

Program exited normally.
(gdb) 
程式竟然直接結速,並不能breaking在_start上????

類似的編譯方式也會發生同樣問題
$ gcc -nostartfiles --static foo.s -o foo
$ gcc -nostartfiles -nostdlib foo.s -o foo
但是以下的方式就OK
$ gcc -nostartfiles foo.s -o foo

原因不明,但至少可以確定的事...

(1)可以用GDB停在_start上是一個動態連結檔
$ ldd foo
 linux-gate.so.1 =>  (0xb80d2000)
 libc.so.6 => /lib/tls/i686/cmov/libc.so.6 (0xb7f60000)
 /lib/ld-linux.so.2 (0xb80d3000)
(2)觀察他的各區段,明顯複雜很多
$ objdump -h foo

foo:     file format elf32-i386

Sections:
Idx Name          Size      VMA       LMA       File off  Algn
  0 .interp       00000013  080480f4  080480f4  000000f4  2**0
                  CONTENTS, ALLOC, LOAD, READONLY, DATA
  1 .hash         0000000c  08048108  08048108  00000108  2**2
                  CONTENTS, ALLOC, LOAD, READONLY, DATA
  2 .gnu.hash     00000018  08048114  08048114  00000114  2**2
                  CONTENTS, ALLOC, LOAD, READONLY, DATA
  3 .dynsym       00000000  0804812c  0804812c  0000012c  2**2
                  CONTENTS, ALLOC, LOAD, READONLY, DATA
  4 .dynstr       0000000b  0804812c  0804812c  0000012c  2**0
                  CONTENTS, ALLOC, LOAD, READONLY, DATA
  5 .text         0000000c  08048138  08048138  00000138  2**2
                  CONTENTS, ALLOC, LOAD, READONLY, CODE
  6 .dynamic      00000070  08049f84  08049f84  00000f84  2**2
                  CONTENTS, ALLOC, LOAD, DATA
  7 .got.plt      0000000c  08049ff4  08049ff4  00000ff4  2**2
                  CONTENTS, ALLOC, LOAD, DATA

Thursday, December 26, 2013

GDB中shared library問題

有時使用GDB做debug,會發生以下的warnning...

warning: Unable to find dynamic linker breakpoint function.
GDB will be unable to debug shared library initializers
and track explicitly loaded dynamic code.

這意思是gdb做shared library的loading不正確,可以用以下的gdb command看看shared library的結果...

以下表示沒有任何shared library被load進gdb debugger中

(gdb) info shared

No shared libraries loaded at this time.
(gdb) 

假設TARGET是ARM,rootfs於/home/nfs/arm
以下表示shared library symbol被load進gdb debugger,但不正確(因為gdb load host中的library)

(gdb) info shared

From To Syms Read Shared Object Library
0x50002080 0x5001a650 Yes /lib/ld-linux.so.2
0x500325b0 0x5003d118 Yes /usr/lib/libmad.so.0
0x5005d598 0x50064f58 Yes /usr/lib/libid3tag.so.0
0x5006d754 0x500782ec Yes /usr/lib/libz.so.1
0x5009a328 0x50138eec Yes /lib/libm.so.6
0x501b2ac8 0x502af008 Yes /lib/libc.so.6
(gdb) 

GDB中的一個command....

set solib-search-path PATH

可以指定GDB尋找正確的shared library....

(gdb) set solib-search-path /home/nfs/arm/lib:/home/nfs/arm/usr/lib
(gdb) info shared
From To Syms Read Shared Object Library
0x50002080 0x5001a650 Yes /home/nfs/arm/lib/ld-linux.so.2
0x500325b0 0x5003d118 Yes /home/nfs/arm/usr/lib/libmad.so.0
0x5005d598 0x50064f58 Yes /home/nfs/arm/usr/lib/libid3tag.so.0
0x5006d754 0x500782ec Yes /home/nfs/arm/usr/lib/libz.so.1
0x5009a328 0x50138eec Yes /home/nfs/arm/lib/libm.so.6
0x501b2ac8 0x502af008 Yes /home/nfs/arm/lib/libc.so.6
(gdb) 

Wednesday, December 25, 2013

GDB Server 使用方式

假設於ARM platform中要debug madplay程式

TARGET(192.168.1.10):
gdbserver HOST:PORT AP_NAME AP_PARAMETER
gdberver 192.168.1.11:1234 /usr/bin/madplay /tmp/aa.mp3
HOST(192.168.1.11):
ddd --debugger arm-linux-gdb /nfs/armroot/usr/bin/madplay
(gdb) target remote 192.168.1.10:1234
(gdb) break main

Breakpoint 1 at 0x12958: file madplay.c, line 742.
(gdb) c

Breakpoint 1, main (argc=2, argv=0xef9f4d84) at madplay.c:742
(gdb)