繁体中文  设为首页  加入收藏 
当前位置:学院首页 >> 开发 >> 木马编程 >> 在Visual C++中使用内联汇编


在Visual C++中使用内联汇编 (2)

2008-04-10 17:02:29  www.hackbase.com  来源:互联网
在 Visual C++ 中使用内联汇编 一、内联汇编的优缺点 因为在Visual C++中使用内联汇编不需要额外的编译器和联接器,且可以处理Visual C++中不能处理的一些事情,而且可以使用在C/C++中的变量,所以非常方 ...


 注意:函数参数是从右向左压栈。 
 不能够访问C++中的类成员函数,但是可以访问extern "C"函数。 
 如果调用Windows API函数,则不需要自己清除堆栈,因为API的返回指令是RET n,会自动清除堆栈 
 比如下面的例子: 
 #include <windows.h> 
 char szAppName[] = "API Test"; 
 void main() 
 { 
 char szHello[] = "Hello, world!"; 
 __asm 
 { 
 PUSHMB_OK or MB_ICONINformATION 
 PUSHOFFSET szAppName; 全局变量用OFFSET 
 LEA EAX, szHello; 局部变量用LEA 
 PUSHEAX 
 PUSH0 
 CALLDWORD PTR [MessageBoxA] ; 注意这里,我费了好大周折才发现不是CALL MessageBoxA 
 } 
 } 
 一般来说,在Visual C++中使用内联汇编是为了提高速度,因此这些函数调用尽可能用C/C++写。 

八、一个例子 
 下面的例子是在VS.NET(即VC7)中C语言写的。先建一个工程,将下列代码放到工程中的.c文件中编译,无需作特别的设置,即可编译通过。 

