用VC写Assembly代码(5) --函数调用(一)

原创 2006年06月07日 19:24:00

用C写一个加载msvcrt.dll的方法如下:

#include <windows.h>
#include <stdio.h>

void main()
{
  char *msvcrt = "msvcrt.dll";
  HINSTANCE h = LoadLibrary(msvcrt);
}

反汇编得到的代码是:

5:    #include <windows.h>
6:    #include <stdio.h>
7:
8:    void main()
9:    {
0040B4B0 55                   push        ebp
0040B4B1 8B EC                mov         ebp,esp
0040B4B3 83 EC 48             sub         esp,48h
0040B4B6 53                   push        ebx
0040B4B7 56                   push        esi
0040B4B8 57                   push        edi
0040B4B9 8D 7D B8             lea         edi,[ebp-48h]
0040B4BC B9 12 00 00 00       mov         ecx,12h
0040B4C1 B8 CC CC CC CC       mov         eax,0CCCCCCCCh
0040B4C6 F3 AB                rep stos    dword ptr [edi]
10:       char *msvcrt = "msvcrt.dll";
0040B4C8 C7 45 FC 1C F0 41 00 mov         dword ptr [ebp-4],offset string "msvcrt.dll" (0041f01c)
11:       HINSTANCE h = LoadLibrary(msvcrt);
0040B4CF 8B F4                mov         esi,esp
0040B4D1 8B 45 FC             mov         eax,dword ptr [ebp-4]
0040B4D4 50                   push        eax
0040B4D5 FF 15 38 41 42 00    call        dword ptr [__imp__LoadLibraryA@4 (00424138)]
0040B4DB 3B F4                cmp         esi,esp
0040B4DD E8 8E 5B FF FF       call        __chkesp (00401070)
0040B4E2 89 45 F8             mov         dword ptr [ebp-8],eax
12:   }
0040B4E5 5F                   pop         edi
0040B4E6 5E                   pop         esi
0040B4E7 5B                   pop         ebx
0040B4E8 83 C4 48             add         esp,48h
0040B4EB 3B EC                cmp         ebp,esp
0040B4ED E8 7E 5B FF FF       call        __chkesp (00401070)
0040B4F2 8B E5                mov         esp,ebp
0040B4F4 5D                   pop         ebp
0040B4F5 C3                   ret


我觉得
call        dword ptr [__imp__LoadLibraryA@4 (00424138)]
非常奇怪,是什么意思呢??

然后我写了个C中汇编程序:

#include <windows.h>
#include <stdio.h>

void main()
{
  char *msvcrt = "msvcrt.dll";
  __asm
  {
    mov ebp, esp
    mov eax, msvcrt
    push eax
    call LoadLibrary
    mov esp, ebp
  }
}

结果出错,然后在
call LoadLibrary
加如break point,调试后说[访问违规],跳出如下代码:

__imp__LoadLibraryA@4:
00424138 C4 2F                les         ebp,fword ptr [edi]
0042413A 88 7C 8D 2C          mov         byte ptr [ebp+ecx*4+2Ch],bh
0042413E 81 7C AB 14 81 7C A2 cmp         dword ptr [ebx+ebp*4+14h],0CAA27C81h
00424146 81 7C 56 99 85 7C A9 cmp         dword ptr [esi+edx*2-67h],2CA97C85h
0042414E 81 7C 9F 0F 81 7C 94 cmp         dword ptr [edi+ebx*4+0Fh],97947C81h
00424156 80 7C 5C 9B 85       cmp         byte ptr [esp+ebx*2-65h],85h
0042415B 7C 28                jl          __imp__GetEnvironmentStringsW@0+1 (00424185)
0042415D AC                   lods        byte ptr [esi]
0042415E 80 7C 7B 97 80       cmp         byte ptr [ebx+edi*2-69h],80h
00424163 7C 57                jl          __imp__GetCPInfo@8 (004241bc)
00424165 B3 80                mov         bl,80h
00424167 7C 16                jl          __imp__WideCharToMultiByte@32+3 (0042417f)
00424169 1E                   push        ds
0042416A 80 7C 0D E0 80       cmp         byte ptr [ebp+ecx-20h],80h
0042416F 7C 8A                jl          __NULL_IMPORT_DESCRIPTOR+0E7h (004240fb)
00424171 2B 86 7C 3F DC 81    sub         eax,dword ptr [esi-7E23C084h]
00424177 7C 5F                jl          __imp__LCMapStringA@24 (004241d8)
00424179 48                   dec         eax
0042417A 81 7C C7 A0 80 7C 23 cmp         dword ptr [edi+eax*8-60h],0CC237C80h
00424182 81 7C 78 2C 81 7C CF cmp         dword ptr [eax+edi*2+2Ch],0C6CF7C81h
0042418A 80 7C 69 10 81       cmp         byte ptr [ecx+ebp*2+10h],81h
0042418F 7C EE                jl          __imp__WideCharToMultiByte@32+3 (0042417f)
00424191 1E                   push        ds
00424192 80 7C 10 11 81       cmp         byte ptr [eax+edx+11h],81h
00424197 7C 29                jl          __imp__GetACP@0+2 (004241c2)
00424199 29 81 7C 3D 04 93    sub         dword ptr [ecx-6CFBC284h],eax
0042419F 7C 14                jl          __imp__IsBadReadPtr@8+1 (004241b5)
004241A1 9B                   wait
004241A2 80 7C 40 7A 95       cmp         byte ptr [eax+eax*2+7Ah],95h
004241A7 7C 31                jl          __imp__LCMapStringA@24+2 (004241da)
004241A9 03 93 7C 5B B2 81    add         edx,dword ptr [ebx-7E4DA484h]
004241AF 7C 29                jl          __imp__LCMapStringA@24+2 (004241da)
004241B1 9F                   lahf
004241B2 80 7C B3 9E 80       cmp         byte ptr [ebx+esi*4-62h],80h
004241B7 7C 9B                jl          __imp__InterlockedDecrement@4 (00424154)
004241B9 E7 85                out         85h,eax
004241BB 7C E6                jl          __imp__VirtualFree@12+3 (004241a3)
004241BD 2B 81 7C 43 99 80    sub         eax,dword ptr [ecx-7F66BC84h]
004241C3 7C 2A                jl          __imp__SetStdHandle@8+3 (004241ef)
004241C5 E8 81 7C D4 05       call        0616BE4B
004241CA 93                   xchg        eax,ebx
004241CB 7C 81                jl          __imp__GetStdHandle@4+2 (0042414e)
004241CD 9A 80 7C FD 79 93 7C call        __imp__VirtualAlloc@16+2 (004241ce)

