2014年12月

c的类型提升的一点小测试

之前似乎是在哪儿有听说过,今天听人正式的说了一下,自己测试了测试,果然如此。

代码如下
f2.png

编译之后,运行结果是4,char明显变成了一个int
f1.png

使用DDD跟踪,发现编译器在生成阶段就已经算好sizeof 'A'的值是4,硬编码进去了……
f3.png

相反,如果之前定义char x = 'a'; 最后输出sizeof x,那这时又变成了1。
f4.png

发生提升的时候一般都是在表达式中,低于int的整形提升到int,低于double的浮点提升到double。 这个东西完全取决于编译器,上面第二个例子也是编译器提前算好的,只不过由于明确定义了这个东西的类型,所以编译器算出来的是1。 实际上char+char的时候是先int+int然后裁剪成一个char,看看编译出来的代码即知。

花样繁多:函数到底能怎么返回值?

eax返回值不假,但是eax 不就4个字节吗,各种代码通过eax返回时到底有多少花样? have a try:

1、 long long
f1.png

Dump of assembler code for function fun():
=> 0x00401500 <+0>: push   %ebp
   0x00401501 <+1>: mov    %esp,%ebp
   0x00401503 <+3>: mov    $0x11223344,%eax
   0x00401508 <+8>: mov    $0x0,%edx
   0x0040150d <+13>:    pop    %ebp
   0x0040150e <+14>:    ret    
End of assembler dump.

Dump of assembler code for function main(int, char**):
   0x0040150f <+0>: push   %ebp
   0x00401510 <+1>: mov    %esp,%ebp
   0x00401512 <+3>: and    $0xfffffff0,%esp
   0x00401515 <+6>: sub    $0x10,%esp
   0x00401518 <+9>: call   0x409650 <__main>
   0x0040151d <+14>:    call   0x401500 <fun()>
   0x00401522 <+19>:    mov    %eax,0x8(%esp)
   0x00401526 <+23>:    mov    %edx,0xc(%esp)
   0x0040152a <+27>:    mov    $0x0,%eax
   0x0040152f <+32>:    leave  
   0x00401530 <+33>:    ret    
End of assembler dump.

edx小伙加入了。

2、 真 long long。

事实上又拉了一个战友过来
f2.png

->->post-prompt
Dump of assembler code for function main(int, char**):
   0x0040150f <+0>: push   %ebp
   0x00401510 <+1>: mov    %esp,%ebp
   0x00401512 <+3>: and    $0xfffffff0,%esp
   0x00401515 <+6>: sub    $0x10,%esp
   0x00401518 <+9>: call   0x409650 <__main>
=> 0x0040151d <+14>:    call   0x401500 <fun()>
   0x00401522 <+19>:    mov    %eax,0x8(%esp)
   0x00401526 <+23>:    mov    %edx,0xc(%esp)  <==注意这里
   0x0040152a <+27>:    mov    $0x0,%eax
   0x0040152f <+32>:    leave  
   0x00401530 <+33>:    ret    
End of assembler dump.

->->pre-prompt
(gdb) 
->->prompt

->->post-prompt
Dump of assembler code for function fun():
   0x00401500 <+0>: push   %ebp
   0x00401501 <+1>: mov    %esp,%ebp
   0x00401503 <+3>: mov    $0x11223344,%eax
   0x00401508 <+8>: mov    $0x0,%edx
   0x0040150d <+13>:    pop    %ebp
   0x0040150e <+14>:    ret    
End of assembler dump.

3、 超long long long long
ecx参战的感觉。
f33.png

用Intel的吧,大家也方便看一点

fun():
   0x00401500 <+0>: push   ebp
   0x00401501 <+1>: mov    ebp,esp
   0x00401503 <+3>: sub    esp,0xc
=> 0x00401506 <+6>: mov    eax,0xab33bc40
   0x0040150b <+11>:    mov    edx,0x89119a22
   0x00401510 <+16>:    mov    ecx,0x403b
   0x00401515 <+21>:    mov    DWORD PTR [ebp-0xc],eax
   0x00401518 <+24>:    mov    DWORD PTR [ebp-0x8],edx
   0x0040151b <+27>:    mov    DWORD PTR [ebp-0x4],ecx
   0x0040151e <+30>:    fld    TBYTE PTR [ebp-0xc]
   0x00401521 <+33>:    leave  
   0x00401522 <+34>:    ret    

4、 真· 超long long long long
f4.png

long128构造函数:

   0x00415fb0 <+0>: push   ebp
   0x00415fb1 <+1>: mov    ebp,esp
   0x00415fb3 <+3>: sub    esp,0x18
   0x00415fb6 <+6>: mov    DWORD PTR [ebp-0x4],ecx
   0x00415fb9 <+9>: mov    eax,DWORD PTR [ebp+0x8]
   0x00415fbc <+12>:    mov    DWORD PTR [ebp-0x10],eax
   0x00415fbf <+15>:    mov    eax,DWORD PTR [ebp+0xc]
   0x00415fc2 <+18>:    mov    DWORD PTR [ebp-0xc],eax
   0x00415fc5 <+21>:    mov    eax,DWORD PTR [ebp+0x10]
   0x00415fc8 <+24>:    mov    DWORD PTR [ebp-0x18],eax
   0x00415fcb <+27>:    mov    eax,DWORD PTR [ebp+0x14]
   0x00415fce <+30>:    mov    DWORD PTR [ebp-0x14],eax
   0x00415fd1 <+33>:    mov    ecx,DWORD PTR [ebp-0x4]  <== this
   0x00415fd4 <+36>:    mov    eax,DWORD PTR [ebp-0x10]
   0x00415fd7 <+39>:    mov    edx,DWORD PTR [ebp-0xc]
   0x00415fda <+42>:    mov    DWORD PTR [ecx],eax      <== eax, edx合起来就是一个long long
   0x00415fdc <+44>:    mov    DWORD PTR [ecx+0x4],edx
   0x00415fdf <+47>:    mov    ecx,DWORD PTR [ebp-0x4]
   0x00415fe2 <+50>:    mov    eax,DWORD PTR [ebp-0x18]
   0x00415fe5 <+53>:    mov    edx,DWORD PTR [ebp-0x14]
   0x00415fe8 <+56>:    mov    DWORD PTR [ecx+0x8],eax   <== 同上,另一个赋值操作
   0x00415feb <+59>:    mov    DWORD PTR [ecx+0xc],edx
=> 0x00415fee <+62>:    leave  
   0x00415fef <+63>:    ret    0x10

fun():

   0x00401500 <+0>: push   ebp
   0x00401501 <+1>: mov    ebp,esp
   0x00401503 <+3>: sub    esp,0x10 <==本地的缓冲区
   0x00401506 <+6>: mov    DWORD PTR [esp+0x8],0x44332211
   0x0040150e <+14>:    mov    DWORD PTR [esp+0xc],0x88776655
   0x00401516 <+22>:    mov    DWORD PTR [esp],0x55667788
   0x0040151d <+29>:    mov    DWORD PTR [esp+0x4],0x11223344  <==把这几个倒霉数字存进去
   0x00401525 <+37>:    mov    ecx,DWORD PTR [ebp+0x8] <==ebp+0x8,这个临时的long128变量地址
   0x00401528 <+40>:    call   0x415fb0 <long128::long128(long long, long long)>
   0x0040152d <+45>:    sub    esp,0x10  <==栈上的缓冲区释放掉
=> 0x00401530 <+48>:    mov    eax,DWORD PTR [ebp+0x8]   <==变量的地址返回eax……
   0x00401533 <+51>:    leave  
   0x00401534 <+52>:    ret    

main():

   0x00401535 <+0>: push   ebp
   0x00401536 <+1>: mov    ebp,esp
   0x00401538 <+3>: and    esp,0xfffffff0
   0x0040153b <+6>: sub    esp,0x20
   0x0040153e <+9>: call   0x409680 <__main>
   0x00401543 <+14>:    lea    eax,[esp+0x10] <==long128的内存
   0x00401547 <+18>:    mov    DWORD PTR [esp],eax
   0x0040154a <+21>:    call   0x401500 <fun()> <==别忘了这时候已经赋值给long128 tempA了
=> 0x0040154f <+26>:    mov    eax,0x0  <== return 0;
   0x00401554 <+31>:    leave  
   0x00401555 <+32>:    ret    

call = push + jmp,

esp => [ EAX ]

aftercall:

esp =>  [ retnaddr ]
        [   EAX    ]

1st instruction:

esp =>  [   ebp    ] 
        [ retnaddr ]
        [   EAX    ]  <= esp+8

上一层预留空间了,学会废物利用了。

5、假·超long long long long
f5.png
fun():

   0x00401500 <+0>: push   ebp
   0x00401501 <+1>: mov    ebp,esp