//////////////////////////////////////////////////////////////////////////////////////////////////// 
 //预处理 
 #include <Windows.h> 
 //////////////////////////////////////////////////////////////////////////////////////////////////// 

 //////////////////////////////////////////////////////////////////////////////////////////////////// 
 //全局变量 
 HWND g_hWnd; 
 HINSTANCE g_hInst; 
 TCHAR szTemp[1024]; 
 TCHAR szAppName[] = "CRC32 Sample"; 
 //////////////////////////////////////////////////////////////////////////////////////////////////// 

 //////////////////////////////////////////////////////////////////////////////////////////////////// 
 //函数声明 
 DWORD GetCRC32(const BYTE *pbData, int nSize); 
 int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int iCmdShow); 
 LRESULT CALLBACK WindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam); 
 //////////////////////////////////////////////////////////////////////////////////////////////////// 

 //////////////////////////////////////////////////////////////////////////////////////////////////// 
 //主函数 
 int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int iCmdShow) 
 { 
 MSG msg; 
 WNDCLASSEX wndClassEx; 
 g_hInst = hInstance; 
 wndClassEx.cbSize = sizeof(WNDCLASSEX); 
 wndClassEx.style = CS_VREDRAW | CS_HREDRAW; 
 wndClassEx.lpfnWndProc = (WNDPROC) WindowProc; 
 wndClassEx.cbClsExtra = 0; 
 wndClassEx.cbWndExtra = 0; 
 wndClassEx.hInstance = g_hInst; 
 wndClassEx.hIcon = LoadIcon(NULL, IDI_APPLICATION); 
 wndClassEx.hCursor = LoadCursor(NULL, IDC_ARROW); 
 wndClassEx.hbrBackground = (HBRUSH) (COLOR_WINDOW); 
 wndClassEx.lpszMenuName = NULL; 
 wndClassEx.lpszClassName = szAppName; 
 wndClassEx.hIconSm = NULL; 
 RegisterClassEx(&wndClassEx); 
 g_hWnd = CreateWindowEx(0, szAppName, szAppName, WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU | WS_THICK<I>FRame</I> | WS_MINIMIZEBOX, 
 CW_USEDEFAULT, CW_USEDEFAULT, 300, 70, 
 NULL, NULL, g_hInst, NULL); 
 ShowWindow(g_hWnd, iCmdShow); 
 UpdateWindow(g_hWnd); 
 while (GetMessage(&msg, NULL, 0, 0)) 
 { 
 TranslateMessage(&msg); 
 DispatchMessage(&msg); 
 } 
 return ((int) msg.wParam); 
 } 
 //////////////////////////////////////////////////////////////////////////////////////////////////// 
 //////////////////////////////////////////////////////////////////////////////////////////////////// 
 //主窗口回调函数 
 LRESULT CALLBACK WindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) 
 { 
 switch (uMsg) 
 { 
 case WM_CREATE: 
 CreateWindowEx(WS_EX_CLIENTEDGE, "EDIT", NULL, WS_CHILD | WS_VISIBLE | WS_BORDER | ES_AUTOHSCROLL | ES_AUTOVSCROLL | ES_NOHIDESEL | WS_OVERLAPPED, 
 7, 12, 220, 22, 
 hWnd, (HMENU)1000, g_hInst, NULL); 
 CreateWindowEx(0, "BUTTON", "&OK", WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON | WS_OVERLAPPED | BS_FLAT, 
 244, 12, 40, 20, 
 hWnd, (HMENU)IDOK, g_hInst, NULL); 
 break; 
 case WM_COMMAND: 
 switch (LOWORD(wParam)) 
 { 
 case IDOK: 
 GetDlgItemText(g_hWnd, 1000, szTemp + 100, 800); 
 wsprintf(szTemp, "当前文本框内的字符串的CRC32校验码是: 0x%lX", GetCRC32(szTemp + 100, (int)strlen(szTemp + 100))); 
 MessageBox(g_hWnd, szTemp, szAppName, MB_OK|MB_ICONINformATION); 
 } 
 break; 
 case WM_DESTROY: 
 PostQuitMessage(0); 
 break; 
 default: 
 return (DefWindowProc(hWnd, uMsg, wParam, lParam)); 
 } 
 return (0); 
 } 
 //////////////////////////////////////////////////////////////////////////////////////////////////// 

 //////////////////////////////////////////////////////////////////////////////////////////////////// 
 //GetCRC32: 求字节流的CRC32校验码 
 //参数: 
 //pbData: 指向字节流缓冲区首地址 
 //nSize: 字节流长度 
 // 
 //返回值: 
 //字节流的CRC32校验码 
 // 
 //这里使用查表法求CRC32校验码,这部分是参考老罗的文章《 矛与盾的较量(2)——CRC原理篇》该写的。 
 //原文的具体内容请参看: http://www.luocong.com/articles/show_article.asp?Article_ID=15 
 // 
 //下面使用内联汇编求CRC32校验码,充分使用了CPU中的寄存器,速度和方便性都是使用C/C++所不能比拟的 
 // 
 DWORD GetCRC32(const BYTE *pbData, int nSize) 
 { 
 DWORD dwCRC32Table[256]; 
 __asm //这片内联汇编是初始化CRC32表 
 { 
 MOV ECX, 256 
 _NextTable: 
 LEA EAX, [ECX-1] 
 PUSHECX 
 MOV ECX, 8 
 _NextBit: 
 SHR EAX, 1 
 JNC _NotCarry 
 XOR EAX, 0xEDB88320 
 _NotCarry: 
 DEC ECX 
 JNZ _NextBit 
 POP ECX 
 MOV [dwCRC32Table + ECX*4 - 4], EAX 
 DEC ECX 
 JNZ _NextTable 
 } 
 __asm //下面是求CRC32校验码 
 { 
 MOV EAX, -1 
 MOV EBX, pbData 
 OREBX, EBX 
 JZ_Done 
 MOV ECX, nSize 
 ORECX, ECX 
 JZ_Done 
 _NextByte: 
 MOV DL, [EBX] 
 XOR DL, AL 
 MOVZX EDX, DL 
 SHR EAX, 8 
 XOR EAX, [dwCRC32Table + EDX*4] 
 INC EBX 
 LOOP_NextByte 
 _Done: 
 NOT EAX 
 } 
 } 
 //////////////////////////////////////////////////////////////////////////////////////////////////// 

九、后话 
 本来打算写个综合各种内联汇编用法的例子,由于本人拖拖拉拉的习惯,虽经dREAMtHEATER多次催促,到最后还是不免草草了事。如果有什么谬误或不明之处,欢迎批评指正并一起探讨(QQ: 123018)。 
  Yonsm@163.com 
 2002.9.3 
============================================================== 
>> 参考资料: 
 1.Sunwen,《VC内联ASM汇编学习笔记》 
 2.老罗,《矛与盾的较量(2)——CRC原理篇》 
 3.Microsoft,《MSDN Library - January 2001》 
~·全文完 ·~ 

关键字:Visual C++ 内联 汇编
[1] [2]

责任编辑:黑客基地        



本文引用网址: 

在Visual C++中使用内联汇编的相关文章
发表评论