您的位置:首页 > 编程语言

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

2006-06-07 19:24 429 查看
用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]
}
}

谢谢虾爷的指点!
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: