This commit is contained in:
aixianling
2025-01-09 17:45:40 +08:00
commit 5c9f1dae4a
3482 changed files with 1146531 additions and 0 deletions

View File

@@ -0,0 +1,165 @@
#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