note : 使用宏简化代码的输入

来源:互联网 发布:淘宝怎么给五星好评 编辑:程序博客网 时间:2024/05/16 05:33

在开源工程中, 看到类似下面的代码很蛋疼.

 

ReLoadNtosCALL((PVOID)(&RObReferenceObjectByHandle),L"ObReferenceObjectByHandle",g_ulSystemKernelModuleBase,(ULONG)g_pImageModuleBase);ReLoadNtosCALL((PVOID)(&RKeInitializeEvent),L"KeInitializeEvent",g_ulSystemKernelModuleBase,(ULONG)g_pImageModuleBase);ReLoadNtosCALL((PVOID)(&RIoAllocateIrp),L"IoAllocateIrp",g_ulSystemKernelModuleBase,(ULONG)g_pImageModuleBase);ReLoadNtosCALL((PVOID)(&RIoCallDriver),L"IoCallDriver",g_ulSystemKernelModuleBase,(ULONG)g_pImageModuleBase);ReLoadNtosCALL((PVOID)(&RKeWaitForSingleObject),L"KeWaitForSingleObject",g_ulSystemKernelModuleBase,(ULONG)g_pImageModuleBase);


如果是一句就算了,关键是铺天盖地的都是.

该函数的后两个参数是全局的, 由于原版没有加 g_ 来标记,改的时候,花了一些时间.

如果是用宏来写, 那只需要改该宏的定义.

 

这是内核重载用的, 进了一个自己的函数, 如果要用到内核API, 都要用自己重载的那份.

所以在工程中,到处都是 ReLoadNtosCALL函数.

经过观察, 这句代码只有前2个参数是不同的,且有关联性。

如果搞成一个宏, 会使工程的可读性,可维护性提高.

 

做了一个试验, 验证了宏的写法, 用.cod文件做了验证,宏写的正确.

// testMicro.cpp : Defines the entry point for the console application.//#include "stdafx.h"#include <windows.h>/// 测试字符串和变量名有关联时, 如何定义一个合适的宏, 简化输入/// _tcscpy(szMsg, L"Msg");#define MY_PRINT(x) _tcscpy(sz##x, L#x);int _tmain(int argc, _TCHAR* argv[]){    wchar_t szMsg1[_MAX_PATH];    // _tcscpy(szMsg, L"Msg");    MY_PRINT(Msg1)    _tprintf(L"%s\r\n", szMsg1);    getwchar();return 0;}


在VS2010IDE, 设置列表文件输出.

打开 testMicro.cod , 查看 testMicro.cpp 编译产生的内容, 看是自己是否将宏写对了?

