我正在尝试编译某人的程序,该程序部分用汇编语言编写,部分用C语言编写。该程序具有编译版本,但是我需要对其进行一些更改。该程序的源代码由一个.c文件和一个.asm文件组成。 在不进行任何更改的情况下,我尝试在Visual Studio 2017和Flat Assembler(1.73版)中编译程序。我编译了.asm文件,而Flat Assembler给了我.obj文件(unlzws4.obj)。然后,我在VS中创建了一个新的空项目,并从FASM中导入了.c文件和.obj文件。
此处出现问题。在编译期间,Visual Studio给我这个链接错误:
1>------ Rebuild All started: Project: unlibs4, Configuration: Debug Win32 ------
1>unlibs4.c
1>unlzws4.obj : fatal error LNK1107: invalid or corrupt file: cannot read at 0x10EE4
1>Done building project "unlibs4.vcxproj" -- FAILED.
========== Rebuild All: 0 succeeded, 1 failed, 0 skipped ==========
我试图找出为什么会出现此错误,但是没有结果。该代码应该是正确的。
unlibs4.c文件:
// (c) CTPAX-X Team 2018 http://www.CTPAX-X.org/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <malloc.h>
#include <windows.h>
#ifdef GCC32HACK
#include "win32gcc.h"
#endif
#define S4L_REVISION 0x1000
#define S4F_PACKED 1
#define S4F_CRYPTED 2
#pragma pack(push, 1)
typedef struct
{
DWORD headsize; /* size of this header with all data */
DWORD revision; /* MUST be equal to 0x1000 */
DWORD dnamelen; /* directory names block len */
DWORD dcounter; /* directory count in block */
DWORD fnamelen; /* file names block len */
DWORD fcounter; /* files counter */
} headinfo;
typedef struct
{
DWORD floffs; /* looks like first always 1 (.LIB file starts with one zero byte) */
DWORD pksize; /* packed size */
DWORD unsize; /* unpacked size (zero if file not packed) */
DWORD dindex; /* directory name index */
DWORD xflags; /* flags: 1 - packed; 2 - crypted; */
DWORD crcsum; /* file CRC (16 bit); can be zero; only for packed files? */
} fileinfo;
#pragma pack(pop)
extern void WINAPI unlzws4(BYTE *undata, DWORD *unsize, BYTE *pkdata, DWORD *pksize);
int main(int argc, char *argv[])
{
char *dnames, *fnames, *s, *d, name[MAX_PATH];
fileinfo *list;
FILE *fl, *f;
headinfo hi;
DWORD i, j;
BYTE *p, *u;
printf("The Settlers IV .LIB unpacker v1.0\n(c) CTPAX-X Team 2018\nhttp://www.CTPAX-X.org/\n\n");
if (argc != 2)
{
printf("Usage: unlibs4 <filename.lib>\n\n");
return(1);
}
fl = fopen(argv[1], "rb");
if (!fl)
{
printf("Error: can't open input file.\n\n");
return(2);
}
/* read TOC offs */
fseek(fl, 0, SEEK_END);
fseek(fl, ftell(fl) - 4, SEEK_SET);
fread(&i, 4, 1, fl);
/* read TOC */
fseek(fl, i, SEEK_SET);
memset(&hi, 0, sizeof(hi));
fread(&hi, sizeof(hi), 1, fl);
if (hi.revision != S4L_REVISION)
{
fclose(fl);
printf("Error: invalid/unknown input file format.\n\n");
return(3);
}
/* allocate memory */
dnames = (char *)malloc(hi.dnamelen);
fnames = (char *)malloc(hi.fnamelen);
list = (fileinfo *)malloc(hi.fcounter * sizeof(list[0]));
if (dnames && fnames && list)
{
/* read strings */
fread(dnames, hi.dnamelen, 1, fl);
fread(fnames, hi.fnamelen, 1, fl);
/* read file infos */
fread(list, hi.fcounter, sizeof(list[0]), fl);
/* create all directories before */
d = dnames;
for (i = 0; i < hi.dcounter; i++)
{
CreateDirectory(d, NULL);
d += strlen(d) + 1;
}
/* unpack */
s = fnames;
for (i = 0; i < hi.fcounter; i++)
{
/* find directory name */
d = dnames;
j = list[i].dindex;
while (j > 0)
{
d += strlen(d) + 1;
j--;
}
/* merge directory with file */
sprintf(name, "%s\\%s", d, s);
/* dump to disk */
printf("%s\n", name);
f = fopen(name, "wb");
if (f)
{
p = (BYTE *)malloc(list[i].pksize);
if (p)
{
fseek(fl, list[i].floffs, SEEK_SET);
fread(p, list[i].pksize, 1, fl);
if (list[i].xflags & S4F_CRYPTED)
{
printf("Warning: encrypted file, but decryption not supported - saving as is.\n");
}
/* decryption not supported, that's why '==' instead of just '&' */
if ((list[i].xflags & (S4F_CRYPTED | S4F_PACKED)) == S4F_PACKED)
{
u = (BYTE *)malloc(list[i].unsize);
if (u)
{
j = list[i].unsize;
unlzws4(u, &list[i].unsize, p, &list[i].pksize);
free(p);
p = u;
list[i].pksize = j;
}
}
fwrite(p, list[i].pksize, 1, f);
free(p);
}
fclose(f);
}
/* next filename */
s += strlen(s) + 1;
}
printf("\ndone\n\n");
}
if (dnames) { free(dnames); }
if (fnames) { free(fnames); }
if (list) { free(list); }
fclose(fl);
return(0);
}
unlzws4.asm文件的开头:
; To compile this source code you'll need FASM:
; http://flatassembler.net/
FORMAT COFF
include 'win32ax.inc'
; define section so this can be merged to the code block
section '.text' code
public @startup as '_unlzws4@16'
; some consts
;dword_616478 - start
dword_6167E0 = buf_all + 6167E0h - 616478h
dword_6167E4 = buf_all + 6167E4h - 616478h
dword_616DF8 = buf_all + 616DF8h - 616478h
dword_617060 = buf_all + 617060h - 616478h
dword_617064 = buf_all + 617064h - 616478h
; ###########################################################################
; some startup initialization code
@startup:
push esi
push edi
xor eax, eax
cld
; clear all buffers
mov edi, buf_65536
mov ecx, 65536 / 4
rep stosd
; ---
mov edi, buf_548
mov ecx, 548 / 4
rep stosd
; reinit static buffer since it can be modified due unpacking (sic!)
mov esi, dword_616478
mov edi, buf_all
mov ecx, (3112d + 152d) / 4
rep movsd
; ---
pop edi
pop esi
; emulate some class structure
mov ecx, _buf
; jump to the actual unpacking routine
jmp @sub_573090
; ###########################################################################
@sub_572450:
var_4 = -4
arg_0 = 4
arg_4 = 8
push ecx
push ebx
mov ebx, [esp+8+arg_0]
push ebp
mov ebp, [esp+0Ch+arg_4]
push esi
push edi
mov esi, 28h
@loc_572462:
...
我对汇编器了解不多,我只需要更改程序的C部分并将其编译为.dll库即可。我想知道错误是否只是由于Visual Studio项目中的某些设置而出现。一切都设置为默认选项。
答案 0 :(得分:1)
要使用Microsoft链接器链接,您需要具有MSCOFF格式的目标文件。哪里有
FORMAT COFF
您需要:
FORMAT MS COFF
来自https://flatassembler.net/docs.php?article=manual#2.4.3:
2.4.3通用对象文件格式
要选择“公共目标文件格式”,请使用格式COFF或格式MS COFF指令,具体取决于您是否 要创建经典(DJGPP)或Microsoft的COFF文件变体。 此格式的默认代码设置为32位。创建文件 以Microsoft的x86-64架构的COFF格式使用格式 MS64 COFF设置,在这种情况下,长模式代码由 默认。