pc端的linux下可以正常运行,放到arm11的开发板上运行就会...
时间:10-02
整理:3721RD
点击:
我写了个程序,放在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("\nI am ChangeProtection !\n");
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 !\n");
return FALSE;
}
printf("\nI am ChangeProtection Runover!\n");
return TRUE;
}
/*
函数名称: ModProtectMemContent
功能 : 完成修改某段保护内存的内容
参数 :
[in] pBassAddress 待写内存开始地址
[in] ucCmd 待写内存长度
[in] dwData 数据区内容
返回值 :成功返回TRUE 失败返回FALSE
*/
unsigned int ModProtectMemContent(void* pBaseAddress, BYTE ucCmd, unsigned long dwData)
{
printf("\nI am ModProtectionMemContent !\n");
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!'\n'");
return FALSE;
}
if((ChangeProtection((unsigned int)pBaseAddress ,5 ,PROT_EXEC | PROT_READ)) == FALSE)
{
return FALSE;
}
printf("\nI am ModProtectionMemContent Runover!\n");
return TRUE;
}
/*
函数名称: RecoverReplaceOldFunc
功能 :在新函数调用完原函数后恢复对原函数的修改
参数 :
[in] oldFunc 旧函数指针
返回值 :成功返回TRUE 失败返回FALSE
*/
unsigned int RecoverReplaceOldFunc(FUNCPTR oldFunc)
{
printf("\nI am RecoverReplaceOldFunc !\n");
BOOL bRtn;
int i;
//printf("**********Enter RecoverReplaceOldFunc!**********\n");
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!\n");
return FALSE;
}
//printf("**********Exit RecoverReplaceOldFunc!**********\n");
printf("\nI am RecoverReplaceOldFunc Runover!\n");
return TRUE;
}
}
printf("Can not find the old func!\n");
return FALSE;
}
int ContainerAdd(void *pOldFunc,void *pNewFunc)
{
printf("\nI am ContainerAdd !\n");
BOOL bRtn;
//printf("**********Enter ContainerAdd!**********\n");
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 !\n");
return FALSE;
}
newFuncList[i]=(FUNCPTR)pNewFunc;
oldFuncList[i]=(FUNCPTR)pOldFunc;
newFuncJumpOffset[i] = dwNewInstructOffset;
oldFuncJumpOffset[i]= dwOldJumpOffset;
oldFuncFirstCode[i] = *(BYTE*)pOldFunc;
printf("\nI am ContainerAdd RunOver!\n");
return 1;
}
}
if(i>=MAX_FUNC_NUM)
{
printf("The func list is full !\n");
return TRUE;
}
return TRUE;
}
/********************************************************************************/
//函数执行跳转指令后 所跳向的函数
void * my_malloc(size_t len)
{
printf("\nMy_malloc run\n");
FILE *q=fopen("MemoryMallocInfo.txt","a+");
fprintf(q,"\r\n");
char* temp;
RecoverReplaceOldFunc(malloc);
temp=(char *)malloc(len);
ContainerAdd(malloc,my_malloc);
printf("\nMalloc Address : %10p Length : %d\n",temp,len);
fprintf(q," %s %10p
%d
%d\n",__FILE__,temp,__LINE__,len);
fclose(q);
printf("\nMy_malloc run RunOver !\n");
return temp;
}
//函数执行跳转指令后 所跳向的函数
void *my_free(void *p)
{
printf("\nMy_free Run !\n");
FILE *q=fopen("MemoryFreeInfo.txt","a+");
fprintf(q,"\r\n");
char* temp;
int len;
len=sizeof(*p);
//printf("\nName :%s : Line\n",*file,line);
RecoverReplaceOldFunc(free);
printf("\nFree Address : %10p Length : %d\n",p,len);
fprintf(q," %s %10p\n",__FILE__,p);
free(p);
p=NULL;
fclose(q);
ContainerAdd(free,my_free);
printf("\nMy_free Run RunOver!\n");
}
//跳转函数的启动
int test()
{
printf("\nTest run\n");
FILE *p=fopen("MemoryMallocInfo.txt","a+");
fprintf(p,"\r\n");
fprintf(p,"
FileName
Address
LineNumber
TotalByte\n");
fprintf(p,"\r\n");
FILE *q=fopen("MemoryFreeInfo.txt","a+");
fprintf(q,"\r\n");
fprintf(q,"
FileName
Address\n");
fprintf(q,"\r\n");
fclose(p);
fclose(q);
ContainerAdd(malloc,my_malloc);
ContainerAdd(free,my_free);
printf("The Address of malloc() = %p.\nThe Address of my_malloc = %p.\n", malloc, my_malloc);
printf("\nTest run Runover\n");
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);
}
#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("\nI am ChangeProtection !\n");
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 !\n");
return FALSE;
}
printf("\nI am ChangeProtection Runover!\n");
return TRUE;
}
/*
函数名称: ModProtectMemContent
功能 : 完成修改某段保护内存的内容
参数 :
[in] pBassAddress 待写内存开始地址
[in] ucCmd 待写内存长度
[in] dwData 数据区内容
返回值 :成功返回TRUE 失败返回FALSE
*/
unsigned int ModProtectMemContent(void* pBaseAddress, BYTE ucCmd, unsigned long dwData)
{
printf("\nI am ModProtectionMemContent !\n");
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!'\n'");
return FALSE;
}
if((ChangeProtection((unsigned int)pBaseAddress ,5 ,PROT_EXEC | PROT_READ)) == FALSE)
{
return FALSE;
}
printf("\nI am ModProtectionMemContent Runover!\n");
return TRUE;
}
/*
函数名称: RecoverReplaceOldFunc
功能 :在新函数调用完原函数后恢复对原函数的修改
参数 :
[in] oldFunc 旧函数指针
返回值 :成功返回TRUE 失败返回FALSE
*/
unsigned int RecoverReplaceOldFunc(FUNCPTR oldFunc)
{
printf("\nI am RecoverReplaceOldFunc !\n");
BOOL bRtn;
int i;
//printf("**********Enter RecoverReplaceOldFunc!**********\n");
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!\n");
return FALSE;
}
//printf("**********Exit RecoverReplaceOldFunc!**********\n");
printf("\nI am RecoverReplaceOldFunc Runover!\n");
return TRUE;
}
}
printf("Can not find the old func!\n");
return FALSE;
}
int ContainerAdd(void *pOldFunc,void *pNewFunc)
{
printf("\nI am ContainerAdd !\n");
BOOL bRtn;
//printf("**********Enter ContainerAdd!**********\n");
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 !\n");
return FALSE;
}
newFuncList[i]=(FUNCPTR)pNewFunc;
oldFuncList[i]=(FUNCPTR)pOldFunc;
newFuncJumpOffset[i] = dwNewInstructOffset;
oldFuncJumpOffset[i]= dwOldJumpOffset;
oldFuncFirstCode[i] = *(BYTE*)pOldFunc;
printf("\nI am ContainerAdd RunOver!\n");
return 1;
}
}
if(i>=MAX_FUNC_NUM)
{
printf("The func list is full !\n");
return TRUE;
}
return TRUE;
}
/********************************************************************************/
//函数执行跳转指令后 所跳向的函数
void * my_malloc(size_t len)
{
printf("\nMy_malloc run\n");
FILE *q=fopen("MemoryMallocInfo.txt","a+");
fprintf(q,"\r\n");
char* temp;
RecoverReplaceOldFunc(malloc);
temp=(char *)malloc(len);
ContainerAdd(malloc,my_malloc);
printf("\nMalloc Address : %10p Length : %d\n",temp,len);
fprintf(q," %s %10p
%d
%d\n",__FILE__,temp,__LINE__,len);
fclose(q);
printf("\nMy_malloc run RunOver !\n");
return temp;
}
//函数执行跳转指令后 所跳向的函数
void *my_free(void *p)
{
printf("\nMy_free Run !\n");
FILE *q=fopen("MemoryFreeInfo.txt","a+");
fprintf(q,"\r\n");
char* temp;
int len;
len=sizeof(*p);
//printf("\nName :%s : Line\n",*file,line);
RecoverReplaceOldFunc(free);
printf("\nFree Address : %10p Length : %d\n",p,len);
fprintf(q," %s %10p\n",__FILE__,p);
free(p);
p=NULL;
fclose(q);
ContainerAdd(free,my_free);
printf("\nMy_free Run RunOver!\n");
}
//跳转函数的启动
int test()
{
printf("\nTest run\n");
FILE *p=fopen("MemoryMallocInfo.txt","a+");
fprintf(p,"\r\n");
fprintf(p,"
FileName
Address
LineNumber
TotalByte\n");
fprintf(p,"\r\n");
FILE *q=fopen("MemoryFreeInfo.txt","a+");
fprintf(q,"\r\n");
fprintf(q,"
FileName
Address\n");
fprintf(q,"\r\n");
fclose(p);
fclose(q);
ContainerAdd(malloc,my_malloc);
ContainerAdd(free,my_free);
printf("The Address of malloc() = %p.\nThe Address of my_malloc = %p.\n", malloc, my_malloc);
printf("\nTest run Runover\n");
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);
}
我复制运行了,你这个还是有很多错误啊。可能是你copy的格式不对吧。
哥,arm11下的相对跳转指令的机器码也是0xE9吗?
X86数值是小端模式保存,arm是不是也是小端模式?
要不加修改跨平台移植,不要使用没弄明白的机器码