[OBJ2BIN]

- Rewrite large parts of the tool
- Support IMAGE_REL_I386_DIR32

svn path=/trunk/; revision=52217
This commit is contained in:
Timo Kreuzer 2011-06-13 19:23:51 +00:00
parent 1d9a93046a
commit 330b33ea0d

View file

@ -13,29 +13,43 @@ Usage(void)
static static
void void
RelocateImage( RelocateSection(
char *pData, char *pData,
unsigned int nSize, IMAGE_SECTION_HEADER *pSectionHeader,
PIMAGE_RELOCATION pReloc,
unsigned int cNumRelocs,
PIMAGE_SYMBOL pSymbols, PIMAGE_SYMBOL pSymbols,
unsigned int iOffset) unsigned int iOffset)
{ {
unsigned int i; unsigned int i, nOffset;
PIMAGE_RELOCATION pReloc;
char *pSection;
WORD *p16; WORD *p16;
DWORD *p32;
for (i = 0; i < cNumRelocs; i++) pSection = pData + pSectionHeader->PointerToRawData;
/* Calculate pointer to relocation table */
pReloc = (PIMAGE_RELOCATION)(pData + pSectionHeader->PointerToRelocations);
/* Loop all relocations */
for (i = 0; i < pSectionHeader->NumberOfRelocations; i++)
{ {
if (pReloc->VirtualAddress > nSize) continue; nOffset = pReloc->VirtualAddress - pSectionHeader->VirtualAddress;
if (nOffset > pSectionHeader->SizeOfRawData) continue;
switch (pReloc->Type) switch (pReloc->Type)
{ {
case IMAGE_REL_I386_ABSOLUTE: case IMAGE_REL_I386_ABSOLUTE:
case 16: case 16:
p16 = (void*)(pData + pReloc->VirtualAddress); p16 = (void*)(pSection + nOffset);
*p16 += (WORD)(pSymbols[pReloc->SymbolTableIndex].Value + iOffset); *p16 += (WORD)(pSymbols[pReloc->SymbolTableIndex].Value + iOffset);
break; break;
case IMAGE_REL_I386_DIR32:
p32 = (void*)(pSection + nOffset);
*p32 += (DWORD)(pSymbols[pReloc->SymbolTableIndex].Value + iOffset);
break;
default: default:
printf("Unknown relocatation type %ld address %ld\n", printf("Unknown relocatation type %ld address %ld\n",
pReloc->Type, pReloc->VirtualAddress); pReloc->Type, pReloc->VirtualAddress);
@ -49,13 +63,13 @@ int main(int argc, char *argv[])
{ {
char *pszSourceFile; char *pszSourceFile;
char *pszDestFile; char *pszDestFile;
unsigned long iOffset; unsigned long nFileSize, nBaseAddress, nOffsetSectionHeaders;
FILE *pSourceFile, *pDestFile; FILE *pSourceFile, *pDestFile;
IMAGE_FILE_HEADER FileHeader; IMAGE_FILE_HEADER *pFileHeader;
IMAGE_SECTION_HEADER SectionHeader; IMAGE_SECTION_HEADER *pSectionHeader;
unsigned int i; unsigned int i;
size_t nSize; size_t nSize;
void *pData; char *pData;
PIMAGE_RELOCATION pReloc; PIMAGE_RELOCATION pReloc;
PIMAGE_SYMBOL pSymbols; PIMAGE_SYMBOL pSymbols;
@ -67,144 +81,81 @@ int main(int argc, char *argv[])
pszSourceFile = argv[1]; pszSourceFile = argv[1];
pszDestFile = argv[2]; pszDestFile = argv[2];
nBaseAddress = strtol(argv[3], 0, 16);
pSourceFile = fopen(pszSourceFile, "rb"); pSourceFile = fopen(pszSourceFile, "rb");
if (!pSourceFile) if (!pSourceFile)
{ {
fprintf(stderr, "Couldn't open source file '%s'\n", pszSourceFile); fprintf(stderr, "Couldn't open source file '%s'\n", pszSourceFile);
return -1; return -2;
} }
/* Get file size */
fseek(pSourceFile, 0, SEEK_END);
nFileSize = ftell(pSourceFile);
rewind(pSourceFile);
/* Allocate memory for the file */
pData = malloc(nFileSize);
if (!pData)
{
fprintf(stderr, "Failed to allocate %ld bytes\n", nFileSize);
return -3;
}
/* Read the whole source file */
if (!fread(pData, nFileSize, 1, pSourceFile))
{
fprintf(stderr, "Failed to read source file: %ld\n", nFileSize);
return -4;
}
/* Close source file */
fclose(pSourceFile);
/* Open the destination file */
pDestFile = fopen(pszDestFile, "wb"); pDestFile = fopen(pszDestFile, "wb");
if (!pszDestFile) if (!pszDestFile)
{ {
fprintf(stderr, "Couldn't open dest file '%s'\n", pszDestFile); fprintf(stderr, "Couldn't open dest file '%s'\n", pszDestFile);
return -2; return -5;
} }
iOffset = strtol(argv[3], 0, 16); /* Calculate table pointers */
pFileHeader = (IMAGE_FILE_HEADER*)pData;
/* Load the coff header */ pSymbols = (void*)(pData + pFileHeader->PointerToSymbolTable);
nSize = fread(&FileHeader, 1, sizeof(FileHeader), pSourceFile); pSectionHeader = (void*)(((char*)(pFileHeader + 1)) + pFileHeader->SizeOfOptionalHeader);
if (nSize != sizeof(FileHeader))
{
fprintf(stderr, "Failed to read source file\n");
return -3;
}
/* Jump to section headers (skip optional header) */
if (fseek(pSourceFile, FileHeader.SizeOfOptionalHeader, SEEK_CUR))
{
fprintf(stderr, "Failed to set file pointer\n");
return -4;
}
/* Loop all sections */ /* Loop all sections */
for (i = 0; i < FileHeader.NumberOfSections; i++) for (i = 0; i < pFileHeader->NumberOfSections; i++)
{ {
/* Read section header */
nSize = fread(&SectionHeader, 1, sizeof(SectionHeader), pSourceFile);
if (nSize != sizeof(SectionHeader))
{
fprintf(stderr, "Failed to read section %ld file\n", i);
return -5;
}
/* Skip empty sections */ /* Skip empty sections */
if (SectionHeader.SizeOfRawData == 0) continue; if (pSectionHeader->SizeOfRawData == 0) continue;
/* Check if this is '.text' section */ /* Check if this is '.text' section */
if (strcmp(SectionHeader.Name, ".text") == 0) break; if (strcmp(pSectionHeader->Name, ".text") == 0)
} {
RelocateSection(pData,
pSectionHeader,
pSymbols,
nBaseAddress);
if (i == FileHeader.NumberOfSections) /* Write the section to the destination file */
{ if (!fwrite(pData + pSectionHeader->PointerToRawData,
fprintf(stderr, "No .text section found\n"); pSectionHeader->SizeOfRawData, 1, pDestFile))
return -6; {
} fprintf(stderr, "Failed to write data %ld\n",
pSectionHeader->SizeOfRawData);
return -6;
}
/* Move file pointer to the symbol table */ nBaseAddress += pSectionHeader->SizeOfRawData;
if (fseek(pSourceFile, FileHeader.PointerToSymbolTable, SEEK_SET)) }
{
fprintf(stderr, "Failed to set file pointer\n");
return -7;
}
/* Allocate memory for the symbols */ pSectionHeader++;
nSize = FileHeader.NumberOfSymbols * sizeof(IMAGE_SYMBOL);
pSymbols = malloc(nSize);
if (!pSymbols)
{
fprintf(stderr, "Failed to allocate %ld bytes\n", nSize);
return -8;
}
/* Read symbol data */
if (!fread(pSymbols, nSize, 1, pSourceFile))
{
fprintf(stderr, "Failed to read symbols: %ld\n", nSize);
return -9;
}
/* Move file pointer to the start of the section */
if (fseek(pSourceFile, SectionHeader.PointerToRawData, SEEK_SET))
{
fprintf(stderr, "Failed to set file pointer\n");
return -10;
}
/* Allocate memory for the section */
pData = malloc(SectionHeader.SizeOfRawData);
if (!pData)
{
fprintf(stderr, "Failed to allocate %ld bytes\n", SectionHeader.SizeOfRawData);
return -11;
}
/* Read section data */
if (!fread(pData, SectionHeader.SizeOfRawData, 1, pSourceFile))
{
fprintf(stderr, "Failed to read section %ld, at 0x%lx size=0x%lx \n",
i, SectionHeader.PointerToRawData, SectionHeader.SizeOfRawData);
return -12;
}
/* Allocate memory for the relocation */
nSize = SectionHeader.NumberOfRelocations * sizeof(IMAGE_RELOCATION);
pReloc = malloc(nSize);
if (!pReloc)
{
fprintf(stderr, "Failed to allocate %ld bytes\n", nSize);
return -13;
}
/* Move file pointer to the relocation table */
if (fseek(pSourceFile, SectionHeader.PointerToRelocations, SEEK_SET))
{
fprintf(stderr, "Failed to set file pointer\n");
return -14;
}
/* Read relocation data */
if (!fread(pReloc, nSize, 1, pSourceFile))
{
fprintf(stderr, "Failed to read section %ld file\n", i);
return -15;
}
RelocateImage(pData, SectionHeader.SizeOfRawData,
pReloc, SectionHeader.NumberOfRelocations, pSymbols, iOffset);
/* Write the section to the destination file */
if (!fwrite(pData, SectionHeader.SizeOfRawData, 1, pDestFile))
{
fprintf(stderr, "Failed to write data %ld\n",
SectionHeader.SizeOfRawData);
return -16;
} }
fclose(pDestFile); fclose(pDestFile);
fclose(pSourceFile);
return 0; return 0;
} }