首页
社区
课程
招聘
ASM编译产生的obj文件在VC2008 LINK时报错
发表于: 2013-4-3 11:38 9213

ASM编译产生的obj文件在VC2008 LINK时报错

2013-4-3 11:38
9213
ASM编译产生的obj文件在VC2008 LINK时报错,哪位朋友帮忙看下该怎么解决?

error LNK2019: 无法解析的外部符号 _GetModuleHandleA,该符号在函数 ____crtInitCritSecAndSpinCount 中被引用

LINK /nologo /NODEFAULTLIB /OPT:NOREF  /out:testnew.exe testnew.obj lmgr.lib libsb.lib libcrvs.lib .\activation\lib\libnoact.lib oldnames.lib kernel32.lib user32.lib netapi32.lib  advapi32.lib  gdi32.lib comdlg32.lib  comctl32.lib wsock32.lib libcmt.lib _tolower.obj

[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!

上传的附件:
收藏
免费 0
支持
分享
最新回复 (20)
雪    币: 952
活跃值: (1821)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
2
看起来像是你把GetModuleHandleA当成c调用了
2013-4-3 13:24
0
雪    币: 952
活跃值: (1821)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
3
正常的__stdcall找不到符号应该是GetModuleHandleA@0
2013-4-3 13:24
0
雪    币: 406
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
4
extern "C"
2013-4-3 13:59
0
雪    币: 484
活跃值: (269)
能力值: ( LV7,RANK:100 )
在线值:
发帖
回帖
粉丝
5
这个好像是C++程序里才行,我用的是Flexm SDK,是C程序的
2013-4-3 15:36
0
雪    币: 484
活跃值: (269)
能力值: ( LV7,RANK:100 )
在线值:
发帖
回帖
粉丝
6
论坛的朋友给的解答,其余的问题未给答复。

kernel32.lib does not export GetModuleHandleA, but _imp__GetModuleHandleA
So need to replace Code:
externdef GetModuleHandleA:dword

with Code:
pr1 typedef PROTO :DWORD
externdef _imp__GetModuleHandleA@4:PTR pr1
GetModuleHandleA equ <_imp__GetModuleHandleA@4>

我想知道<1> 怎么知道_imp__GetModuleHandleA <2>pr1是关键字吗,用pr2呢?<3>_imp__GetModuleHandleA@4,这里4是什么意思,参数个数?

我还有几十个类似的错,该怎么改呢?

_GetLastError
_MultiByteToWideChar
_WideCharToMultiByte
_GetCurrentProcess
_VirtualAlloc
_VirtualFree
_SetLastError
_WriteFile
_GetModuleFileNameA
_GetSystemInfo
_VirtualProtect
_GetCPInfo
_GetLocaleInfoA
_VirtualQuery
_InterlockedExchange
_InitializeCriticalSection
_GetStringTypeW
_GetStringTypeA
_LoadLibraryA
_GetProcAddress
_GetStdHandle
_GetCurrentThreadId
_LCMapStringW
_LCMapStringA
_ExitProcess
_TerminateProcess
_HeapReAlloc
_HeapAlloc
_HeapFree
2013-4-3 15:42
0
雪    币: 484
活跃值: (269)
能力值: ( LV7,RANK:100 )
在线值:
发帖
回帖
粉丝
7
这段ASM代码是从IDA中dump出来的,我想产生obj文件,拿去和C程序LINK在一起用,结果就报了一堆无法解析的外部符号的错误。
2013-4-3 15:44
0
雪    币: 406
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
8
vs2008 连接是没问题的
2013-4-3 15:46
0
雪    币: 293
活跃值: (287)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
9
你下面的定义确实有问题
externdef __imp__GetModuleHandle@4:DWORD  这样才对

用masm的inc文件就没问题啦
2013-4-3 16:17
0
雪    币: 7
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
cbb
10
你的asm文件中都没有加入头文件和库文件的声明,当然报错。你看看罗云彬的《windows环境下32位汇编语言》中的asm的格式吧!
2013-4-3 16:20
0
雪    币: 952
活跃值: (1821)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
11
4是指一个参数 8是两个参数
包含inc文件就行了
2013-4-3 16:47
0
雪    币: 484
活跃值: (269)
能力值: ( LV7,RANK:100 )
在线值:
发帖
回帖
粉丝
12
加了也还是报这个错,是我加得不对吗?能否改一个给我参考下呢?谢谢啦:)
2013-4-3 16:55
0
雪    币: 484
活跃值: (269)
能力值: ( LV7,RANK:100 )
在线值:
发帖
回帖
粉丝
13
瀚海兄,怎么用呢,我在asm文件里加了,可是VC LINK的时候还是报错啊?

.686p
.mmx
.xmm
.k3d
.model flat, C
option casemap: none

;Include定义
include user32.inc
includelib user32.lib
includelib ntdll.lib
include kernel32.inc
includelib kernel32.lib
include comdlg32.inc
includelib comdlg32.lib
2013-4-3 17:01
0
雪    币: 484
活跃值: (269)
能力值: ( LV7,RANK:100 )
在线值:
发帖
回帖
粉丝
14
是不是就是number = 参数个数乘以4?
2013-4-3 17:02
0
雪    币: 293
活跃值: (287)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
15
在这之前还还要修改默认调用方式为stdcall方式 .model flat, C   修改成   .model  flat,stdcall。
在inc文件里面并没有写调用方式是C还是stdcall
2013-4-5 10:53
0
雪    币: 484
活跃值: (269)
能力值: ( LV7,RANK:100 )
在线值:
发帖
回帖
粉丝
16
这个我之前我还真不了解,急着获得答案继续往前,没去了解基础知识:)
明天试下,多谢瀚海兄指点:)
2013-4-6 01:22
0
雪    币: 484
活跃值: (269)
能力值: ( LV7,RANK:100 )
在线值:
发帖
回帖
粉丝
17
瀚海兄, 我参照你的建议修改如下
.686
.model flat, stdcall, C ; => 不加"C", LINK编译时会报函数找不到
option casemap :none ;case sensitive