=> 0x00401503 <+3>: mov    eax,DWORD PTR [ebp+0x8] <==long128的地址
   0x00401506 <+6>: mov    DWORD PTR [eax],0x55667788  <==第一次赋值
   0x0040150c <+12>:    mov    DWORD PTR [eax+0x4],0x11223344
   0x00401513 <+19>:    mov    eax,DWORD PTR [ebp+0x8] 
   0x00401516 <+22>:    mov    DWORD PTR [eax+0x8],0x44332211 <==第二次赋值
   0x0040151d <+29>:    mov    DWORD PTR [eax+0xc],0x88776655
   0x00401524 <+36>:    nop
   0x00401525 <+37>:    mov    eax,DWORD PTR [ebp+0x8]
   0x00401528 <+40>:    pop    ebp
   0x00401529 <+41>:    ret    

main():

   0x0040152a <+0>: push   ebp
   0x0040152b <+1>: mov    ebp,esp
   0x0040152d <+3>: and    esp,0xfffffff0
   0x00401530 <+6>: sub    esp,0x20
   0x00401533 <+9>: call   0x409670 <__main>
   0x00401538 <+14>:    lea    eax,[esp+0x10]
   0x0040153c <+18>:    mov    DWORD PTR [esp],eax
   0x0040153f <+21>:    call   0x401500 <fun()>
=> 0x00401544 <+26>:    mov    eax,0x0
   0x00401549 <+31>:    leave  
   0x0040154a <+32>:    ret    

看来跟之前一样。

6、 terminated
多加一句varA.h1++;

   0x0040152a <+0>: push   ebp
   0x0040152b <+1>: mov    ebp,esp
   0x0040152d <+3>: and    esp,0xfffffff0
   0x00401530 <+6>: sub    esp,0x20
   0x00401533 <+9>: call   0x409680 <__main>
=> 0x00401538 <+14>:    lea    eax,[esp+0x10]
   0x0040153c <+18>:    mov    DWORD PTR [esp],eax
   0x0040153f <+21>:    call   0x401500 <fun()>
   0x00401544 <+26>:    mov    eax,DWORD PTR [esp+0x10]
   0x00401548 <+30>:    mov    edx,DWORD PTR [esp+0x14]
   0x0040154c <+34>:    add    eax,0x1
   0x0040154f <+37>:    adc    edx,0x0
   0x00401552 <+40>:    mov    DWORD PTR [esp+0x10],eax
   0x00401556 <+44>:    mov    DWORD PTR [esp+0x14],edx
   0x0040155a <+48>:    mov    eax,0x0
   0x0040155f <+53>:    leave  
   0x00401560 <+54>:    ret    

ok done.有空再研究研究其他的。

Linux下奇怪库破坏导致一大堆程序启动失败一例

给开发板装了一个postgre,可是启动的时候问题多多

