pc端的linux下可以正常运行,放到arm11的开发板上运行就会...

2019-07-16 09:32发布

我写了个程序,放在pc上的linux编译之后可以正常运行,但是交叉编译完之后放到开发板上运行就会报segment fault的错误(错误是在执行被修改的函数中报出来的),板子(linux)没有什么问题,交叉编译器也没问题,我写的程序的功能是当调用一个函数时,就会立马跳转到另一个函数执行,该功能是通过修改函数的入口的第一条指令来完成,修改为跳转指令,跳转的值是相对的地址距离的差(相对跳转)。哪位大侠可以帮我调试一下啊,跪谢!!已经折磨了我好几个星期了。这个程序的跳转是碰到malloc或free就跳转到我自己的函数中,来收集一些信息。代码如下,复制直接就可以运行。函数的入口指令的修改通过ContainerAdd()这个函数来实现的。

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<sys/mman.h>


#define FUNCLISTLENTH 100
#define BYTE char
#define MAX_FUNC_NUM 10
#define VOS_VOID  void
#define BOOL int
#define size_t unsigned int


int FALSE = 0;
int TRUE = 1;


typedef int (*FUNCPTR)();


int content[][5] = {{0}};
FUNCPTR newFuncList[FUNCLISTLENTH]={NULL};
FUNCPTR oldFuncList[FUNCLISTLENTH]={NULL};


unsigned long oldFuncJumpOffset[FUNCLISTLENTH]={0};
unsigned long newFuncJumpOffset[FUNCLISTLENTH]={0};


BYTE oldFuncFirstCode[MAX_FUNC_NUM] = {0};


extern tmpRepFuncList[FUNCLISTLENTH] = {0};




/*
   函数名称: ChangeProtection
   功能   : 修改某段内存的保护模式
   参数   :
          [in]  ulFrom   待写内存开始地址

  [in]  ulLength 待写内存长度

  [in]  ulMode   模式
   返回值  :成功返回TRUE 失败返回FALSE
*/
unsigned int ChangeProtection(unsigned int ulFrom,unsigned int ulLength,unsigned int ulMode)
{

printf(" I am   ChangeProtection ! ");

int iRtn;

unsigned int ulLastPageEnd;

unsigned int ulFirstPageStart;





ulFirstPageStart = ulFrom - (ulFrom % 4096);



ulLastPageEnd = ulFrom + ulLength;



ulLastPageEnd += 4096 - (ulLastPageEnd % 4096);





iRtn = mprotect((VOS_VOID *)ulFirstPageStart,ulLastPageEnd-ulFirstPageStart,ulMode);

if( 0 != iRtn)

{

printf("Call mprotect fail in ChangeProtection ! ");

return FALSE;

}
printf(" I am   ChangeProtection Runover! ");

return TRUE;


}




/*
   函数名称: ModProtectMemContent
   功能   : 完成修改某段保护内存的内容
   参数   :
          [in]  pBassAddress   待写内存开始地址

  [in]  ucCmd          待写内存长度

  [in]  dwData         数据区内容
   返回值  :成功返回TRUE 失败返回FALSE
*/




unsigned int ModProtectMemContent(void* pBaseAddress, BYTE ucCmd, unsigned long  dwData)  
{



printf(" I am   ModProtectionMemContent ! ");
        BYTE aBuf[10] = {0};

BOOL bRtn;



if((ChangeProtection((unsigned int)pBaseAddress, 5, PROT_EXEC | PROT_READ | PROT_WRITE)) == FALSE)

{


return FALSE;


}



//准备要填入的指令机器码,需要修改五个字节内容

aBuf[0] = ucCmd;//0XE9为相对跳转指令的机器码

aBuf[1] = (BYTE)(dwData & 0xFF);

aBuf[2] = (BYTE)((dwData & 0xFF00)>> 8);

aBuf[3] = (BYTE)((dwData & 0xFF0000)>> 16);

aBuf[4] = (BYTE)((dwData & 0xFF000000)>> 24);



//修改老函数入口处的指令

bRtn = memcpy(pBaseAddress, aBuf, 5);

if(!bRtn)

{

printf("Modify old func entry instruct fail in ModProtectMemContent!' '");

return FALSE;


}





if((ChangeProtection((unsigned int)pBaseAddress ,5 ,PROT_EXEC | PROT_READ)) == FALSE)

{

return FALSE;



}

printf(" I am   ModProtectionMemContent Runover! ");

return TRUE;
}






/*
   函数名称: RecoverReplaceOldFunc
   功能   :在新函数调用完原函数后恢复对原函数的修改
   参数   :
          [in]  oldFunc    旧函数指针
   返回值  :成功返回TRUE 失败返回FALSE
*/


