tccpe: fill checksum header field
This commit is contained in:
parent
569c20f104
commit
834b782a9c
1 changed files with 58 additions and 27 deletions
85
tccpe.c
85
tccpe.c
|
@ -417,13 +417,6 @@ ST_FN DWORD umax(DWORD a, DWORD b)
|
||||||
return a < b ? b : a;
|
return a < b ? b : a;
|
||||||
}
|
}
|
||||||
|
|
||||||
ST_FN void pe_fpad(FILE *fp, DWORD new_pos)
|
|
||||||
{
|
|
||||||
DWORD pos = ftell(fp);
|
|
||||||
while (++pos <= new_pos)
|
|
||||||
fputc(0, fp);
|
|
||||||
}
|
|
||||||
|
|
||||||
ST_FN DWORD pe_file_align(DWORD n)
|
ST_FN DWORD pe_file_align(DWORD n)
|
||||||
{
|
{
|
||||||
return (n + (0x200 - 1)) & ~(0x200 - 1);
|
return (n + (0x200 - 1)) & ~(0x200 - 1);
|
||||||
|
@ -447,6 +440,28 @@ ST_FN void pe_set_datadir(struct pe_header *hdr, int dir, DWORD addr, DWORD size
|
||||||
hdr->opthdr.DataDirectory[dir].Size = size;
|
hdr->opthdr.DataDirectory[dir].Size = size;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ST_FN int pe_fwrite(void *data, unsigned len, FILE *fp, DWORD *psum)
|
||||||
|
{
|
||||||
|
if (psum) {
|
||||||
|
DWORD sum = *psum;
|
||||||
|
WORD *p = data;
|
||||||
|
int i;
|
||||||
|
for (i = len; i > 0; i -= 2) {
|
||||||
|
sum += (i >= 2) ? *p++ : *(BYTE*)p;
|
||||||
|
sum = (sum + (sum >> 16)) & 0xFFFF;
|
||||||
|
}
|
||||||
|
*psum = sum;
|
||||||
|
}
|
||||||
|
return len == fwrite(data, 1, len, fp) ? 0 : -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
ST_FN void pe_fpad(FILE *fp, DWORD new_pos)
|
||||||
|
{
|
||||||
|
DWORD pos = ftell(fp);
|
||||||
|
while (++pos <= new_pos)
|
||||||
|
fputc(0, fp);
|
||||||
|
}
|
||||||
|
|
||||||
/*----------------------------------------------------------------------------*/
|
/*----------------------------------------------------------------------------*/
|
||||||
ST_FN int pe_write(struct pe_info *pe)
|
ST_FN int pe_write(struct pe_info *pe)
|
||||||
{
|
{
|
||||||
|
@ -549,15 +564,18 @@ ST_FN int pe_write(struct pe_info *pe)
|
||||||
{0,0}, {0,0}, {0,0}, {0,0}, {0,0}, {0,0}, {0,0}, {0,0}}
|
{0,0}, {0,0}, {0,0}, {0,0}, {0,0}, {0,0}, {0,0}, {0,0}}
|
||||||
}};
|
}};
|
||||||
|
|
||||||
|
struct pe_header pe_header = pe_template;
|
||||||
|
|
||||||
int i;
|
int i;
|
||||||
FILE *op;
|
FILE *op;
|
||||||
DWORD file_offset, r;
|
DWORD file_offset, sum;
|
||||||
struct pe_header pe_header = pe_template;
|
struct section_info *si;
|
||||||
|
IMAGE_SECTION_HEADER *psh;
|
||||||
|
|
||||||
op = fopen(pe->filename, "wb");
|
op = fopen(pe->filename, "wb");
|
||||||
if (NULL == op) {
|
if (NULL == op) {
|
||||||
error_noabort("could not write '%s': %s", pe->filename, strerror(errno));
|
error_noabort("could not write '%s': %s", pe->filename, strerror(errno));
|
||||||
return 1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
pe->sizeofheaders = pe_file_align(
|
pe->sizeofheaders = pe_file_align(
|
||||||
|
@ -566,18 +584,19 @@ ST_FN int pe_write(struct pe_info *pe)
|
||||||
);
|
);
|
||||||
|
|
||||||
file_offset = pe->sizeofheaders;
|
file_offset = pe->sizeofheaders;
|
||||||
pe_fpad(op, file_offset);
|
|
||||||
|
|
||||||
if (2 == pe->s1->verbose)
|
if (2 == pe->s1->verbose)
|
||||||
printf("-------------------------------"
|
printf("-------------------------------"
|
||||||
"\n virt file size section" "\n");
|
"\n virt file size section" "\n");
|
||||||
|
|
||||||
for (i = 0; i < pe->sec_count; ++i) {
|
for (i = 0; i < pe->sec_count; ++i) {
|
||||||
struct section_info *si = pe->sec_info + i;
|
unsigned long addr, size;
|
||||||
const char *sh_name = si->name;
|
const char *sh_name;
|
||||||
unsigned long addr = si->sh_addr - pe->imagebase;
|
|
||||||
unsigned long size = si->sh_size;
|
si = pe->sec_info + i;
|
||||||
IMAGE_SECTION_HEADER *psh = &si->ish;
|
sh_name = si->name;
|
||||||
|
addr = si->sh_addr - pe->imagebase;
|
||||||
|
size = si->sh_size;
|
||||||
|
psh = &si->ish;
|
||||||
|
|
||||||
if (2 == pe->s1->verbose)
|
if (2 == pe->s1->verbose)
|
||||||
printf("%6lx %6lx %6lx %s\n",
|
printf("%6lx %6lx %6lx %s\n",
|
||||||
|
@ -632,15 +651,13 @@ ST_FN int pe_write(struct pe_info *pe)
|
||||||
umax(pe_virtual_align(size + addr), pe_header.opthdr.SizeOfImage);
|
umax(pe_virtual_align(size + addr), pe_header.opthdr.SizeOfImage);
|
||||||
|
|
||||||
if (si->data_size) {
|
if (si->data_size) {
|
||||||
psh->PointerToRawData = r = file_offset;
|
psh->PointerToRawData = file_offset;
|
||||||
fwrite(si->data, 1, si->data_size, op);
|
|
||||||
file_offset = pe_file_align(file_offset + si->data_size);
|
file_offset = pe_file_align(file_offset + si->data_size);
|
||||||
psh->SizeOfRawData = file_offset - r;
|
psh->SizeOfRawData = file_offset - psh->PointerToRawData;
|
||||||
pe_fpad(op, file_offset);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// pe_header.filehdr.TimeDateStamp = time(NULL);
|
//pe_header.filehdr.TimeDateStamp = time(NULL);
|
||||||
pe_header.filehdr.NumberOfSections = pe->sec_count;
|
pe_header.filehdr.NumberOfSections = pe->sec_count;
|
||||||
pe_header.opthdr.SizeOfHeaders = pe->sizeofheaders;
|
pe_header.opthdr.SizeOfHeaders = pe->sizeofheaders;
|
||||||
pe_header.opthdr.ImageBase = pe->imagebase;
|
pe_header.opthdr.ImageBase = pe->imagebase;
|
||||||
|
@ -649,10 +666,24 @@ ST_FN int pe_write(struct pe_info *pe)
|
||||||
else if (PE_GUI != pe->type)
|
else if (PE_GUI != pe->type)
|
||||||
pe_header.opthdr.Subsystem = 3;
|
pe_header.opthdr.Subsystem = 3;
|
||||||
|
|
||||||
fseek(op, SEEK_SET, 0);
|
sum = 0;
|
||||||
fwrite(&pe_header, 1, sizeof pe_header, op);
|
pe_fwrite(&pe_header, sizeof pe_header, op, &sum);
|
||||||
for (i = 0; i < pe->sec_count; ++i)
|
for (i = 0; i < pe->sec_count; ++i)
|
||||||
fwrite(&pe->sec_info[i].ish, 1, sizeof(IMAGE_SECTION_HEADER), op);
|
pe_fwrite(&pe->sec_info[i].ish, sizeof(IMAGE_SECTION_HEADER), op, &sum);
|
||||||
|
pe_fpad(op, pe->sizeofheaders);
|
||||||
|
for (i = 0; i < pe->sec_count; ++i) {
|
||||||
|
si = pe->sec_info + i;
|
||||||
|
psh = &si->ish;
|
||||||
|
if (si->data_size) {
|
||||||
|
pe_fwrite(si->data, si->data_size, op, &sum);
|
||||||
|
file_offset = psh->PointerToRawData + psh->SizeOfRawData;
|
||||||
|
pe_fpad(op, file_offset);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pe_header.opthdr.CheckSum = sum + file_offset;
|
||||||
|
fseek(op, offsetof(struct pe_header, opthdr.CheckSum), SEEK_SET);
|
||||||
|
pe_fwrite(&pe_header.opthdr.CheckSum, sizeof pe_header.opthdr.CheckSum, op, NULL);
|
||||||
fclose (op);
|
fclose (op);
|
||||||
|
|
||||||
if (2 == pe->s1->verbose)
|
if (2 == pe->s1->verbose)
|
||||||
|
@ -1201,7 +1232,7 @@ ST_FN int pe_check_symbols(struct pe_info *pe)
|
||||||
|
|
||||||
not_found:
|
not_found:
|
||||||
error_noabort("undefined symbol '%s'", name);
|
error_noabort("undefined symbol '%s'", name);
|
||||||
ret = 1;
|
ret = -1;
|
||||||
|
|
||||||
} else if (pe->s1->rdynamic
|
} else if (pe->s1->rdynamic
|
||||||
&& ELFW_ST_BIND(sym->st_info) != STB_LOCAL) {
|
&& ELFW_ST_BIND(sym->st_info) != STB_LOCAL) {
|
||||||
|
@ -1628,7 +1659,7 @@ PUB_FN int pe_output_file(TCCState * s1, const char *filename)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (s1->nb_errors)
|
if (s1->nb_errors)
|
||||||
ret = 1;
|
ret = -1;
|
||||||
else
|
else
|
||||||
ret = pe_write(&pe);
|
ret = pe_write(&pe);
|
||||||
tcc_free(pe.sec_info);
|
tcc_free(pe.sec_info);
|
||||||
|
|
Loading…
Reference in a new issue