diff --git a/README.md b/README.md index 777838c..f5109b7 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,13 @@ # siutf8 -Source insight 3.X UTF8 plugin in c language +ABOUT: +siutf8 is a UTF8 Support plugin for source insight 3.x. + + +BUILD: +siutf8 is build with w32-gcc,siutf8.cbp is a codeblocks project file. +you can also make it use Makefile. + + +INSTALL: +copy siutf8.dll to source insight dir. +you can use msimg32.dll Auto load the plugin. or use the loader.exe. diff --git a/hook/hookapi.c b/hook/hookapi.c new file mode 100644 index 0000000..ba8e7c0 --- /dev/null +++ b/hook/hookapi.c @@ -0,0 +1,111 @@ +#include "ldasm.h" +#include "hookapi.h" +#include + +//指定API进行HOOK,并返回一个进入原函数的代理函数地址。 +void* HookFunction(char* ModuleName,char* FunctionName,void* pNewFunction) +{ + HMODULE hModule = NULL; + UCHAR JumpCode[6] = {0x68,0x00,0x00,0x00,0x00,0xC3}; //push xxxxxxxx ret + UCHAR JumpBackCode[6] = {0x68,0x00,0x00,0x00,0x00,0xC3}; //push xxxxxxxx ret + PVOID pSourceFunction; + char buf[256]; + + hModule = GetModuleHandleA(ModuleName); + if(hModule == NULL) + { + memset(buf,0,sizeof(buf)); + sprintf(buf,"[HookFunction]GetModuleHandleA(%s) failed",ModuleName); + OutputDebugString(buf); + return NULL; + } + + pSourceFunction = (PVOID)GetProcAddress(hModule,FunctionName); + if (!pSourceFunction) + { + memset(buf,0,sizeof(buf)); + sprintf(buf,"[HookFunction]GetProcAddress(%s,%s) failed",ModuleName,FunctionName); + OutputDebugString(buf); + return NULL; + } + + *(ULONG *)((ULONG)JumpCode + 1) = (ULONG)pNewFunction; + + + PVOID pProxyFunction = 0; + PUCHAR pOpCode; + ULONG BackupLength = 0; + + + while (BackupLength < 6) + { + BackupLength += SizeOfCode((PVOID)((ULONG)pSourceFunction + BackupLength),&pOpCode); + } + + + pProxyFunction = VirtualAlloc(NULL,BackupLength + 6,MEM_RESERVE|MEM_COMMIT,PAGE_EXECUTE_READWRITE); + if (!pProxyFunction)return NULL; + + *(ULONG *)((ULONG)JumpBackCode + 1) = (ULONG)pSourceFunction + BackupLength; + + RtlCopyMemory(pProxyFunction,pSourceFunction,BackupLength); + RtlCopyMemory((PVOID)((ULONG)pProxyFunction + BackupLength),JumpBackCode,6); + + FlushInstructionCache((HANDLE)-1,pProxyFunction,BackupLength + 6); + + DWORD OldProtect = 0; + VirtualProtect(pSourceFunction,6,PAGE_EXECUTE_READWRITE,&OldProtect); + + RtlCopyMemory(pSourceFunction,JumpCode,6); + + VirtualProtect(pSourceFunction,6,OldProtect,&OldProtect); + + FlushInstructionCache((HANDLE)-1,pSourceFunction,6); + + return pProxyFunction; +} + +//恢复被HOOK的函数,它需要HookFunction函数返回的代理函数地址作为参数。 +BOOL UnHookFunction(char* ModuleName,char* FunctionName,PVOID pProxyFunction) +{ + PVOID pSourceFunction = (PVOID)GetProcAddress(GetModuleHandleA(ModuleName),FunctionName); + if (!pSourceFunction)return FALSE; + + DWORD OldProtect = 0; + VirtualProtect(pSourceFunction,6,PAGE_EXECUTE_READWRITE,&OldProtect); + + RtlCopyMemory(pSourceFunction,pProxyFunction,6); + + VirtualProtect(pSourceFunction,6,OldProtect,&OldProtect); + + FlushInstructionCache((HANDLE)-1,pSourceFunction,6); + + BOOL res = VirtualFree(pProxyFunction,0,MEM_RELEASE); + if (!res)return FALSE; + + return TRUE; +} + +//检查某个函数是否被HOOK +BOOL IsFuncHooked(char* ModuleName,char* FunctionName) +{ + PVOID pFunction = (PVOID)GetProcAddress(GetModuleHandleA(ModuleName),FunctionName); + + if (!pFunction)return FALSE; + + DWORD OldProtect = 0; + VirtualProtect(pFunction,6,PAGE_EXECUTE_READWRITE,&OldProtect); + + //UCHAR chas = *(UCHAR *)((ULONG)pFunction + 5); + + if (((*(UCHAR *)pFunction == 0x68)&&(*(UCHAR *)((ULONG)pFunction + 5) == 0xC3))||(*(UCHAR *)pFunction == 0xEB)||(*(UCHAR *)pFunction == 0xEA)) + { + VirtualProtect(pFunction,6,OldProtect,&OldProtect); + return TRUE; + } + else + { + VirtualProtect(pFunction,6,OldProtect,&OldProtect); + return FALSE; + } +} diff --git a/hook/hookapi.h b/hook/hookapi.h new file mode 100644 index 0000000..c946699 --- /dev/null +++ b/hook/hookapi.h @@ -0,0 +1,23 @@ +#ifndef __HOOKAPI__H__ +#define __HOOKAPI__H__ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +//指定API进行HOOK,并返回一个进入原函数的代理函数地址。 +void* HookFunction(char* ModuleName,char* FunctionName,void* pNewFunction); + +//恢复被HOOK的函数,它需要HookFunction函数返回的代理函数地址作为参数。 +BOOL UnHookFunction(char* ModuleName,char* FunctionName,void* pProxyFunction); + +//检查某个函数是否被HOOK +BOOL IsFuncHooked(char* ModuleName,char* FunctionName); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/hook/ldasm.c b/hook/ldasm.c new file mode 100644 index 0000000..dae1cc2 --- /dev/null +++ b/hook/ldasm.c @@ -0,0 +1,654 @@ +/* + ___________________________________________________ + Opcode Length Disassembler. + Coded By Ms-Rem ( Ms-Rem@yandex.ru ) ICQ 286370715 + --------------------------------------------------- + 12.08.2005 - fixed many bugs... + 09.08.2005 - fixed bug with 0F BA opcode. + 07.08.2005 - added SSE, SSE2, SSE3 and 3Dnow instruction support. + 06.08.2005 - fixed bug with F6 and F7 opcodes. + 29.07.2005 - fixed bug with OP_WORD opcodes. +*/ +#include "LDasm.h" + +#define OP_NONE 0x00 +#define OP_MODRM 0x01 +#define OP_DATA_I8 0x02 +#define OP_DATA_I16 0x04 +#define OP_DATA_I32 0x08 +#define OP_DATA_PRE66_67 0x10 +#define OP_WORD 0x20 +#define OP_REL32 0x40 + +#define UCHAR unsigned char +#define ULONG unsigned long +#define PVOID void* +#define PUCHAR unsigned char* +#define BOOLEAN char +#define FALSE 0 +#define TRUE 1 + +UCHAR OpcodeFlags[256] = +{ + OP_MODRM, // 00 + OP_MODRM, // 01 + OP_MODRM, // 02 + OP_MODRM, // 03 + OP_DATA_I8, // 04 + OP_DATA_PRE66_67, // 05 + OP_NONE, // 06 + OP_NONE, // 07 + OP_MODRM, // 08 + OP_MODRM, // 09 + OP_MODRM, // 0A + OP_MODRM, // 0B + OP_DATA_I8, // 0C + OP_DATA_PRE66_67, // 0D + OP_NONE, // 0E + OP_NONE, // 0F + OP_MODRM, // 10 + OP_MODRM, // 11 + OP_MODRM, // 12 + OP_MODRM, // 13 + OP_DATA_I8, // 14 + OP_DATA_PRE66_67, // 15 + OP_NONE, // 16 + OP_NONE, // 17 + OP_MODRM, // 18 + OP_MODRM, // 19 + OP_MODRM, // 1A + OP_MODRM, // 1B + OP_DATA_I8, // 1C + OP_DATA_PRE66_67, // 1D + OP_NONE, // 1E + OP_NONE, // 1F + OP_MODRM, // 20 + OP_MODRM, // 21 + OP_MODRM, // 22 + OP_MODRM, // 23 + OP_DATA_I8, // 24 + OP_DATA_PRE66_67, // 25 + OP_NONE, // 26 + OP_NONE, // 27 + OP_MODRM, // 28 + OP_MODRM, // 29 + OP_MODRM, // 2A + OP_MODRM, // 2B + OP_DATA_I8, // 2C + OP_DATA_PRE66_67, // 2D + OP_NONE, // 2E + OP_NONE, // 2F + OP_MODRM, // 30 + OP_MODRM, // 31 + OP_MODRM, // 32 + OP_MODRM, // 33 + OP_DATA_I8, // 34 + OP_DATA_PRE66_67, // 35 + OP_NONE, // 36 + OP_NONE, // 37 + OP_MODRM, // 38 + OP_MODRM, // 39 + OP_MODRM, // 3A + OP_MODRM, // 3B + OP_DATA_I8, // 3C + OP_DATA_PRE66_67, // 3D + OP_NONE, // 3E + OP_NONE, // 3F + OP_NONE, // 40 + OP_NONE, // 41 + OP_NONE, // 42 + OP_NONE, // 43 + OP_NONE, // 44 + OP_NONE, // 45 + OP_NONE, // 46 + OP_NONE, // 47 + OP_NONE, // 48 + OP_NONE, // 49 + OP_NONE, // 4A + OP_NONE, // 4B + OP_NONE, // 4C + OP_NONE, // 4D + OP_NONE, // 4E + OP_NONE, // 4F + OP_NONE, // 50 + OP_NONE, // 51 + OP_NONE, // 52 + OP_NONE, // 53 + OP_NONE, // 54 + OP_NONE, // 55 + OP_NONE, // 56 + OP_NONE, // 57 + OP_NONE, // 58 + OP_NONE, // 59 + OP_NONE, // 5A + OP_NONE, // 5B + OP_NONE, // 5C + OP_NONE, // 5D + OP_NONE, // 5E + OP_NONE, // 5F + OP_NONE, // 60 + OP_NONE, // 61 + OP_MODRM, // 62 + OP_MODRM, // 63 + OP_NONE, // 64 + OP_NONE, // 65 + OP_NONE, // 66 + OP_NONE, // 67 + OP_DATA_PRE66_67, // 68 + OP_MODRM | OP_DATA_PRE66_67, // 69 + OP_DATA_I8, // 6A + OP_MODRM | OP_DATA_I8, // 6B + OP_NONE, // 6C + OP_NONE, // 6D + OP_NONE, // 6E + OP_NONE, // 6F + OP_DATA_I8, // 70 + OP_DATA_I8, // 71 + OP_DATA_I8, // 72 + OP_DATA_I8, // 73 + OP_DATA_I8, // 74 + OP_DATA_I8, // 75 + OP_DATA_I8, // 76 + OP_DATA_I8, // 77 + OP_DATA_I8, // 78 + OP_DATA_I8, // 79 + OP_DATA_I8, // 7A + OP_DATA_I8, // 7B + OP_DATA_I8, // 7C + OP_DATA_I8, // 7D + OP_DATA_I8, // 7E + OP_DATA_I8, // 7F + OP_MODRM | OP_DATA_I8, // 80 + OP_MODRM | OP_DATA_PRE66_67, // 81 + OP_MODRM | OP_DATA_I8, // 82 + OP_MODRM | OP_DATA_I8, // 83 + OP_MODRM, // 84 + OP_MODRM, // 85 + OP_MODRM, // 86 + OP_MODRM, // 87 + OP_MODRM, // 88 + OP_MODRM, // 89 + OP_MODRM, // 8A + OP_MODRM, // 8B + OP_MODRM, // 8C + OP_MODRM, // 8D + OP_MODRM, // 8E + OP_MODRM, // 8F + OP_NONE, // 90 + OP_NONE, // 91 + OP_NONE, // 92 + OP_NONE, // 93 + OP_NONE, // 94 + OP_NONE, // 95 + OP_NONE, // 96 + OP_NONE, // 97 + OP_NONE, // 98 + OP_NONE, // 99 + OP_DATA_I16 | OP_DATA_PRE66_67,// 9A + OP_NONE, // 9B + OP_NONE, // 9C + OP_NONE, // 9D + OP_NONE, // 9E + OP_NONE, // 9F + OP_DATA_PRE66_67, // A0 + OP_DATA_PRE66_67, // A1 + OP_DATA_PRE66_67, // A2 + OP_DATA_PRE66_67, // A3 + OP_NONE, // A4 + OP_NONE, // A5 + OP_NONE, // A6 + OP_NONE, // A7 + OP_DATA_I8, // A8 + OP_DATA_PRE66_67, // A9 + OP_NONE, // AA + OP_NONE, // AB + OP_NONE, // AC + OP_NONE, // AD + OP_NONE, // AE + OP_NONE, // AF + OP_DATA_I8, // B0 + OP_DATA_I8, // B1 + OP_DATA_I8, // B2 + OP_DATA_I8, // B3 + OP_DATA_I8, // B4 + OP_DATA_I8, // B5 + OP_DATA_I8, // B6 + OP_DATA_I8, // B7 + OP_DATA_PRE66_67, // B8 + OP_DATA_PRE66_67, // B9 + OP_DATA_PRE66_67, // BA + OP_DATA_PRE66_67, // BB + OP_DATA_PRE66_67, // BC + OP_DATA_PRE66_67, // BD + OP_DATA_PRE66_67, // BE + OP_DATA_PRE66_67, // BF + OP_MODRM | OP_DATA_I8, // C0 + OP_MODRM | OP_DATA_I8, // C1 + OP_DATA_I16, // C2 + OP_NONE, // C3 + OP_MODRM, // C4 + OP_MODRM, // C5 + OP_MODRM | OP_DATA_I8, // C6 + OP_MODRM | OP_DATA_PRE66_67, // C7 + OP_DATA_I8 | OP_DATA_I16, // C8 + OP_NONE, // C9 + OP_DATA_I16, // CA + OP_NONE, // CB + OP_NONE, // CC + OP_DATA_I8, // CD + OP_NONE, // CE + OP_NONE, // CF + OP_MODRM, // D0 + OP_MODRM, // D1 + OP_MODRM, // D2 + OP_MODRM, // D3 + OP_DATA_I8, // D4 + OP_DATA_I8, // D5 + OP_NONE, // D6 + OP_NONE, // D7 + OP_WORD, // D8 + OP_WORD, // D9 + OP_WORD, // DA + OP_WORD, // DB + OP_WORD, // DC + OP_WORD, // DD + OP_WORD, // DE + OP_WORD, // DF + OP_DATA_I8, // E0 + OP_DATA_I8, // E1 + OP_DATA_I8, // E2 + OP_DATA_I8, // E3 + OP_DATA_I8, // E4 + OP_DATA_I8, // E5 + OP_DATA_I8, // E6 + OP_DATA_I8, // E7 + OP_DATA_PRE66_67 | OP_REL32, // E8 + OP_DATA_PRE66_67 | OP_REL32, // E9 + OP_DATA_I16 | OP_DATA_PRE66_67,// EA + OP_DATA_I8, // EB + OP_NONE, // EC + OP_NONE, // ED + OP_NONE, // EE + OP_NONE, // EF + OP_NONE, // F0 + OP_NONE, // F1 + OP_NONE, // F2 + OP_NONE, // F3 + OP_NONE, // F4 + OP_NONE, // F5 + OP_MODRM, // F6 + OP_MODRM, // F7 + OP_NONE, // F8 + OP_NONE, // F9 + OP_NONE, // FA + OP_NONE, // FB + OP_NONE, // FC + OP_NONE, // FD + OP_MODRM, // FE + OP_MODRM | OP_REL32 // FF +}; + + +UCHAR OpcodeFlagsExt[256] = +{ + OP_MODRM, // 00 + OP_MODRM, // 01 + OP_MODRM, // 02 + OP_MODRM, // 03 + OP_NONE, // 04 + OP_NONE, // 05 + OP_NONE, // 06 + OP_NONE, // 07 + OP_NONE, // 08 + OP_NONE, // 09 + OP_NONE, // 0A + OP_NONE, // 0B + OP_NONE, // 0C + OP_MODRM, // 0D + OP_NONE, // 0E + OP_MODRM | OP_DATA_I8, // 0F + OP_MODRM, // 10 + OP_MODRM, // 11 + OP_MODRM, // 12 + OP_MODRM, // 13 + OP_MODRM, // 14 + OP_MODRM, // 15 + OP_MODRM, // 16 + OP_MODRM, // 17 + OP_MODRM, // 18 + OP_NONE, // 19 + OP_NONE, // 1A + OP_NONE, // 1B + OP_NONE, // 1C + OP_NONE, // 1D + OP_NONE, // 1E + OP_NONE, // 1F + OP_MODRM, // 20 + OP_MODRM, // 21 + OP_MODRM, // 22 + OP_MODRM, // 23 + OP_MODRM, // 24 + OP_NONE, // 25 + OP_MODRM, // 26 + OP_NONE, // 27 + OP_MODRM, // 28 + OP_MODRM, // 29 + OP_MODRM, // 2A + OP_MODRM, // 2B + OP_MODRM, // 2C + OP_MODRM, // 2D + OP_MODRM, // 2E + OP_MODRM, // 2F + OP_NONE, // 30 + OP_NONE, // 31 + OP_NONE, // 32 + OP_NONE, // 33 + OP_NONE, // 34 + OP_NONE, // 35 + OP_NONE, // 36 + OP_NONE, // 37 + OP_NONE, // 38 + OP_NONE, // 39 + OP_NONE, // 3A + OP_NONE, // 3B + OP_NONE, // 3C + OP_NONE, // 3D + OP_NONE, // 3E + OP_NONE, // 3F + OP_MODRM, // 40 + OP_MODRM, // 41 + OP_MODRM, // 42 + OP_MODRM, // 43 + OP_MODRM, // 44 + OP_MODRM, // 45 + OP_MODRM, // 46 + OP_MODRM, // 47 + OP_MODRM, // 48 + OP_MODRM, // 49 + OP_MODRM, // 4A + OP_MODRM, // 4B + OP_MODRM, // 4C + OP_MODRM, // 4D + OP_MODRM, // 4E + OP_MODRM, // 4F + OP_MODRM, // 50 + OP_MODRM, // 51 + OP_MODRM, // 52 + OP_MODRM, // 53 + OP_MODRM, // 54 + OP_MODRM, // 55 + OP_MODRM, // 56 + OP_MODRM, // 57 + OP_MODRM, // 58 + OP_MODRM, // 59 + OP_MODRM, // 5A + OP_MODRM, // 5B + OP_MODRM, // 5C + OP_MODRM, // 5D + OP_MODRM, // 5E + OP_MODRM, // 5F + OP_MODRM, // 60 + OP_MODRM, // 61 + OP_MODRM, // 62 + OP_MODRM, // 63 + OP_MODRM, // 64 + OP_MODRM, // 65 + OP_MODRM, // 66 + OP_MODRM, // 67 + OP_MODRM, // 68 + OP_MODRM, // 69 + OP_MODRM, // 6A + OP_MODRM, // 6B + OP_MODRM, // 6C + OP_MODRM, // 6D + OP_MODRM, // 6E + OP_MODRM, // 6F + OP_MODRM | OP_DATA_I8, // 70 + OP_MODRM | OP_DATA_I8, // 71 + OP_MODRM | OP_DATA_I8, // 72 + OP_MODRM | OP_DATA_I8, // 73 + OP_MODRM, // 74 + OP_MODRM, // 75 + OP_MODRM, // 76 + OP_NONE, // 77 + OP_NONE, // 78 + OP_NONE, // 79 + OP_NONE, // 7A + OP_NONE, // 7B + OP_MODRM, // 7C + OP_MODRM, // 7D + OP_MODRM, // 7E + OP_MODRM, // 7F + OP_DATA_PRE66_67 | OP_REL32, // 80 + OP_DATA_PRE66_67 | OP_REL32, // 81 + OP_DATA_PRE66_67 | OP_REL32, // 82 + OP_DATA_PRE66_67 | OP_REL32, // 83 + OP_DATA_PRE66_67 | OP_REL32, // 84 + OP_DATA_PRE66_67 | OP_REL32, // 85 + OP_DATA_PRE66_67 | OP_REL32, // 86 + OP_DATA_PRE66_67 | OP_REL32, // 87 + OP_DATA_PRE66_67 | OP_REL32, // 88 + OP_DATA_PRE66_67 | OP_REL32, // 89 + OP_DATA_PRE66_67 | OP_REL32, // 8A + OP_DATA_PRE66_67 | OP_REL32, // 8B + OP_DATA_PRE66_67 | OP_REL32, // 8C + OP_DATA_PRE66_67 | OP_REL32, // 8D + OP_DATA_PRE66_67 | OP_REL32, // 8E + OP_DATA_PRE66_67 | OP_REL32, // 8F + OP_MODRM, // 90 + OP_MODRM, // 91 + OP_MODRM, // 92 + OP_MODRM, // 93 + OP_MODRM, // 94 + OP_MODRM, // 95 + OP_MODRM, // 96 + OP_MODRM, // 97 + OP_MODRM, // 98 + OP_MODRM, // 99 + OP_MODRM, // 9A + OP_MODRM, // 9B + OP_MODRM, // 9C + OP_MODRM, // 9D + OP_MODRM, // 9E + OP_MODRM, // 9F + OP_NONE, // A0 + OP_NONE, // A1 + OP_NONE, // A2 + OP_MODRM, // A3 + OP_MODRM | OP_DATA_I8, // A4 + OP_MODRM, // A5 + OP_NONE, // A6 + OP_NONE, // A7 + OP_NONE, // A8 + OP_NONE, // A9 + OP_NONE, // AA + OP_MODRM, // AB + OP_MODRM | OP_DATA_I8, // AC + OP_MODRM, // AD + OP_MODRM, // AE + OP_MODRM, // AF + OP_MODRM, // B0 + OP_MODRM, // B1 + OP_MODRM, // B2 + OP_MODRM, // B3 + OP_MODRM, // B4 + OP_MODRM, // B5 + OP_MODRM, // B6 + OP_MODRM, // B7 + OP_NONE, // B8 + OP_NONE, // B9 + OP_MODRM | OP_DATA_I8, // BA + OP_MODRM, // BB + OP_MODRM, // BC + OP_MODRM, // BD + OP_MODRM, // BE + OP_MODRM, // BF + OP_MODRM, // C0 + OP_MODRM, // C1 + OP_MODRM | OP_DATA_I8, // C2 + OP_MODRM, // C3 + OP_MODRM | OP_DATA_I8, // C4 + OP_MODRM | OP_DATA_I8, // C5 + OP_MODRM | OP_DATA_I8, // C6 + OP_MODRM, // C7 + OP_NONE, // C8 + OP_NONE, // C9 + OP_NONE, // CA + OP_NONE, // CB + OP_NONE, // CC + OP_NONE, // CD + OP_NONE, // CE + OP_NONE, // CF + OP_MODRM, // D0 + OP_MODRM, // D1 + OP_MODRM, // D2 + OP_MODRM, // D3 + OP_MODRM, // D4 + OP_MODRM, // D5 + OP_MODRM, // D6 + OP_MODRM, // D7 + OP_MODRM, // D8 + OP_MODRM, // D9 + OP_MODRM, // DA + OP_MODRM, // DB + OP_MODRM, // DC + OP_MODRM, // DD + OP_MODRM, // DE + OP_MODRM, // DF + OP_MODRM, // E0 + OP_MODRM, // E1 + OP_MODRM, // E2 + OP_MODRM, // E3 + OP_MODRM, // E4 + OP_MODRM, // E5 + OP_MODRM, // E6 + OP_MODRM, // E7 + OP_MODRM, // E8 + OP_MODRM, // E9 + OP_MODRM, // EA + OP_MODRM, // EB + OP_MODRM, // EC + OP_MODRM, // ED + OP_MODRM, // EE + OP_MODRM, // EF + OP_MODRM, // F0 + OP_MODRM, // F1 + OP_MODRM, // F2 + OP_MODRM, // F3 + OP_MODRM, // F4 + OP_MODRM, // F5 + OP_MODRM, // F6 + OP_MODRM, // F7 + OP_MODRM, // F8 + OP_MODRM, // F9 + OP_MODRM, // FA + OP_MODRM, // FB + OP_MODRM, // FC + OP_MODRM, // FD + OP_MODRM, // FE + OP_NONE // FF +}; + +unsigned long __fastcall SizeOfCode(void *Code, unsigned char **pOpcode) +{ + PUCHAR cPtr; + UCHAR Flags; + BOOLEAN PFX66, PFX67; + BOOLEAN SibPresent; + UCHAR iMod, iRM, iReg; + UCHAR OffsetSize, Add; + UCHAR Opcode; + + OffsetSize = 0; + PFX66 = FALSE; + PFX67 = FALSE; + cPtr = (PUCHAR)Code; + + while ( (*cPtr == 0x2E) || (*cPtr == 0x3E) || (*cPtr == 0x36) || + (*cPtr == 0x26) || (*cPtr == 0x64) || (*cPtr == 0x65) || + (*cPtr == 0xF0) || (*cPtr == 0xF2) || (*cPtr == 0xF3) || + (*cPtr == 0x66) || (*cPtr == 0x67) ) + { + if (*cPtr == 0x66) PFX66 = TRUE; + if (*cPtr == 0x67) PFX67 = TRUE; + cPtr++; + if (cPtr > (PUCHAR)Code + 16) return 0; + } + Opcode = *cPtr; + if (pOpcode) *pOpcode = cPtr; + + if (*cPtr == 0x0F) + { + cPtr++; + Flags = OpcodeFlagsExt[*cPtr]; + } else + { + Flags = OpcodeFlags[Opcode]; + + if (Opcode >= 0xA0 && Opcode <= 0xA3) PFX66 = PFX67; + } + cPtr++; + if (Flags & OP_WORD) cPtr++; + + if (Flags & OP_MODRM) + { + iMod = *cPtr >> 6; + iReg = (*cPtr & 0x38) >> 3; + iRM = *cPtr & 7; + cPtr++; + + if ((Opcode == 0xF6) && !iReg) Flags |= OP_DATA_I8; + if ((Opcode == 0xF7) && !iReg) Flags |= OP_DATA_PRE66_67; + + SibPresent = !PFX67 & (iRM == 4); + switch (iMod) + { + case 0: + if ( PFX67 && (iRM == 6)) OffsetSize = 2; + if (!PFX67 && (iRM == 5)) OffsetSize = 4; + break; + case 1: OffsetSize = 1; + break; + case 2: if (PFX67) OffsetSize = 2; else OffsetSize = 4; + break; + case 3: SibPresent = FALSE; + } + if (SibPresent) + { + if (((*cPtr & 7) == 5) && ( (!iMod) || (iMod == 2) )) OffsetSize = 4; + cPtr++; + } + cPtr = (PUCHAR)(ULONG)cPtr + OffsetSize; + } + + if (Flags & OP_DATA_I8) cPtr++; + if (Flags & OP_DATA_I16) cPtr += 2; + if (Flags & OP_DATA_I32) cPtr += 4; + if (PFX66) Add = 2; else Add = 4; + if (Flags & OP_DATA_PRE66_67) cPtr += Add; + return (ULONG)cPtr - (ULONG)Code; +} + +unsigned long __fastcall SizeOfProc(void *Proc) +{ + ULONG Length; + PUCHAR pOpcode; + ULONG Result = 0; + + do + { + Length = SizeOfCode(Proc, &pOpcode); + Result += Length; + if ((Length == 1) && (*pOpcode == 0xC3)) break; + Proc = (PVOID)((ULONG)Proc + Length); + } while (Length); + return Result; +} + +char __fastcall IsRelativeCmd(unsigned char *pOpcode) +{ + UCHAR Flags; + if (*pOpcode == 0x0F) Flags = OpcodeFlagsExt[*(PUCHAR)((ULONG)pOpcode + 1)]; + else Flags = OpcodeFlags[*pOpcode]; + return (Flags & OP_REL32); +} \ No newline at end of file diff --git a/hook/ldasm.h b/hook/ldasm.h new file mode 100644 index 0000000..3fcc267 --- /dev/null +++ b/hook/ldasm.h @@ -0,0 +1,18 @@ +#ifndef __LDASM__H__ +#define __LDASM__H__ + +#ifdef __cplusplus +extern "C" { +#endif + +unsigned long __fastcall SizeOfCode(void *Code, unsigned char **pOpcode); + +unsigned long __fastcall SizeOfProc(void *Proc); + +char __fastcall IsRelativeCmd(unsigned char *pOpcode); + +#ifdef __cplusplus +} +#endif + +#endif \ No newline at end of file diff --git a/sifilemgr.c b/sifilemgr.c new file mode 100644 index 0000000..973b089 --- /dev/null +++ b/sifilemgr.c @@ -0,0 +1,96 @@ +#include "sifilemgr.h" +#include +#include + + + +//文件链表 +typedef struct SiFileLink +{ + struct SiFileInfo fileinfo; + struct SiFileLink* next; +}; + + +static struct SiFileLink* si_file_link = NULL; + +//创建一个SiFileLink结构 +static struct SiFileLink* SiFile_Create(unsigned long hash,int u8flag,char* orgfile,char* gbkfile) +{ + struct SiFileLink* tmp = (struct SiFileLink*)malloc(sizeof(struct SiFileLink)); + memset(tmp,0,sizeof(struct SiFileLink)); + tmp->fileinfo.hash = hash; + tmp->fileinfo.u8flag = u8flag; + strcpy(tmp->fileinfo.orgfile,orgfile); + strcpy(tmp->fileinfo.gbkfile,gbkfile); + return tmp; +} + +//useless +static void SiFile_Destory(struct SiFileLink* file) +{ + if(file != NULL) + { + file->next = NULL; + free(file); + } +} + +//添加到链表 +void SiFile_Add(unsigned long hash,int u8flag,char* orgfile,char* gbkfile) +{ + struct SiFileLink* file = SiFile_Create(hash,u8flag,orgfile,gbkfile); + + struct SiFileLink* tmp = si_file_link; + if(tmp == NULL) + { + si_file_link = file; + return; + } + + while(tmp->next) + { + tmp = tmp->next; + } + tmp->next = file; + + return; +} + +//从链表中查找文件 +struct SiFileInfo* FindSiFileFromLink(unsigned long hash) +{ + struct SiFileLink* cur = si_file_link; + + while(cur) + { + if(cur->fileinfo.hash == hash) + return &cur->fileinfo; + + cur = cur->next; + } + + return NULL; +} + +//删除临时文件 +void SiFile_Unlink(void) +{ + struct SiFileLink* cur = si_file_link; + + while(cur) + { + if(cur->fileinfo.u8flag != 0) + { + DeleteFile(cur->fileinfo.gbkfile); + } + + cur = cur->next; + } + + return; +} + + + + diff --git a/sifilemgr.h b/sifilemgr.h new file mode 100644 index 0000000..ddfa565 --- /dev/null +++ b/sifilemgr.h @@ -0,0 +1,26 @@ +#ifndef __SIFILEMGR__H__ +#define __SIFILEMGR__H__ + + +//文件结构 +typedef struct SiFileInfo +{ + unsigned long hash; + int u8flag; + char orgfile[256]; + char gbkfile[256]; +}; + + +//添加到链表 +void SiFile_Add(unsigned long hash,int u8flag,char* orgfile,char* gbkfile); + + +//删除临时文件 +void SiFile_Unlink(void); + +//从链表中查找文件 +struct SiFileInfo* FindSiFileFromLink(unsigned long hash); + + +#endif diff --git a/sihandlemgr.c b/sihandlemgr.c new file mode 100644 index 0000000..52c6557 --- /dev/null +++ b/sihandlemgr.c @@ -0,0 +1,115 @@ +#include "sihandlemgr.h" +#include + + + + +//句柄链表 +typedef struct SiHandleLink +{ + struct SiHandleInfo handleinfo; + struct SiHandleLink* next; +}; + +static struct SiHandleLink* si_handle_link = NULL; + +//创建一个SiHandleLink结构 +static struct SiHandleLink* SiHandle_Create(HANDLE handle,int u8flag,char* orgfile,char* gbkfile) +{ + struct SiHandleLink* tmp = (struct SiHandleLink*)malloc(sizeof(struct SiHandleLink)); + memset(tmp,0,sizeof(struct SiHandleLink)); + tmp->handleinfo.handle = handle; + tmp->handleinfo.u8flag = u8flag; + strcpy(tmp->handleinfo.orgfile,orgfile); + strcpy(tmp->handleinfo.gbkfile,gbkfile); + return tmp; +} + +static void SiHandle_Destory(struct SiHandleLink* node) +{ + free(node); +} + +//添加到链表 +void SiHandle_Add(HANDLE handle,int u8flag,char* orgfile,char* gbkfile) +{ + struct SiHandleLink* file = SiHandle_Create(handle,u8flag,orgfile,gbkfile); + struct SiHandleLink* tmp = si_handle_link; + + if(tmp == NULL) + { + si_handle_link = file; + return; + } + + while(tmp->next) + { + tmp = tmp->next; + } + tmp->next = file; + + return; +} + + +//从链表删除 +void SiHandle_Del(HANDLE handle) +{ + struct SiHandleLink* cur = si_handle_link; + struct SiHandleLink* prev = NULL; + + while(cur) + { + if(cur->handleinfo.handle == handle) + { + if(cur == si_handle_link) + { + si_handle_link = si_handle_link->next; + } + else + { + prev->next = cur->next; + } + SiHandle_Destory(cur); + return; + } + + prev = cur; + cur = cur->next; + } + return; +} + +//调试 +void SiHandle_Debug(void) +{ + struct SiHandleLink* cur = si_handle_link; + int size = 0; + if(cur == NULL) + { + OutputDebugString("SiHandleLink size=0"); + return; + } + while(cur) + { + size++; + cur = cur->next; + } + OutputDebugStringEx("SiHandleLink size=%d",size); +} + +//从链表中查找句柄 +struct SiHandleInfo* FindSiHandleFromLink(HANDLE handle) +{ + struct SiHandleLink* cur = si_handle_link; + + while(cur) + { + if(cur->handleinfo.handle == handle) + return &cur->handleinfo; + + cur = cur->next; + } + + return NULL; +} diff --git a/sihandlemgr.h b/sihandlemgr.h new file mode 100644 index 0000000..a00e5ba --- /dev/null +++ b/sihandlemgr.h @@ -0,0 +1,30 @@ +#ifndef __SIHANDLEMGR__H__ +#define __SIHANDLEMGR__H__ + +#include + +//句柄结构 +typedef struct SiHandleInfo +{ + HANDLE handle; + int u8flag; + char orgfile[256]; + char gbkfile[256]; +}; + + +//添加到链表 +void SiHandle_Add(HANDLE handle,int u8flag,char* orgfile,char* gbkfile); + + +//从链表删除 +void SiHandle_Del(HANDLE handle); + +//调试 +void SiHandle_Debug(void); + +//从链表中查找句柄 +struct SiHandleInfo* FindSiHandleFromLink(HANDLE handle); + +#endif + diff --git a/siloader.zip b/siloader.zip new file mode 100644 index 0000000..0faf78f Binary files /dev/null and b/siloader.zip differ diff --git a/siutf8.c b/siutf8.c new file mode 100644 index 0000000..f31881c --- /dev/null +++ b/siutf8.c @@ -0,0 +1,36 @@ +#include +#include "winapihook.h" +#include "sifilemgr.h" + +static void HookSI(void) +{ + HookWinApi(); +} + +static void UnhookSI(void) +{ + SiFile_Unlink(); +} + + +BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved) +{ + switch (fdwReason) + { + case DLL_PROCESS_ATTACH: + HookSI(); + break; + + case DLL_PROCESS_DETACH: + UnhookSI(); + break; + + case DLL_THREAD_ATTACH: + break; + + case DLL_THREAD_DETACH: + break; + } + return TRUE; // succesful +} + diff --git a/siutf8.cbp b/siutf8.cbp new file mode 100644 index 0000000..e4f4bcd --- /dev/null +++ b/siutf8.cbp @@ -0,0 +1,81 @@ + + + + + + diff --git a/utf8.c b/utf8.c new file mode 100644 index 0000000..fbcc699 --- /dev/null +++ b/utf8.c @@ -0,0 +1,123 @@ +#include +#include +#include +#include +#include "utf8.h" + +void utf8_to_gbk(const char* u8,char* gbk,DWORD* gbksize) +{ + if(u8 == NULL) + { + return; + } + //u8->unicode + size_t size = MultiByteToWideChar(CP_UTF8,0,u8,-1,NULL,0); + wchar_t* wansi = (wchar_t *)malloc((size)*sizeof(wchar_t)); + memset(wansi,0,(size)*sizeof(wchar_t)); + MultiByteToWideChar(CP_UTF8,0,u8,-1,wansi,size); + + //unicode->ascii + size = WideCharToMultiByte(CP_ACP,0,wansi,-1,NULL,0,NULL,NULL); + char* ansi = (char *)malloc(size); + memset(ansi,0,size); + WideCharToMultiByte(CP_ACP,0,wansi,-1,ansi,size,NULL,NULL); + + memcpy(gbk,ansi,size); + *gbksize = size; + + //clear + free(wansi); + free(ansi); +} + +void gbk_to_utf8(const char* gbk,char* u8,DWORD* u8size) +{ + if(gbk == NULL) + { + return; + } + + //gbk->unicode + size_t size = MultiByteToWideChar(CP_ACP,0,gbk,-1,NULL,0); + wchar_t* wansi = (wchar_t *)malloc((size)*sizeof(wchar_t)); + memset(wansi,0,(size)*sizeof(wchar_t)); + MultiByteToWideChar(CP_ACP,0,gbk,-1,wansi,size); + + //unicode->ascii + size = WideCharToMultiByte(CP_UTF8,0,wansi,-1,NULL,0,NULL,NULL); + char* ansi = (char *)malloc(size); + memset(ansi,0,size); + WideCharToMultiByte(CP_UTF8,0,wansi,-1,ansi,size,NULL,NULL); + + memcpy(u8,ansi,size); + *u8size = size; + + //clear + free(wansi); + free(ansi); +} + +//2 utf8 dom +//1 utf8 +//0 not utf8 +int IsUtf8(char* buf,int size) +{ + int isu8; + unsigned char* pstart = (unsigned char*)buf; + unsigned char* pend = (unsigned char*)buf+size; + const char BOM[3] = {0xef,0xbb,0xbf}; + unsigned char current_byte; + unsigned char previous_byte; + int good,bad; + good = bad = 0; + + if(size == 0) + { + return 0; + } + if(strncmp(buf,BOM,3) == 0) + { + return 2; + } + + current_byte = previous_byte = *pstart; + while(pstart < pend) + { + current_byte = *pstart; + if((current_byte & 0xc0) == 0x80) + { + if((previous_byte & 0xc0) == 0xc0) + { + good++; + } + else if((previous_byte & 0x80) == 0x00) + { + bad++; + } + } + else if((previous_byte & 0xc0) == 0xc0) + { + bad++; + } + + previous_byte = current_byte; + pstart++; + } + + if(good > bad) + { + isu8 = 1; + } + else if(good == bad) + { + //pure ascii + isu8 = 0; + } + else + { + isu8 = 0; + } + + return isu8; +} + diff --git a/utf8.h b/utf8.h new file mode 100644 index 0000000..f004da9 --- /dev/null +++ b/utf8.h @@ -0,0 +1,16 @@ +#ifndef __UTF8__H__ +#define __UTF8__H__ + +//utf8转gbk +void utf8_to_gbk(const char* u8,char* gbk,DWORD* gbksize); + +//gbk转utf8 +void gbk_to_utf8(const char* gbk,char* u8,DWORD* u8size); + +//2 utf8 dom +//1 utf8 +//0 not utf8 +int IsUtf8(char* buf,int size); + + +#endif diff --git a/utils.c b/utils.c new file mode 100644 index 0000000..25136eb --- /dev/null +++ b/utils.c @@ -0,0 +1,70 @@ +#include +#include +#include "utils.h" + +//输出调试信息 +void WINAPI OutputDebugStringEx(LPCTSTR lpcFormatText, ...) +{ + char szBuffer[1024]; + + va_list argptr; + va_start(argptr, lpcFormatText); + vsprintf(szBuffer, lpcFormatText, argptr); + va_end(argptr); + + OutputDebugString(szBuffer); +} + + +//copy from openssl +//字符串hash +unsigned long HashString(const char* str) +{ + int i,l; + unsigned long ret=0; + unsigned short *s; + + + if(str == NULL) + return(0); + l=(strlen(str)+1)/2; + s=(unsigned short *)str; + for (i=0; i=0;i--) + { + if(path[i] == '\\') + { + strcpy(filename,&path[i+1]); + return; + } + } + + strcpy(filename,path); +} + +/* +void GetTmpFilename(const char* orgfile,char* newfile) +{ + char tmppath[256]; + char filename[256]; + GetFilenameFromPath(orgfile,filename); + GetTempPath(sizeof(tmppath),tmppath); + sprintf(newfile,"%s\\%s.gbk",tmppath,filename); +} +*/ + +void GetTmpFilename(unsigned long hash,char* newfile) +{ + char tmppath[256]; + GetTempPath(sizeof(tmppath),tmppath); + sprintf(newfile,"%s\\%lu.gbk",tmppath,hash); +} + diff --git a/utils.h b/utils.h new file mode 100644 index 0000000..1866e1b --- /dev/null +++ b/utils.h @@ -0,0 +1,16 @@ +#ifndef __UTILS__H__ +#define __UTILS__H__ + +#include + +//输出调试信息 +void WINAPI OutputDebugStringEx(LPCTSTR lpcFormatText, ...); + +//字符串hash +unsigned long HashString(const char* str); + +//获取临时文件名 +//void GetTmpFilename(const char* orgfile,char* newfile); +void GetTmpFilename(unsigned long hash,char* newfile); + +#endif diff --git a/winapihook.c b/winapihook.c new file mode 100644 index 0000000..e10b891 --- /dev/null +++ b/winapihook.c @@ -0,0 +1,232 @@ +#include "winapihook.h" +#include "hook/hookapi.h" +#include "utils.h" +#include "utf8.h" +#include "sifilemgr.h" +#include "sihandlemgr.h" + + +typedef HANDLE (WINAPI *CreateFileFn)( + LPCTSTR lpFileName, + DWORD dwDesiredAccess, + DWORD dwShareMode, + LPSECURITY_ATTRIBUTES lpSecurityAttributes, + DWORD dwCreationDisposition, + DWORD dwFlagsAndAttributes, + HANDLE hTemplateFile +); + +typedef BOOL (WINAPI *CloseHandleFn)( + HANDLE hObject +); + +typedef BOOL (WINAPI *SetEndOfFileFn)( + HANDLE hFile +); + + +CreateFileFn OrgCreateFile = NULL; +CloseHandleFn OrgCloseHandle = NULL; +SetEndOfFileFn OrgSetEndOfFile = NULL; + + + + +HANDLE WINAPI HookCreateFile( + LPCTSTR lpFileName, + DWORD dwDesiredAccess, + DWORD dwShareMode, + LPSECURITY_ATTRIBUTES lpSecurityAttributes, + DWORD dwCreationDisposition, + DWORD dwFlagsAndAttributes, + HANDLE hTemplateFile +) +{ + HANDLE handle; + int u8flag = 0; + char hookfilename[256]; + struct SiFileInfo* si_file_info = NULL; + unsigned long hash = HashString(lpFileName); + + memset(hookfilename,0,sizeof(hookfilename)); + strcpy(hookfilename,lpFileName); + si_file_info = FindSiFileFromLink(hash); + if(si_file_info == NULL) + { + HANDLE hFile = OrgCreateFile(lpFileName, + GENERIC_READ, + FILE_SHARE_READ, + NULL, + OPEN_EXISTING, + FILE_ATTRIBUTE_NORMAL, + NULL); + if(hFile == INVALID_HANDLE_VALUE) + { + OutputDebugStringEx("Function :%s OrgCreateFile %s Failed[%d]",__FUNCTION__,lpFileName,GetLastError()); + goto RECOVER; + } + DWORD fread; + DWORD fsize = GetFileSize(hFile,NULL); + char* buffer = (char*)malloc(fsize+1); + memset(buffer,0,fsize+1); + ReadFile(hFile,buffer,fsize,&fread,NULL); + OrgCloseHandle(hFile); + u8flag = IsUtf8(buffer,fsize); + + //convert + if(u8flag != 0) + { + DWORD gbksize = 0; + DWORD gbkwriten; + char* gbk = (char *)malloc(fsize+1); + if(u8flag == 1) + utf8_to_gbk(buffer,gbk,&gbksize); + else if(u8flag == 2) + utf8_to_gbk(buffer+3,gbk,&gbksize); + //sprintf(hookfilename,"%s.gbk",lpFileName); + GetTmpFilename(hash,hookfilename); + HANDLE hGbk = OrgCreateFile(hookfilename, + GENERIC_WRITE, + 0, + NULL, + CREATE_ALWAYS, + FILE_ATTRIBUTE_NORMAL, + NULL); + if(hGbk != INVALID_HANDLE_VALUE) + { + WriteFile(hGbk,gbk,gbksize-1,&gbkwriten,NULL); + OrgCloseHandle(hGbk); + } + else + { + OutputDebugStringEx("CreateFile %s Failed![Error=%ld]",hookfilename,GetLastError()); + } + free(gbk); + } + + free(buffer); + SiFile_Add(hash,u8flag,(char *)lpFileName,hookfilename); + } + else + { + u8flag = si_file_info->u8flag; + strcpy(hookfilename,si_file_info->gbkfile); + } + +RECOVER: + handle = OrgCreateFile(hookfilename,dwDesiredAccess,dwShareMode,lpSecurityAttributes, + dwCreationDisposition,dwFlagsAndAttributes,hTemplateFile); + if(u8flag != 0) + { + SiHandle_Add(handle,u8flag,(char *)lpFileName,hookfilename); + } + + return handle; +} + + + +BOOL WINAPI HookCloseHandle( + HANDLE hObject +) +{ + BOOL rtv; + + SiHandle_Del(hObject); + rtv = OrgCloseHandle(hObject); + + return rtv; +} + +BOOL WINAPI HookSetEndOfFile( + HANDLE hFile +) +{ + BOOL rtv; + + rtv = OrgSetEndOfFile(hFile); + + struct SiHandleInfo* si_handle_info = NULL; + si_handle_info = FindSiHandleFromLink(hFile); + if(si_handle_info != NULL) + { + //读文件 + DWORD fread; + DWORD fsize = SetFilePointer(hFile,0,NULL,FILE_CURRENT); + char* gbk = (char *)malloc(fsize+1); + memset(gbk,0,fsize+1); + SetFilePointer(hFile,0,NULL,FILE_BEGIN); + ReadFile(hFile,gbk,fsize,&fread,NULL); + SetFilePointer(hFile,fsize,NULL,FILE_BEGIN); + + //转成utf8 + DWORD utf8size = 0; + DWORD utf8writen; + char* utf8 = (char *)malloc(2*fsize+3); + memset(utf8,0,2*fsize+3); + if(si_handle_info->u8flag == 1) + gbk_to_utf8(gbk,utf8,&utf8size); + else if(si_handle_info->u8flag == 2) + { + gbk_to_utf8(gbk,utf8+3,&utf8size); + utf8[0] = 0xef; + utf8[1] = 0xbb; + utf8[2] = 0xbf; + utf8size += 3; + } + else + { + OutputDebugStringEx("Function :%s Error HandleInfo!",__FUNCTION__); + } + + //写回utf8 + HANDLE hUtf8 = OrgCreateFile(si_handle_info->orgfile, + GENERIC_WRITE, + 0, + NULL, + CREATE_ALWAYS, + FILE_ATTRIBUTE_NORMAL, + NULL); + if(hUtf8 != INVALID_HANDLE_VALUE) + { + WriteFile(hUtf8,utf8,utf8size-1,&utf8writen,NULL); + OrgCloseHandle(hUtf8); + } + else + { + OutputDebugStringEx("CreateFile %s Failed![Error=%ld]",si_handle_info->orgfile,GetLastError()); + } + + free(utf8); + free(gbk); + } + + return rtv; +} + + +BOOL HookWinApi(void) +{ + OrgCreateFile = (CreateFileFn)HookFunction("kernel32.dll","CreateFileA",(void *)HookCreateFile); + if(OrgCreateFile == NULL) + { + OutputDebugString("Hook CreateFile Failed!"); + return FALSE; + } + + OrgCloseHandle = (CloseHandleFn)HookFunction("kernel32.dll","CloseHandle",(void *)HookCloseHandle); + if(OrgCloseHandle == NULL) + { + OutputDebugString("Hook CloseHandle Failed!"); + return FALSE; + } + + OrgSetEndOfFile = (SetEndOfFileFn)HookFunction("kernel32.dll","SetEndOfFile",(void *)HookSetEndOfFile); + if(OrgSetEndOfFile == NULL) + { + OutputDebugString("Hook SetEndOfFile Failed!"); + return FALSE; + } + + return TRUE; +} diff --git a/winapihook.h b/winapihook.h new file mode 100644 index 0000000..f318fd9 --- /dev/null +++ b/winapihook.h @@ -0,0 +1,8 @@ +#ifndef __WINAPIHOOK__H__ +#define __WINAPIHOOK__H__ + +#include + +BOOL HookWinApi(void); + +#endif