如何在没有源代码的情况下替换.so文件中的错误函数?

时间:2013-07-07 15:51:19

标签: assembly patch sparc

我在共享库中有一个错误的功能。当recv()返回0时,它进入无限循环。

没有源代码。我能够反编译错误部分并更改一些处理器指令而不调整功能,但没有完全修复的余地。

我想用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
! }

1 个答案:

答案 0 :(得分:0)

使用LD_PRELOAD技巧:

What is the LD_PRELOAD trick?