note : 使用宏简化代码的输入
发布日期:2021-06-30 22:01:34 浏览次数:2 分类:技术文章

本文共 6863 字,大约阅读时间需要 22 分钟。

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

 

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 
/// 测试字符串和变量名有关联时, 如何定义一个合适的宏, 简化输入/// _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 	TITLE	D:\LsTemp\test\testMicro\testMicro.cpp	.686P	.XMM	include listing.inc	.model	flatINCLUDELIB 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.cppCONST	SEGMENT??_C@_19EEPNDKNE@?$AA?$CF?$AAs?$AA?$AN?$AA?6?$AA?$AA@ DB '%', 00H, 's', 00H	DB	0dH, 00H, 0aH, 00H, 00H, 00H			; `string'CONST	ENDS;	COMDAT ??_C@_19IIICNMM@?$AAM?$AAs?$AAg?$AA1?$AA?$AA@CONST	SEGMENT??_C@_19IIICNMM@?$AAM?$AAs?$AAg?$AA1?$AA?$AA@ DB 'M', 00H, 's', 00H, 'g', 00H	DB	'1', 00H, 00H, 00H				; `string'CONST	ENDS;	COMDAT rtc$TMZrtc$TMZ	SEGMENT__RTC_Shutdown.rtc$TMZ DD FLAT:__RTC_Shutdownrtc$TMZ	ENDS;	COMDAT rtc$IMZrtc$IMZ	SEGMENT__RTC_InitBase.rtc$IMZ DD FLAT:__RTC_InitBase; Function compile flags: /Odtp /RTCsu /ZIrtc$IMZ	ENDS;	COMDAT _wmain_TEXT	SEGMENT_szMsg1$ = -528						; size = 520__$ArrayPad$ = -4					; size = 4_argc$ = 8						; size = 4_argv$ = 12						; size = 4_wmain	PROC						; COMDAT; 13   : {  00000	55		 push	 ebp  00001	8b ec		 mov	 ebp, esp  00003	81 ec d4 02 00	00		 sub	 esp, 724		; 000002d4H  00009	53		 push	 ebx  0000a	56		 push	 esi  0000b	57		 push	 edi  0000c	8d bd 2c fd ff	ff		 lea	 edi, DWORD PTR [ebp-724]  00012	b9 b5 00 00 00	 mov	 ecx, 181		; 000000b5H  00017	b8 cc cc cc cc	 mov	 eax, -858993460		; ccccccccH  0001c	f3 ab		 rep stosd  0001e	a1 00 00 00 00	 mov	 eax, DWORD PTR ___security_cookie  00023	33 c5		 xor	 eax, ebp  00025	89 45 fc	 mov	 DWORD PTR __$ArrayPad$[ebp], eax; 14   :     wchar_t szMsg1[_MAX_PATH];; 15   : ; 16   :     // _tcscpy(szMsg, L"Msg");; 17   :     MY_PRINT(Msg1)  00028	8b f4		 mov	 esi, esp  0002a	68 00 00 00 00	 push	 OFFSET ??_C@_19IIICNMM@?$AAM?$AAs?$AAg?$AA1?$AA?$AA@  0002f	8d 85 f0 fd ff	ff		 lea	 eax, DWORD PTR _szMsg1$[ebp]  00035	50		 push	 eax  00036	ff 15 00 00 00	00		 call	 DWORD PTR __imp__wcscpy  0003c	83 c4 08	 add	 esp, 8  0003f	3b f4		 cmp	 esi, esp  00041	e8 00 00 00 00	 call	 __RTC_CheckEsp; 18   : ; 19   :     _tprintf(L"%s\r\n", szMsg1);  00046	8b f4		 mov	 esi, esp  00048	8d 85 f0 fd ff	ff		 lea	 eax, DWORD PTR _szMsg1$[ebp]  0004e	50		 push	 eax  0004f	68 00 00 00 00	 push	 OFFSET ??_C@_19EEPNDKNE@?$AA?$CF?$AAs?$AA?$AN?$AA?6?$AA?$AA@  00054	ff 15 00 00 00	00		 call	 DWORD PTR __imp__wprintf  0005a	83 c4 08	 add	 esp, 8  0005d	3b f4		 cmp	 esi, esp  0005f	e8 00 00 00 00	 call	 __RTC_CheckEsp; 20   : ; 21   :     getwchar();  00064	8b f4		 mov	 esi, esp  00066	ff 15 00 00 00	00		 call	 DWORD PTR __imp__getwchar  0006c	3b f4		 cmp	 esi, esp  0006e	e8 00 00 00 00	 call	 __RTC_CheckEsp; 22   : 	return 0;  00073	33 c0		 xor	 eax, eax; 23   : }  00075	52		 push	 edx  00076	8b cd		 mov	 ecx, ebp  00078	50		 push	 eax  00079	8d 15 00 00 00	00		 lea	 edx, DWORD PTR $LN5@wmain  0007f	e8 00 00 00 00	 call	 @_RTC_CheckStackVars@8  00084	58		 pop	 eax  00085	5a		 pop	 edx  00086	5f		 pop	 edi  00087	5e		 pop	 esi  00088	5b		 pop	 ebx  00089	8b 4d fc	 mov	 ecx, DWORD PTR __$ArrayPad$[ebp]  0008c	33 cd		 xor	 ecx, ebp  0008e	e8 00 00 00 00	 call	 @__security_check_cookie@4  00093	81 c4 d4 02 00	00		 add	 esp, 724		; 000002d4H  00099	3b ec		 cmp	 ebp, esp  0009b	e8 00 00 00 00	 call	 __RTC_CheckEsp  000a0	8b e5		 mov	 esp, ebp  000a2	5d		 pop	 ebp  000a3	c3		 ret	 0$LN5@wmain:  000a4	01 00 00 00	 DD	 1  000a8	00 00 00 00	 DD	 $LN4@wmain$LN4@wmain:  000ac	f0 fd ff ff	 DD	 -528			; fffffdf0H  000b0	08 02 00 00	 DD	 520			; 00000208H  000b4	00 00 00 00	 DD	 $LN3@wmain$LN3@wmain:  000b8	73		 DB	 115			; 00000073H  000b9	7a		 DB	 122			; 0000007aH  000ba	4d		 DB	 77			; 0000004dH  000bb	73		 DB	 115			; 00000073H  000bc	67		 DB	 103			; 00000067H  000bd	31		 DB	 49			; 00000031H  000be	00		 DB	 0_wmain	ENDP_TEXT	ENDSEND

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

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

宏操作该串的语句也为_tcscpy

; 17   :     MY_PRINT(Msg1)  00028	8b f4		 mov	 esi, esp  0002a	68 00 00 00 00	 push	 OFFSET ??_C@_19IIICNMM@?$AAM?$AAs?$AAg?$AA1?$AA?$AA@  0002f	8d 85 f0 fd ff	ff		 lea	 eax, DWORD PTR _szMsg1$[ebp]  00035	50		 push	 eax  00036	ff 15 00 00 00	00		 call	 DWORD PTR __imp__wcscpy  0003c	83 c4 08	 add	 esp, 8  0003f	3b f4		 cmp	 esi, esp  00041	e8 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__

 

 

 

 

转载地址:https://lostspeed.blog.csdn.net/article/details/10031147 如侵犯您的版权,请留言回复原文章的地址,我们会给您删除此文章,给您带来不便请您谅解!

上一篇:note : get address of KiFastCallEntry
下一篇:在QT4.7中使用QJson

发表评论

最新留言

不错!
[***.144.177.141]2024年04月10日 07时53分37秒

关于作者

    喝酒易醉,品茶养心,人生如梦,品茶悟道,何以解忧?唯有杜康!
-- 愿君每日到此一游!

推荐文章