note : 使用宏简化代码的输入
在开源工程中, 看到类似下面的代码很蛋疼. ReLoadNtosCALL((PVOID)(&RObReferenceObjectByHandle),L"ObReferenceObjectByHandle",g_ulSystemKernelModuleBase,(ULONG)g_pImageModuleBase);ReLoadNtosCALL((PVOID)(&RKeInitializ
·
在开源工程中, 看到类似下面的代码很蛋疼.
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
TITLE D:\LsTemp\test\testMicro\testMicro.cpp
.686P
.XMM
include listing.inc
.model flat
INCLUDELIB MSVCRTD
INCLUDELIB OLDNAMES
PUBLIC ??_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 _wmain
EXTRN __imp__getwchar:PROC
EXTRN __imp__wprintf:PROC
EXTRN __imp__wcscpy:PROC
EXTRN ___security_cookie:DWORD
EXTRN @__security_check_cookie@4:PROC
EXTRN @_RTC_CheckStackVars@8:PROC
EXTRN __RTC_CheckEsp:PROC
EXTRN __RTC_Shutdown:PROC
EXTRN __RTC_InitBase:PROC
; COMDAT ??_C@_19EEPNDKNE@?$AA?$CF?$AAs?$AA?$AN?$AA?6?$AA?$AA@
; File d:\lstemp\test\testmicro\testmicro.cpp
CONST 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$TMZ
rtc$TMZ SEGMENT
__RTC_Shutdown.rtc$TMZ DD FLAT:__RTC_Shutdown
rtc$TMZ ENDS
; COMDAT rtc$IMZ
rtc$IMZ SEGMENT
__RTC_InitBase.rtc$IMZ DD FLAT:__RTC_InitBase
; Function compile flags: /Odtp /RTCsu /ZI
rtc$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 ENDS
END
可以看到, 宏操作的串确实为一个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__
更多推荐
已为社区贡献10条内容
所有评论(0)