unsigned int RecoverReplaceOldFunc(FUNCPTR oldFunc)
{



printf(" I am   RecoverReplaceOldFunc ! ");

BOOL bRtn;

int i;

//printf("**********Enter RecoverReplaceOldFunc!********** ");

for(i=0;i<MAX_FUNC_NUM;i++)

{


if(oldFuncList[i] == oldFunc)

{

  if((ChangeProtection(oldFunc, 5, PROT_EXEC | PROT_READ | PROT_WRITE)) == 0)

    {

      return 0;

    }

  bRtn = memcpy(oldFunc, content[i], 5);

  oldFuncList[i] = NULL;

newFuncList[i] = NULL;

oldFuncJumpOffset[i] = 0;

newFuncJumpOffset[i] = 0;

oldFuncFirstCode[i] = 0;

  if(!bRtn)

    {

      printf("memcpy fail in RecoverReplaceOldFunc! ");

      return FALSE;

    }

  //printf("**********Exit RecoverReplaceOldFunc!********** ");

  printf(" I am   RecoverReplaceOldFunc Runover! ");

  return TRUE;

}



}



printf("Can not find the old func! ");

return FALSE;
}


int ContainerAdd(void *pOldFunc,void *pNewFunc)
{





printf(" I am   ContainerAdd ! ");

BOOL bRtn;


//printf("**********Enter ContainerAdd!********** ");



unsigned long dwNewInstructOffset = 0;

unsigned long dwOldJumpOffset = 0;

unsigned long dwTmpJumpOffset = 0;

unsigned long dwNewOffset = 0;



int i;

for(i = 0; i < MAX_FUNC_NUM; i++)

{

if(newFuncList[i] == NULL)

{



        //得到临时替代函数相对原函数的偏移

  memcpy(content[i],pOldFunc,5);

  tmpRepFuncList[i]=(unsigned long)pNewFunc;

  dwTmpJumpOffset = (unsigned long)pNewFunc - (unsigned long )pOldFunc - 5;

  dwNewInstructOffset = (unsigned long)pOldFunc - (unsigned long)pNewFunc - 5;



  bRtn = ModProtectMemContent(pOldFunc, 0XE9, dwTmpJumpOffset);

  if(!bRtn)

  {

    printf("ModProtectMemContent fail in ContainerAdd ! ");

    return FALSE;

  }

   

  newFuncList[i]=(FUNCPTR)pNewFunc;

  oldFuncList[i]=(FUNCPTR)pOldFunc;

  newFuncJumpOffset[i] = dwNewInstructOffset;

  oldFuncJumpOffset[i]= dwOldJumpOffset;

  oldFuncFirstCode[i] = *(BYTE*)pOldFunc;

printf(" I am   ContainerAdd RunOver! ");

  return 1;

}



}





if(i>=MAX_FUNC_NUM)

{

printf("The func list is full ! ");

return TRUE;

}





return TRUE;
}




/********************************************************************************/
//函数执行跳转指令后 所跳向的函数
void * my_malloc(size_t len)
{





printf(" My_malloc run ");

FILE *q=fopen("MemoryMallocInfo.txt","a+");

fprintf(q," ");
  char* temp;
  RecoverReplaceOldFunc(malloc);
  temp=(char *)malloc(len);
  ContainerAdd(malloc,my_malloc);
  printf(" Malloc Address : %10p Length : %d ",temp,len);
  fprintf(q,"  %s       %10p   
   %d
  %d ",__FILE__,temp,__LINE__,len);
  fclose(q);


  printf(" My_malloc run RunOver ! ");
  return temp;


}




//函数执行跳转指令后 所跳向的函数


void *my_free(void *p)
{



printf(" My_free Run ! ");

FILE *q=fopen("MemoryFreeInfo.txt","a+");

fprintf(q," ");

char* temp;

int len;

len=sizeof(*p);

//printf(" Name :%s  :  Line ",*file,line);

RecoverReplaceOldFunc(free);

printf(" Free Address : %10p        Length : %d ",p,len);

  fprintf(q,"  %s       %10p ",__FILE__,p);

free(p);

  p=NULL;

  fclose(q);

  ContainerAdd(free,my_free);

  printf(" My_free Run RunOver! ");

   
}




  
//跳转函数的启动
int test()
{





printf(" Test run ");

FILE *p=fopen("MemoryMallocInfo.txt","a+");

fprintf(p," ");
fprintf(p,"
FileName  
Address  
LineNumber  
TotalByte ");
fprintf(p," ");
FILE *q=fopen("MemoryFreeInfo.txt","a+");

fprintf(q," ");
fprintf(q,"
FileName  
Address ");
fprintf(q," ");
fclose(p);
fclose(q);


  ContainerAdd(malloc,my_malloc);


  ContainerAdd(free,my_free);
  printf("The Address of malloc() = %p. The Address of my_malloc = %p. ", malloc, my_malloc);
printf(" Test run Runover ");
  return 0;
}



void main()
{
test();
  char *zhang=malloc(sizeof(char)*100);
  char *p1=malloc(20*sizeof(char));//337行
  char *p2=malloc(24*sizeof(char));//338行
  char *p3=malloc(28*sizeof(char));//339行
  char *p4=malloc(32*sizeof(char));//340行
  char *p5=malloc(36*sizeof(char));//341行

free(zhang);


free(p1);
free(p2);
free(p3);
free(p4);
free(p5);


}
友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
该问题目前已经被作者或者管理员关闭, 无法添加新回复
2条回答
wuchangwei
1楼-- · 2019-07-16 13:37
我复制运行了,你这个还是有很多错误啊。可能是你copy的格式不对吧。
woodmice
2楼-- · 2019-07-16 19:26
 精彩回答 2  元偷偷看……

一周热门 更多>