← Back to team overview

sslug-teknik team mailing list archive

Crash i libc

 

Hey

Jeg har været så heldig at overtage et program uden den tilhørende C
kode...og det crasher i et kald til system() og jeg har debugget mig
frem til følgende:

system() kalder videre til do_system() som ligger i sysdeps/posix/system.c
Den relevante kode er:

112 #ifdef CLEANUP_HANDLER
113   CLEANUP_HANDLER;
114 #endif
115
116 #ifdef FORK
117   pid = FORK ();
118 #else
119   pid = __fork ();
120 #endif
    ....
    klippet væk....koden bliver ikke udført
    ....
153 #ifdef CLEANUP_HANDLER
154   CLEANUP_RESET;
155 #endif

FORK må have været defineret for jeg når til linje 117:

(gdb) next
117    in ../sysdeps/posix/system.c
(gdb) x/6i $eip
0xb7ecde30 <do_system+288>:    xor    ecx,ecx
0xb7ecde32 <do_system+290>:    mov    edi,0x100011
0xb7ecde37 <do_system+295>:    mov    edx,esi
0xb7ecde39 <do_system+297>:    xchg   edi,ebx
0xb7ecde3b <do_system+299>:    mov    eax,0x78    <-- sys_clone
0xb7ecde40 <do_system+304>:    call   DWORD PTR gs:0x10

Jeg kan ikke finde definitionen på FORK men det er muligvis den som også
ligger i sysdeps/unix/sysv/linux/system.c. Der har den følgende definition:

# define FORK() \
  INLINE_SYSCALL (clone, 3, CLONE_PARENT_SETTID | SIGCHLD, 0, &pid)
#endif

Tager jeg et skridt videre (med 'follow-fork-mode child') går det galt:
(gdb) next
[New process 5692]

Program received signal SIGSEGV, Segmentation fault.
[Switching to process 5692]
0xb7ecdf9f in do_system (line=<value optimized out>) at
../sysdeps/posix/system.c:154
154    in ../sysdeps/posix/system.c
(gdb) x/i $eip
0xb7ecdf9f <do_system+655>:    mov    eax,DWORD PTR [ebx+0x37e8]
(gdb) i r ebx
ebx            0x100011    1048593


På do_system+290 fik EDI registeret værdien 0x100011 og på do_system+297
bliver EBX og EDI byttet. På do_system+655 bliver EBX så uændret brugt
som en adresse...hvorfor?
Og hvorfor sprang vi fra do_system+304 til do_system+665?

Det har jo højst sandsynligt noget med de der CLEANUP_HANDLER ting at
gøre, men hvad er de?

Igen er der definitioner i en anden C fil:
# define CLEANUP_HANDLER \
  __libc_cleanup_region_start (1, cancel_handler, &pid)

# define CLEANUP_RESET \
  __libc_cleanup_region_end (0)
#endif

Er det en slags exception handlere?
Hvordan finder man ud af, hvad der gik galt?

VH
Robert