首页
社区
课程
招聘
字符串函数的汇编代码是怎样的
发表于: 2009-12-21 11:41 5288

字符串函数的汇编代码是怎样的

2009-12-21 11:41
5288
请问调用windoows中的字符串函数例如strcpy,在汇编代码中的最终实现与调用其他windows函数一样,就是call 0000000(00000000表示字符串函数地址)的格式,还是直接在调用的地方把字符串函数用字符串汇编指令展开的?

[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课

收藏
免费 0
支持
分享
最新回复 (12)
雪    币: 50
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
2
展开的,编译器会直接把代码链接到程序中
2009-12-21 11:47
0
雪    币: 43
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
3
是所有windows字符串函数都直接展开吗
2009-12-21 11:48
0
雪    币: 50
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
4
API不会展开,直接在DLL执行
2009-12-21 11:51
0
雪    币: 75
活跃值: (883)
能力值: ( LV6,RANK:90 )
在线值:
发帖
回帖
粉丝
5
是这个:
在汇编代码中的最终实现与调用其他windows函数一样,就是call 0000000(00000000表示字符串函数地址)的格式.

不是展开
2009-12-21 11:56
0
雪    币: 43
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
6
比如在c代码中调用了strcpy函数,那么汇编码是直接展开,还是直接调用了api?
2009-12-21 14:36
0
雪    币: 75
活跃值: (883)
能力值: ( LV6,RANK:90 )
在线值:
发帖
回帖
粉丝
7
举例说明下把,一个简单程序源代码如下
        .data?
szBuffer        db 1024 dup (?)
sdBuffer   db 1024 dup (?)
       
        .code

start:
        invoke lstrcpy,offset szBuffer,offset sdBuffer
        invoke ExitProcess,NULL
        end start
编译后生成的汇编代码如下:
00401000 >/$  68 00344000      push    00403400
00401005  |?  68 00304000       push    00403000
0040100A  |?  E8 0D000000       call    <jmp.&kernel32.lstrcpyA>
0040100F  |.  6A 00                    push    0                              
00401011  |?  E8 00000000       call    <jmp.&kernel32.ExitProcess>
00401016  |?- FF25 04204000    jmp     dword ptr [<&kernel32.ExitProces>;  kernel32.ExitProcess
0040101C  |?- FF25 00204000   jmp     dword ptr [<&kernel32.lstrcpyA>] ;  kernel32.lstrcpyA

很清晰把,你在源程序中调用 lstrcpy函数,生成的汇编码没有把 lstrcpy的实现代码全部插这里来,只是做了一个跳转,跳转到kernel32.dll中的lstrcpy实现代码处去执行.
2009-12-21 22:40
0
雪    币: 724
活跃值: (81)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
8
我想楼主是需要“展开”, 这也是可能的,这涉及内联(intrinsic)函数的概念,编译器为了特殊的原因会自己实现一些函数,称为内联(instrinsic), 比如strcpy, 对于VC6而言是支持内联的, 但是编译器默认并不内联strcpy, 打开strcpy内联的方法如下:
#pragma intrinsic(strcpy)
在这一条语句后面调用strcpy都是内联的。
需要注意的不同版本的编译器支持的内联函数不同,对同一函数的实现也可能不同。编译支持的内联函数列表请参考MSDN中intrinsic相关项。
2009-12-21 22:55
0
雪    币: 458
活跃值: (426)
能力值: ( LV9,RANK:610 )
在线值:
发帖
回帖
粉丝
9
如果是调用了win 系统Dll中提供函数 如CreateFileA  MessageBoxA 等等Win API 是直接Call过去的,然后你提的strcpy strcmp 之类的  我不太清楚 ,但是我做了个实验 发现这函数是展开的,代码如下

void CMy1111Dlg::OnOK()
{
        char szContent[100] = {"Hi"};
        if (strcmp(szContent, "Hello World") == 0)
        {
                ::MessageBox(NULL ,"OK" ,NULL ,NULL);
        }
        else
        {
                ::MessageBox(NULL ,"不 OK" ,NULL ,NULL);

        }
}

OD反之:
0040147F      90            NOP
00401480   .  83EC 64       SUB ESP,64
00401483   .  66:A1 3830400>MOV AX,WORD PTR DS:[403038]
00401489   .  8A0D 3A304000 MOV CL,BYTE PTR DS:[40303A]
0040148F   .  53            PUSH EBX
00401490   .  56            PUSH ESI
00401491   .  57            PUSH EDI
00401492   .  66:894424 0C  MOV WORD PTR SS:[ESP+C],AX
00401497   .  884C24 0E     MOV BYTE PTR SS:[ESP+E],CL
0040149B   .  B9 18000000   MOV ECX,18
004014A0   .  33C0          XOR EAX,EAX
004014A2   .  8D7C24 0F     LEA EDI,DWORD PTR SS:[ESP+F]
004014A6   .  F3:AB         REP STOS DWORD PTR ES:[EDI]
004014A8   .  AA            STOS BYTE PTR ES:[EDI]
004014A9   .  BE 2C304000   MOV ESI,1111.0040302C                    ;  ASCII "Hello World"
004014AE   .  8D4424 0C     LEA EAX,DWORD PTR SS:[ESP+C]
004014B2   >  8A10          MOV DL,BYTE PTR DS:[EAX]
004014B4   .  8A1E          MOV BL,BYTE PTR DS:[ESI]
004014B6   .  8ACA          MOV CL,DL
004014B8   .  3AD3          CMP DL,BL
004014BA   .  75 1E         JNZ SHORT 1111.004014DA
004014BC   .  84C9          TEST CL,CL
004014BE   .  74 16         JE SHORT 1111.004014D6
004014C0   .  8A50 01       MOV DL,BYTE PTR DS:[EAX+1]
004014C3   .  8A5E 01       MOV BL,BYTE PTR DS:[ESI+1]
004014C6   .  8ACA          MOV CL,DL
004014C8   .  3AD3          CMP DL,BL
004014CA   .  75 0E         JNZ SHORT 1111.004014DA
004014CC   .  83C0 02       ADD EAX,2
004014CF   .  83C6 02       ADD ESI,2
004014D2   .  84C9          TEST CL,CL
004014D4   .^ 75 DC         JNZ SHORT 1111.004014B2
004014D6   >  33C0          XOR EAX,EAX
004014D8   .  EB 05         JMP SHORT 1111.004014DF
004014DA   >  1BC0          SBB EAX,EAX
004014DC   .  83D8 FF       SBB EAX,-1
004014DF   >  5F            POP EDI
004014E0   .  5E            POP ESI
004014E1   .  5B            POP EBX
004014E2   .  85C0          TEST EAX,EAX
004014E4   .  6A 00         PUSH 0                                   ; /Style = MB_OK|MB_APPLMODAL
004014E6   .  6A 00         PUSH 0                                   ; |Title = NULL
004014E8   .  75 11         JNZ SHORT 1111.004014FB                  ; |
004014EA   .  68 28304000   PUSH 1111.00403028                       ; |Text = "OK"
004014EF   .  6A 00         PUSH 0                                   ; |hOwner = NULL
004014F1   .  FF15 CC214000 CALL DWORD PTR DS:[<&USER32.MessageBoxA>>; \MessageBoxA
004014F7   .  83C4 64       ADD ESP,64
004014FA   .  C3            RETN
004014FB   >  68 20304000   PUSH 1111.00403020                       ; |Text = "不 OK"
00401500   .  6A 00         PUSH 0                                   ; |hOwner = NULL
00401502   .  FF15 CC214000 CALL DWORD PTR DS:[<&USER32.MessageBoxA>>; \MessageBoxA
00401508   .  83C4 64       ADD ESP,64
0040150B   .  C3            RETN
0040150C      90            NOP
0040150D      90            NOP


建议LZ动动手  实践一下,这样更有说服力  进步更快~
2009-12-22 16:38
0
雪    币: 247
活跃值: (11)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
10
如果你调用的是lib库的函数要展开的
如果是dll里的 就执行dll里的函数了
2009-12-22 17:08
0
雪    币: 94
活跃值: (25)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
11
为了效率,一般都是:call ptr ds[XXXXXXXX]
XXXXXXXX就是这些函数的地址
2009-12-28 12:04
0
雪    币: 4
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
12
看下罗老师的书。。
2009-12-28 14:04
0
雪    币: 43
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
13
谢谢各位,我知道答案了
2010-1-14 08:04
0
游客
登录 | 注册 方可回帖
返回