📄 pe.c
字号:
| enter_pe_Fixup |
| |
+-------------------------------------------------------------------------+*/
void enter_pe_fixup(bit_32 address,loc_type location)
BeginDeclarations
EndDeclarations
BeginCode
If pefile.val IsTrue
Then
If location IsNotEqualTo offset32_location AndIf location IsNotEqualTo secondary_offset32_location
Then
linker_error(4,"PE Fixup error:\n"
" Error: segment-relative fixups in PE files must be 32 bits\n");
return ;
EndIf ;
If n_pe_fixups IsEqualTo max_pe_fixups
Then
max_pe_fixups += 10000 ;
pe_fixup_array = (fixup_hold_ptr_array)reallocate_memory(pe_fixup_array, max_pe_fixups*sizeof(fixup_hold_ptr)) ;
EndIf ;
pe_fixup_array[n_pe_fixups] = (fixup_hold_ptr)allocate_memory(sizeof(fixup_hold_type));
pe_fixup_array[n_pe_fixups]->offset = address ;
pe_fixup_array[n_pe_fixups++]->type = PE_FIXUP_HIGHLOW ;
EndIf ;
EndCode
/*+-------------------------------------------------------------------------+
| |
| SortFixups |
| |
+-------------------------------------------------------------------------+*/
static int sortcmp(fixup_hold_ptr *left, fixup_hold_ptr *right)
{
if ((*left)->offset < (*right)->offset)
return -1;
if ((*left)->offset < (*right)->offset)
return 1;
return 0;
}
static void SortFixups(void)
BeginDeclarations
bit_32 i,j;
fixup_hold_ptr temp ;
EndDeclarations
BeginCode
qsort(pe_fixup_array,n_pe_fixups,sizeof(void *),(int (*)(const void *, const void *))sortcmp);
#ifdef XXXXX
For i=0 ; i < n_pe_fixups; i++
BeginFor
For j=i+1; j < n_pe_fixups; j++
BeginFor
If pe_fixup_array[i]->offset > pe_fixup_array[j]->offset
Then
temp = pe_fixup_array[i] ;
pe_fixup_array[i] = pe_fixup_array[j] ;
pe_fixup_array[j] = temp ;
EndIf ;
EndFor ;
EndFor ;
#endif
EndCode
/*+-------------------------------------------------------------------------+
| |
| BuildPERelocs |
| |
+-------------------------------------------------------------------------+*/
void BuildPERelocs(bit_32 sectNum, pe_object_ptr objectTable, pe_header_ptr pehead)
BeginDeclarations
fixup_block_type block ;
int_32 pos ;
int_32 base ;
int_32 current ;
pe_section_ptr sect ;
int_32 k ;
pe_object_ptr lastObjectTable ;
int_32 current_size;
#define PEHead (*pehead)
#define LastObjectTable (*lastObjectTable)
#define ObjectTable (*objectTable)
#define Sect (*sect)
EndDeclarations
BeginCode
SortFixups() ;
pos = 0;
current_size = 0;
sect = outList[sectNum] ;
// Make winnt happy if no fixups
If n_pe_fixups IsZero
Then
block.rva = 0 ;
block.size = 12;
block.data[0] = block.data[1] = 0;
Sect.data = allocate_memory(block.size) ;
memcpy(Sect.data, &block, block.size);
Sect.length = Sect.initlength = block.size ;
EndIf ;
While pos LessThan n_pe_fixups
BeginWhile
base = pe_fixup_array[pos]->offset And Complement 4095;
current = 0;
block.rva = base - imageBase.val ;
block.size = 8 ;
While pos LessThan n_pe_fixups AndIf base IsEqualTo (pe_fixup_array[pos]->offset And Complement 4095)
BeginWhile
block.size += 2 ;
block.data[current++] = (pe_fixup_array[pos]->offset And 4095) Or (pe_fixup_array[pos]->type ShiftedLeft 12);
pos++ ;
EndWhile ;
If block.size And 3
Then
block.size += 2 ;
block.data[current++] = 0;
EndIf ;
if (Sect.length + block.size >= current_size) {
current_size += (n_pe_fixups - pos) * (8 + 1024) + 10000 ;
if (current_size < Sect.length + block.size) // should never happen
current_size = Sect.length + block.size;
Sect.data = reallocate_memory(Sect.data, current_size) ;
}
memcpy(Sect.data + Sect.length, &block, block.size);
Sect.initlength = Sect.length += block.size ;
// fixme max lengths
EndWhile ;
lastObjectTable = objectTable + sectNum-1 ;
objectTable = lastObjectTable + 1;
k=Sect.length + objectAlign.val-1 ;
k&=(0xffffffff-(objectAlign.val-1));
Sect.virtualSize=k;
ObjectTable.virtual_size = k ;
ObjectTable.raw_size = Sect.length ;
k = LastObjectTable.raw_size + LastObjectTable.raw_ptr + fileAlign.val - 1;
k&=(0xffffffff-(fileAlign.val-1)); /* aligned */
/* k is now physical location of this object */
ObjectTable.raw_ptr = k ;
k = ObjectTable.virtual_addr = LastObjectTable.virtual_size + LastObjectTable.virtual_addr ;
Sect.base=k+imageBase.val; /* relocate section */
PEHead.fixup_rva = Sect.base - imageBase.val ;
PEHead.fixup_size = Sect.length;
return;
}
#undef ObjectTable
#undef Sect
#undef PEHead
/*+-------------------------------------------------------------------------+
| |
| BuildPEExports |
| |
+-------------------------------------------------------------------------+*/
int expfunc(void *a, void *b)
{
return strcmp(String(((public_entry_ptr)*(void **)a)->entryident), String(((public_entry_ptr)*(void **)b)->entryident));
}
void BuildPEExports(int_32 sectNum,pe_object_ptr objectTable, pe_header_ptr pehead)
BeginDeclarations
bit_32 i,j,k;
pe_section_ptr sect;
bit_32 nameLen;
bit_32 numNames=0;
bit_32 RVAStart;
bit_32 nameRVAStart;
bit_32 ordinalStart;
bit_32 nameSpaceStart;
bit_32 minOrd;
bit_32 maxOrd;
bit_32 numOrds;
pe_object_ptr lastObjectTable ;
public_entry_ptr pub ;
bit_32_ptr ordinals ;
bit_16_ptr ordinals2 ;
bit_32_ptr rvas ;
export_header_ptr exportHeader ;
byte_ptr nm,nm1,nm2 ;
public_entry_ptr_array nameList ;
#define PEHead (*pehead)
#define Sect (*sect)
#define ObjectTable (*objectTable)
#define Pub (*pub)
#define LastObjectTable (*lastObjectTable)
#define ExportHeader (*exportHeader)
EndDeclarations
BeginCode
ReturnIf (Not n_exports OrIf sectNum < 0) ;
sect=outList[sectNum];
lastObjectTable = objectTable + sectNum - 1;
objectTable = lastObjectTable + 1;
nm = exe_file_list.first->filename ;
nm1 = strrchr(nm,'\\') ;
If nm1 IsNotNull
Then
nm = nm1 + 1;
Else
nm1 = strrchr(nm,':');
If nm1 IsNotNull
Then
nm = nm1 + 1;
EndIf ;
EndIf ;
nameLen = strlen(nm) ;
Sect.initlength = Sect.length=sizeof(export_header_type)+nameLen+1;
/* min section size= header size + num exports * pointer size */
/* plus space for null-terminated name */
minOrd=0xffffffff; /* max ordinal num */
maxOrd=0;
numOrds=n_exports ;
For i=0; i < n_exports; i++
BeginFor
pub = exports[i] ;
If Length(Pub.entryident) IsNotZero
Then
Sect.initlength = Sect.length += Length(Pub.entryident) + 1 + 6;
numNames++ ;
EndIf ;
If Pub.ordinal IsNotEqualTo 0xffffffff
Then
If Pub.ordinal LessThan minOrd
Then
minOrd = Pub.ordinal ;
EndIf ;
If Pub.ordinal GreaterThan maxOrd
Then
maxOrd = Pub.ordinal ;
EndIf ;
EndIf ;
EndFor ;
If maxOrd GreaterThanOrEqualTo minOrd
Then
numOrds = (maxOrd-minOrd + 1) ;
Else
minOrd = 0 ;
EndIf ;
Sect.initlength = Sect.length += 4* numOrds ;
exportHeader = (export_header_ptr) (Sect.data= allocate_memory(Sect.length)) ;
k=Sect.length+objectAlign.val-1;
k&=(0xffffffff-(objectAlign.val-1));
Sect.virtualSize = ObjectTable.virtual_size = k;
ObjectTable.raw_size = Sect.length ;
k = LastObjectTable.raw_size + LastObjectTable.raw_ptr + fileAlign.val - 1;
k&=(0xffffffff-(fileAlign.val-1)); /* aligned */
ObjectTable.raw_ptr = k ;
k = ObjectTable.virtual_addr = LastObjectTable.virtual_addr + LastObjectTable.virtual_size ;
Sect.base=k+imageBase.val; /* relocate section */
memset(Sect.data,0,Sect.length) ;
ExportHeader.time = time(0) ;
ExportHeader.ord_base = minOrd ;
ExportHeader.n_eat_entries = numOrds ;
ExportHeader.n_name_ptrs = numNames ;
RVAStart=sizeof(export_header_type); /* start address of RVA table */
nameRVAStart=RVAStart+numOrds*4; /* start of name table entries */
ordinalStart=nameRVAStart+numNames*4; /* start of associated ordinal entries */
nameSpaceStart=ordinalStart+numNames*2; /* start of actual names */
ExportHeader.address_rva = RVAStart + Sect.base - imageBase.val ;
ExportHeader.name_rva = nameRVAStart + Sect.base - imageBase.val ;
ExportHeader.ordinal_rva = ordinalStart + Sect.base - imageBase.val ;
If numNames
Then
/* sort */
nameList = (public_entry_ptr_array)allocate_memory(numNames * sizeof (public_entry_ptr));
j=0; /* no entries yet */
For i=0; i < n_exports; i++
BeginFor
pub = exports[i] ;
If Length(Pub.entryident)
Then ;
nameList[j++] = pub ;
EndIf ;
EndFor ;
qsort(nameList,numNames,sizeof(nameList[0]),expfunc);
EndIf
/* process numbered exports */
rvas = (bit_32_ptr)(Sect.data + RVAStart) ;
For i=0; i LessThan n_exports; i++
BeginFor
pub = exports[i] ;
If Pub.ordinal IsNotEqualTo 0xffffffff
Then
k = rvas[Pub.ordinal - minOrd] ;
If k IsNotZero
Then
linker_error(4,"Export error:\n"
"\tExport: \"%s\"\n"
"\t Ord: %08lx\n"
"\t Error: Ordinal already assigned to \n"
"\t another export\n",
String(Pub.entryident),
Pub.ordinal);
Else
If Pub.Internal.lseg IsNull
Then
k = (Bit_32(Pub.Internal.frame) ShiftedLeft 4);
Else
k = (*Pub.Internal.lseg).address;
EndIf;
k = k + Pub.Internal.offset ;
rvas[Pub.ordinal - minOrd] = k -imageBase.val;
EndIf ;
EndIf ;
EndFor ;
/* process non-numbered exports */
For i=0,j=0; i < n_exports; i++
BeginFor
pub = exports[i] ;
If Pub.ordinal IsEqualTo 0xffffffff
Then
While rvas[j]
BeginWhile
j++ ;
EndWhile ;
Pub.ordinal = j + minOrd ;
If Pub.Internal.lseg IsNull
Then
k = (Bit_32(Pub.Internal.frame) ShiftedLeft 4);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -