Subversion Repositories Kolibri OS

Compare Revisions

Regard whitespace Rev 8947 → Rev 8948

/programs/develop/clink/epep/epep.h
12,6 → 12,7
#define EPEP_READER FILE *
#define EPEP_READER_GET(preader) getc(*preader)
#define EPEP_READER_SEEK(preader, offset) fseek(*preader, offset, SEEK_SET)
#define EPEP_READER_SEEK_END(preader, offset) fseek(*preader, offset, SEEK_END)
#define EPEP_READER_TELL(preader) ftell(*preader)
#define EPEP_READER_GET_BLOCK(preader, size, buf) fread(buf, 1, size, *preader);
#endif
39,6 → 40,27
EPEP_ERR_EXPORT_ADDRESS_TABLE_ENTRY_NAME_NOT_FOUND,
EPEP_ERR_NO_BASE_RELOCATION_TABLE,
EPEP_ERR_BASE_RELOCATION_IS_ALREADY_END,
EPEP_ERR_INVALID_DATA_DIRECTORY_OFFSET,
EPEP_ERR_INVALID_SECTION_HEADER_OFFSET,
EPEP_ERR_INVALID_SECTION_DATA_OFFSET,
EPEP_ERR_INVALID_STRING_TABLE_SIZE_OFFSET,
EPEP_ERR_INVALID_SYMBOL_OFFSET,
EPEP_ERR_INVALID_IMPORT_DIRECTORY_OFFSET,
EPEP_ERR_INVALID_IMPORT_DIRECTORY_NAME_OFFSET,
EPEP_ERR_INVALID_LOOKUP_OFFSET,
EPEP_ERR_INVALID_LOOKUP_NAME_OFFSET,
EPEP_ERR_INVALID_EXPORT_TABLE_OFFSET,
EPEP_ERR_INVALID_DLL_NAME_OFFSET,
EPEP_ERR_INVALID_EXPORT_NAME_POINTER_OFFSET,
EPEP_ERR_INVALID_ORDINAL_TABLE_OFFSET,
EPEP_ERR_INVALID_EXPORT_NAME_OFFSET,
EPEP_ERR_INVALID_EXPORT_ADDRESS_OFFSET,
EPEP_ERR_INVALID_FORWARDER_OFFSET,
EPEP_ERR_INVALID_BASE_RELOCATION_BLOCK_OFFSET,
EPEP_ERR_INVALID_NEXT_BASE_RELOCATION_BLOCK_OFFSET,
EPEP_ERR_INVALID_BASE_RELOCATION_BLOCK_BASE_RELOCATION_OFFSET,
EPEP_ERR_INVALID_SECTION_RELOCATION_OFFSET,
EPEP_ERR_INVALID_LINENUMBER_OFFSET,
} EpepError;
 
//
49,6 → 71,7
EPEP_READER reader;
EpepKind kind;
EpepError error_code;
size_t file_size;
size_t signature_offset_offset;
size_t signature_offset;
size_t first_data_directory_offset;
364,6 → 387,11
return 1;
}
 
static int epep_seek_end(Epep *epep, size_t offset) {
EPEP_READER_SEEK_END(&epep->reader, offset);
return 1;
}
 
static int epep_read_block(Epep *epep, size_t size, void *block) {
EPEP_READER_GET_BLOCK(&epep->reader, size, block);
return 1;
407,6 → 435,10
return is_pe32(epep) ? epep_read_u32(epep) : epep_read_u64(epep);
}
 
static int epep_valid_offset(Epep *epep, size_t offset, size_t size) {
return (offset + size) <= epep->file_size;
}
 
//
// Generic
//
415,14 → 447,13
*epep = (Epep){ 0 };
epep->kind = EPEP_IMAGE;
epep->reader = reader;
epep_seek_end(epep, 0);
epep->file_size = EPEP_READER_TELL(&epep->reader);
epep_seek(epep, 0);
epep->error_code = EPEP_ERR_SUCCESS;
epep->signature_offset_offset = 0x3c;
epep_seek(epep, epep->signature_offset_offset);
epep->signature_offset = 0;
epep->signature_offset |= epep_read_u8(epep);
epep->signature_offset |= epep_read_u8(epep) << 8;
epep->signature_offset |= epep_read_u8(epep) << 16;
epep->signature_offset |= epep_read_u8(epep) << 24;
epep->signature_offset = epep_read_u32(epep);
epep_seek(epep, epep->signature_offset);
char signature_buf[4];
signature_buf[0] = epep_read_u8(epep);
508,7 → 539,12
epep->error_code = EPEP_ERR_DATA_DIRECTORY_INDEX_IS_INVALID;
return 0;
}
epep_seek(epep, epep->first_data_directory_offset + sizeof(EpepImageDataDirectory) * index);
size_t offset = epep->first_data_directory_offset + sizeof(EpepImageDataDirectory) * index;
if (!epep_valid_offset(epep, offset, sizeof(EpepImageDataDirectory))) {
epep->error_code = EPEP_ERR_INVALID_DATA_DIRECTORY_OFFSET;
return 0;
}
epep_seek(epep, offset);
idd->VirtualAddress = epep_read_u32(epep);
idd->Size = epep_read_u32(epep);
return 1;
523,7 → 559,12
epep->error_code = EPEP_ERR_SECTION_HEADER_INDEX_IS_INVALID;
return 0;
}
epep_seek(epep, epep->first_section_header_offset + sizeof(EpepSectionHeader) * index);
size_t offset = epep->first_section_header_offset + sizeof(EpepSectionHeader) * index;
if (!epep_valid_offset(epep, offset, sizeof(EpepSectionHeader))) {
epep->error_code = EPEP_ERR_INVALID_SECTION_HEADER_OFFSET;
return 0;
}
epep_seek(epep, offset);
for (int i = 0; i < 8; i++) {
sh->Name[i] = epep_read_u8(epep);
}
553,8 → 594,13
}
 
int epep_get_section_contents(Epep *epep, EpepSectionHeader *sh, void *buf) {
size_t offset = sh->PointerToRawData;
size_t size_of_raw_data = sh->SizeOfRawData;
epep_seek(epep, sh->PointerToRawData);
if (!epep_valid_offset(epep, offset, size_of_raw_data)) {
epep->error_code = EPEP_ERR_INVALID_SECTION_DATA_OFFSET;
return 0;
}
epep_seek(epep, offset);
epep_read_block(epep, size_of_raw_data, buf);
return 1;
}
564,7 → 610,12
//
 
int epep_get_string_table_size(Epep *epep, size_t *size) {
epep_seek(epep, epep->coffFileHeader.PointerToSymbolTable + 18 * epep->coffFileHeader.NumberOfSymbols);
size_t offset = epep->coffFileHeader.PointerToSymbolTable + 18 * epep->coffFileHeader.NumberOfSymbols;
if (!epep_valid_offset(epep, offset, sizeof(uint32_t))) {
epep->error_code = EPEP_ERR_INVALID_STRING_TABLE_SIZE_OFFSET;
return 0;
}
epep_seek(epep, offset);
*size = epep_read_u32(epep);
return 1;
}
592,7 → 643,12
epep->error_code = EPEP_ERR_SYMBOL_INDEX_IS_INVALID;
return 0;
}
epep_seek(epep, epep->coffFileHeader.PointerToSymbolTable + 18 * index);
size_t offset = epep->coffFileHeader.PointerToSymbolTable + 18 * index;
if (!epep_valid_offset(epep, offset, 18)) {
epep->error_code = EPEP_ERR_INVALID_SYMBOL_OFFSET;
return 0;
}
epep_seek(epep, offset);
for (size_t i = 0; i < 18; i++) {
sym->auxFile.FileName[i] = epep_read_u8(epep);
}
631,7 → 687,12
return 0;
}
}
epep_seek(epep, epep->import_table_offset + index * sizeof(*import_directory));
size_t offset = epep->import_table_offset + index * sizeof(*import_directory);
if (!epep_valid_offset(epep, offset, sizeof(*import_directory))) {
epep->error_code = EPEP_ERR_INVALID_IMPORT_DIRECTORY_OFFSET;
return 0;
}
epep_seek(epep, offset);
epep_read_block(epep, sizeof(*import_directory), import_directory);
return 1;
}
642,6 → 703,10
if (!epep_get_file_offset_by_rva(epep, &name_offset, name_rva)) {
return 0;
}
if (!epep_valid_offset(epep, name_offset, 0)) {
epep->error_code = EPEP_ERR_INVALID_IMPORT_DIRECTORY_NAME_OFFSET;
return 0;
}
epep_seek(epep, name_offset);
epep_read_block(epep, name_max, name);
return 1;
654,6 → 719,10
}
size_t size_of_lookup = is_pe32(epep) ? 4 : 8;
size_t lookup_offset = first_lookup_offset + size_of_lookup * index;
if (!epep_valid_offset(epep, lookup_offset, size_of_lookup)) {
epep->error_code = EPEP_ERR_INVALID_LOOKUP_OFFSET;
return 0;
}
epep_seek(epep, lookup_offset);
epep_read_block(epep, size_of_lookup, lookup);
return 1;
680,6 → 749,10
}
// skip 2 bytes (Name Table :: Hint)
name_offset += 2;
if (!epep_valid_offset(epep, name_offset, 0)) {
epep->error_code = EPEP_ERR_INVALID_LOOKUP_NAME_OFFSET;
return 0;
}
epep_seek(epep, name_offset);
epep_read_block(epep, name_max, name);
return 1;
717,6 → 790,10
return 0;
}
}
if (!epep_valid_offset(epep, epep->export_table_offset, sizeof(epep->export_directory))) {
epep->error_code = EPEP_ERR_INVALID_EXPORT_TABLE_OFFSET;
return 0;
}
epep_seek(epep, epep->export_table_offset);
epep_read_block(epep, sizeof(epep->export_directory), &epep->export_directory);
return 1;
727,6 → 804,10
if (!epep_get_file_offset_by_rva(epep, &offset, epep->export_directory.NameRva)) {
return 0;
}
if (!epep_valid_offset(epep, offset, 0)) {
epep->error_code = EPEP_ERR_INVALID_DLL_NAME_OFFSET;
return 0;
}
epep_seek(epep, offset);
epep_read_block(epep, name_max, name);
return 1;
738,7 → 819,12
if (!epep_get_file_offset_by_rva(epep, &name_pointer_table_offset, name_pointer_table_rva)) {
return 0;
}
epep_seek(epep, name_pointer_table_offset + sizeof(uint32_t) * index);
size_t offset = name_pointer_table_offset + sizeof(uint32_t) * index;
if (!epep_valid_offset(epep, offset, sizeof(uint32_t))) {
epep->error_code = EPEP_ERR_INVALID_EXPORT_NAME_POINTER_OFFSET;
return 0;
}
epep_seek(epep, offset);
*name_rva = epep_read_u32(epep);
return 1;
}
748,6 → 834,10
if (!epep_get_file_offset_by_rva(epep, &ordinal_table_offset, epep->export_directory.OrdinalTableRva)) {
return 0;
}
if (!epep_valid_offset(epep, ordinal_table_offset, 0)) {
epep->error_code = EPEP_ERR_INVALID_ORDINAL_TABLE_OFFSET;
return 0;
}
epep_seek(epep, ordinal_table_offset);
for (size_t i = 0; i < epep->export_directory.NumberOfNamePointers; i++) {
uint16_t ordinal = epep_read_u16(epep);
760,6 → 850,10
if (!epep_get_file_offset_by_rva(epep, &name_offset, name_rva)) {
return 0;
}
if (!epep_valid_offset(epep, name_offset, 0)) {
epep->error_code = EPEP_ERR_INVALID_EXPORT_NAME_OFFSET;
return 0;
}
epep_seek(epep, name_offset);
epep_read_block(epep, name_max, name);
return 1;
775,7 → 869,12
return 0;
}
EPEP_ASSERT(sizeof(EpepExportAddress) == sizeof(uint32_t));
epep_seek(epep, export_address_table_offset + sizeof(EpepExportAddress) * index);
size_t offset = export_address_table_offset + sizeof(EpepExportAddress) * index;
if (!epep_valid_offset(epep, offset, sizeof(*export_address))) {
epep->error_code = EPEP_ERR_INVALID_EXPORT_ADDRESS_OFFSET;
return 0;
}
epep_seek(epep, offset);
epep_read_block(epep, sizeof(*export_address), export_address);
return 1;
}
785,6 → 884,10
if (!epep_get_file_offset_by_rva(epep, &forwarder_offset, export_address->ForwarderRva)) {
return 0;
}
if (!epep_valid_offset(epep, forwarder_offset, 0)) {
epep->error_code = EPEP_ERR_INVALID_FORWARDER_OFFSET;
return 0;
}
epep_seek(epep, forwarder_offset);
epep_read_block(epep, forwarder_max, forwarder);
return 1;
838,6 → 941,10
epep->error_code = EPEP_ERR_NO_BASE_RELOCATION_TABLE;
return 0;
}
if (!epep_valid_offset(epep, epep->base_relocation_table_offset, 0)) {
epep->error_code = EPEP_ERR_INVALID_BASE_RELOCATION_BLOCK_OFFSET;
return 0;
}
if (!epep_seek(epep, epep->base_relocation_table_offset)) {
return 0;
}
857,6 → 964,10
*it = (EpepBaseRelocationBlock){ 0 };
return 1;
}
if (!epep_valid_offset(epep, it->offset, 0)) {
epep->error_code = EPEP_ERR_INVALID_NEXT_BASE_RELOCATION_BLOCK_OFFSET;
return 0;
}
if (!epep_seek(epep, it->offset)) {
return 0;
}
866,9 → 977,14
}
 
