網站首頁 編程語言 正文
在內核編程中字符串有兩種格式ANSI_STRING
與UNICODE_STRING
,這兩種格式是微軟推出的安全版本的字符串結構體,也是微軟推薦使用的格式,通常情況下ANSI_STRING
代表的類型是char *
也就是ANSI多字節模式的字符串,而UNICODE_STRING
則代表的是wchar*
也就是UNCODE類型的字符,如下文章將介紹這兩種字符格式在內核中是如何轉換的。
在內核開發模式下初始化字符串也需要調用專用的初始化函數,如下分別初始化ANSI和UNCODE字符串,我們來看看代碼是如何實現的。
#include <ntifs.h> #include <ntstrsafe.h> VOID UnDriver(PDRIVER_OBJECT driver) { DbgPrint("驅動卸載成功 \n"); } NTSTATUS DriverEntry(IN PDRIVER_OBJECT Driver, PUNICODE_STRING RegistryPath) { // 定義內核字符串 ANSI_STRING ansi; UNICODE_STRING unicode; UNICODE_STRING str; // 定義普通字符串 char * char_string = "hello lyshark"; wchar_t *wchar_string = (WCHAR*)"hello lyshark"; // 初始化字符串的多種方式 RtlInitAnsiString(&ansi, char_string); RtlInitUnicodeString(&unicode, wchar_string); RtlUnicodeStringInit(&str, L"hello lyshark"); // 改變原始字符串(亂碼位置,此處僅用于演示賦值方式) char_string[0] = (CHAR)"A"; // char類型每個占用1字節 char_string[1] = (CHAR)"B"; wchar_string[0] = (WCHAR)"A"; // wchar類型每個占用2字節 wchar_string[2] = (WCHAR)"B"; // 輸出字符串 %Z DbgPrint("輸出ANSI: %Z \n", &ansi); DbgPrint("輸出WCHAR: %Z \n", &unicode); DbgPrint("輸出字符串: %wZ \n", &str); DbgPrint("驅動加載成功 \n"); Driver->DriverUnload = UnDriver; return STATUS_SUCCESS; }
代碼輸出效果:
內核中還可實現字符串與整數之間的靈活轉換,內核中提供了RtlUnicodeStringToInteger
這個函數來實現字符串轉整數,與之對應的RtlIntegerToUnicodeString
則是將整數轉為字符串這兩個內核函數也是非常常用的。
#include <ntifs.h> #include <ntstrsafe.h> VOID UnDriver(PDRIVER_OBJECT driver) { DbgPrint("驅動卸載成功 \n"); } // Power: lyshark NTSTATUS DriverEntry(IN PDRIVER_OBJECT Driver, PUNICODE_STRING RegistryPath) { NTSTATUS flag; ULONG number; DbgPrint("hello lyshark \n"); UNICODE_STRING uncode_buffer_source = { 0 }; UNICODE_STRING uncode_buffer_target = { 0 }; // 字符串轉為數字 // By:LyShark RtlInitUnicodeString(&uncode_buffer_source, L"100"); flag = RtlUnicodeStringToInteger(&uncode_buffer_source, 10, &number); if (NT_SUCCESS(flag)) { DbgPrint("字符串 -> 數字: %d \n", number); } // 數字轉為字符串 uncode_buffer_target.Buffer = (PWSTR)ExAllocatePool(PagedPool, 1024); uncode_buffer_target.MaximumLength = 1024; flag = RtlIntegerToUnicodeString(number, 10, &uncode_buffer_target); if (NT_SUCCESS(flag)) { DbgPrint("數字 -> 字符串: %wZ \n", &uncode_buffer_target); } // 釋放堆空間 RtlFreeUnicodeString(&uncode_buffer_target); DbgPrint("驅動加載成功 \n"); Driver->DriverUnload = UnDriver; return STATUS_SUCCESS; }
代碼輸出效果:
繼續看另一種轉換模式,將UNICODE_STRING
結構轉換成ANSI_STRING
結構,代碼中調用了RtlUnicodeStringToAnsiString
內核函數,該函數也是微軟提供的。
#include <ntifs.h> #include <ntstrsafe.h> VOID UnDriver(PDRIVER_OBJECT driver) { DbgPrint("驅動卸載成功 \n"); } // Power: lyshark NTSTATUS DriverEntry(IN PDRIVER_OBJECT Driver, PUNICODE_STRING RegistryPath) { DbgPrint("hello lyshark \n"); UNICODE_STRING uncode_buffer_source = { 0 }; ANSI_STRING ansi_buffer_target = { 0 }; // 初始化 UNICODE 字符串 RtlInitUnicodeString(&uncode_buffer_source, L"hello lyshark"); // 轉換函數 NTSTATUS flag = RtlUnicodeStringToAnsiString(&ansi_buffer_target, &uncode_buffer_source, TRUE); if (NT_SUCCESS(flag)) { DbgPrint("ANSI: %Z \n", &ansi_buffer_target); } // 銷毀ANSI字符串 RtlFreeAnsiString(&ansi_buffer_target); DbgPrint("驅動加載成功 \n"); Driver->DriverUnload = UnDriver; return STATUS_SUCCESS; }
代碼輸出效果:
如果將上述過程反過來,將ANSI_STRING
轉換為UNICODE_STRING
結構,則需要調用RtlAnsiStringToUnicodeString
這個內核專用函數實現。
#include <ntifs.h> #include <ntstrsafe.h> VOID UnDriver(PDRIVER_OBJECT driver) { DbgPrint("驅動卸載成功 \n"); } // Power: lyshark NTSTATUS DriverEntry(IN PDRIVER_OBJECT Driver, PUNICODE_STRING RegistryPath) { DbgPrint("hello lyshark \n"); UNICODE_STRING uncode_buffer_source = { 0 }; ANSI_STRING ansi_buffer_target = { 0 }; // 初始化字符串 RtlInitString(&ansi_buffer_target, "hello lyshark"); // 轉換函數 NTSTATUS flag = RtlAnsiStringToUnicodeString(&uncode_buffer_source, &ansi_buffer_target, TRUE); if (NT_SUCCESS(flag)) { DbgPrint("UNICODE: %wZ \n", &uncode_buffer_source); } // 銷毀UNICODE字符串 RtlFreeUnicodeString(&uncode_buffer_source); DbgPrint("驅動加載成功 \n"); Driver->DriverUnload = UnDriver; return STATUS_SUCCESS; }
代碼輸出效果:
如上代碼是內核通用結構體之間的轉換類型,又是還需要將各類結構體轉為普通的字符類型,例如下方的兩個案例:
例如將UNICODE_STRING
?轉為?CHAR*
類型。
#define _CRT_SECURE_NO_WARNINGS #include <ntifs.h> #include <windef.h> #include <ntstrsafe.h> VOID UnDriver(PDRIVER_OBJECT driver) { DbgPrint("驅動卸載成功 \n"); } // powerBY: LyShark NTSTATUS DriverEntry(IN PDRIVER_OBJECT Driver, PUNICODE_STRING RegistryPath) { DbgPrint("hello lyshark \n"); UNICODE_STRING uncode_buffer_source = { 0 }; ANSI_STRING ansi_buffer_target = { 0 }; char szBuf[1024] = { 0 }; // 初始化 UNICODE 字符串 RtlInitUnicodeString(&uncode_buffer_source, L"hello lyshark"); // 轉換函數 NTSTATUS flag = RtlUnicodeStringToAnsiString(&ansi_buffer_target, &uncode_buffer_source, TRUE); if (NT_SUCCESS(flag)) { strcpy(szBuf, ansi_buffer_target.Buffer); DbgPrint("輸出char*字符串: %s \n", szBuf); } // 銷毀ANSI字符串 RtlFreeAnsiString(&ansi_buffer_target); DbgPrint("驅動加載成功 \n"); Driver->DriverUnload = UnDriver; return STATUS_SUCCESS; }
代碼輸出效果:
如果反過來,將?CHAR*
類型轉為UNICODE_STRING
結構呢,可以進行中轉最終轉為UNICODE_STRING
結構體。
#define _CRT_SECURE_NO_WARNINGS #include <ntifs.h> #include <windef.h> #include <ntstrsafe.h> VOID UnDriver(PDRIVER_OBJECT driver) { DbgPrint("驅動卸載成功 \n"); } // powerBY: LyShark NTSTATUS DriverEntry(IN PDRIVER_OBJECT Driver, PUNICODE_STRING RegistryPath) { DbgPrint("hello lyshark \n"); UNICODE_STRING uncode_buffer_source = { 0 }; ANSI_STRING ansi_buffer_target = { 0 }; // 設置CHAR* char szBuf[1024] = { 0 }; strcpy(szBuf, "hello lyshark"); // 初始化ANSI字符串 RtlInitString(&ansi_buffer_target, szBuf); // 轉換函數 NTSTATUS flag = RtlAnsiStringToUnicodeString(&uncode_buffer_source, &ansi_buffer_target, TRUE); if (NT_SUCCESS(flag)) { DbgPrint("UNICODE: %wZ \n", &uncode_buffer_source); } // 銷毀UNICODE字符串 RtlFreeUnicodeString(&uncode_buffer_source); DbgPrint("驅動加載成功 \n"); Driver->DriverUnload = UnDriver; return STATUS_SUCCESS; }
代碼輸出效果:
原文鏈接:https://www.cnblogs.com/LyShark/p/16739228.html
相關推薦
- 2022-11-15 python列表中常見的一些排序方法_python
- 2023-06-19 Linux下使用Shell腳本實現進程監控的流程_linux shell
- 2023-01-17 python中終止協程和異常處理方式_python
- 2022-11-20 RC4加密關鍵變量及算法特點原理詳解_腳本加解密
- 2022-12-15 python中的閉包和裝飾器的使用示例_python
- 2022-10-18 CommonLisp中解析命令行參數示例_其它綜合
- 2022-10-13 python中arrow庫用法大全_python
- 2024-03-23 asp.net web api 用戶身份驗證
- 最近更新
-
- window11 系統安裝 yarn
- 超詳細win安裝深度學習環境2025年最新版(
- Linux 中運行的top命令 怎么退出?
- MySQL 中decimal 的用法? 存儲小
- get 、set 、toString 方法的使
- @Resource和 @Autowired注解
- Java基礎操作-- 運算符,流程控制 Flo
- 1. Int 和Integer 的區別,Jav
- spring @retryable不生效的一種
- Spring Security之認證信息的處理
- Spring Security之認證過濾器
- Spring Security概述快速入門
- Spring Security之配置體系
- 【SpringBoot】SpringCache
- Spring Security之基于方法配置權
- redisson分布式鎖中waittime的設
- maven:解決release錯誤:Artif
- restTemplate使用總結
- Spring Security之安全異常處理
- MybatisPlus優雅實現加密?
- Spring ioc容器與Bean的生命周期。
- 【探索SpringCloud】服務發現-Nac
- Spring Security之基于HttpR
- Redis 底層數據結構-簡單動態字符串(SD
- arthas操作spring被代理目標對象命令
- Spring中的單例模式應用詳解
- 聊聊消息隊列,發送消息的4種方式
- bootspring第三方資源配置管理
- GIT同步修改后的遠程分支