📄 pe.c
字号:
Else
k = (*Pub.Internal.lseg).address;
EndIf;
k = k + Pub.Internal.offset ;
rvas[j++] = k -imageBase.val;
EndIf
EndFor ;
If numNames
Then
nm1 = Sect.data + nameSpaceStart ;
ordinals = (bit_32_ptr)(Sect.data + nameRVAStart) ;
ordinals2 = (bit_16_ptr)(Sect.data + ordinalStart) ;
/* and store */
For i=0; i < numNames; i++
BeginFor
pub = nameList[i] ;
*(ordinals2)++ = Pub.ordinal ;
*(ordinals)++ = nm1 - Sect.data + Sect.base - imageBase.val ;
nm2 = String(Pub.entryident);
For j=0; j < Length(Pub.entryident); j++
BeginFor
*nm1++ =*nm2++ ;
EndFor ;
*nm1++ = 0;
EndFor
EndIf ;
If nameLen IsNotZero
Then
ExportHeader.exe_name_rva = nm1 - Sect.data + Sect.base - imageBase.val ;
For j=0; j < nameLen; j++
BeginFor
*nm1++ =toupper(*nm++) ;
EndFor ;
*nm1++ = 0 ;
EndIf ;
PEHead.export_rva = Sect.base - imageBase.val ;
PEHead.export_size = Sect.length;
EndCode ;
#undef ObjectTable
#undef Pub
#undef LastObjectTable
#undef ExportHeader
#undef Sect
#undef PEHead
/*+-------------------------------------------------------------------------+
| |
| CountResource |
| |
+-------------------------------------------------------------------------+*/
void CountResource(resource_data_ptr resource, bit_32_ptr dirs, bit_32_ptr entries, bit_32_ptr data_headers, bit_32_ptr datasize, bit_32_ptr name_size, bit_32 typeorhead)
BeginDeclarations
resource_data_ptr res ;
#define Resource (*resource)
EndDeclarations
BeginCode
If typeorhead OrIf (Resource.name_count + Resource.ident_count) IsNotZero
Then
(*dirs)++;
EndIf ;
*entries += Resource.name_count + Resource.ident_count ;
If Resource.length
Then
(*data_headers) ++ ;
(*datasize) += (Resource.length + 3) & 0xFFFFFFFC ;
EndIf ;
If Resource.name
Then
(*name_size) += wstrlen(Resource.name) * 2 + 2 ;
EndIf ;
TraverseList(Resource.name_list,res)
BeginTraverse
CountResource(res,dirs,entries,data_headers,datasize, name_size, resource IsEqualTo &resource_head) ;
EndTraverse ;
TraverseList(Resource.ident_list,res)
BeginTraverse
CountResource(res,dirs,entries,data_headers,datasize, name_size, resource IsEqualTo &resource_head) ;
EndTraverse ;
EndCode
#undef Resource
/*+-------------------------------------------------------------------------+
| |
| DumpResources |
| |
+-------------------------------------------------------------------------+*/
void DumpResources(byte_ptr data, resource_data_ptr resource, bit_32_ptr dir_start, bit_32_ptr data_header_start, bit_32_ptr name_start, bit_32_ptr data_start, bit_32 va)
BeginDeclarations
resource_data_ptr res ;
resource_dir_table_ptr dirhead ;
resource_dir_entry_ptr direntries ;
resource_data_entry_ptr datahead ;
bit_32 i;
#define DirHead (*dirhead)
#define DirEntries (*direntries)
#define Res (*res)
#define DataHead (*datahead)
#define Resource (*resource)
EndDeclarations
BeginCode
If Resource.name_count + Resource.ident_count IsNotZero
Then
dirhead = (resource_dir_table_ptr)(data + *dir_start) ;
direntries = (resource_dir_entry_ptr)(dirhead + 1) ;
*dir_start = (byte_ptr) (direntries + (Resource.name_count + Resource.ident_count)) - data;
DirHead.time = time(0) ;
DirHead.name_entry = Resource.name_count ;
DirHead.ident_entry = Resource.ident_count ;
TraverseList(Resource.name_list,res)
BeginTraverse
DirEntries.rva_or_id = *name_start + 0x80000000 ;
DirEntries.subdir_or_data = (bit_32)*dir_start ;
DirEntries.escape = 1 ; /* Subdir */
direntries++ ;
*(bit_16_ptr)(data + *name_start) = i = wstrlen(Res.name) ;
wstrcpy((bit_16_ptr)(data + *name_start + 2),Res.name) ;
*name_start += i*2+2 ;
DumpResources(data,res,dir_start, data_header_start, name_start, data_start,va) ;
EndTraverse
TraverseList(Resource.ident_list,res)
BeginTraverse
DirEntries.rva_or_id = Res.id ;
DirEntries.escape = (Res.name_count + Res.ident_count) ? 1 : 0 ;
If DirEntries.escape
Then
DirEntries.subdir_or_data = (bit_32)*dir_start;
Else
DirEntries.subdir_or_data = (bit_32)*data_header_start;
EndIf ;
direntries++ ;
DumpResources(data,res,dir_start, data_header_start, name_start, data_start,va) ;
EndTraverse
Else
If Resource.data IsNull
Then
If Resource.name_count
Then
res = Resource.name_list.first ;
Else
res = Resource.ident_list.first ;
EndIf ;
EndIf ;
datahead = (resource_data_entry_ptr)(data + *data_header_start) ;
*data_header_start += sizeof (resource_data_entry_type) ;
memcpy(data + *data_start, Resource.data, Resource.length) ;
DataHead.rva = *data_start + va ;
*data_start += (Resource.length + 3) & 0xfffffffc ;
DataHead.size = Resource.length ;
DataHead.codepage = 0;
DataHead.reserved = 0 ;
EndIf ;
EndCode
#undef DirHead
#undef DirEntries
#undef Res
#undef DataHead
#undef Resource
/*+-------------------------------------------------------------------------+
| |
| BuildPEResources |
| |
+-------------------------------------------------------------------------+*/
void BuildPEResources(int_32 sectNum,pe_object_ptr objectTable, pe_header_ptr pehead)
BeginDeclarations
bit_32 num_dirs = 1 ;
bit_32 num_dir_entries =0 ;
bit_32 num_data_headers =0 ;
bit_32 data_size = 0 ;
bit_32 name_size = 0 ;
bit_32 i,j,k ;
bit_32 dir_start = 0;
bit_32 data_start ;
bit_32 data_header_start ;
bit_32 name_start ;
bit_32 total_size ;
pe_object_ptr lastObjectTable ;
pe_section_ptr sect ;
#define ObjectTable (*objectTable)
#define LastObjectTable (*lastObjectTable)
#define Sect (*sect)
#define PEHead (*pehead)
EndDeclarations
BeginCode
ReturnIf(sectNum LessThan 0 OrIf Not n_resources) ;
CountResource(&resource_head,&num_dirs, &num_dir_entries, &num_data_headers, & data_size, &name_size, True) ;
data_header_start = num_dirs * sizeof(resource_dir_table_type) +
num_dir_entries * sizeof(resource_dir_entry_type) ;
name_start = data_header_start + num_data_headers * sizeof(resource_data_entry_type) ;
data_start = (name_start + name_size + 3) & 0xfffffffc;
total_size = (data_start + data_size + 3) & 0xfffffffc;
lastObjectTable = objectTable + sectNum - 1;
objectTable = lastObjectTable + 1 ;
k = LastObjectTable.raw_ptr + LastObjectTable.raw_size +fileAlign.val-1 ;
k&=(0xffffffff-(fileAlign.val-1)); /* aligned */
ObjectTable.raw_ptr = k ;
k = ObjectTable.virtual_addr = LastObjectTable.virtual_addr + LastObjectTable.virtual_size ;
sect = outList[sectNum] ;
Sect.length = Sect.initlength = total_size ;
Sect.data = allocate_memory(total_size) ;
Sect.base = k + imageBase.val ;
k=total_size + objectAlign.val - 1;
k&=(0xffffffff-(objectAlign.val-1));
Sect.virtualSize=ObjectTable.virtual_size = k;
ObjectTable.raw_size = total_size ;
DumpResources(Sect.data, &resource_head, &dir_start, &data_header_start, &name_start, &data_start, ObjectTable.virtual_addr) ;
PEHead.resource_rva = Sect.base - imageBase.val ;
PEHead.resource_size = Sect.length;
EndCode
#undef PEHead
#undef Sect
#undef ObjectTable
#undef LastObjecTable
/*+-------------------------------------------------------------------------+
| |
| BuildPEDebug |
| |
+-------------------------------------------------------------------------+*/
void BuildPEDebug(int_32 sectNum,pe_object_ptr objectTable, pe_header_ptr pehead)
BeginDeclarations
bit_32 k ;
bit_32 total_size ;
byte_ptr data ;
pe_object_ptr lastObjectTable ;
pe_section_ptr sect ;
#define ObjectTable (*objectTable)
#define LastObjectTable (*lastObjectTable)
#define Sect (*sect)
#define PEHead (*pehead)
EndDeclarations
BeginCode
// ReturnIf(sectNum LessThan 0) ;
ReturnIf (debug.val IsFalse) ;
create_codeview_data( &data, &total_size) ;
file_open_for_write(cv_file_list.first);
file_write(data+32, total_size-32) ;
file_close_for_write() ;
#ifdef XXXXX // Win2K doesn't support embedded debug info...
lastObjectTable = objectTable + sectNum - 1;
objectTable = lastObjectTable + 1 ;
k = LastObjectTable.raw_ptr + LastObjectTable.raw_size + fileAlign.val-1 ;
k&=(0xffffffff-(fileAlign.val-1)); /* aligned */
ObjectTable.raw_ptr = k ;
k = ObjectTable.virtual_addr = LastObjectTable.virtual_addr + LastObjectTable.virtual_size ;
sect = outList[sectNum] ;
Sect.length = Sect.initlength = total_size ;
Sect.data = data ;
Sect.base = k + imageBase.val ;
k=total_size + objectAlign.val - 1;
k&=(0xffffffff-(objectAlign.val-1));
Sect.virtualSize=ObjectTable.virtual_size = k;
ObjectTable.raw_size = total_size ;
PEHead.debug_rva = Sect.base - imageBase.val ;
PEHead.debug_size = Sect.length;
*(bit_32 *)(data + 16) = total_size - 32 ;
*(bit_32 *)(data + 20) = ObjectTable.virtual_addr + 0x20 ;
*(bit_32 *)(data + 24) = ObjectTable.raw_ptr + 0x20 ;
#endif
EndCode
/*+-------------------------------------------------------------------------+
| |
| load_stub |
| |
+-------------------------------------------------------------------------+*/
void load_stub(byte_ptr *pstubData,bit_32_ptr pstubSize)
BeginDeclarations
EXE_header_type headbuf;
byte_ptr headerdata;
bit_32 imageSize;
bit_32 headerSize;
bit_32 relocSize;
bit_32 relocStart;
int_32 i;
EndDeclarations
BeginCode
If stub_file_list.first IsNotNull
Then
file_open_for_read(stub_file_list.first) ;
file_read((byte_ptr)&headbuf,sizeof(headbuf)) ;
If headbuf.signature IsNotEqualTo 0x5a4d
Then
linker_error(4,"Invalid EXE Stub File:\n"
"\t File: \"%s\"\n"
"\tOffset: %08lx\n"
"\t Error: Invalid header\n",
stub_file_list.first->filename,0L) ;
file_close_for_read() ;
return ;
EndIf ;
/* get size of image */
imageSize=headbuf.image_length_MOD_512+(headbuf.image_length_DIV_512<<9);
If (imageSize Mod 512) IsNotZero
Then
imageSize-=512;
EndIf ;
headerSize=(headbuf.n_header_paragraphs)<<4;
relocSize= headbuf.n_relocation_items << 2;
imageSize-=headerSize;
/* allocate buffer for load image */
headerdata=allocate_memory(imageSize+0x40+((relocSize+15) And Not 15));
/* copy header */
memcpy(headerdata,(byte_ptr)&headbuf,sizeof(headbuf)) ;
relocStart=headbuf.offset_to_relocation_table ;
/* load relocs */
file_position(relocStart) ;
file_read(headerdata+0x40,relocSize) ;
/* paragraph align reloc size */
relocSize += 15;
relocSize &= Complement 15;
/* move to start of data */
file_position(headerSize) ;
/* new header is 4 paragraphs long + relocSize*/
headbuf.n_header_paragraphs = (headerSize = (relocSize + 0x40)) >> 4 ;
headbuf.offset_to_relocation_table = 0x40 ;
/* load data into correct position */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -