2013-07-07 8 views
0

J'ai une fonction buggée dans une bibliothèque partagée. Il entre en boucle infinie lorsque recv() renvoie 0.Comment remplacer une fonction buggy dans un fichier .so sans le code source?

Il n'y a pas de code source. J'ai été capable de décompiler la partie buggy et de changer certaines instructions du processeur sans redimensionner la fonction, mais il n'y a pas de place pour un correctif complet.

Je veux compiler la nouvelle version avec gcc et la remettre dans la bibliothèque. La fonction utilise des variables globales et, ce qui est pire, statiques. La fonction fixe est plus grande que la fonction d'origine, elle ne peut donc pas être placée au même endroit.

Ici, il est:

#include <sys/types.h> 
#include <stdio.h> 

#define PM_ERROR_INVALID_CLIENT   210 

typedef struct 
{ 
    int code; 
    int detail_code; 
    char* message; 
} pm_error; 

typedef struct 
{ 
    char *server_name; 
    int port; 
    int socket_descriptor; 
    int status; 
    int timeout; 
} pm_client; 

extern int debug; 
int pmprotocol_read(pm_client *param0_client, char *param1_data, int param2_length, pm_error *param3_error) 
{ 
    size_t local_bytes_received; 
    size_t local_total_bytes; 
    int local_status; 
    char local_message[128]; 
    int local_retval; 
    // init globals pointer 
    // copy params to stack 
    // pmprotocol.c:896 
    if (debug > 0) 
    { 
    fprintf(
     stderr 
     ,"pmprotocol_read:enter\n" 
     ); 
    } 
    // pmprotocol.c:897 
    // pmprotocol.c:898 
    local_retval = 0; 
    // pmprotocol.c:900 
    local_status = 0; 
    // pmprotocol.c:901 
    // pmprotocol.c:902 
    if (param0_client->status != 0) 
    { 
    // pmprotocol.c:904 
    pm_error_set_internal(
     param3_error 
     ,"pmprotocol_read" 
     ,"function called with invalid client" 
     ,PM_ERROR_INVALID_CLIENT 
    ); 
    // pmprotocol.c:905 
    return 1; 
    } 
    // pmprotocol.c:908 
    local_retval = pmprotocol_waitfor_read(param0_client, param3_error); 
    // pmprotocol.c:909 
    if (local_retval != 0) 
    { 
    return local_retval; 
    } 
    // pmprotocol.c:910 
    // pmprotocol.c:911 
    local_total_bytes = 0; 
    //pmprotocol.c:913 
    while ((size_t)param2_length > local_total_bytes) 
    { 
    //pmprotocol.c:915 
    local_bytes_received = recv(
     param0_client->socket_descriptor 
     ,param1_data + local_total_bytes 
     ,param2_length - local_total_bytes 
     ,0 
     ); 
    //pmprotocol.c:924 
    local_total_bytes += local_bytes_received; 
    } 
    //pmprotocol.c:928 
    if (debug > 1) 
    pmutil_dump_buf(param1_data, param2_length, stderr, "From wire"); 
    //pmprotocol.c:929 
    if (debug > 0) 
    fprintf(
     stderr 
     ,"pmprotocol_read:finish\n" 
     ); 
    //pmprotocol.c:930 
    return local_status; 
} 

Le démontage:

.skip 0x697c 
! typedef long long longlong_t; 
! #include "../include/pmtypes.h" 
! #include "../include/pmclient.h" 
! extern int debug; 
global_debug = 0x17c 
global__iob = 0x2ac 
global_LLC54 = 0x168 ! // "pmprotocol_read:enter\n" 
global_LLC56 = 0x170 ! // "From wire" 
global_LLC57 = 0x174 ! // "pmprotocol_read:finish\n" 
global_LLC55 = 0x16c ! // "pmprotocol_read" 
global_LLC38 = 0x128 ! // "function called with invalid client" 

.type pmprotocol_read , STT_FUNC 
.global pmprotocol_read 
.align 4 

! int pmprotocol_read(pm_client *param0_client, char *param1_data, int param2_length, pm_error *param3_error) 
pmprotocol_read: 