到低是什么问题啊?为什么程序要这么整我这个菜鸟.....

原来是这样:

这是你自己的写法错误,不能怨编译器。
#include <windows.h>
#include <stdio.h>

void main()
{
  char *msvcrt = "msvcrt.dll";
  __asm
  {
    mov ebp, esp /* 这句是多余的,你写上这一句将会破坏函数堆结构,因为C编译器会自动维护这个ebp和esp的,不用自己写。 */
    mov eax, msvcrt
    push eax
    call LoadLibrary /* 这一句写法也是错误的。*/
    mov esp, ebp /* 这句也是多余的 */
  }
}

修改如下:
#include <windows.h>
#include <stdio.h>

void main()
{
  char *msvcrt = "msvcrt.dll";
  __asm
  {
    mov eax, msvcrt
    push eax
    call DWORD ptr [LoadLibrary]
  }
}

谢谢虾爷的指点!

C技巧:VC函数调用的汇编代码

主要谈谈vc里面函数调用汇编成汇编代码的情形,首先针对之前的一个小程序,说说vc编译器的优化。   例子程序:   #include   using namespace std;   int...

使用DbgHelp获取函数调用堆栈之inline assembly(内联汇编)法

http://www.cnblogs.com/lbq1221119/archive/2008/04/18/1159956.html 如果想自己获取应用程序的Call Stack,就需要查...

使用DbgHelp获取函数调用堆栈之inline assembly(内联汇编)法

如果想自己获取应用程序的Call Stack,就需要查看Stack的内容。Stack Walker,在最近查看SSCLI源码的时候发现这个东西是和Stack Frame紧密联系在一起的。 Walki...
  • weiqubo
  • weiqubo
  • 2013年12月04日 16:35
  • 1213

利用VC中函数调用一个.exe文件

以前总是感觉各大项目之间的结合很神奇,今日一见“不过如此”。 写一个利用VC调用ACDSee打开一个图片文件的简单程序,于是了解了一些VC中调用其他程序的方法。 VC中调用其他程序的方...
  • welshon
  • welshon
  • 2013年12月19日 16:41
  • 599

通过VC学习反汇编——函数调用

1         参数传递(默认调用约定) 用VC6.0新建一个空的控制台应用程序,新建源文件main.c,编写如下代码,注意用debug编译,不要用release,以免代码被VC优化,反汇编对应...
  • gyh198
  • gyh198
  • 2011年10月17日 20:05
  • 1437

VC 资源和函数调用

资源  凡是运用程序要用到数据就叫资源。  资源是被链入运用程序当中的,但有时看不见资源,只有一个exe文件,这是因为资源已经被链入可执行文件中去了,也就是说,资源被编译为二进制文件,像源...

VC++中的函数调用(CALLBACK WINAPI PASCAL 等)

#define   CALLBACK         __stdcall    #define   WINAPI             __stdcall    #define   WINAP...

VC++自释放指针、自释放虚拟内存、自关闭句柄、局部作用域回调函数调用等辅助开发类

VC++自释放指针、自释放虚拟内存、自关闭句柄、局部作用域回调函数调用等辅助开发类...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:用VC写Assembly代码(5) --函数调用(一)
举报原因:
原因补充:

(最多只允许输入30个字)