Line 2... |
Line 2... |
//set $gp and zero .sbss and .bss
|
//set $gp and zero .sbss and .bss
|
#include <stdio.h>
|
#include <stdio.h>
|
#include <stdlib.h>
|
#include <stdlib.h>
|
|
|
#define BUF_SIZE (1024*1024)
|
#define BUF_SIZE (1024*1024)
|
|
/*Assumes running on PC little endian*/
|
#define ntohl(A) ((A>>24)|((A&0x00ff0000)>>8)|((A&0xff00)<<8)|(A<<24))
|
#define ntohl(A) ((A>>24)|((A&0x00ff0000)>>8)|((A&0xff00)<<8)|(A<<24))
|
|
|
enum {
|
#define CODE_START 0x60
|
TEXT_OFFSET, TEXT_LENGTH,
|
#define SECTION_START 0x4c
|
RDATA_OFFSET, RDATA_LENGTH,
|
#define SECTION_END 0x160
|
DATA_OFFSET, DATA_LENGTH,
|
#define SECTION_SIZE 0x28
|
SDATA_OFFSET, SDATA_LENGTH,
|
#define SECTION_OFFSET 0xc
|
SBSS_OFFSET, SBSS_LENGTH,
|
#define SECTION_LENGTH 0x10
|
BSS_OFFSET, BSS_LENGTH
|
|
};
|
struct header_t {
|
|
unsigned long text_offset,text_length;
|
long code_start_offset=0x60;
|
unsigned long rdata_offset,rdata_length;
|
unsigned long map[12];
|
unsigned long data_offset,data_length;
|
long offset[]={
|
unsigned long sdata_offset,sdata_length;
|
0x58, 0x5c, //.text offset,length
|
unsigned long sbss_offset,sbss_length;
|
0x80, 0x84, //.rdata offset,length
|
unsigned long bss_offset,bss_length;
|
0xa8, 0xac, //.data offset,length
|
} header;
|
0xd0, 0xd4, //.sdata offset,length
|
|
0xf8, 0xfc, //.sbss offset,length
|
|
0x120,0x124 //.bss offset,length
|
|
};
|
|
|
|
unsigned long load(char *ptr,unsigned long address)
|
unsigned long load(char *ptr,unsigned long address)
|
{
|
{
|
unsigned long value;
|
unsigned long value;
|
value=*(unsigned long*)(ptr+address);
|
value=*(unsigned long*)(ptr+address);
|
Line 46... |
Line 43... |
|
|
int main(int argc,char *argv[])
|
int main(int argc,char *argv[])
|
{
|
{
|
FILE *infile,*outfile,*txtfile;
|
FILE *infile,*outfile,*txtfile;
|
unsigned char *buf,*code;
|
unsigned char *buf,*code;
|
long size,code_offset;
|
long size;
|
unsigned long i,d,gp_ptr;
|
unsigned long code_offset,index,name,offset,length,d,i,gp_ptr;
|
|
|
printf("test.exe -> code.txt & test2.exe\n");
|
printf("test.exe -> code.txt & test2.exe\n");
|
infile=fopen("test.exe","rb");
|
infile=fopen("test.exe","rb");
|
if(infile==NULL) {
|
if(infile==NULL) {
|
printf("Can't open test.exe");
|
printf("Can't open test.exe");
|
Line 59... |
Line 56... |
}
|
}
|
buf=(unsigned char*)malloc(BUF_SIZE);
|
buf=(unsigned char*)malloc(BUF_SIZE);
|
size=fread(buf,1,BUF_SIZE,infile);
|
size=fread(buf,1,BUF_SIZE,infile);
|
fclose(infile);
|
fclose(infile);
|
|
|
code_offset=load(buf,code_start_offset);
|
code_offset=load(buf,CODE_START);
|
printf("code_offset=0x%x\n",code_offset);
|
printf("code_offset=0x%x ",code_offset);
|
code=buf+code_offset;
|
code=buf+code_offset;
|
|
|
/*load all of the segment offsets and lengths*/
|
/*load all of the segment offsets and lengths*/
|
for(i=0;i<12;++i) {
|
for(index=SECTION_START;index<code_offset-0x20;index+=SECTION_SIZE) {
|
map[i]=load(buf,offset[i]);
|
name=load(buf,index);
|
}
|
offset=load(buf,index+SECTION_OFFSET);
|
if(code_offset<0x120) {
|
length=load(buf,index+SECTION_LENGTH);
|
printf("no .sdata\n");
|
switch(name) {
|
for(i=6;i<12;i+=2) {
|
case 0x2e746578: /*.text*/
|
map[i]=map[4];
|
header.text_offset=offset;
|
map[i+1]=map[5];
|
header.text_length=length;
|
}
|
offset+=length;
|
} else if(code_offset<0x140) {
|
length=0;
|
printf("no .rdata\n");
|
header.rdata_offset=offset;
|
for(i=11;i>4;--i) {
|
header.rdata_length=length;
|
map[i]=map[i-2];
|
header.data_offset=offset;
|
}
|
header.data_length=length;
|
|
header.sdata_offset=offset;
|
|
header.sdata_length=length;
|
|
header.sbss_offset=offset;
|
|
header.sbss_length=length;
|
|
header.bss_offset=offset;
|
|
header.bss_length=length;
|
|
break;
|
|
case 0x2e726461: /*.rdata*/
|
|
header.rdata_offset=offset;
|
|
header.rdata_length=length;
|
|
offset+=length;
|
|
length=0;
|
|
header.data_offset=offset;
|
|
header.data_length=length;
|
|
header.sdata_offset=offset;
|
|
header.sdata_length=length;
|
|
header.sbss_offset=offset;
|
|
header.sbss_length=length;
|
|
header.bss_offset=offset;
|
|
header.bss_length=length;
|
|
break;
|
|
case 0x2e646174: /*.data*/
|
|
header.data_offset=offset;
|
|
header.data_length=length;
|
|
offset+=length;
|
|
length=0;
|
|
header.sdata_offset=offset;
|
|
header.sdata_length=length;
|
|
header.sbss_offset=offset;
|
|
header.sbss_length=length;
|
|
header.bss_offset=offset;
|
|
header.bss_length=length;
|
|
break;
|
|
case 0x2e736461: /*.sdata*/
|
|
header.sdata_offset=offset;
|
|
header.sdata_length=length;
|
|
offset+=length;
|
|
length=0;
|
|
header.sbss_offset=offset;
|
|
header.sbss_length=length;
|
|
header.bss_offset=offset;
|
|
header.bss_length=length;
|
|
break;
|
|
case 0x2e736273: /*.sbss*/
|
|
header.sbss_offset=offset;
|
|
header.sbss_length=length;
|
|
offset+=length;
|
|
length=0;
|
|
header.bss_offset=offset;
|
|
header.bss_length=length;
|
|
break;
|
|
case 0x2e627373: /*.bss*/
|
|
header.bss_offset=offset;
|
|
header.bss_length=length;
|
|
break;
|
|
default: printf("unknown 0x%x\n",name);
|
}
|
}
|
for(i=0;i<12;i+=2) {
|
|
printf("0x%x 0x%x\n",map[i],map[i+1]);
|
|
}
|
}
|
|
|
/*Initialize the $gp register for sdata and sbss*/
|
/*Initialize the $gp register for sdata and sbss*/
|
gp_ptr=map[SDATA_OFFSET]+0x8000;
|
gp_ptr=header.sdata_offset+0x8000;
|
printf("gp_ptr=0x%x\n",gp_ptr);
|
printf("gp_ptr=0x%x ",gp_ptr);
|
/*modify the first opcodes in boot.asm*/
|
/*modify the first opcodes in boot.asm*/
|
/*modify the lui opcode*/
|
/*modify the lui opcode*/
|
set_low(code,0,gp_ptr>>16);
|
set_low(code,0,gp_ptr>>16);
|
/*modify the ori opcode*/
|
/*modify the ori opcode*/
|
set_low(code,4,gp_ptr&0xffff);
|
set_low(code,4,gp_ptr&0xffff);
|
|
|
/*Clear .sbss and .bss*/
|
/*Clear .sbss and .bss*/
|
printf(".sbss=0x%x .bss_end=0x%x\n",
|
printf(".sbss=0x%x .bss_end=0x%x\n",
|
map[SBSS_OFFSET],map[BSS_OFFSET]+map[BSS_LENGTH]);
|
header.sbss_offset,header.bss_offset+header.bss_length);
|
set_low(code,8,map[SBSS_OFFSET]);
|
set_low(code,8,header.sbss_offset);
|
set_low(code,12,map[BSS_OFFSET]+map[BSS_LENGTH]);
|
set_low(code,12,header.bss_offset+header.bss_length);
|
|
|
/*write out code.txt*/
|
/*write out code.txt*/
|
outfile=fopen("test2.exe","wb");
|
outfile=fopen("test2.exe","wb");
|
txtfile=fopen("code.txt","w");
|
txtfile=fopen("code.txt","w");
|
for(i=0;i<=map[SDATA_OFFSET]+map[SDATA_LENGTH];i+=4) {
|
for(i=0;i<=header.sdata_offset+header.sdata_length;i+=4) {
|
d=load(code,i);
|
d=load(code,i);
|
fprintf(txtfile,"%8.8x\n",d);
|
fprintf(txtfile,"%8.8x\n",d);
|
fwrite(code+i,4,1,outfile);
|
fwrite(code+i,4,1,outfile);
|
}
|
}
|
fclose(outfile);
|
fclose(outfile);
|