Files
mir_server/sdk/system/PathThreadLocale.cpp
aixianling 5c9f1dae4a init
2025-01-09 17:45:40 +08:00

166 lines
3.5 KiB
C++
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#include <stdlib.h>
#include <locale.h>
#ifdef WIN32
#include <tchar.h>
#include <Windows.h>
#endif
#ifdef WIN32
#include <Tick.h>
#include "ShareUtil.h"
/**
* 跳转指令结构
*************************/
#pragma pack(push, 1)
struct JMPInstruct32
{
unsigned char code;
unsigned int offset;
};
struct JMPInstruct64
{
unsigned short code;
unsigned int loAddrCST;
unsigned __int64 offset;
};
union JMPInstruct
{
JMPInstruct32 c32;
JMPInstruct64 c64;
};
#pragma pack(pop)
union JMPInstruct CodeSource;
static char sCP[128];
static HANDLE WINAPI _CreateThread_Path_(
__in_opt LPSECURITY_ATTRIBUTES lpThreadAttributes,
__in SIZE_T dwStackSize,
__in LPTHREAD_START_ROUTINE lpStartAddress,
__in_opt __deref __drv_aliasesMem LPVOID lpParameter,
__in DWORD dwCreationFlags,
__out_opt LPDWORD lpThreadId
);
//计算跳转偏移地址
#define CalcJmpOffset32(s, d) ((SIZE_T)(d) - ((SIZE_T)(s) + 5))
#define CalcJmpOffset64(s, d) ((SIZE_T)(d))
static int PathCreateThreadCode(const JMPInstruct* pCode)
{
JMPInstruct* fn = (JMPInstruct*)&CreateThread;
DWORD dwOldProtect;
MEMORY_BASIC_INFORMATION mbi;
if ( VirtualQuery(fn, &mbi, sizeof(mbi)) != sizeof(mbi) )
return GetLastError();
//修改_output_l函数的内存保护模式增加可读写保护
if ( !VirtualProtect(fn, sizeof(*fn), PAGE_EXECUTE_READWRITE, &dwOldProtect) )
return GetLastError();
//改写跳转代码
if (sizeof(void*) == 8)
fn->c64 = pCode->c64;
else if (sizeof(void*) == 4)
fn->c32 = pCode->c32;
//还原_output_l函数的内存保护模式
if ( !VirtualProtect(fn, sizeof(*fn), dwOldProtect, &dwOldProtect) )
return GetLastError();
return 0;
}
//设置代码跳转补丁
static int PathCreateThread()
{
JMPInstruct pc;
if (sizeof(void*) == 8)
{
//JMP [OFFSET]
pc.c64.code = 0x25FF;
pc.c64.loAddrCST = 0;//固定为0
pc.c64.offset = CalcJmpOffset64(&CreateThread, &_CreateThread_Path_);
}
else if (sizeof(void*) == 4)
{
pc.c32.code = 0xE9;
pc.c32.offset = (UINT)CalcJmpOffset32(&CreateThread, &_CreateThread_Path_);
}
return PathCreateThreadCode(&pc);
}
//解除代码跳转补丁
static int UnPathCreateThread()
{
return PathCreateThreadCode(&CodeSource);
}
int InstallThreadLocalePath(const char *lc)
{
//保存原始代码字节
if (!CodeSource.c32.code) CodeSource = *((JMPInstruct*)&CreateThread);
//保存设定的数据
_asncpytA(sCP, lc);
//设置跳转
return PathCreateThread();
}
static void SetupThreadLocale()
{
//参见http://msdn.microsoft.com/zh-cn/library/ms235302(VS.80).aspx
//★★★setlocal是针对线程的
//设置locale为C设置mbcp为_MB_CP_SBCS以便支持libc中文字处理相关的函数支持UTF-8
setlocale(LC_ALL, sCP);
}
struct PTD
{
LPTHREAD_START_ROUTINE routine;
LPVOID param;
};
static INT_PTR WINAPI _Path_ThreadLocale_Rountine(PTD *pd)
{
SetupThreadLocale();
PTD td = *pd;
INT_PTR result = td.routine(td.param);
//free(pd);
return result;
}
static HANDLE WINAPI _CreateThread_Path_(
__in_opt LPSECURITY_ATTRIBUTES lpThreadAttributes,
__in SIZE_T dwStackSize,
__in LPTHREAD_START_ROUTINE lpStartAddress,
__in_opt __deref __drv_aliasesMem LPVOID lpParameter,
__in DWORD dwCreationFlags,
__out_opt LPDWORD lpThreadId
)
{
UnPathCreateThread();
PTD *p = (PTD*)malloc(sizeof(*p));
p->routine = lpStartAddress;
p->param = lpParameter;
HANDLE result = CreateThread(lpThreadAttributes, dwStackSize,
(LPTHREAD_START_ROUTINE)_Path_ThreadLocale_Rountine,
p, dwCreationFlags, lpThreadId);
PathCreateThread();
return result;
}
#endif