资源简介
使用C++解析一个so文件,很是使用的一个工具类。
代码片段和文件信息
#include
#include
#include
#include “elf.h“
/**
非常重要的一个宏,功能很简单:
P:需要对其的段地址
ALIGNBYTES:对其的字节数
功能:将P值补充到时ALIGNBYTES的整数倍
这个函数也叫:页面对其函数
eg: 0x3e45/0x1000 == >0x4000
*/
#define ALIGN(P ALIGNBYTES) ( ((unsigned long)P + ALIGNBYTES -1)&~(ALIGNBYTES-1) )
int addSectionFun(char* char* unsigned int);
int main()
{
addSectionFun(“D:\libhello-jni.so“ “.jiangwei“ 0x1000);
return 0;
}
int addSectionFun(char *lpPath char *szSecname unsigned int nNewSecSize)
{
char name[50];
FILE *fdr *fdw;
char *base = NULL;
Elf32_Ehdr *ehdr;
Elf32_Phdr *t_phdr *load1 *load2 *dynamic;
Elf32_Shdr *s_hdr;
int flag = 0;
int i = 0;
unsigned mapSZ = 0;
unsigned nLoop = 0;
unsigned int nAddInitFun = 0;
unsigned int nNewSecAddr = 0;
unsigned int nModulebase = 0;
memset(name 0 sizeof(name));
if(nNewSecSize == 0)
{
return 0;
}
fdr = fopen(lpPath “rb“);
strcpy(name lpPath);
if(strchr(name ‘.‘))
{
strcpy(strchr(name ‘.‘) “_new.so“);
}
else
{
strcat(name “_new“);
}
fdw = fopen(name “wb“);
if(fdr == NULL || fdw == NULL)
{
printf(“Open file failed“);
return 1;
}
fseek(fdr 0 SEEK_END);
mapSZ = ftell(fdr);//源文件的长度大小
printf(“mapSZ:0x%x\n“ mapSZ);
base = (char*)malloc(mapSZ * 2 + nNewSecSize);//2*源文件大小+新加的Section size
printf(“base 0x%x \n“ base);
memset(base 0 mapSZ * 2 + nNewSecSize);
fseek(fdr 0 SEEK_SET);
fread(base 1 mapSZ fdr);//拷贝源文件内容到base
if(base == (void*) -1)
{
printf(“fread fd failed“);
return 2;
}
//判断Program Header
ehdr = (Elf32_Ehdr*) base;
t_phdr = (Elf32_Phdr*)(base + sizeof(Elf32_Ehdr));
for(i=0;ie_phnum;i++)
{
if(t_phdr->p_type == PT_LOAD)
{
//这里的flag只是一个标志位,去除第一个LOAD的Segment的值
if(flag == 0)
{
load1 = t_phdr;
flag = 1;
nModulebase = load1->p_vaddr;
printf(“load1 = %p offset = 0x%x \n“ load1 load1->p_offset);
}
else
{
load2 = t_phdr;
printf(“load2 = %p offset = 0x%x \n“ load2 load2->p_offset);
}
}
if(t_phdr->p_type == PT_DYNAMIC)
{
dynamic = t_phdr;
printf(“dynamic = %p offset = 0x%x \n“ dynamic dynamic->p_offset);
}
t_phdr ++;
}
//section header
s_hdr = (Elf32_Shdr*)(base + ehdr->e_shoff);
//获取到新加section的位置,这个是重点需要进行页面对其操作
printf(“addr:0x%x\n“load2->p_paddr);
nNewSecAddr = ALIGN(load2->p_paddr + load2->p_memsz - nModulebase load2->p_align);
printf(“new section add:%x \n“ nNewSecAddr);
if(load1->p_filesz < ALIGN(load2->p_paddr + load2->p_memsz load2->p_align) )
{
printf(“offset:%x\n“(ehdr->e_shoff + sizeof(Elf32_Shdr) * ehdr->e_shnum));
//注意这里的代码的执行条件,这里其实就是判断section header是不是在文件的末尾
if( (ehdr->e_shoff + sizeof(Elf32_Shdr) * ehdr->e_shnum) != mapSZ)
{
if(mapSZ + sizeof(Elf32_Shdr) * (ehdr->e_shnum + 1) > nNewSecAddr)
{
printf(“无法添加节\n“);
return 3;
}
else
{
memcpy(base + mapSZ base + ehdr-
属性 大小 日期 时间 名称
----------- --------- ---------- ----- ----
文件 163901 2015-10-21 18:47 ParseSo\Debug\ParseSo.exe
文件 240464 2015-10-21 18:47 ParseSo\Debug\ParseSo.ilk
文件 18628 2015-10-21 18:47 ParseSo\Debug\ParseSo.obj
文件 250324 2015-10-21 13:24 ParseSo\Debug\ParseSo.pch
文件 467968 2015-10-21 18:47 ParseSo\Debug\ParseSo.pdb
文件 148480 2015-10-21 18:47 ParseSo\Debug\vc60.idb
文件 86016 2015-10-21 18:47 ParseSo\Debug\vc60.pdb
文件 23493 2014-10-20 13:53 ParseSo\elf.h
文件 5182 2015-10-21 19:04 ParseSo\ParseSo.cpp
文件 3413 2015-10-21 13:24 ParseSo\ParseSo.dsp
文件 537 2015-10-22 15:41 ParseSo\ParseSo.dsw
文件 33792 2015-10-22 15:41 ParseSo\ParseSo.ncb
文件 48640 2015-10-22 15:41 ParseSo\ParseSo.opt
文件 1228 2015-10-21 18:47 ParseSo\ParseSo.plg
目录 0 2015-10-21 18:47 ParseSo\Debug
目录 0 2015-10-22 15:41 ParseSo
----------- --------- ---------- ----- ----
1492066 16
- 上一篇:AES CBC加解密源代码
- 下一篇:图形化界面的万年历代码
评论
共有 条评论