📄 coffimpl.c
字号:
{
AddDataImpLib( coff_file_hnd, c_file->symbol, c_file->header.num_symbols * COFF_SYM_SIZE );
}
static void CreateCoffReloc( coff_file_handle coff_file_hnd, unsigned_32 offset, unsigned_32 sym_tab_index, unsigned_16 type )
{
//output is buffered so no point in putting COFF_RELOC struct
AddDataImpLib( coff_file_hnd, &offset, sizeof( offset ) );
AddDataImpLib( coff_file_hnd, &sym_tab_index, sizeof( sym_tab_index ) );
AddDataImpLib( coff_file_hnd, &type, sizeof( type ) );
}
static void CreateCoffStringTable( coff_file_handle coff_file_hnd, coff_lib_file *c_file )
{
c_file->string_table_size += 4;
AddDataImpLib( coff_file_hnd, &( c_file->string_table_size ), 4 );
AddDataImpLib( coff_file_hnd, c_file->string_table, c_file->string_table_size - 4 );
}
char * getImportName(char * src, int type){
char *end;
/*
I got following information from Microsoft about name type and name conversion.
IMPORT_OBJECT_ORDINAL = 0, // Import by ordinal
IMPORT_OBJECT_NAME = 1, // Import name == public symbol name.
IMPORT_OBJECT_NAME_NO_PREFIX = 2, // Import name == public symbol name skipping leading ?, @, or optionally _.
IMPORT_OBJECT_NAME_UNDECORATE = 3, // Import name == public symbol name skipping leading ?, @, or optionally _
// and truncating at first @
*/
// Note:
// IMPORT_OBJECT_NAME_NO_PREFIX is used for C symbols with underscore as prefix
// IMPORT_OBJECT_NAME_UNDECORATE is used for __stdcall and __fastcall name mangling
// __stdcall uses underscore as prefix and @nn as suffix
// __fastcall uses @ as prefix and @nn as suffix
// this solution is stupid, probably it needs improvement
// there is no more information from Microsoft
if( *src != 0 ) {
switch (type) {
case IMPORT_OBJECT_ORDINAL:
case IMPORT_OBJECT_NAME:
break;
case IMPORT_OBJECT_NAME_UNDECORATE:
// remove suffix @nn or @ if any
end = src + strlen( src );
while( end != src ) {
--end;
if( *end < '0' || *end > '9' ) {
if( *end == '@' ) {
*end = 0;
}
break;
}
}
// fall through
case IMPORT_OBJECT_NAME_NO_PREFIX:
// remove prefix @ or _ if any
if(( *src == '@' ) || ( *src == '_' ))
src++;
break;
}
}
return( src );
}
static int CoffCreateImport( coff_file_handle coff_file_hnd, import_sym * import )
{
unsigned_16 type;
coff_lib_file c_file;
unsigned_16 ordinal;
char * buffer;
union {
char b32[4];
char b64[8];
} bnull;
unsigned symbol_name_len;
int symbol_text_exportedName;
int symbol___imp_exportedName;
int symbol_idata6 = 0;
int symbol_toc = 0;
char * DLLSymbolName;
int dllsymbol_name_len;
int section_no;
InitCoffFile( &c_file );
memset( bnull.b64, 0, sizeof(bnull.b64) );
symbol_name_len = strlen(import->exportedName);
DLLSymbolName = alloca(symbol_name_len + 1 );
strcpy(DLLSymbolName, import->exportedName);
DLLSymbolName = getImportName(DLLSymbolName, import->type);
dllsymbol_name_len = strlen(DLLSymbolName);
buffer = alloca(max( strlen(import->DLLName), symbol_name_len) + 64 );
SetCoffFile( &c_file, import->processor, import->time_date_stamp, 0 );
switch( import->processor ) {
case IMAGE_FILE_MACHINE_ALPHA:
/* .text section header */
section_no = AddCoffSection( &c_file, ".text", sizeof(CoffImportAxpText), 3, IMAGE_SCN_ALIGN_16BYTES | IMAGE_SCN_LNK_COMDAT | IMAGE_SCN_CNT_CODE | IMAGE_SCN_MEM_READ | IMAGE_SCN_MEM_EXECUTE );
AddCoffSymSec( &c_file, IMAGE_COMDAT_SELECT_NODUPLICATES, section_no );
symbol_text_exportedName = AddCoffSymbol( &c_file, import->exportedName, 0x0, section_no, 0x20, IMAGE_SYM_CLASS_EXTERNAL, 0 );
break;
case IMAGE_FILE_MACHINE_POWERPC:
/* .text section header */
section_no = AddCoffSection( &c_file, ".text", sizeof(CoffImportPpcText), 1, IMAGE_SCN_ALIGN_4BYTES | IMAGE_SCN_LNK_COMDAT | IMAGE_SCN_CNT_CODE | IMAGE_SCN_MEM_READ | IMAGE_SCN_MEM_EXECUTE );
AddCoffSymSec( &c_file, IMAGE_COMDAT_SELECT_NODUPLICATES, section_no );
strcpy( buffer, ".." );
strcpy( buffer + 2, import->exportedName );
symbol_text_exportedName = AddCoffSymbol( &c_file, buffer, 0x0, section_no, 0x20, IMAGE_SYM_CLASS_EXTERNAL, 0 );
/* .pdata section header */
section_no = AddCoffSection( &c_file, ".pdata", sizeof(CoffImportPpcPdata), 4, IMAGE_SCN_ALIGN_1BYTES | IMAGE_SCN_LNK_COMDAT | IMAGE_SCN_CNT_INITIALIZED_DATA | IMAGE_SCN_MEM_READ );
AddCoffSymSec( &c_file, IMAGE_COMDAT_SELECT_ASSOCIATIVE, section_no );
/* .reldata section header */
section_no = AddCoffSection( &c_file, ".reldata", sizeof(bnull.b64), 2, IMAGE_SCN_ALIGN_8BYTES | IMAGE_SCN_LNK_COMDAT | IMAGE_SCN_CNT_INITIALIZED_DATA | IMAGE_SCN_MEM_READ | IMAGE_SCN_MEM_WRITE );
if( import->type != IMPORT_OBJECT_ORDINAL) {
AddCoffSymSec( &c_file, IMAGE_COMDAT_SELECT_NODUPLICATES, section_no );
}
AddCoffSymbol( &c_file, import->exportedName, 0x0, section_no, IMAGE_SYM_TYPE_NULL, IMAGE_SYM_CLASS_EXTERNAL, 0 );
break;
default:
import->processor = IMAGE_FILE_MACHINE_I386;
case IMAGE_FILE_MACHINE_I386:
/* .text section header */
section_no = AddCoffSection( &c_file, ".text", sizeof(CoffImportX86Text), 1, IMAGE_SCN_ALIGN_2BYTES | IMAGE_SCN_LNK_COMDAT | IMAGE_SCN_CNT_CODE | IMAGE_SCN_MEM_READ | IMAGE_SCN_MEM_EXECUTE );
AddCoffSymSec( &c_file, IMAGE_COMDAT_SELECT_NODUPLICATES, section_no );
symbol_text_exportedName = AddCoffSymbol( &c_file, import->exportedName, 0x0, section_no, 0x20, IMAGE_SYM_CLASS_EXTERNAL, 0 );
break;
}
/* .idata$5 section header */
if( import->type == IMPORT_OBJECT_ORDINAL) {
section_no = AddCoffSection( &c_file, ".idata$5", sizeof(bnull.b32), 0, IMAGE_SCN_ALIGN_4BYTES | IMAGE_SCN_LNK_COMDAT | IMAGE_SCN_CNT_INITIALIZED_DATA | IMAGE_SCN_MEM_READ | IMAGE_SCN_MEM_WRITE );
} else {
section_no = AddCoffSection( &c_file, ".idata$5", sizeof(bnull.b32), 1, IMAGE_SCN_ALIGN_4BYTES | IMAGE_SCN_LNK_COMDAT | IMAGE_SCN_CNT_INITIALIZED_DATA | IMAGE_SCN_MEM_READ | IMAGE_SCN_MEM_WRITE );
}
AddCoffSymSec( &c_file, IMAGE_COMDAT_SELECT_NODUPLICATES, section_no );
strcpy( buffer, "__imp_" );
strcat( buffer, import->exportedName );
symbol___imp_exportedName = AddCoffSymbol( &c_file, buffer, 0x0, section_no, IMAGE_SYM_TYPE_NULL, IMAGE_SYM_CLASS_EXTERNAL, 0 );
/* .idata$4 section header */
if( import->type == IMPORT_OBJECT_ORDINAL) {
section_no = AddCoffSection( &c_file, ".idata$4", sizeof(bnull.b32), 0, IMAGE_SCN_ALIGN_4BYTES | IMAGE_SCN_LNK_COMDAT | IMAGE_SCN_CNT_INITIALIZED_DATA | IMAGE_SCN_MEM_READ | IMAGE_SCN_MEM_WRITE );
AddCoffSymSec( &c_file, IMAGE_COMDAT_SELECT_ASSOCIATIVE, section_no );
} else {
section_no = AddCoffSection( &c_file, ".idata$4", sizeof(bnull.b32), 1, IMAGE_SCN_ALIGN_4BYTES | IMAGE_SCN_LNK_COMDAT | IMAGE_SCN_CNT_INITIALIZED_DATA | IMAGE_SCN_MEM_READ | IMAGE_SCN_MEM_WRITE );
AddCoffSymSec( &c_file, IMAGE_COMDAT_SELECT_ASSOCIATIVE, section_no );
/* .idata$6 section header */
section_no = AddCoffSection( &c_file, ".idata$6", sizeof(ordinal) + ( dllsymbol_name_len | 1 ) + 1, 0, IMAGE_SCN_ALIGN_2BYTES | IMAGE_SCN_LNK_COMDAT | IMAGE_SCN_CNT_INITIALIZED_DATA | IMAGE_SCN_MEM_READ | IMAGE_SCN_MEM_WRITE );
symbol_idata6 = AddCoffSymSec( &c_file, IMAGE_COMDAT_SELECT_ASSOCIATIVE, section_no );
}
/* other symbols */
if( import->processor == IMAGE_FILE_MACHINE_POWERPC ) {
symbol_toc = AddCoffSymbol( &c_file, ".toc", 0x0, 0, IMAGE_SYM_TYPE_NULL, IMAGE_SYM_CLASS_EXTERNAL, 0 );
}
strcpy( buffer, "__IMPORT_DESCRIPTOR_" );
strcat( buffer, import->DLLName );
AddCoffSymbol( &c_file, buffer, 0x0, 0, IMAGE_SYM_TYPE_NULL, IMAGE_SYM_CLASS_EXTERNAL, 0 );
/* COFF file header */
CreateCoffFileHeader( coff_file_hnd, &c_file );
/* COFF sections header */
CreateCoffSections( coff_file_hnd, &c_file );
/* COFF section data */
switch( import->processor ) {
case IMAGE_FILE_MACHINE_ALPHA:
/* .text section data */
AddDataImpLib( coff_file_hnd, CoffImportAxpText, sizeof(CoffImportAxpText) );
/* .text relocations records */
CreateCoffReloc( coff_file_hnd, 0x0, symbol___imp_exportedName, IMAGE_REL_ALPHA_REFHI );
CreateCoffReloc( coff_file_hnd, 0x0, symbol_text_exportedName, IMAGE_REL_ALPHA_PAIR );
CreateCoffReloc( coff_file_hnd, 0x4, symbol___imp_exportedName, IMAGE_REL_ALPHA_REFLO );
break;
case IMAGE_FILE_MACHINE_POWERPC:
/* .text section data */
AddDataImpLib( coff_file_hnd, CoffImportPpcText, sizeof(CoffImportPpcText) );
/* .text relocations records */
CreateCoffReloc( coff_file_hnd, 0x0, symbol___imp_exportedName, IMAGE_REL_PPC_TOCREL14 | IMAGE_REL_PPC_TOCDEFN );
/* .pdata section data */
AddDataImpLib( coff_file_hnd, CoffImportPpcPdata, sizeof(CoffImportPpcPdata) );
/* .pdata relocations records */
CreateCoffReloc( coff_file_hnd, 0x0, symbol_text_exportedName, IMAGE_REL_PPC_ADDR32 );
CreateCoffReloc( coff_file_hnd, 0x4, symbol_text_exportedName, IMAGE_REL_PPC_ADDR32 );
CreateCoffReloc( coff_file_hnd, 0x10, symbol_text_exportedName, IMAGE_REL_PPC_ADDR32 );
CreateCoffReloc( coff_file_hnd, 0x80410004, symbol_text_exportedName, IMAGE_REL_PPC_SECTION );
/* .reldata section data */
AddDataImpLib( coff_file_hnd, bnull.b64, sizeof(bnull.b64) );
/* .reldata relocations records */
CreateCoffReloc( coff_file_hnd, 0x0, symbol_text_exportedName, IMAGE_REL_PPC_ADDR32 );
CreateCoffReloc( coff_file_hnd, 0x4, symbol_toc, IMAGE_REL_PPC_ADDR32 );
break;
case IMAGE_FILE_MACHINE_I386:
/* .text section data */
AddDataImpLib( coff_file_hnd, CoffImportX86Text, sizeof(CoffImportX86Text) );
/* .text relocations records */
CreateCoffReloc( coff_file_hnd, 0x2, symbol___imp_exportedName, IMAGE_REL_I386_DIR32 );
break;
}
ordinal = import->ordinal;
if( import->type == IMPORT_OBJECT_ORDINAL) {
/* .idata$5 section data - ordinal */
AddDataImpLib( coff_file_hnd, &ordinal, sizeof(ordinal) );
type = 0x8000;
AddDataImpLib( coff_file_hnd, &type, sizeof(type) );
/* .idata$4 section data - ordinal */
AddDataImpLib( coff_file_hnd, &ordinal, sizeof(ordinal) );
AddDataImpLib( coff_file_hnd, &type, sizeof(type) );
} else {
switch( import->processor ) {
case IMAGE_FILE_MACHINE_ALPHA:
type = IMAGE_REL_ALPHA_REFLONGNB;
case IMAGE_FILE_MACHINE_POWERPC:
type = IMAGE_REL_PPC_ADDR32NB;
case IMAGE_FILE_MACHINE_I386:
type = IMAGE_REL_I386_DIR32NB;
}
/* .idata$5 section data - name */
AddDataImpLib( coff_file_hnd, bnull.b32, sizeof(bnull.b32) );
/* .idata$5 relocations records */
CreateCoffReloc( coff_file_hnd, 0, symbol_idata6, type );
/* .idata$4 section data - name */
AddDataImpLib( coff_file_hnd, bnull.b32, sizeof(bnull.b32) );
/* .idata$4 relocations records */
CreateCoffReloc( coff_file_hnd, 0, symbol_idata6, type );
/* .idata$6 section data - name */
AddDataImpLib( coff_file_hnd, &ordinal, sizeof( ordinal ) );
AddDataImpLib( coff_file_hnd, DLLSymbolName, dllsymbol_name_len + 1 );
if( !( dllsymbol_name_len & 1 ) ) {
AddDataImpLib( coff_file_hnd, "\0", 1 );
}
}
/* COFF symbol table */
CreateCoffSymbols( coff_file_hnd, &c_file );
/* COFF strings table */
CreateCoffStringTable( coff_file_hnd, &c_file );
FiniCoffLibFile( &c_file );
return ORL_OKAY;
}
int convert_import_library(coff_file_handle coff_file_hnd)
{
coff_import_object_header * i_hdr;
import_sym sym;
// init import library data structure
if ( AddDataImpLib( coff_file_hnd, &sym, 0 ) != ORL_OKAY )
return ORL_OUT_OF_MEMORY;
i_hdr = (coff_import_object_header*)coff_file_hnd->f_hdr_buffer;
sym.processor = i_hdr->machine;
sym.exportedName = coff_file_hnd->coff_hnd->funcs->read( coff_file_hnd->file,
i_hdr->size_of_data );
sym.DLLName = sym.exportedName + strlen(sym.exportedName) + 1;
sym.time_date_stamp = i_hdr->time_date_stamp;
sym.type = i_hdr->name_type;
sym.ordinal = i_hdr->ordinal;
return CoffCreateImport( coff_file_hnd, &sym);
}
#pragma pack ( pop )
orl_funcs ImportLibData = {ImportLibRead, ImportLibSeek, NULL, NULL};
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -