package
com.tudou.soshelltest;
import
java.io.ByteArrayOutputStream;
import
java.util.List;
import
com.tudou.soshell.ELF32_Phdr;
import
com.tudou.soshell.ELF32_Shdr;
import
com.tudou.soshell.ELFType32;
import
com.tudou.soshell.ELFUtils;
public
class
MGPBaseMainRepair {
public
static
String sofile =
"so/liba.so"
;
public
static
String dumpsofile =
"so/liba_dump.so"
;
public
static
String repairsofile =
"so/liba_repair.so"
;
public
static
void
main(String[] args){
try
{
byte
[] srcElfFileBytes = ELFUtils.readFile(sofile);
ELFType32 elfsrc =
new
ELFType32(srcElfFileBytes);
elfsrc.parseELFHeader();
elfsrc.parseSegmentHeader();
elfsrc.printSegmentHeaderList();
elfsrc.parseDynamicSegment();
elfsrc.parseSectionNames();
elfsrc.parseSectionHeader();
elfsrc.printSectionHeaderList();
elfsrc.parseSectionHeaderDetail();
byte
[] destElfFileBytes = ELFUtils.readFile(dumpsofile);
ELFType32 elfdest =
new
ELFType32(destElfFileBytes);
elfdest.parseELFHeader();
elfdest.parseSegmentHeader();
elfdest.printSegmentHeaderList();
System.out.println(
"\n\n********************************************************************************"
);
System.out.println(
"************************************ 开始修复 **********************************"
);
System.out.println(
"********************************************************************************\n\n"
);
/**
* 判断是否需要移动Section头信息
*/
int
__SECTION_START_OFFSET__ =
0
;
List<ELF32_Shdr> srcShdrList = elfsrc.secheaderList;
if
(srcShdrList !=
null
&& srcShdrList.size() >
0
){
int
startoffset =
0
;
for
(ELF32_Shdr shdr : srcShdrList){
int
offset = ELFUtils.byte2Int(shdr.sh_offset);
int
addr = ELFUtils.byte2Int(shdr.sh_addr);
if
(addr >
0
&& offset >
0
&& Math.abs(addr - offset) ==
0x1000
){
if
(startoffset ==
0
){
startoffset = ELFUtils.byte2Int(shdr.sh_offset);
}
if
(__SECTION_START_OFFSET__ ==
0
){
__SECTION_START_OFFSET__ = startoffset;
}
System.arraycopy(shdr.sh_addr,
0
, shdr.sh_offset,
0
,
4
);
}
else
if
((offset > startoffset) && addr ==
0
){
offset +=
0x1000
;
byte
[] offsetbytes = ELFUtils.int2Byte(offset);
System.arraycopy(offsetbytes,
0
, shdr.sh_offset,
0
,
4
);
}
}
ELFUtils.log(
"在源包上,更新section的offset,使之与addr一样"
);
}
List< ELF32_Phdr> srcPhdrList = elfsrc.proheaderList;
if
(srcPhdrList !=
null
&& srcPhdrList.size() >
0
){
int
startoffset =
0
;
for
( ELF32_Phdr phdr : srcPhdrList){
int
offset = ELFUtils.byte2Int(phdr.p_offset);
int
vaddr = ELFUtils.byte2Int(phdr.p_vaddr);
if
(vaddr >
0
&& offset >
0
&& Math.abs(vaddr - offset) ==
0x1000
){
if
(startoffset ==
0
){
startoffset = ELFUtils.byte2Int(phdr.p_offset);
}
System.arraycopy(phdr.p_vaddr,
0
, phdr.p_offset,
0
,
4
);
}
else
if
((offset > startoffset) && vaddr ==
0
){
offset +=
0x1000
;
byte
[] offsetbytes = ELFUtils.int2Byte(offset);
System.arraycopy(offsetbytes,
0
, phdr.p_offset,
0
,
4
);
}
}
ELFUtils.log(
"在源包上,更新segment的offset,使之与addr一样"
);
}
ByteArrayOutputStream baos =
new
ByteArrayOutputStream();
for
(ELF32_Shdr shdr : srcShdrList){
baos.write(shdr.toByteArray());
}
baos.close();
baos.flush();
byte
[] updateSectionDumpBytes = baos.toByteArray();
elfdest.updateSectionHeader(updateSectionDumpBytes);
System.out.println(
"将源包的Section头信息更新到dump包上"
);
ByteArrayOutputStream pbaos =
new
ByteArrayOutputStream();
for
(ELF32_Phdr shdr : srcPhdrList){
pbaos.write(shdr.toByteArray());
}
pbaos.close();
pbaos.flush();
byte
[] updateSegmentDumpBytes = pbaos.toByteArray();
elfdest.updateProgramHeadert(updateSegmentDumpBytes);
System.out.println(
"将源包的Segment头信息更新到dump包上"
);
elfdest.shstrtab = elfsrc.shstrtab;
elfdest.dynamic = elfsrc.dynamic;
elfdest.dynstr = elfsrc.dynstr;
elfdest.comment = elfsrc.comment;
elfdest.noteGunGoldVe = elfsrc.noteGunGoldVe;
elfdest.armattributes = elfsrc.armattributes;
elfdest.data = elfsrc.data;
elfdest.got = elfsrc.got;
elfdest.copySectionList(elfsrc.secheaderList);
elfdest.copySegmentList(elfsrc.proheaderList);
elfdest.setZeroInitArray();
elfdest.updateSectionData();
int
shoff = ELFUtils.byte2Int(elfdest.elfheader.e_shoff);
if
(shoff > __SECTION_START_OFFSET__){
System.out.println(
"准备移动Section头信息。。。"
);
shoff +=
0x1000
;
byte
[] offsetbytes = ELFUtils.int2Byte(shoff);
System.arraycopy(offsetbytes,
0
, elfdest.elfheader.e_shoff,
0
,
4
);
byte
[] dataupdate = elfdest.elfheader.getSrcDataUpdate();
elfdest.updateELFHeader();
elfdest.updateSectionHeader(updateSectionDumpBytes);
System.out.println(
"将源包的Section头信息更新到dump包上,第二次更新"
);
}
else
{
System.out.println(
"不需要移动Section头信息"
);
}
ELFUtils.saveFile(repairsofile, elfdest.getELFFileBytes());
}
catch
(Exception e) {
e.printStackTrace();
}
}
}