首页
社区
课程
招聘
VC中使用内联汇编的一个问题~~~~~~~~~~~~~~~~~~~~~
2005-1-17 10:27 16397

VC中使用内联汇编的一个问题~~~~~~~~~~~~~~~~~~~~~

lee 活跃值
3
2005-1-17 10:27
16397
char szFormat[]="%s %s\n";
char szHello[]="Hello";
char szWorld[]="World";

void main()
{
        __asm
        {
                LEA EAX,szWorld
                PUSH EAX
                LEA EAX,szHello
                PUSH EAX
                LEA EAX,szFormat
                PUSH EAX
                CALL printf //这个地方
                ADD ESP,12
        }
}

TCHAR appname[]=TEXT("API Test");

void main()
{
        TCHAR tszHello[]=TEXT("hello,word");
        __asm
        {
                PUSH MB_OK OR MB_ICONINFORMATION
                PUSH OFFSET appname
                LEA  EAX,tszHello
                PUSH EAX
                PUSH 0
                CALL DWORD PTR[MessageBox]//这个地方
     ;注意这里不是CALL MessageBox,而是重定位过的函数地址
        }
}

同样是调用函数,为什么方法不一样啊,虽然上面有句注释,但是我还是不懂

那位指点一下!!!

有《软件加密技术内幕》的可以看398页

[培训]《安卓高级研修班(网课)》月薪三万计划,掌 握调试、分析还原ollvm、vmp的方法,定制art虚拟机自动化脱壳的方法

收藏
点赞7
打赏
分享
最新回复 (19)
雪    币: 262
活跃值: (152)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
vcasm 1 2005-1-17 10:53
2
0
这主要是这2个函数的参数定义不一样造成的

printf函数调用的堆栈是调用者负责平衡的,所以调用的时候必须在call后面add esp,4*参数数目,MessageBoxA函数是函数内部负责堆栈平衡 所以直接调用就可以了

在使用call的时候最好看看调用的函数定义的申明
雪    币: 255
活跃值: (175)
能力值: ( LV8,RANK:130 )
在线值:
发帖
回帖
粉丝
lee 3 2005-1-17 11:00
3
0
CALL printf //这种是直接调用函数
CALL DWORD PTR[MessageBox] //这种为什么是地址

我想要知道的是调用方式,两者的区别。。。
雪    币: 262
活跃值: (152)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
vcasm 1 2005-1-17 11:16
4
0
由于使用了内联汇编,C编译器将MessageBox申明为一个指向dword地址的指针,这个地址用于存放MessageBoxA加载后的内存地址,所以需要call [MessageBox]

上面的例子不同 printf函数在c编译器里面 函数实体已经被编译到程序里面了,函数的地址明确不需要重定位,所以可以使用call addr
雪    币: 233
活跃值: (85)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
dssz 2005-1-17 11:39
5
0
换种说法
printf是使用静态连接,直接把函数代码写到EXE中

MessageBox是动态连接,MessageBox在程序中只是一个指针,当EXE要使用的时候,只能根据这个指针去读取DLL中函数代码
雪    币: 255
活跃值: (175)
能力值: ( LV8,RANK:130 )
在线值:
发帖
回帖
粉丝
lee 3 2005-1-17 12:04
6
0
谢谢!!!
雪    币: 226
活跃值: (330)
能力值: ( LV7,RANK:100 )
在线值:
发帖
回帖
粉丝
goldenegg 2 2005-1-17 13:42
7
0
最初由 vcasm 发布
由于使用了内联汇编,C编译器将MessageBox申明为一个指向dword地址的指针,这个地址用于存放MessageBoxA加载后的内存地址,所以需要call [MessageBox]

上面的例子不同 printf函数在c编译器里面 函数实体已经被编译到程序里面了,函数的地址明确不需要重定位,所以可以使用call addr

错了,真正的原因在于定义方式。

不要包含任何头文件:
这样写:
int __stdcall MessageBoxA(void* hWnd,
    const char * lpText,
    const char * lpCaption,
    unsigned int  uType
);
就要这样调用
call MessageBoxA

如果这样写:
__declspec(dllimport) int __stdcall MessageBoxA(void* hWnd,
    const char * lpText,
    const char * lpCaption,
    unsigned int  uType
);
就要这样调:
call dword ptr [MessageBoxA]

因为vc的头文件已经默认给写上了__declspec(dllimport)
所以就必须call dword ptr [MessageBox]
雪    币: 255
活跃值: (175)
能力值: ( LV8,RANK:130 )
在线值:
发帖
回帖
粉丝
lee 3 2005-1-19 11:57
8
0
到底那一个说的对啊???
雪    币: 3246
活跃值: (339)
能力值: (RANK:20 )
在线值:
发帖
回帖
粉丝
blowfish 2005-1-19 12:54
9
0
他们说的不矛盾,是因为__declspec(dllimport)关键字的原因。对于使用了__declspec(dllimport)关键字来声明的函数,VC会将对这些函数的调用翻译成一个间址的call,通过IAT来调用,如果你是用C/C++自然不用关心怎么调用,但用汇编就得按编译器的翻译规则来。MSDN里对__declspec(dllimport)有详细描述。
雪    币: 255
活跃值: (175)
能力值: ( LV8,RANK:130 )
在线值:
发帖
回帖
粉丝
lee 3 2005-1-19 17:03
10
0
终于明白了!!!!!!
雪    币: 255
活跃值: (175)
能力值: ( LV8,RANK:130 )
在线值:
发帖
回帖
粉丝
lee 3 2005-1-19 17:03
11
0
对了,谢谢!!!!!!!

呵呵~~~~~~~~~~~~
雪    币: 216
活跃值: (40)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
阵雨 2005-1-25 07:18
12
0
各位~~~~看图吧
雪    币: 216
活跃值: (40)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
阵雨 2005-1-25 07:22
13
0
雪    币: 216
活跃值: (40)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
阵雨 2005-1-25 07:25
14
0
多了图
雪    币: 1829
活跃值: (1333)
能力值: (RANK:50 )
在线值:
发帖
回帖
粉丝
backer 1 2005-1-26 23:36
15
0
最后贴的是静态联编的是吧?
把源代码也贴出来对比看看啊
雪    币: 216
活跃值: (40)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
阵雨 2005-1-27 03:09
16
0
晕,你别看错了啊,黑体就是源代码,编译出来的是灰体
雪    币: 1829
活跃值: (1333)
能力值: (RANK:50 )
在线值:
发帖
回帖
粉丝
backer 1 2005-1-28 18:52
17
0
没注意,呵呵,真不好意思啊
雪    币: 239
活跃值: (473)
能力值: ( LV6,RANK:90 )
在线值:
发帖
回帖
粉丝
hmimys 2 2005-6-27 09:24
18
0
看了比较有收获,谁在说说在BCB中的吧
雪    币: 81
活跃值: (41)
能力值: (RANK:220 )
在线值:
发帖
回帖
粉丝
Yonsm 5 2005-9-30 14:44
19
0
关键是――MessageBoxA 是在DLL中引入的,而printf却不是。就是这点区别。

DLL 引入的函数,因为DLL的Base Address是不确定的,所以需要重定位,即载入DLL后才知道MessageBoxA的真正的地址。(理论上)

而 printf 是编译后就确定了的,所以没问题。
雪    币: 200
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
winnet 2005-11-9 21:10
20
0
收获不小呀!!支持..
游客
登录 | 注册 方可回帖
返回