pmutil_dump_buf_plt = pmprotocol_read+81856 
recv_plt = pmprotocol_read+83308 
fprintf_plt = pmprotocol_read+81724 
pm_error_set_internal_plt = pmprotocol_read+81868 
pmprotocol_waitfor_read_plt = pmprotocol_read+82360 

globals = 0x13f70 

param0_client = 0x44 
param1_data = 0x48 
param2_length = 0x4c 
param3_error = 0x50 

! { 

    auto_retval = -168 

! size_t local_bytes_received; 
    local_bytes_received = -164 

! size_t local_total_bytes; 
    local_total_bytes = -160 

! int local_status; 
    local_status = -156 

! char local_message[128]; 
    local_message = -152 

! int local_retval; 
    local_retval = -20 

! // init globals pointer 
    0xff38691c <+0>:  save %sp, -264, %sp 
    0xff386920 <+4>:  sethi %hi(globals), %l7 
    0xff386924 <+8>:  call .-9152 
    0xff386928 <+12>: add %l7, %lo(globals), %l7 
                ! now %l7==0x13be8 
                ! "No function contains program counter for selected frame." 
                ! now %l7==0xff39a50c 

! // copy params to stack 
    0xff38692c <+16>: st %i0, [ %fp + param0_client ] 
    0xff386930 <+20>: st %i1, [ %fp + param1_data ] 
    0xff386934 <+24>: st %i2, [ %fp + param2_length ] 
    0xff386938 <+28>: st %i3, [ %fp + param3_error ] 

! // pmprotocol.c:896 
! if (debug > 0) 
    0xff38693c <+32>: sethi %hi(0), %g1 
    0xff386940 <+36>: or %g1, global_debug, %g1  ! global_debug 
    0xff386944 <+40>: ld [ %l7 + %g1 ], %g1    ! (%l7 + %g1)==0xff39a688 
                  ! now %g1==0xff39ad54 
    0xff386948 <+44>: ld [ %g1 ], %g1 
    0xff38694c <+48>: cmp %g1, 0 
    0xff386950 <+52>: ble .+48 ! <pmprotocol_read+100> 
    0xff386954 <+56>: nop 
! { 
!  fprintf(
!  stderr 
     0xff386958 <+60>: sethi %hi(0), %g1 
     0xff38695c <+64>: or %g1, global__iob, %g1  ! global__iob 
     0xff386960 <+68>: ld [ %l7 + %g1 ], %g1 
     0xff386964 <+72>: add %g1, 0x20, %o0 

!  ,"pmprotocol_read:enter\n" 
     0xff386968 <+76>: sethi %hi(0), %g1 
     0xff38696c <+80>: or %g1, global_LLC54, %g1  ! global_LLC54 
     0xff386970 <+84>: ld [ %l7 + %g1 ], %g1 
     0xff386974 <+88>: mov %g1, %o1 

!  ); 
     0xff386978 <+92>: call fprintf_plt 
     0xff38697c <+96>: nop 
! } 

! // pmprotocol.c:897 
! // pmprotocol.c:898 
! local_retval = 0; 
    0xff386980 <+100>: clr [ %fp + local_retval ] 
! // pmprotocol.c:900 
! local_status = 0; 
    0xff386984 <+104>: clr [ %fp + local_status ] 

! // pmprotocol.c:901 
! // pmprotocol.c:902 
! if (param0_client->status != 0) 
    0xff386988 <+108>: ld [ %fp + param0_client ], %g1 
    0xff38698c <+112>: ld [ %g1 + 0xc ], %g1 
    0xff386990 <+116>: cmp %g1, 0 
    0xff386994 <+120>: be .+72 ! <pmprotocol_read+192> 
    0xff386998 <+124>: nop 
! { 
! // pmprotocol.c:904 
!  pm_error_set_internal(
!  param3_error 
     0xff38699c <+128>: ld [ %fp + param3_error ], %o0 

!  ,"pmprotocol_read" 
     0xff3869a0 <+132>: sethi %hi(0), %g1 
     0xff3869a4 <+136>: or %g1, global_LLC55, %g1  ! global_LLC55 
     0xff3869a8 <+140>: ld [ %l7 + %g1 ], %g1 
     0xff3869ac <+144>: mov %g1, %o1 

!  ,"function called with invalid client" 
     0xff3869b0 <+148>: sethi %hi(0), %g1 
     0xff3869b4 <+152>: or %g1, global_LLC38, %g1  ! global_LLC38 
     0xff3869b8 <+156>: ld [ %l7 + %g1 ], %g1 
     0xff3869bc <+160>: mov %g1, %o2 

!  ,PM_ERROR_INVALID_CLIENT 
     0xff3869c0 <+164>: mov 0xd2, %o3 
! ); 
     0xff3869c4 <+168>: call pm_error_set_internal_plt 
     0xff3869c8 <+172>: nop 

! // pmprotocol.c:905 
!  return 1; 
     0xff3869cc <+176>: mov 1, %g1  ! 0x1 
     0xff3869d0 <+180>: st %g1, [ %fp + auto_retval ] 
     0xff3869d4 <+184>: b .+320 ! <pmprotocol_read+504> 
     0xff3869d8 <+188>: nop 
! } 

! // pmprotocol.c:908 
! local_retval = pmprotocol_waitfor_read(param0_client, param3_error); 
    0xff3869dc <+192>: ld [ %fp + param0_client ], %o0 
    0xff3869e0 <+196>: ld [ %fp + param3_error ], %o1 
    0xff3869e4 <+200>: call pmprotocol_waitfor_read_plt 
    0xff3869e8 <+204>: nop 
    0xff3869ec <+208>: mov %o0, %g1 
    0xff3869f0 <+212>: st %g1, [ %fp + local_retval ] 

! // pmprotocol.c:909 
! if (local_retval != 0) 
    0xff3869f4 <+216>: ld [ %fp + local_retval ], %g1 
    0xff3869f8 <+220>: cmp %g1, 0 
    0xff3869fc <+224>: be .+24 ! <pmprotocol_read+248> 
    0xff386a00 <+228>: nop 
! { 
!  return local_retval; 
     0xff386a04 <+232>: ld [ %fp + local_retval ], %g1 
     0xff386a08 <+236>: st %g1, [ %fp + auto_retval ] 
     0xff386a0c <+240>: b .+264 ! <pmprotocol_read+504> 
     0xff386a10 <+244>: nop 
! } 

! // pmprotocol.c:910 
! // pmprotocol.c:911 
! local_total_bytes = 0; 
    0xff386a14 <+248>: clr [ %fp + local_total_bytes ] 

! //pmprotocol.c:913 
! while ((size_t)param2_length > local_total_bytes) 
    0xff386a18 <+252>: ld [ %fp + param2_length ], %o5 
    0xff386a1c <+256>: ld [ %fp + local_total_bytes ], %g1 
    0xff386a20 <+260>: cmp %o5, %g1 
    0xff386a24 <+264>: bleu .+88 ! <pmprotocol_read+352> 
    0xff386a28 <+268>: nop 
! { 

!  //pmprotocol.c:915 
!  local_bytes_received = recv(
     0xff386a2c <+272>: ld [ %fp + param0_client ], %o3 
     0xff386a30 <+276>: ld [ %fp + param1_data ], %o5   
     0xff386a34 <+280>: ld [ %fp + local_total_bytes ], %g1 
     0xff386a38 <+284>: add %o5, %g1, %o4     
     0xff386a3c <+288>: ld [ %fp + param2_length ], %o5 
     0xff386a40 <+292>: ld [ %fp + local_total_bytes ], %g1 
     0xff386a44 <+296>: sub %o5, %g1, %g1 

!  param0_client->socket_descriptor 
      0xff386a48 <+300>: ld [ %o3 + 8 ], %o0 

!  ,param1_data + local_total_bytes 
      0xff386a4c <+304>: mov %o4, %o1      

!  ,param2_length - local_total_bytes 
      0xff386a50 <+308>: mov %g1, %o2 

!  ,0 
      0xff386a54 <+312>: clr %o3 
!  ); 
      0xff386a58 <+316>: call recv_plt 
      0xff386a5c <+320>: nop 
      0xff386a60 <+324>: st %o0, [ %fp + local_bytes_received ] 

!  //pmprotocol.c:924 
!  local_total_bytes += local_bytes_received; 
     0xff386a64 <+328>: ld [ %fp + local_total_bytes ], %o5 
     0xff386a68 <+332>: ld [ %fp + local_bytes_received ], %g1 
     0xff386a6c <+336>: add %o5, %g1, %g1 
     0xff386a70 <+340>: st %g1, [ %fp + local_total_bytes ] 

! } 
    0xff386a74 <+344>: b .-92 ! <pmprotocol_read+252> 
    0xff386a78 <+348>: nop 

! //pmprotocol.c:928 
! if (debug > 1) 
    0xff386a7c <+352>: sethi %hi(0), %g1 
    0xff386a80 <+356>: or %g1, global_debug, %g1  ! global_debug 
    0xff386a84 <+360>: ld [ %l7 + %g1 ], %g1 
    0xff386a88 <+364>: ld [ %g1 ], %g1 
    0xff386a8c <+368>: cmp %g1, 1 
    0xff386a90 <+372>: ble .+56 ! <pmprotocol_read+428> 
    0xff386a94 <+376>: nop 
!  pmutil_dump_buf(param1_data, param2_length, stderr, "From wire"); 
     0xff386a98 <+380>: ld [ %fp + param1_data ], %o0 
     0xff386a9c <+384>: ld [ %fp + param2_length ], %o1 
     0xff386aa0 <+388>: sethi %hi(0), %g1 
     0xff386aa4 <+392>: or %g1, global__iob, %g1  ! global__iob 
     0xff386aa8 <+396>: ld [ %l7 + %g1 ], %g1 
     0xff386aac <+400>: add %g1, 0x20, %o2 
     0xff386ab0 <+404>: sethi %hi(0), %g1 
     0xff386ab4 <+408>: or %g1, global_LLC56, %g1  ! global_LLC56 
     0xff386ab8 <+412>: ld [ %l7 + %g1 ], %g1 
     0xff386abc <+416>: mov %g1, %o3 
     0xff386ac0 <+420>: call pmutil_dump_buf_plt 
     0xff386ac4 <+424>: nop 

! //pmprotocol.c:929 
! if (debug > 0) 
    0xff386ac8 <+428>: sethi %hi(0), %g1 
    0xff386acc <+432>: or %g1, global_debug, %g1  ! global_debug 
    0xff386ad0 <+436>: ld [ %l7 + %g1 ], %g1 
    0xff386ad4 <+440>: ld [ %g1 ], %g1 
    0xff386ad8 <+444>: cmp %g1, 0 
    0xff386adc <+448>: ble .+48 ! <pmprotocol_read+496> 
    0xff386ae0 <+452>: nop 
!  fprintf(
!  stderr 
     0xff386ae4 <+456>: sethi %hi(0), %g1 
     0xff386ae8 <+460>: or %g1, global__iob, %g1  ! global__iob 
     0xff386aec <+464>: ld [ %l7 + %g1 ], %g1 
     0xff386af0 <+468>: add %g1, 0x20, %o0 
!  ,"pmprotocol_read:finish\n" 
     0xff386af4 <+472>: sethi %hi(0), %g1 
     0xff386af8 <+476>: or %g1, global_LLC57, %g1  ! global_LLC57 
     0xff386afc <+480>: ld [ %l7 + %g1 ], %g1 
     0xff386b00 <+484>: mov %g1, %o1 
!  ); 
     0xff386b04 <+488>: call fprintf_plt 
     0xff386b08 <+492>: nop 
! //pmprotocol.c:930 
! return local_status; 
    0xff386b0c <+496>: ld [ %fp + local_status ], %g1 
    0xff386b10 <+500>: st %g1, [ %fp + auto_retval ] 

    0xff386b14 <+504>: ld [ %fp + auto_retval ], %i0 
    0xff386b18 <+508>: ret 
    0xff386b1c <+512>: restore 
! } 
+0

a été en mesure d'ajouter la section avec objcopy. Mais ld se plaint de la section non mappée au segment de chargement. – basin

Répondre

Questions connexes