資源簡介
使用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?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加解密源代碼
- 下一篇:圖形化界面的萬年歷代碼
評論
共有 條評論