int epep_get_base_relocation_block_base_relocation_by_index(Epep *epep, EpepBaseRelocationBlock *brb, EpepBaseRelocation *br, size_t index) {
if (!epep_seek(epep, brb->offset + 8 + sizeof(EpepBaseRelocation) * index)) {
size_t offset = brb->offset + 8 + sizeof(EpepBaseRelocation) * index;
if (!epep_valid_offset(epep, offset, sizeof(EpepBaseRelocation))) {
epep->error_code = EPEP_ERR_INVALID_BASE_RELOCATION_BLOCK_BASE_RELOCATION_OFFSET;
return 0;
}
if (!epep_seek(epep, offset)) {
return 0;
}
br->u16 = epep_read_u16(epep);
return 1;
}
878,8 → 994,12
//
 
int epep_get_section_relocation_by_index(Epep *epep, EpepSectionHeader *sh, EpepCoffRelocation *rel, size_t index) {
size_t relocationsOffset = sh->PointerToRelocations;
epep_seek(epep, relocationsOffset + 10 * index);
size_t offset = sh->PointerToRelocations + 10 * index;
if (!epep_valid_offset(epep, offset, 10)) {
epep->error_code = EPEP_ERR_INVALID_SECTION_RELOCATION_OFFSET;
return 0;
}
epep_seek(epep, offset);
epep_read_block(epep, 10, rel);
return 1;
}
889,8 → 1009,12
//
 
int epep_get_section_line_number_by_index(Epep *epep, EpepSectionHeader *sh, EpepCoffLinenumber *ln, size_t index) {
size_t LinenumbersOffset = sh->PointerToLinenumbers;
epep_seek(epep, LinenumbersOffset + 6 * index);
size_t offset = sh->PointerToLinenumbers + 6 * index;
if (!epep_valid_offset(epep, offset, 6)) {
epep->error_code = EPEP_ERR_INVALID_LINENUMBER_OFFSET;
return 0;
}
epep_seek(epep, offset);
epep_read_block(epep, 6, ln);
return 1;
}
/programs/develop/clink/main.c
1,6 → 1,3
// TODO: Substract section's RVA from external and static defined symbol's value
// TODO: Substract section's RVA from relocations
 
#include <stdlib.h>
#include <stdio.h>
#include <stdint.h>
10,6 → 7,42
#define EPEP_INST
#include "epep/epep.h"
 
const char *epep_errors[] = {
"EPEP_ERR_SUCCESS",
"EPEP_ERR_DATA_DIRECTORY_INDEX_IS_INVALID",
"EPEP_ERR_SECTION_HEADER_INDEX_IS_INVALID",
"EPEP_ERR_SYMBOL_INDEX_IS_INVALID",
"EPEP_ERR_NOT_AN_OBJECT",
"EPEP_ERR_ADDRESS_IS_OUT_OF_SECTION_RAW_DATA",
"EPEP_ERR_OUTPUT_CAPACITY_IS_ZERO",
"EPEP_ERR_OUTPUT_IS_NULL",
"EPEP_ERR_ADDRESS_IS_OUT_OF_ANY_SECTION",
"EPEP_ERR_EXPORT_ADDRESS_TABLE_ENTRY_NAME_NOT_FOUND",
"EPEP_ERR_NO_BASE_RELOCATION_TABLE",
"EPEP_ERR_BASE_RELOCATION_IS_ALREADY_END",
"EPEP_ERR_INVALID_DATA_DIRECTORY_OFFSET",
"EPEP_ERR_INVALID_SECTION_HEADER_OFFSET",
"EPEP_ERR_INVALID_SECTION_DATA_OFFSET",
"EPEP_ERR_INVALID_STRING_TABLE_SIZE_OFFSET",
"EPEP_ERR_INVALID_SYMBOL_OFFSET",
"EPEP_ERR_INVALID_IMPORT_DIRECTORY_OFFSET",
"EPEP_ERR_INVALID_IMPORT_DIRECTORY_NAME_OFFSET",
"EPEP_ERR_INVALID_LOOKUP_OFFSET",
"EPEP_ERR_INVALID_LOOKUP_NAME_OFFSET",
"EPEP_ERR_INVALID_EXPORT_TABLE_OFFSET",
"EPEP_ERR_INVALID_DLL_NAME_OFFSET",
"EPEP_ERR_INVALID_EXPORT_NAME_POINTER_OFFSET",
"EPEP_ERR_INVALID_ORDINAL_TABLE_OFFSET",
"EPEP_ERR_INVALID_EXPORT_NAME_OFFSET",
"EPEP_ERR_INVALID_EXPORT_ADDRESS_OFFSET",
"EPEP_ERR_INVALID_FORWARDER_OFFSET",
"EPEP_ERR_INVALID_BASE_RELOCATION_BLOCK_OFFSET",
"EPEP_ERR_INVALID_NEXT_BASE_RELOCATION_BLOCK_OFFSET",
"EPEP_ERR_INVALID_BASE_RELOCATION_BLOCK_BASE_RELOCATION_OFFSET",
"EPEP_ERR_INVALID_SECTION_RELOCATION_OFFSET",
"EPEP_ERR_INVALID_LINENUMBER_OFFSET",
};
 
typedef char *pchar;
 
typedef struct {
79,8 → 112,8
#define CVEC_TYPE EpepCoffSymbol
#include "cvec/cvec.h"
 
#define ERROR_EPEP(epep) printf("Error: epep returned %u at "__FILE__":%u", \
(epep)->error_code, __LINE__); exit(-1)
#define ERROR_EPEP(epep) printf("Error: epep returned %u (%s) at "__FILE__":%u", \
(epep)->error_code, epep_errors[(epep)->error_code], __LINE__); exit(-1)
 
#define ERROR_CDICT(cdict) printf("Error: cdict returned %u at "__FILE__":%u", \
(cdict)->error_code, __LINE__); exit(-1);