; Listing generated by Microsoft (R) Optimizing Compiler Version 16.00.40219.01 TITLED:\LsTemp\test\testMicro\testMicro.cpp.686P.XMMinclude listing.inc.modelflatINCLUDELIB MSVCRTDINCLUDELIB OLDNAMESPUBLIC??_C@_19EEPNDKNE@?$AA?$CF?$AAs?$AA?$AN?$AA?6?$AA?$AA@ ; `string'PUBLIC??_C@_19IIICNMM@?$AAM?$AAs?$AAg?$AA1?$AA?$AA@; `string'PUBLIC__$ArrayPad$PUBLIC_wmainEXTRN__imp__getwchar:PROCEXTRN__imp__wprintf:PROCEXTRN__imp__wcscpy:PROCEXTRN___security_cookie:DWORDEXTRN@__security_check_cookie@4:PROCEXTRN@_RTC_CheckStackVars@8:PROCEXTRN__RTC_CheckEsp:PROCEXTRN__RTC_Shutdown:PROCEXTRN__RTC_InitBase:PROC;COMDAT ??_C@_19EEPNDKNE@?$AA?$CF?$AAs?$AA?$AN?$AA?6?$AA?$AA@; File d:\lstemp\test\testmicro\testmicro.cppCONSTSEGMENT??_C@_19EEPNDKNE@?$AA?$CF?$AAs?$AA?$AN?$AA?6?$AA?$AA@ DB '%', 00H, 's', 00HDB0dH, 00H, 0aH, 00H, 00H, 00H; `string'CONSTENDS;COMDAT ??_C@_19IIICNMM@?$AAM?$AAs?$AAg?$AA1?$AA?$AA@CONSTSEGMENT??_C@_19IIICNMM@?$AAM?$AAs?$AAg?$AA1?$AA?$AA@ DB 'M', 00H, 's', 00H, 'g', 00HDB'1', 00H, 00H, 00H; `string'CONSTENDS;COMDAT rtc$TMZrtc$TMZSEGMENT__RTC_Shutdown.rtc$TMZ DD FLAT:__RTC_Shutdownrtc$TMZENDS;COMDAT rtc$IMZrtc$IMZSEGMENT__RTC_InitBase.rtc$IMZ DD FLAT:__RTC_InitBase; Function compile flags: /Odtp /RTCsu /ZIrtc$IMZENDS;COMDAT _wmain_TEXTSEGMENT_szMsg1$ = -528; size = 520__$ArrayPad$ = -4; size = 4_argc$ = 8; size = 4_argv$ = 12; size = 4_wmainPROC; COMDAT; 13   : {  0000055 push ebp  000018b ec mov ebp, esp  0000381 ec d4 02 0000 sub esp, 724; 000002d4H  0000953 push ebx  0000a56 push esi  0000b57 push edi  0000c8d bd 2c fd ffff lea edi, DWORD PTR [ebp-724]  00012b9 b5 00 00 00 mov ecx, 181; 000000b5H  00017b8 cc cc cc cc mov eax, -858993460; ccccccccH  0001cf3 ab rep stosd  0001ea1 00 00 00 00 mov eax, DWORD PTR ___security_cookie  0002333 c5 xor eax, ebp  0002589 45 fc mov DWORD PTR __$ArrayPad$[ebp], eax; 14   :     wchar_t szMsg1[_MAX_PATH];; 15   : ; 16   :     // _tcscpy(szMsg, L"Msg");; 17   :     MY_PRINT(Msg1)  000288b f4 mov esi, esp  0002a68 00 00 00 00 push OFFSET ??_C@_19IIICNMM@?$AAM?$AAs?$AAg?$AA1?$AA?$AA@  0002f8d 85 f0 fd ffff lea eax, DWORD PTR _szMsg1$[ebp]  0003550 push eax  00036ff 15 00 00 0000 call DWORD PTR __imp__wcscpy  0003c83 c4 08 add esp, 8  0003f3b f4 cmp esi, esp  00041e8 00 00 00 00 call __RTC_CheckEsp; 18   : ; 19   :     _tprintf(L"%s\r\n", szMsg1);  000468b f4 mov esi, esp  000488d 85 f0 fd ffff lea eax, DWORD PTR _szMsg1$[ebp]  0004e50 push eax  0004f68 00 00 00 00 push OFFSET ??_C@_19EEPNDKNE@?$AA?$CF?$AAs?$AA?$AN?$AA?6?$AA?$AA@  00054ff 15 00 00 0000 call DWORD PTR __imp__wprintf  0005a83 c4 08 add esp, 8  0005d3b f4 cmp esi, esp  0005fe8 00 00 00 00 call __RTC_CheckEsp; 20   : ; 21   :     getwchar();  000648b f4 mov esi, esp  00066ff 15 00 00 0000 call DWORD PTR __imp__getwchar  0006c3b f4 cmp esi, esp  0006ee8 00 00 00 00 call __RTC_CheckEsp; 22   : return 0;  0007333 c0 xor eax, eax; 23   : }  0007552 push edx  000768b cd mov ecx, ebp  0007850 push eax  000798d 15 00 00 0000 lea edx, DWORD PTR $LN5@wmain  0007fe8 00 00 00 00 call @_RTC_CheckStackVars@8  0008458 pop eax  000855a pop edx  000865f pop edi  000875e pop esi  000885b pop ebx  000898b 4d fc mov ecx, DWORD PTR __$ArrayPad$[ebp]  0008c33 cd xor ecx, ebp  0008ee8 00 00 00 00 call @__security_check_cookie@4  0009381 c4 d4 02 0000 add esp, 724; 000002d4H  000993b ec cmp ebp, esp  0009be8 00 00 00 00 call __RTC_CheckEsp  000a08b e5 mov esp, ebp  000a25d pop ebp  000a3c3 ret 0$LN5@wmain:  000a401 00 00 00 DD 1  000a800 00 00 00 DD $LN4@wmain$LN4@wmain:  000acf0 fd ff ff DD -528; fffffdf0H  000b008 02 00 00 DD 520; 00000208H  000b400 00 00 00 DD $LN3@wmain$LN3@wmain:  000b873 DB 115; 00000073H  000b97a DB 122; 0000007aH  000ba4d DB 77; 0000004dH  000bb73 DB 115; 00000073H  000bc67 DB 103; 00000067H  000bd31 DB 49; 00000031H  000be00 DB 0_wmainENDP_TEXTENDSEND


可以看到,  宏操作的串确实为一个const wchar_t *

;COMDAT ??_C@_19IIICNMM@?$AAM?$AAs?$AAg?$AA1?$AA?$AA@CONSTSEGMENT??_C@_19IIICNMM@?$AAM?$AAs?$AAg?$AA1?$AA?$AA@ DB 'M', 00H, 's', 00H, 'g', 00HDB'1', 00H, 00H, 00H; `string'


宏操作该串的语句也为_tcscpy

; 17   :     MY_PRINT(Msg1)  000288b f4 mov esi, esp  0002a68 00 00 00 00 push OFFSET ??_C@_19IIICNMM@?$AAM?$AAs?$AAg?$AA1?$AA?$AA@  0002f8d 85 f0 fd ffff lea eax, DWORD PTR _szMsg1$[ebp]  0003550 push eax  00036ff 15 00 00 0000 call DWORD PTR __imp__wcscpy  0003c83 c4 08 add esp, 8  0003f3b f4 cmp esi, esp  00041e8 00 00 00 00 call __RTC_CheckEsp


用类似的宏替换完成后, 工程会清爽好多.

 

最终版 宏定义的文件:

/// @file       ReLoadNtOsDefine.h/// @note       重载内核API的宏定义, 使程序的书写简洁些#ifndef __RE_LOAD_NT_OS_DEFINE_H__#define __RE_LOAD_NT_OS_DEFINE_H__/// ReLoadNtosCALL Micro Define/// 宏的例子/// _tcscpy(szMsg, L"Msg");/// #define MY_PRINT(x) _tcscpy(sz##x, L#x);#define  RE_LOAD_NTOS_CALL_API_NAME(x) ReLoadNtosCALL((PVOID)(&R##x),L#x,g_ulSystemKernelModuleBase,(ULONG)g_pImageModuleBase);#define  RE_LOAD_NTOS_CALL_ExAllocatePool           RE_LOAD_NTOS_CALL_API_NAME(ExAllocatePool)#define  RE_LOAD_NTOS_CALL_ExFreePool               RE_LOAD_NTOS_CALL_API_NAME(ExFreePool)#define  RE_LOAD_NTOS_CALL_memcpy                   RE_LOAD_NTOS_CALL_API_NAME(memcpy)#endif  // #ifndef __RE_LOAD_NT_OS_DEFINE_H__


 

 

 


 

原创粉丝点击