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__
- note : 使用宏简化代码的输入
- 在NetBeans中使用代码模板及宏功能简化输入
- TiXmlHandle的使用-简化tinyxml的代码
- 使用二级指针简化臃肿的代码
- 使用Lombok简化java代码的编写
- 使用Lombok简化你的代码
- lombok的使用,简化代码又省力
- 208,使用#define宏定义简化代码
- lombok使用,简化代码
- 懒人代码-简化ActivityIndicatorView的创建和使用代码
- typedef的代码简化
- jquery中使用javascript的with简化代码的写法
- 使用Python简化循环代码
- 使用Lombok简化Java代码
- 使用反射、特性简化代码
- 使用 lombok 简化 Java 代码
- 使用Lambda表达式来简化我们的代码
- 使用Graph库的多种机制来简化BFS代码
- Python变量类型及变量引用
- DSP之中断总结篇
- Linux 查看网络流量脚本(两种)
- Flex索引数组
- shh整合后web.xml、spring配置文件和struts.xml的内容
- note : 使用宏简化代码的输入
- 内核通知链机制的原理及实现
- 冒泡排序
- poj 2421
- Android系统信息获取 之十一:获取IMEI,IMSI号
- libcurl多线程超时设置不安全
- css简介(二)property
- 求两个数的最大值
- Java 自动装箱与拆箱