2013-07-07 6 views
0

У меня есть функция с ошибкой в ​​общей библиотеке. Он вводит бесконечный цикл, когда recv() возвращает 0.Как заменить функцию buggy в файле .so без исходного кода?

Исходный код отсутствует. Я смог декомпилировать багги-часть и изменить некоторые инструкции процессора без изменения размера функции, но нет полного места для исправления.

Я хочу скомпилировать новую версию с помощью gcc и вернуть ее обратно в библиотеку. Функция использует некоторые глобальные и, что еще хуже, статические переменные. Фиксированная функция больше оригинальной, поэтому ее нельзя разместить в одном месте.

Здесь:

#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; 
} 

Разборка:

.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

Умел добавить раздел с objcopy. Но ld жалуется на раздел, не привязанный к сегменту нагрузки. – basin

ответ

0

Используйте LD_PRELOAD трюк:

What is the LD_PRELOAD trick?

+0

Это будет работать только с кросс-двоичными вызовами, не так ли ?. Моя функция внутренняя. – basin