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在VS2010IDE, 设置列表文件输出./// 测试字符串和变量名有关联时, 如何定义一个合适的宏, 简化输入/// _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;}
打开 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 如侵犯您的版权,请留言回复原文章的地址,我们会给您删除此文章,给您带来不便请您谅解!
发表评论
最新留言
不错!
[***.144.177.141]2024年04月10日 07时53分37秒
关于作者
喝酒易醉,品茶养心,人生如梦,品茶悟道,何以解忧?唯有杜康!
-- 愿君每日到此一游!
推荐文章
scala var val
2019-05-01
oracle sql
2019-05-01
java.net.BindException: 无法指定被请求的地址
2019-05-01
scala list
2019-05-01
多人协作流程与规范
2019-05-01
k8s设置阿里云仓库
2019-05-01
svn服务器安装
2019-05-01
spark 笔记1
2019-05-01
SVN服务器多个项目的权限分组管理
2019-05-01
svn 没有作者信息) | (没有时间信息
2019-05-01
shell笔记1
2019-05-01
shell参数
2019-05-01
shell dirname basename
2019-05-01
eureka rest operations
2019-05-01
线程分析
2019-05-01
jenkins
2019-05-01
DOM(总结)
2019-05-01
JS判断一个数据的数据类型
2019-05-01
MySQL学习总结(一)
2019-05-01
MySQL学习总结(二)
2019-05-01