【WIN32/逆向】字符编码转换

共计3718字,阅读大约13分钟。
图片[1]-【WIN32/逆向】字符编码转换-galgame

字符编码转换代码

MultiByteToWideChar和WideCharToMultiByte是Windows API中用于字符编码转换的两个重要函数。它们主要用于在多字节字符串(如ANSI或UTF-8)和宽字符字符串(UTF-16)之间进行转换。

下面我们详细介绍这两个函数:

MultiByteToWideChar

这个函数用于将多字节字符串转换为宽字符(Unicode)字符串。 字符串不一定来自多字节字符集。

函数结构

int MultiByteToWideChar(
  UINT   CodePage,
  DWORD  dwFlags,
  LPCCH  lpMultiByteStr,
  int    cbMultiByte,
  LPWSTR lpWideCharStr,
  int    cchWideChar
);

参数

  • CodePage: 指定源字符串的代码页,如CP_ACP(当前系统ANSI代码页)、CP_UTF8等。
  • lpMultiByteStr: 指向要转换的多字节字符串。
  • cbMultiByte: 指定要转换的字节数。
  • lpWideCharStr: 指向接收转换后的宽字符字符串的缓冲区。
  • cchWideChar: 指定宽字符缓冲区的大小(以字符为单位)。

WideCharToMultiByte

这个函数用于将宽字符(Unicode)字符串转换为多字节字符串。 字符串不一定来自多字节字符集。

函数结构

int WideCharToMultiByte(
  UINT   CodePage,
  DWORD  dwFlags,
  LPCWCH lpWideCharStr,
  int    cchWideChar,
  LPSTR  lpMultiByteStr,
  int    cbMultiByte,
  LPCCH  lpDefaultChar,
  LPBOOL lpUsedDefaultChar
);

参数

  • CodePage: 指定目标多字节字符串的代码页。
  • lpWideCharStr: 指向要转换的宽字符字符串。
  • cchWideChar: 指定要转换的宽字符数。
  • lpMultiByteStr: 指向接收转换后的多字节字符串的缓冲区。
  • cbMultiByte: 指定多字节缓冲区的大小(以字节为单位)。

主要关注的点:CodePage代码页

  1. CP_ACP (0): 当前系统 ANSI 代码页
  2. CP_OEMCP (1): 当前系统 OEM 代码页
  3. CP_MACCP (2): Macintosh 代码页
  4. CP_THREAD_ACP (3): 当前线程的 ANSI 代码页
  5. CP_SYMBOL (42): Symbol 代码页
  6. CP_UTF7 (65000): UTF-7
  7. CP_UTF8 (65001): UTF-8

具体到不同语言和地区的代码页:

  1. 936: 简体中文 GBK
  2. 950: 繁体中文 Big5
  3. 932: 日语 Shift-JIS
  4. 949: 韩语
  5. 1250: 中欧语言 (波兰、捷克等)
  6. 1251: 西里尔字母 (俄语等)
  7. 1252: 西欧语言 (英语、德语、法语等)
  8. 1253: 希腊语
  9. 1254: 土耳其语
  10. 1255: 希伯来语
  11. 1256: 阿拉伯语
  12. 1257: 波罗的海语言
  13. 1258: 越南语
  1. 54936: GB18030

HOOK代码示例

#include <windows.h>
#include <detours.h>

// 原始函数的类型定义
typedef int (WINAPI *MULTIBYTETOWIDECHAR)(UINT, DWORD, LPCSTR, int, LPWSTR, int);
typedef int (WINAPI *WIDECHARTOMULTIBYTE)(UINT, DWORD, LPCWSTR, int, LPSTR, int, LPCSTR, LPBOOL);

// 保存原始函数的指针
MULTIBYTETOWIDECHAR TrueMultiByteToWideChar = MultiByteToWideChar;
WIDECHARTOMULTIBYTE TrueWideCharToMultiByte = WideCharToMultiByte;

// Hook函数:MultiByteToWideChar
int WINAPI HookedMultiByteToWideChar(UINT CodePage, DWORD dwFlags, LPCSTR lpMultiByteStr, 
                                     int cbMultiByte, LPWSTR lpWideCharStr, int cchWideChar)
{
    // 强制使用GBK编码(代码页936)
    return TrueMultiByteToWideChar(936, dwFlags, lpMultiByteStr, cbMultiByte, lpWideCharStr, cchWideChar);
}

// Hook函数:WideCharToMultiByte
int WINAPI HookedWideCharToMultiByte(UINT CodePage, DWORD dwFlags, LPCWSTR lpWideCharStr, 
                                     int cchWideChar, LPSTR lpMultiByteStr, int cbMultiByte, 
                                     LPCSTR lpDefaultChar, LPBOOL lpUsedDefaultChar)
{
    // 强制使用GBK编码(代码页936)
    return TrueWideCharToMultiByte(936, dwFlags, lpWideCharStr, cchWideChar, lpMultiByteStr, 
                                   cbMultiByte, lpDefaultChar, lpUsedDefaultChar);
}

BOOL APIENTRY DllMain(HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved)
{
    if (ul_reason_for_call == DLL_PROCESS_ATTACH)
    {
        DisableThreadLibraryCalls(hModule);
        DetourTransactionBegin();
        DetourUpdateThread(GetCurrentThread());
        DetourAttach(&(PVOID&)TrueMultiByteToWideChar, HookedMultiByteToWideChar);
        DetourAttach(&(PVOID&)TrueWideCharToMultiByte, HookedWideCharToMultiByte);
        DetourTransactionCommit();
    }
    else if (ul_reason_for_call == DLL_PROCESS_DETACH)
    {
        DetourTransactionBegin();
        DetourUpdateThread(GetCurrentThread());
        DetourDetach(&(PVOID&)TrueMultiByteToWideChar, HookedMultiByteToWideChar);
        DetourDetach(&(PVOID&)TrueWideCharToMultiByte, HookedWideCharToMultiByte);
        DetourTransactionCommit();
    }
    return TRUE;
}

举个例子

图片[2]-【WIN32/逆向】字符编码转换-galgame

温馨提示:
本文最后更新于2024-07-20 15:26:15,本文具有时效性,若有错误或已失效,请在下方留言或联系站长
© 版权声明
THE END
喜欢就支持一下吧
点赞6 分享
评论 抢沙发

请登录后发表评论

    暂无评论内容