Options marked [*] produce a lot of output - pipe it through `less' or `more' !
pi@BLASTN2 ~ :( $ sudo dpkg --configure postgresql-9.1 postgre-contrib-9.1
Setting up postgresql-9.1 (9.1.14-0+deb7u1) ...
[....] Starting PostgreSQL 9.1 database server: main[....] The PostgreSQL server failed to start. Please check the log output: 2014-11-13 18:16:55 CST LOG: could not bind IPv6 socket: Cannot assign requested address 2014-11-13 18:16:55 CST HINT: Is another postmaster already running on port 5432? If not, wait a few seconds and retry. 2014-11-13 18:16:55 CST WARNING: could not create listen socket for "localhost" 2014-11-13 18:16:55 CST FATAL: cou[FAILt create any TCP/IP sockets ... failed!
 failed!
invoke-rc.d: initscript postgresql, action "start" failed.
dpkg: error processing postgresql-9.1 (--configure):
 subprocess installed post-installation script returned error exit status 1
dpkg: error processing postgre-contrib-9.1 (--configure):
 no package named `postgre-contrib-9.1' is installed, cannot configure
Errors were encountered while processing:
 postgresql-9.1
 postgre-contrib-9.1
pi@BLASTN2 ~ :( $ ps aux|grep postgre
pi       23286  0.0  0.0   3648   716 pts/0    S+   18:19   0:00 grep --colour=auto postgre

提示5432可能被占用,但是仔细看了看端口也没被占用啊

pi@BLASTN2 ~ :( $ sudo netstat -apn|
......
unix  3      [ ]         STREAM     CONNECTED     3639     2266/dbus-daemon    /var/run/dbus/system_bus_socket
unix  3      [ ]         STREAM     CONNECTED     3638     2400/gdm3           
unix  3      [ ]         STREAM     CONNECTED     3626     2266/dbus-daemon    /var/run/dbus/system_bus_socket
unix  3      [ ]         STREAM     CONNECTED     3625     2349/NetworkManager 
unix  3      [ ]         STREAM     CONNECTED     3614     2266/dbus-daemon    /var/run/dbus/system_bus_socket
unix  3      [ ]         STREAM     CONNECTED     3613     2354/bluetoothd     
unix  3      [ ]         STREAM     CONNECTED     3610     2266/dbus-daemon    /var/run/dbus/system_bus_socket
unix  3      [ ]         STREAM     CONNECTED     2914     2349/NetworkManager 
unix  3      [ ]         STREAM     CONNECTED     3556     2266/dbus-daemon    /var/run/dbus/system_bus_socket
unix  3      [ ]         STREAM     CONNECTED     3555     2303/avahi-daemon:  
unix  3      [ ]         STREAM     CONNECTED     3549     2304/avahi-daemon:  
unix  3      [ ]         STREAM     CONNECTED     3548     2303/avahi-daemon:  
unix  3      [ ]         STREAM     CONNECTED     2872     2266/dbus-daemon    
unix  3      [ ]         STREAM     CONNECTED     2871     2266/dbus-daemon    
unix  3      [ ]         DGRAM                    484      199/udevd           
unix  3      [ ]         DGRAM                    483      199/udevd           
pi@BLASTN2 ~ $ sudo netstat -apn>>~/temp.log

看看log,然后试试看ping 127.0.0.1,what's the fuck

pi@BLASTN2 ~ $ ping localhost
PING localhost (127.0.0.1) 56(84) bytes of data.

^C
--- localhost ping statistics ---
9 packets transmitted, 0 received, 100% packet loss, time 8005ms

pi@BLASTN2 ~ :( $ ping 127.0.0.1
PING 127.0.0.1 (127.0.0.1) 56(84) bytes of data.
^C
--- 127.0.0.1 ping statistics ---
61 packets transmitted, 0 received, 100% packet loss, time 60001ms

pi@BLASTN2 ~ :( $ sudo ifconfig -a
eth0      Link encap:Ethernet  HWaddr 02:41:0a:81:93:a9  
          inet addr:192.168.0.109  Bcast:192.168.0.255  Mask:255.255.255.0
          inet6 addr: fe80::41:aff:fe81:93a9/64 Scope:Link
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:247688 errors:0 dropped:0 overruns:0 frame:0
          TX packets:387753 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000 
          RX bytes:80379923 (76.6 MiB)  TX bytes:406363850 (387.5 MiB)
          Interrupt:117 Base address:0xc000 

lo        Link encap:Local Loopback  
          LOOPBACK  MTU:16436  Metric:1
          RX packets:0 errors:0 dropped:0 overruns:0 frame:0
          TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:0 
          RX bytes:0 (0.0 B)  TX bytes:0 (0.0 B)

tunl0     Link encap:IPIP Tunnel  HWaddr   
          NOARP  MTU:1480  Metric:1
          RX packets:0 errors:0 dropped:0 overruns:0 frame:0
          TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:0 
          RX bytes:0 (0.0 B)  TX bytes:0 (0.0 B)

解决方案:
f1.png

保存之后,

$ sudo ifconfig eth0 down
$ sudo ifconfig eth0 up

或者干脆直接

$ sudo reboot

再来ping一次,可以ping通。

pi@BLASTN2 ~ :( $ file /usr/lib/arm-linux-gnueabihf/libxml2.so.2
/usr/lib/arm-linux-gnueabihf/libxml2.so.2: symbolic link to `libxml2.so.2.8.0'
pi@BLASTN2 ~ $ file /usr/lib/arm-linux-gnueabihf/libxml2.so.2.8.0
/usr/lib/arm-linux-gnueabihf/libxml2.so.2.8.0: ELF 32-bit LSB shared object, ARM, version 1 (SYSV), dynamically linked, BuildID[sha1]=0x44c6070a41ab03bd54581e371d529871ebf91e77, stripped
pi@BLASTN2 ~ $ 
pi@BLASTN2 ~ :( $ ping 127.0.0.1
PING 127.0.0.1 (127.0.0.1) 56(84) bytes of data.
64 bytes from 127.0.0.1: icmp_req=1 ttl=64 time=0.155 ms
64 bytes from 127.0.0.1: icmp_req=2 ttl=64 time=0.101 ms
64 bytes from 127.0.0.1: icmp_req=3 ttl=64 time=0.113 ms
^C
--- 127.0.0.1 ping statistics ---
3 packets transmitted, 3 received, 0% packet loss, time 1998ms
rtt min/avg/max/mdev = 0.101/0.123/0.155/0.023 ms

可是奇葩的是obconf失败了,所有窗口都没标题栏了。。。一看提示

error while loading shared libraries: /lib/libxml2.so.2: invalid ELF header

and

(obconf:3513): GdkPixbuf-CRITICAL **: gdk_pixbuf_copy_area: assertion `src_pixbuf != NULL' failed
/lib/arm-linux-gnueabihf/libgcrypt.so.11: invalid ELF header
Failed to load module: /usr/lib/arm-linux-gnueabihf/gio/modules/libgiognutls.so
pi@BLASTN2 ~ $ sudo apt-get install libgcrypt-dev --reinstall
[sudo] password for pi: 
^Cpi@BLASTN2 ~ :( $ sudo apt-get install libgcrypt-dev --reinstall
Reading package lists... Done
Building dependency tree       
Reading state information... Done
Note, selecting 'libgcrypt11-dev' instead of 'libgcrypt-dev'
The following packages were automatically installed and are no longer required:
  libmozjs24d xulrunner-24.0
Use 'apt-get autoremove' to remove them.
0 upgraded, 0 newly installed, 1 reinstalled, 0 to remove and 0 not upgraded.
Need to get 0 B/383 kB of archives.
After this operation, 0 B of additional disk space will be used.
(Reading database ... 186234 files and directories currently installed.)
Preparing to replace libgcrypt11-dev 1.5.0-5+deb7u2 (using .../libgcrypt11-dev_1.5.0-5+deb7u2_armhf.deb) ...
Unpacking replacement libgcrypt11-dev ...
Processing triggers for man-db ...
Setting up libgcrypt11-dev (1.5.0-5+deb7u2) ...

dafuq?啥玩意儿,file一下结果居然是ISO-8859-TEXT,我操,说好的库呢,干脆重装一次得了,

$ sudo apt-get -f install obconf
$ sudo apt-get install obconf --reinstall
$ sudo reboot

ok, done。其实猜测是因为之前用了错的opera源导致的,这个一般都是32、64以及arm的库弄混了的原因。待会儿清个源。

然后,虽然这个没问题了,但是libcrypt.so.11还是有同样的问题,浏览器起不了,reinstall libgcrypt11-dev无果,拷贝debug下的更是不行,直接报segment fault。

pi@BLASTN2 ~ :( $ netsurf-gtk
netsurf-gtk: error while loading shared libraries: /lib/arm-linux-gnueabihf/libgcrypt.so.11: invalid ELF header
pi@BLASTN2 ~ :( $ file /lib/arm-linux-gnueabihf/libgcrypt.so.11
/lib/arm-linux-gnueabihf/libgcrypt.so.11: symbolic link to `libgcrypt.so.11.7.0'
pi@BLASTN2 ~ $ file /lib/arm-linux-gnueabihf/libgcrypt.so.11.7.0
/lib/arm-linux-gnueabihf/libgcrypt.so.11.7.0: ISO-8859 text, with very long lines, with no line terminators
pi@BLASTN2 ~ $ 

只好祭出大杀器。
f2.png

附上so文件,用自带的传输功能传的,信得过就下吧,自己改名回去:
http://www.nul.pw/usr/uploads/2014/12/595411591.png

注意,如果你缺这个文件,连wget curl都是启动不了的,如果是远程机器,自求多福如果开了啥samba sftp ftp之类的还可以一拼= =,物理机器就靠u盘吧。
f3.png

修完了真是开心啊,postgre?去你的,不装了- -
f4.png

360压缩,看来又是个粗制滥造的软件

不下两分钟已经弄崩四五次了,出现这么个栈调用,大家也都知道是什么情况了吧:

0:000> kvn
 # ChildEBP RetAddr  Args to Child              
00 00128688 7c92de5c 7c801e3a ffffffff c0000409 ntdll!KiFastSystemCallRet (FPO: [0,0,0])
01 0012868c 7c801e3a ffffffff c0000409 001289d4 ntdll!ZwTerminateProcess+0xc (FPO: [2,0,0])
02 0012869c 004c9453 ffffffff c0000409 310a3291 kernel32!TerminateProcess+0x20 (FPO: [Non-Fpo])
WARNING: Stack unwind information not available. Following frames may be wrong.
03 001289d4 004712e9 0000011e 0324028a 00000109 360zip+0xc9453