;include windows.inc
include kernel32.inc
includelib kernel32.lib

这样编译是通过了, 可是LINK时还是报同样的错, 能再帮我看一下不? 多谢啦!

error LNK2019: 无法解析的外部符号 _GetModuleHandleA,该符号在函数 ____crtInitCritSecAndSpinCount 中被引用
2013-4-6 09:17
0
雪    币: 293
活跃值: (287)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
18
我还是把这些语法解释下吧
.model 后面的C\stdcall等是不同的调用方式,编译的时候名字修改成不同的方式,C是直接在名字前加个下划线,stdcall是下划线后面再加@参数个数
option casemap :none  是告诉编译器,里面的函数名区分大小写。

根据你说的错误信息,应该是修改成  .model  flat,stdcall ,不过其他函数在C里面调用定义前面都必须加上__stdcall或者WINAPI又或者是CALLBACK\APIENTRY\APIPRIVATE。

你先自己写一个小模块试试怎么用么。
; asm.asm
        .386
        .model stdcall,flat
        option casemap:none
       
include     windows.inc
include         user32.inc
include         kernel32.inc
includelib        user32.lib
includelib        kernel32.lib
        .code
TestFunctionAdd proc ,v1:DWORD, v2:DWORD
                mov eax,v1
                add eax,v2
                ret
TestFunctionAdd endp
       
GetExeModule proc
                invoke GetModuleHandle,NULL
                ret
GetExeModule endp
                end
; 编译选项  ml /c /coff /Cp asm.asm

// callasm.Cpp文件
#include <windows.h>
#include <stdio.h>

#define CALLSTATIC  WINAPI

#ifdef __cplusplus
extern "C" {
#endif

DWORD CALLSTATIC TestFunctionAdd(DWORD, DWORD);
HANDLE CALLSTATIC GetExeModule(VOID);

#ifdef __cplusplus
        };
#endif

int main()
{
        printf("3+5 = %d\n", TestFunctionAdd(3,5));
        printf("Module Address: 0x%08X\n", GetExeModule());
        return 0;
}
// 编译选项  cl callasm.cpp asm.obj

////************************************************************//////
////************************************************************//////
////************************************************************//////
如果model 后面一定要跟C,则在定义API的时候必须加stdcall
// asm.asm
        .386
        .model C,flat
        option casemap:none
       
GetModuleHandleA proto stdcall ,:DWORD

        .code
TestFunctionAdd proc ,v1:DWORD, v2:DWORD
                mov eax,v1
                add eax,v2
                ret
TestFunctionAdd endp
       
GetExeModule proc
                invoke GetModuleHandleA,0
                ret
GetExeModule endp
                end
; 编译选项 ml /c /coff /Cp asm.asm

// callasm.cpp
// 相应的调用方式变成C的调用方式。
#include <windows.h>
#include <stdio.h>

#define CALLSTATIC  __cdecl

#ifdef __cplusplus
extern "C" {
#endif

DWORD CALLSTATIC TestFunctionAdd(DWORD, DWORD);
HANDLE CALLSTATIC GetExeModule(VOID);

#ifdef __cplusplus
};
#endif

int main()
{
        printf("3+5 = %d\n", TestFunctionAdd(3,5));
        printf("Module Address: 0x%08X\n", GetExeModule());
        return 0;
}
// 编译选项  cl callasm.cpp asm.obj
2013-4-7 15:44
0
雪    币: 484
活跃值: (269)
能力值: ( LV7,RANK:100 )
在线值:
发帖
回帖
粉丝
19
瀚海兄,参照你的例子,我做了一个test case,能否帮忙看下LINK时报的错,为什么newtolower函数还是找不到呢?是不是newtest.c里定义的不对?谢谢啦!

LINK newtest.obj newtolower.obj /out:newtest.exe
Microsoft (R) Incremental Linker Version 9.00.21022.08
Copyright (C) Microsoft Corporation.  All rights reserved.

newtest.obj : error LNK2019: 无法解析的外部符号 _newtolower@4,该符号在函数 _main 中被引用
newtest.exe : fatal error LNK1120: 1 个无法解析的外部命令
上传的附件:
2013-4-8 17:11
0
雪    币: 293
活跃值: (287)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
20
你申明的 newtolower 没有参数的牙,。你要传递一个参数后面要跟的
newtolower proc near ,argv1:DWORD
2013-4-8 17:39
0
雪    币: 484
活跃值: (269)
能力值: ( LV7,RANK:100 )
在线值:
发帖
回帖
粉丝
21
的确过了,不过产生的newtest.exe在运行的时候出错(如附图),之前用下面的方法,exe文件产生了,不过也有同样的运行错误。

pr1 typedef PROTO :DWORD
externdef _imp__GetModuleHandleA@4:PTR pr1
GetModuleHandleA equ <_imp__GetModuleHandleA@4>

这段代码是从IDA中dump出来修改而来的,看来dump的时候最好还是不要dump库函数,实在是难弄

之前只想弄个结果出来,中间的很多基础知识都暂时忽略了,还得好好学习啊。

我先结贴,兄如果有空就再帮我看看这个运行的错误,多谢瀚海兄的耐心指导:)
上传的附件:
2013-4-8 17:49
0
游客
登录 | 注册 方可回帖
返回
//