Visual Studio LNK1107:无效或损坏的文件-Flat Assembler中的.obj(COFF)

时间:2019-02-23 23:43:24

标签: c visual-studio fasm coff

我正在尝试编译某人的程序,该程序部分用汇编语言编写,部分用C语言编写。该程序具有编译版本,但是我需要对其进行一些更改。该程序的源代码由一个.c文件和一个.asm文件组成。 在不进行任何更改的情况下,我尝试在Visual Studio 2017和Flat Assembler(1.73版)中编译程序。我编译了.asm文件,而Flat Assembler给了我.obj文件(unlzws4.obj)。然后,我在VS中创建了一个新的空项目,并从FASM中导入了.c文件和.obj文件。

enter image description here

此处出现问题。在编译期间,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项目中的某些设置而出现。一切都设置为默认选项。

1 个答案:

答案 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设置,在这种情况下,长模式代码由   默认。