diff --git a/test.sln b/DNF_DLL编写.sln similarity index 100% rename from test.sln rename to DNF_DLL编写.sln diff --git a/test/MinHook.h b/test/MinHook.h new file mode 100644 index 0000000..15c0a87 --- /dev/null +++ b/test/MinHook.h @@ -0,0 +1,186 @@ +/* + * MinHook - The Minimalistic API Hooking Library for x64/x86 + * Copyright (C) 2009-2017 Tsuda Kageyu. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A + * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER + * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#pragma once + +#if !(defined _M_IX86) && !(defined _M_X64) && !(defined __i386__) && !(defined __x86_64__) + #error MinHook supports only x86 and x64 systems. +#endif + +#include + +// MinHook Error Codes. +typedef enum MH_STATUS +{ + // Unknown error. Should not be returned. + MH_UNKNOWN = -1, + + // Successful. + MH_OK = 0, + + // MinHook is already initialized. + MH_ERROR_ALREADY_INITIALIZED, + + // MinHook is not initialized yet, or already uninitialized. + MH_ERROR_NOT_INITIALIZED, + + // The hook for the specified target function is already created. + MH_ERROR_ALREADY_CREATED, + + // The hook for the specified target function is not created yet. + MH_ERROR_NOT_CREATED, + + // The hook for the specified target function is already enabled. + MH_ERROR_ENABLED, + + // The hook for the specified target function is not enabled yet, or already + // disabled. + MH_ERROR_DISABLED, + + // The specified pointer is invalid. It points the address of non-allocated + // and/or non-executable region. + MH_ERROR_NOT_EXECUTABLE, + + // The specified target function cannot be hooked. + MH_ERROR_UNSUPPORTED_FUNCTION, + + // Failed to allocate memory. + MH_ERROR_MEMORY_ALLOC, + + // Failed to change the memory protection. + MH_ERROR_MEMORY_PROTECT, + + // The specified module is not loaded. + MH_ERROR_MODULE_NOT_FOUND, + + // The specified function is not found. + MH_ERROR_FUNCTION_NOT_FOUND +} +MH_STATUS; + +// Can be passed as a parameter to MH_EnableHook, MH_DisableHook, +// MH_QueueEnableHook or MH_QueueDisableHook. +#define MH_ALL_HOOKS NULL + +#ifdef __cplusplus +extern "C" { +#endif + + // Initialize the MinHook library. You must call this function EXACTLY ONCE + // at the beginning of your program. + MH_STATUS WINAPI MH_Initialize(VOID); + + // Uninitialize the MinHook library. You must call this function EXACTLY + // ONCE at the end of your program. + MH_STATUS WINAPI MH_Uninitialize(VOID); + + // Creates a Hook for the specified target function, in disabled state. + // Parameters: + // pTarget [in] A pointer to the target function, which will be + // overridden by the detour function. + // pDetour [in] A pointer to the detour function, which will override + // the target function. + // ppOriginal [out] A pointer to the trampoline function, which will be + // used to call the original target function. + // This parameter can be NULL. + MH_STATUS WINAPI MH_CreateHook(LPVOID pTarget, LPVOID pDetour, LPVOID *ppOriginal); + + // Creates a Hook for the specified API function, in disabled state. + // Parameters: + // pszModule [in] A pointer to the loaded module name which contains the + // target function. + // pszTarget [in] A pointer to the target function name, which will be + // overridden by the detour function. + // pDetour [in] A pointer to the detour function, which will override + // the target function. + // ppOriginal [out] A pointer to the trampoline function, which will be + // used to call the original target function. + // This parameter can be NULL. + MH_STATUS WINAPI MH_CreateHookApi( + LPCWSTR pszModule, LPCSTR pszProcName, LPVOID pDetour, LPVOID *ppOriginal); + + // Creates a Hook for the specified API function, in disabled state. + // Parameters: + // pszModule [in] A pointer to the loaded module name which contains the + // target function. + // pszTarget [in] A pointer to the target function name, which will be + // overridden by the detour function. + // pDetour [in] A pointer to the detour function, which will override + // the target function. + // ppOriginal [out] A pointer to the trampoline function, which will be + // used to call the original target function. + // This parameter can be NULL. + // ppTarget [out] A pointer to the target function, which will be used + // with other functions. + // This parameter can be NULL. + MH_STATUS WINAPI MH_CreateHookApiEx( + LPCWSTR pszModule, LPCSTR pszProcName, LPVOID pDetour, LPVOID *ppOriginal, LPVOID *ppTarget); + + // Removes an already created hook. + // Parameters: + // pTarget [in] A pointer to the target function. + MH_STATUS WINAPI MH_RemoveHook(LPVOID pTarget); + + // Enables an already created hook. + // Parameters: + // pTarget [in] A pointer to the target function. + // If this parameter is MH_ALL_HOOKS, all created hooks are + // enabled in one go. + MH_STATUS WINAPI MH_EnableHook(LPVOID pTarget); + + // Disables an already created hook. + // Parameters: + // pTarget [in] A pointer to the target function. + // If this parameter is MH_ALL_HOOKS, all created hooks are + // disabled in one go. + MH_STATUS WINAPI MH_DisableHook(LPVOID pTarget); + + // Queues to enable an already created hook. + // Parameters: + // pTarget [in] A pointer to the target function. + // If this parameter is MH_ALL_HOOKS, all created hooks are + // queued to be enabled. + MH_STATUS WINAPI MH_QueueEnableHook(LPVOID pTarget); + + // Queues to disable an already created hook. + // Parameters: + // pTarget [in] A pointer to the target function. + // If this parameter is MH_ALL_HOOKS, all created hooks are + // queued to be disabled. + MH_STATUS WINAPI MH_QueueDisableHook(LPVOID pTarget); + + // Applies all queued changes in one go. + MH_STATUS WINAPI MH_ApplyQueued(VOID); + + // Translates the MH_STATUS to its name as a string. + const char * WINAPI MH_StatusToString(MH_STATUS status); + +#ifdef __cplusplus +} +#endif + diff --git a/test/dllmain.cpp b/test/dllmain.cpp index 9838e0b..9881caa 100644 --- a/test/dllmain.cpp +++ b/test/dllmain.cpp @@ -3,10 +3,6 @@ //#include "函数块.h" -/* -typedef int func(int a,class b); -func* f = (func*)0x1127D60; -*/ @@ -14,10 +10,122 @@ func* f = (func*)0x1127D60; + + + +typedef int(SqGetStringFunc)(uint32_t v, uint32_t stackIndex, wchar_t** ppString); +static SqGetStringFunc* SQGetString = (SqGetStringFunc*)0x1358E70; + + + +static realSqNewClosure* MLnewclosure = NULL; + +uint32_t NewClosure(uint32_t v, void* f, int freeVarsCnt) +{ + std::cout << std::endl; + + wchar_t* funcName; + SQGetString(v, -1 - freeVarsCnt, &funcName); + //if (funcName == L"sq_CreateAICharacter") + //{ + //wprintf(L"Funaddr:%s\t", f); + //std::cout << f << std::endl; + //} + wprintf(L"Funname:%s\tAbli:%d\tFunAddr:0x%p", funcName, freeVarsCnt, f); + + + return MLnewclosure(v, f, freeVarsCnt); +} + +static realSqPushString* MLSqPushString = NULL; + +uint32_t NewPushString(uint32_t v, wchar_t* f, int freeVarsCnt) +{ + std::cout << std::endl; + + wprintf(L"Funname:%s\tAbli:%d\tFunAddr:0x%p", f, freeVarsCnt, f); + + return MLSqPushString(v, f, freeVarsCnt); +} + + + +int HOOK() +{ + std::cout << u8"开始hook" << std::endl; + + if (MH_Initialize() != MH_OK) + { + return 1; + } + + /* + if (MH_CreateHook((void*)0x135B850, &NewClosure, + reinterpret_cast(&MLnewclosure)) != MH_OK) + { + return 2; + } + + // Enable the hook for MessageBoxW. + if (MH_EnableHook((void*)0x135B850) != MH_OK) + { + return 3; + } + */ + + /* + if (MH_CreateHook((void*)0x1358A60, &NewClosure, + reinterpret_cast(&MLnewclosure)) != MH_OK) + { + return 2; + } + + // Enable the hook for MessageBoxW. + if (MH_EnableHook((void*)0x1358A60) != MH_OK) + { + return 3; + } + */ + + + return 0; +} + + + +typedef int(isgm)(int C); +static isgm* gm = (isgm*)0x176F380; + + void testcall() { + + //std::cout << gm(0x186FB828) << std::endl; + + //_SendpacksType(*_SendClass, 0, 0x2D); //_SendPacks(); + + /* + _SendpacksType(*_SendClass, 0, 75); + _SendPacksByte(*_SendClass, 0, 2); + _SendPacksByte(*_SendClass, 0, 2); + _SendPacks(); + + _SendpacksType(*_SendClass, 0, 75); + _SendPacksByte(*_SendClass, 0, 1); + _SendPacksByte(*_SendClass, 0, 2); + _SendPacks(); + + + _SendpacksType(*_SendClass, 0, 37); + _SendPacksWord(*_SendClass, 0, 636); + _SendPacksWord(*_SendClass, 0, 268); + _SendPacksByte(*_SendClass, 0, 5); + _SendPacksWord(*_SendClass, 0, 200); + _SendPacks(); + */ + /* _SendpacksType(*_SendClass, 0, 38); _SendPacksByte(*_SendClass, 0, 1); @@ -39,33 +147,35 @@ void testcall() _SendPacksDWord(*_SendClass, 6, 1); _SendPacks(); */ - + /* _SendpacksType(*_SendClass, 0, 0x3); _SendPacks(); + */ } - -void ThreadFun(void) +void LenheartThread(void) { // 下方写全局变量 static int Nut头地址; static int 属性头地址; static int 可开始执行判断; + while (true) { - Sleep(500); + Sleep(10); if (GetHook(0x1A5FB4C, "0x14+0x28+") == 6)可开始执行判断 = 1; if (可开始执行判断 == 1) { + RegisterNut(); + while (true) { Sleep(10); if (GetExeNutWrtNum(61) != 0 && Nut头地址 == 0)Nut头地址 = GetExeNutWrtNum(61); //if (GetExeNutWrtNum(61 != 0))属性头地址 = GetExeNutWrtNum(61); - if (GetExeNutWrtNum(0) == 666) { std::cout << u8"写成功" << std::endl;; @@ -82,7 +192,7 @@ void ThreadFun(void) __declspec(dllexport) void Lenheart() { DWORD threadID; - CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)ThreadFun, NULL, 0, &threadID); + CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)LenheartThread, NULL, 0, &threadID); } @@ -95,9 +205,9 @@ BOOL APIENTRY DllMain( HMODULE hModule, switch (ul_reason_for_call) { case DLL_PROCESS_ATTACH: - //int i = f(60,80); - //std::cout << "12132132" << std::endl; + //HOOK(); Lenheart(); + break; case DLL_THREAD_ATTACH: case DLL_THREAD_DETACH: case DLL_PROCESS_DETACH: diff --git a/test/framework.h b/test/framework.h index 35967b2..d920597 100644 --- a/test/framework.h +++ b/test/framework.h @@ -5,3 +5,6 @@ #include #include #include + +#include "squirrel.h" +#include "MinHook.h" \ No newline at end of file diff --git a/test/libMinHook.x86.lib b/test/libMinHook.x86.lib new file mode 100644 index 0000000..b21e474 Binary files /dev/null and b/test/libMinHook.x86.lib differ diff --git a/test/pch.h b/test/pch.h index 30c0905..9a3fc2a 100644 --- a/test/pch.h +++ b/test/pch.h @@ -14,6 +14,81 @@ + + + + + + + + + + + + +//-------------------------------------------------------------------------------------------Squirrel + +// Push 根表 +typedef int(SqPushRootT)(uint32_t v); +static SqPushRootT* SQPushRootTable = (SqPushRootT*)0x1358C50; +// Push 函数名 +typedef int(realSqPushString)(uint32_t v, const wchar_t* funcName, int a); +static realSqPushString* RealSqPushString = (realSqPushString*)0x1358A60; +// Push 函数绑定闭包 +typedef int(realSqNewClosure)(uint32_t v, void* funcAddr, int a); +static realSqNewClosure* RealSqNewClosure = (realSqNewClosure*)0x135B850; +// New槽 +typedef int(SqNewSlot)(uint32_t v, int a, bool b); +static SqNewSlot* SQNewSlot = (SqNewSlot*)0x135AA80; +// 平栈 +typedef int(SqPopTop)(uint32_t v); +static SqPopTop* SQPopTop = (SqPopTop*)0x1358FF0; + + +//获取Squirrel v 基址 +inline uint32_t GetSqVm(); + +//新增nut接口funcName绑定C语言函数funcAddr +void RegisterNutApi(const wchar_t* funcName, void* funcAddr, uint32_t v = NULL); + +//注册Nut函数 +void RegisterNut(); + +//新增Nut接口绑定C函数 返回值必须为 SQInteger +// 示例如下 +/* +static SQInteger math_abs(HSQUIRRELVM v) +{ + SQInteger n; + const SQChar* str; + + //获取nut脚本传来的第一个参数, 索引为2 + //索引为1的参数是this指针 + //sq_getinteger(v, 2, &n); + + //获取字符串 + //sq_getstring(v, 2, &str); + + + //返回一个整数给nut脚本 + //sq_pushinteger(v, (SQInteger)(n)); + + //返回一个字符串给nut脚本 参数3为大小? + sq_pushstring(v, str, 5); + + //return 1 表示该函数有返回值传给nut脚本 + return 1; +} +*/ +//-------------------------------------------------------------------------------------------Squirrel + + + + + + + + //获取EXE使用头 号位数据 int GetExeNutWrtNum(int Pos); diff --git a/test/squirrel.h b/test/squirrel.h new file mode 100644 index 0000000..f5d64d3 --- /dev/null +++ b/test/squirrel.h @@ -0,0 +1,420 @@ +/* +Copyright (c) 2003-2006 Alberto Demichelis + +This software is provided 'as-is', without any +express or implied warranty. In no event will the +authors be held liable for any damages arising from +the use of this software. + +Permission is granted to anyone to use this software +for any purpose, including commercial applications, +and to alter it and redistribute it freely, subject +to the following restrictions: + + 1. The origin of this software must not be + misrepresented; you must not claim that + you wrote the original software. If you + use this software in a product, an + acknowledgment in the product + documentation would be appreciated but is + not required. + + 2. Altered source versions must be plainly + marked as such, and must not be + misrepresented as being the original + software. + + 3. This notice may not be removed or + altered from any source distribution. + +*/ +#ifndef _SQUIRREL_H_ +#define _SQUIRREL_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef SQUIRREL_API +#define SQUIRREL_API extern +#endif + +#ifdef _SQ64 +#ifdef _MSC_VER +typedef __int64 SQInteger; +typedef unsigned __int64 SQUnsignedInteger; +typedef unsigned __int64 SQHash; /*should be the same size of a pointer*/ +#else +typedef long SQInteger; +typedef unsigned long SQUnsignedInteger; +typedef unsigned long SQHash; /*should be the same size of a pointer*/ +#endif +typedef int SQInt32; +#else +typedef int SQInteger; +typedef int SQInt32; /*must be 32 bits(also on 64bits processors)*/ +typedef unsigned int SQUnsignedInteger; +typedef unsigned int SQHash; /*should be the same size of a pointer*/ +#endif + +typedef float SQFloat; +typedef void* SQUserPointer; +typedef SQUnsignedInteger SQBool; +typedef SQInteger SQRESULT; + +#define SQTrue (1) +#define SQFalse (0) + + +struct SQVM; +struct SQTable; +struct SQArray; +struct SQString; +struct SQClosure; +struct SQGenerator; +struct SQNativeClosure; +struct SQUserData; +struct SQFunctionProto; +struct SQRefCounted; +struct SQClass; +struct SQInstance; +struct SQDelegable; + +#ifdef _UNICODE +#define SQUNICODE +#endif + +#ifdef SQUNICODE +#if (defined(_MSC_VER) && _MSC_VER >= 1400) // 1400 = VS8 + +#if defined(wchar_t) //this is if the compiler considers wchar_t as native type +#define wchar_t unsigned short +#endif + +#else +typedef unsigned short wchar_t; +#endif + +typedef wchar_t SQChar; +#define _SC(a) L##a +#define scstrcmp wcscmp +#define scsprintf swprintf +#define scstrlen wcslen +#define scstrtod wcstod +#define scstrtol wcstol +#define scatoi _wtoi +#define scstrtoul wcstoul +#define scvsprintf vswprintf +#define scstrstr wcsstr +#define scisspace iswspace +#define scisdigit iswdigit +#define scisxdigit iswxdigit +#define scisalpha iswalpha +#define sciscntrl iswcntrl +#define scisalnum iswalnum +#define scprintf wprintf +#define MAX_CHAR 0xFFFF +#else +typedef char SQChar; +#define _SC(a) a +#define scstrcmp strcmp +#define scsprintf sprintf +#define scstrlen strlen +#define scstrtod strtod +#define scstrtol strtol +#define scatoi atoi +#define scstrtoul strtoul +#define scvsprintf vsprintf +#define scstrstr strstr +#define scisspace isspace +#define scisdigit isdigit +#define scisxdigit isxdigit +#define sciscntrl iscntrl +#define scisalpha isalpha +#define scisalnum isalnum +#define scprintf printf +#define MAX_CHAR 0xFF +#endif + +#define SQUIRREL_VERSION _SC("Squirrel 2.1.1 stable") +#define SQUIRREL_COPYRIGHT _SC("Copyright (C) 2003-2006 Alberto Demichelis") +#define SQUIRREL_AUTHOR _SC("Alberto Demichelis") + +#define SQ_VMSTATE_IDLE 0 +#define SQ_VMSTATE_RUNNING 1 +#define SQ_VMSTATE_SUSPENDED 2 + +#define SQUIRREL_EOB 0 +#define SQ_BYTECODE_STREAM_TAG 0xFAFA + +#define SQOBJECT_REF_COUNTED 0x08000000 +#define SQOBJECT_NUMERIC 0x04000000 +#define SQOBJECT_DELEGABLE 0x02000000 +#define SQOBJECT_CANBEFALSE 0x01000000 + +#define SQ_MATCHTYPEMASKSTRING (-99999) + +#define _RT_MASK 0x00FFFFFF +#define _RAW_TYPE(type) (type&_RT_MASK) + +#define _RT_NULL 0x00000001 +#define _RT_INTEGER 0x00000002 +#define _RT_FLOAT 0x00000004 +#define _RT_BOOL 0x00000008 +#define _RT_STRING 0x00000010 +#define _RT_TABLE 0x00000020 +#define _RT_ARRAY 0x00000040 +#define _RT_USERDATA 0x00000080 +#define _RT_CLOSURE 0x00000100 +#define _RT_NATIVECLOSURE 0x00000200 +#define _RT_GENERATOR 0x00000400 +#define _RT_USERPOINTER 0x00000800 +#define _RT_THREAD 0x00001000 +#define _RT_FUNCPROTO 0x00002000 +#define _RT_CLASS 0x00004000 +#define _RT_INSTANCE 0x00008000 +#define _RT_WEAKREF 0x00010000 + +typedef enum tagSQObjectType{ + OT_NULL = (_RT_NULL|SQOBJECT_CANBEFALSE), + OT_INTEGER = (_RT_INTEGER|SQOBJECT_NUMERIC|SQOBJECT_CANBEFALSE), + OT_FLOAT = (_RT_FLOAT|SQOBJECT_NUMERIC|SQOBJECT_CANBEFALSE), + OT_BOOL = (_RT_BOOL|SQOBJECT_CANBEFALSE), + OT_STRING = (_RT_STRING|SQOBJECT_REF_COUNTED), + OT_TABLE = (_RT_TABLE|SQOBJECT_REF_COUNTED|SQOBJECT_DELEGABLE), + OT_ARRAY = (_RT_ARRAY|SQOBJECT_REF_COUNTED), + OT_USERDATA = (_RT_USERDATA|SQOBJECT_REF_COUNTED|SQOBJECT_DELEGABLE), + OT_CLOSURE = (_RT_CLOSURE|SQOBJECT_REF_COUNTED), + OT_NATIVECLOSURE = (_RT_NATIVECLOSURE|SQOBJECT_REF_COUNTED), + OT_GENERATOR = (_RT_GENERATOR|SQOBJECT_REF_COUNTED), + OT_USERPOINTER = _RT_USERPOINTER, + OT_THREAD = (_RT_THREAD|SQOBJECT_REF_COUNTED) , + OT_FUNCPROTO = (_RT_FUNCPROTO|SQOBJECT_REF_COUNTED), //internal usage only + OT_CLASS = (_RT_CLASS|SQOBJECT_REF_COUNTED), + OT_INSTANCE = (_RT_INSTANCE|SQOBJECT_REF_COUNTED|SQOBJECT_DELEGABLE), + OT_WEAKREF = (_RT_WEAKREF|SQOBJECT_REF_COUNTED) +}SQObjectType; + +#define ISREFCOUNTED(t) (t&SQOBJECT_REF_COUNTED) + + +typedef union tagSQObjectValue +{ + struct SQTable *pTable; + struct SQArray *pArray; + struct SQClosure *pClosure; + struct SQGenerator *pGenerator; + struct SQNativeClosure *pNativeClosure; + struct SQString *pString; + struct SQUserData *pUserData; + SQInteger nInteger; + SQFloat fFloat; + SQUserPointer pUserPointer; + struct SQFunctionProto *pFunctionProto; + struct SQRefCounted *pRefCounted; + struct SQDelegable *pDelegable; + struct SQVM *pThread; + struct SQClass *pClass; + struct SQInstance *pInstance; + struct SQWeakRef *pWeakRef; +}SQObjectValue; + + +typedef struct tagSQObject +{ + SQObjectType _type; + SQObjectValue _unVal; +}SQObject; + +typedef struct tagSQStackInfos{ + const SQChar* funcname; + const SQChar* source; + SQInteger line; +}SQStackInfos; + +typedef struct SQVM* HSQUIRRELVM; +typedef SQObject HSQOBJECT; +typedef SQInteger (*SQFUNCTION)(HSQUIRRELVM); +typedef SQInteger (*SQRELEASEHOOK)(SQUserPointer,SQInteger size); +typedef void (*SQCOMPILERERROR)(HSQUIRRELVM,const SQChar * /*desc*/,const SQChar * /*source*/,SQInteger /*line*/,SQInteger /*column*/); +typedef void (*SQPRINTFUNCTION)(HSQUIRRELVM,const SQChar * ,...); + +typedef SQInteger (*SQWRITEFUNC)(SQUserPointer,SQUserPointer,SQInteger); +typedef SQInteger (*SQREADFUNC)(SQUserPointer,SQUserPointer,SQInteger); + +typedef SQInteger (*SQLEXREADFUNC)(SQUserPointer); + +typedef struct tagSQRegFunction{ + const SQChar *name; + SQFUNCTION f; + SQInteger nparamscheck; + const SQChar *typemask; +}SQRegFunction; + +/*vm*/ +SQUIRREL_API HSQUIRRELVM sq_open(SQInteger initialstacksize); +SQUIRREL_API HSQUIRRELVM sq_newthread(HSQUIRRELVM friendvm, SQInteger initialstacksize); +SQUIRREL_API void sq_seterrorhandler(HSQUIRRELVM v); +SQUIRREL_API void sq_close(HSQUIRRELVM v); +SQUIRREL_API void sq_setforeignptr(HSQUIRRELVM v,SQUserPointer p); +SQUIRREL_API SQUserPointer sq_getforeignptr(HSQUIRRELVM v); +SQUIRREL_API void sq_setprintfunc(HSQUIRRELVM v, SQPRINTFUNCTION printfunc); +SQUIRREL_API SQPRINTFUNCTION sq_getprintfunc(HSQUIRRELVM v); +SQUIRREL_API SQRESULT sq_suspendvm(HSQUIRRELVM v); +SQUIRREL_API SQRESULT sq_wakeupvm(HSQUIRRELVM v,SQBool resumedret,SQBool retval,SQBool raiseerror); +SQUIRREL_API SQInteger sq_getvmstate(HSQUIRRELVM v); + +/*compiler*/ +SQUIRREL_API SQRESULT sq_compile(HSQUIRRELVM v,SQLEXREADFUNC read,SQUserPointer p,const SQChar *sourcename,SQBool raiseerror); +SQUIRREL_API SQRESULT sq_compilebuffer(HSQUIRRELVM v,const SQChar *s,SQInteger size,const SQChar *sourcename,SQBool raiseerror); +SQUIRREL_API void sq_enabledebuginfo(HSQUIRRELVM v, SQBool enable); +SQUIRREL_API void sq_notifyallexceptions(HSQUIRRELVM v, SQBool enable); +SQUIRREL_API void sq_setcompilererrorhandler(HSQUIRRELVM v,SQCOMPILERERROR f); + +/*stack operations*/ +SQUIRREL_API void sq_push(HSQUIRRELVM v,SQInteger idx); +SQUIRREL_API void sq_pop(HSQUIRRELVM v,SQInteger nelemstopop); +SQUIRREL_API void sq_poptop(HSQUIRRELVM v); +SQUIRREL_API void sq_remove(HSQUIRRELVM v,SQInteger idx); +SQUIRREL_API SQInteger sq_gettop(HSQUIRRELVM v); +SQUIRREL_API void sq_settop(HSQUIRRELVM v,SQInteger newtop); +SQUIRREL_API void sq_reservestack(HSQUIRRELVM v,SQInteger nsize); +SQUIRREL_API SQInteger sq_cmp(HSQUIRRELVM v); +SQUIRREL_API void sq_move(HSQUIRRELVM dest,HSQUIRRELVM src,SQInteger idx); + +/*object creation handling*/ +SQUIRREL_API SQUserPointer sq_newuserdata(HSQUIRRELVM v,SQUnsignedInteger size); +SQUIRREL_API void sq_newtable(HSQUIRRELVM v); +SQUIRREL_API void sq_newarray(HSQUIRRELVM v,SQInteger size); +SQUIRREL_API void sq_newclosure(HSQUIRRELVM v,SQFUNCTION func,SQUnsignedInteger nfreevars); +SQUIRREL_API SQRESULT sq_setparamscheck(HSQUIRRELVM v,SQInteger nparamscheck,const SQChar *typemask); +SQUIRREL_API SQRESULT sq_bindenv(HSQUIRRELVM v,SQInteger idx); +SQUIRREL_API void sq_pushstring(HSQUIRRELVM v,const SQChar *s,SQInteger len); +SQUIRREL_API void sq_pushfloat(HSQUIRRELVM v,SQFloat f); +SQUIRREL_API void sq_pushinteger(HSQUIRRELVM v,SQInteger n); +SQUIRREL_API void sq_pushbool(HSQUIRRELVM v,SQBool b); +SQUIRREL_API void sq_pushuserpointer(HSQUIRRELVM v,SQUserPointer p); +SQUIRREL_API void sq_pushnull(HSQUIRRELVM v); +SQUIRREL_API SQObjectType sq_gettype(HSQUIRRELVM v,SQInteger idx); +SQUIRREL_API SQInteger sq_getsize(HSQUIRRELVM v,SQInteger idx); +SQUIRREL_API SQRESULT sq_getbase(HSQUIRRELVM v,SQInteger idx); +SQUIRREL_API SQBool sq_instanceof(HSQUIRRELVM v); +SQUIRREL_API void sq_tostring(HSQUIRRELVM v,SQInteger idx); +SQUIRREL_API void sq_tobool(HSQUIRRELVM v, SQInteger idx, SQBool *b); +SQUIRREL_API SQRESULT sq_getstring(HSQUIRRELVM v,SQInteger idx,const SQChar **c); +SQUIRREL_API SQRESULT sq_getinteger(HSQUIRRELVM v,SQInteger idx,SQInteger *i); +SQUIRREL_API SQRESULT sq_getfloat(HSQUIRRELVM v,SQInteger idx,SQFloat *f); +SQUIRREL_API SQRESULT sq_getbool(HSQUIRRELVM v,SQInteger idx,SQBool *b); +SQUIRREL_API SQRESULT sq_getthread(HSQUIRRELVM v,SQInteger idx,HSQUIRRELVM *thread); +SQUIRREL_API SQRESULT sq_getuserpointer(HSQUIRRELVM v,SQInteger idx,SQUserPointer *p); +SQUIRREL_API SQRESULT sq_getuserdata(HSQUIRRELVM v,SQInteger idx,SQUserPointer *p,SQUserPointer *typetag); +SQUIRREL_API SQRESULT sq_settypetag(HSQUIRRELVM v,SQInteger idx,SQUserPointer typetag); +SQUIRREL_API SQRESULT sq_gettypetag(HSQUIRRELVM v,SQInteger idx,SQUserPointer *typetag); +SQUIRREL_API void sq_setreleasehook(HSQUIRRELVM v,SQInteger idx,SQRELEASEHOOK hook); +SQUIRREL_API SQChar *sq_getscratchpad(HSQUIRRELVM v,SQInteger minsize); +SQUIRREL_API SQRESULT sq_getclosureinfo(HSQUIRRELVM v,SQInteger idx,SQUnsignedInteger *nparams,SQUnsignedInteger *nfreevars); +SQUIRREL_API SQRESULT sq_setnativeclosurename(HSQUIRRELVM v,SQInteger idx,const SQChar *name); +SQUIRREL_API SQRESULT sq_setinstanceup(HSQUIRRELVM v, SQInteger idx, SQUserPointer p); +SQUIRREL_API SQRESULT sq_getinstanceup(HSQUIRRELVM v, SQInteger idx, SQUserPointer *p,SQUserPointer typetag); +SQUIRREL_API SQRESULT sq_newclass(HSQUIRRELVM v,SQBool hasbase); +SQUIRREL_API SQRESULT sq_createinstance(HSQUIRRELVM v,SQInteger idx); +SQUIRREL_API SQRESULT sq_setattributes(HSQUIRRELVM v,SQInteger idx); +SQUIRREL_API SQRESULT sq_getattributes(HSQUIRRELVM v,SQInteger idx); +SQUIRREL_API SQRESULT sq_getclass(HSQUIRRELVM v,SQInteger idx); +SQUIRREL_API void sq_weakref(HSQUIRRELVM v,SQInteger idx); +SQUIRREL_API SQRESULT sq_getdefaultdelegate(HSQUIRRELVM v,SQObjectType t); + +/*object manipulation*/ +SQUIRREL_API void sq_pushroottable(HSQUIRRELVM v); +SQUIRREL_API void sq_pushregistrytable(HSQUIRRELVM v); +SQUIRREL_API SQRESULT sq_setroottable(HSQUIRRELVM v); +SQUIRREL_API SQRESULT sq_newslot(HSQUIRRELVM v, SQInteger idx, SQBool bstatic); +SQUIRREL_API SQRESULT sq_deleteslot(HSQUIRRELVM v,SQInteger idx,SQBool pushval); +SQUIRREL_API SQRESULT sq_set(HSQUIRRELVM v,SQInteger idx); +SQUIRREL_API SQRESULT sq_get(HSQUIRRELVM v,SQInteger idx); +SQUIRREL_API SQRESULT sq_rawget(HSQUIRRELVM v,SQInteger idx); +SQUIRREL_API SQRESULT sq_rawset(HSQUIRRELVM v,SQInteger idx); +SQUIRREL_API SQRESULT sq_rawdeleteslot(HSQUIRRELVM v,SQInteger idx,SQBool pushval); +SQUIRREL_API SQRESULT sq_arrayappend(HSQUIRRELVM v,SQInteger idx); +SQUIRREL_API SQRESULT sq_arraypop(HSQUIRRELVM v,SQInteger idx,SQBool pushval); +SQUIRREL_API SQRESULT sq_arrayresize(HSQUIRRELVM v,SQInteger idx,SQInteger newsize); +SQUIRREL_API SQRESULT sq_arrayreverse(HSQUIRRELVM v,SQInteger idx); +SQUIRREL_API SQRESULT sq_setdelegate(HSQUIRRELVM v,SQInteger idx); +SQUIRREL_API SQRESULT sq_getdelegate(HSQUIRRELVM v,SQInteger idx); +SQUIRREL_API SQRESULT sq_clone(HSQUIRRELVM v,SQInteger idx); +SQUIRREL_API SQRESULT sq_setfreevariable(HSQUIRRELVM v,SQInteger idx,SQUnsignedInteger nval); +SQUIRREL_API SQRESULT sq_next(HSQUIRRELVM v,SQInteger idx); +SQUIRREL_API SQRESULT sq_getweakrefval(HSQUIRRELVM v,SQInteger idx); + +/*calls*/ +SQUIRREL_API SQRESULT sq_call(HSQUIRRELVM v,SQInteger params,SQBool retval,SQBool raiseerror); +SQUIRREL_API SQRESULT sq_resume(HSQUIRRELVM v,SQBool retval,SQBool raiseerror); +SQUIRREL_API const SQChar *sq_getlocal(HSQUIRRELVM v,SQUnsignedInteger level,SQUnsignedInteger idx); +SQUIRREL_API const SQChar *sq_getfreevariable(HSQUIRRELVM v,SQInteger idx,SQUnsignedInteger nval); +SQUIRREL_API SQRESULT sq_throwerror(HSQUIRRELVM v,const SQChar *err); +SQUIRREL_API void sq_reseterror(HSQUIRRELVM v); +SQUIRREL_API void sq_getlasterror(HSQUIRRELVM v); + +/*raw object handling*/ +SQUIRREL_API SQRESULT sq_getstackobj(HSQUIRRELVM v,SQInteger idx,HSQOBJECT *po); +SQUIRREL_API void sq_pushobject(HSQUIRRELVM v,HSQOBJECT obj); +SQUIRREL_API void sq_addref(HSQUIRRELVM v,HSQOBJECT *po); +SQUIRREL_API SQBool sq_release(HSQUIRRELVM v,HSQOBJECT *po); +SQUIRREL_API void sq_resetobject(HSQOBJECT *po); +SQUIRREL_API const SQChar *sq_objtostring(HSQOBJECT *o); +SQUIRREL_API SQBool sq_objtobool(HSQOBJECT *o); +SQUIRREL_API SQInteger sq_objtointeger(HSQOBJECT *o); +SQUIRREL_API SQFloat sq_objtofloat(HSQOBJECT *o); +SQUIRREL_API SQRESULT sq_getobjtypetag(HSQOBJECT *o,SQUserPointer * typetag); + +/*GC*/ +SQUIRREL_API SQInteger sq_collectgarbage(HSQUIRRELVM v); + +/*serialization*/ +SQUIRREL_API SQRESULT sq_writeclosure(HSQUIRRELVM vm,SQWRITEFUNC writef,SQUserPointer up); +SQUIRREL_API SQRESULT sq_readclosure(HSQUIRRELVM vm,SQREADFUNC readf,SQUserPointer up); + +/*mem allocation*/ +SQUIRREL_API void *sq_malloc(SQUnsignedInteger size); +SQUIRREL_API void *sq_realloc(void* p,SQUnsignedInteger oldsize,SQUnsignedInteger newsize); +SQUIRREL_API void sq_free(void *p,SQUnsignedInteger size); + +/*debug*/ +SQUIRREL_API SQRESULT sq_stackinfos(HSQUIRRELVM v,SQInteger level,SQStackInfos *si); +SQUIRREL_API void sq_setdebughook(HSQUIRRELVM v); + +/*UTILITY MACRO*/ +#define sq_isnumeric(o) ((o)._type&SQOBJECT_NUMERIC) +#define sq_istable(o) ((o)._type==OT_TABLE) +#define sq_isarray(o) ((o)._type==OT_ARRAY) +#define sq_isfunction(o) ((o)._type==OT_FUNCPROTO) +#define sq_isclosure(o) ((o)._type==OT_CLOSURE) +#define sq_isgenerator(o) ((o)._type==OT_GENERATOR) +#define sq_isnativeclosure(o) ((o)._type==OT_NATIVECLOSURE) +#define sq_isstring(o) ((o)._type==OT_STRING) +#define sq_isinteger(o) ((o)._type==OT_INTEGER) +#define sq_isfloat(o) ((o)._type==OT_FLOAT) +#define sq_isuserpointer(o) ((o)._type==OT_USERPOINTER) +#define sq_isuserdata(o) ((o)._type==OT_USERDATA) +#define sq_isthread(o) ((o)._type==OT_THREAD) +#define sq_isnull(o) ((o)._type==OT_NULL) +#define sq_isclass(o) ((o)._type==OT_CLASS) +#define sq_isinstance(o) ((o)._type==OT_INSTANCE) +#define sq_isbool(o) ((o)._type==OT_BOOL) +#define sq_isweakref(o) ((o)._type==OT_WEAKREF) +#define sq_type(o) ((o)._type) + +/* deprecated */ +#define sq_createslot(v,n) sq_newslot(v,n,SQFalse) + +#define SQ_OK (0) +#define SQ_ERROR (-1) + +#define SQ_FAILED(res) (res<0) +#define SQ_SUCCEEDED(res) (res>=0) + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /*_SQUIRREL_H_*/ diff --git a/test/squirrel.lib b/test/squirrel.lib new file mode 100644 index 0000000..11e136b Binary files /dev/null and b/test/squirrel.lib differ diff --git a/test/test.vcxproj b/test/test.vcxproj index 02b99b5..4b0b68c 100644 --- a/test/test.vcxproj +++ b/test/test.vcxproj @@ -111,6 +111,7 @@ true Use pch.h + MultiThreaded Console @@ -118,6 +119,7 @@ true true false + squirrel.lib;libMinHook.x86.lib;%(AdditionalDependencies) diff --git a/test/函数块.cpp b/test/函数块.cpp index a7f8d76..652a46b 100644 --- a/test/函数块.cpp +++ b/test/函数块.cpp @@ -62,3 +62,361 @@ int GetHook(int Addr, std::string } return num; } + + + +//ܶȡ ַ +int DNFDeCode(int Address) +{ + DWORD nEax, nEcx8, nEsi, nEdx, nTmp; + nEax = *(int*)(Address); + if (nEax == -1) + return nEax; + nEcx8 = *(int*)(Address + 8); + if (nEcx8 == -1) + return nEcx8; + nEsi = *(int*)(0x1AF8D78); + nEdx = nEax >> 16; + nTmp = (nEdx << 2) + nEsi + 36; + nEdx = *(int*)(nTmp); + if (nEdx == -1) + return nEdx; + nEax = nEax & 65535; + nTmp = (nEax << 2) + nEdx + 8468; + nEax = *(int*)(nTmp); + if (nEax == -1) + return nEax; + _asm + { + mov eax, nEax + movzx edx, ax + mov nEdx, edx + } + nEsi = nEdx << 16; + nEsi = nEsi | nEdx; + nEax = nEsi ^ nEcx8; + return nEax; + return 0; +} +//д +void DNFEnCode(int AddreSs, int Data) +{ + long JEdi, JEcx, JEax, JEsi, JEdx, JSs; + JEcx = AddreSs; + JEax = *(int*)(0x1AF8DB8); + JEax = JEax + 1; + *(int*)(0x1AF8DB8) = JEax; + JEdx = JEax; + JEdx = JEdx >> 8; + JEdx = JEdx << 24; + JEdx = JEdx >> 24; + JEdx = *(int*)(JEdx * 2 + 0x1843F58); + JEdx = JEdx & 0xFFFF; + JEax = JEax << 24; + JEax = JEax >> 24; + JSs = *(int*)(JEax * 2 + 0x1844158); + JSs = JSs & 0xFFFF; + JEdx = JEdx ^ JSs; + JEax = JEdx; + JEax = JEax & 0xFFFF; + JEsi = Data; + JEdx = JEsi >> 16; + Sleep(10); + JSs = JEsi & 0xFFFF; + JEdx = JEdx + JSs; + JEdx = JEdx ^ JEax; + JEdi = JEdx; + JEdx = JEax; + JEax = JEax << 16; + JEax = JEax + JEdx; + JEsi = Data; + JEax = JEax ^ JEsi; + JEsi = AddreSs + 8; + *(int*)(JEsi) = JEax; + JEax = *(int*)(AddreSs); + JEsi = *(int*)(0x1AF8D78); + + JEcx = JEdi; + JEcx = JEcx << 16; + JEcx = JEcx + JEdx; + JEdx = JEax; + JEdx = JEdx >> 16; + JEdx = *(int*)(JEsi + JEdx * 4 + 36); + JEax = JEax & 0xFFFF; + *(int*)(JEdx + JEax * 4 + 8468) = JEcx; +} + + +int GetEquAddr(int addr) +{ + switch (addr) + { + case 1: + return 0x3038; + break; + case 2: + return 0x304C; + break; + case 3: + return 0x3048; + break; + case 4: + return 0x3050; + break; + case 5: + return 0x3044; + break; + case 6: + return 0x3040; + break; + case 7: + return 0x3058; + break; + case 8: + return 0x305C; + break; + case 9: + return 0x3054; + break; + case 10: + return 0x3060; + break; + case 11: + return 0x3064; + break; + case 12: + return 0x3038; + break; + + + case 13: + return 0x3008; + break; + case 14: + return 0x300C; + break; + case 15: + return 0x3010; + break; + case 16: + return 0x3014; + break; + case 17: + return 0x3018; + break; + case 18: + return 0x301C; + break; + case 19: + return 0x3020; + break; + case 20: + return 0x3024; + break; + case 21: + return 0x3028; + break; + case 22: + return 0x302C; + break; + case 23: + return 0x3030; + break; + case 24: + return 0x3068; + break; + case 25: + return 0x306C; + break; + case 26: + return 0x3070; + break; + case 27: + return 0x3074; + break; + } + return -1; +} + + +//-------------------------------------------------------------------------------------------Squirrel +//ȡSquirrel v ַ +inline uint32_t GetSqVm() +{ + return *(uint32_t*)0x1AF3544; +} +//nutӿfuncNameCԺfuncAddr +void RegisterNutApi(const wchar_t* funcName, void* funcAddr, uint32_t v) +{ + if (!v) + v = GetSqVm(); + SQPushRootTable(v); + RealSqPushString(v, funcName, -1); + RealSqNewClosure(v, funcAddr, 0); + SQNewSlot(v, -3, false); + SQPopTop(v); +} + +// װ +static SQInteger GetCharacterAttribute(HSQUIRRELVM v) +{ + SQInteger n1 ,n2 ; + sq_getinteger(v, 2, &n1); + sq_getinteger(v, 3, &n2); + int CharAddr = *(int*)(0x1AB7CDC); + if (n1 > 0 && n2 > 0 && n2 <= 27) + { + int TValue = *(int*)(CharAddr + GetEquAddr(n2)); + int SValue = (TValue + n1); + if (n1 != 0x8 && n1 != 0x1C && n1 != 0xF4) + sq_pushinteger(v, (SQInteger)(DNFDeCode(SValue))); + else + sq_pushinteger(v, (SQInteger)(*(int*)(SValue))); + } + else if (n1 > 0) + { + int Value = (CharAddr + n1); + + sq_pushinteger(v, (SQInteger)(DNFDeCode(Value))); + } + else + { + sq_pushinteger(v, -1); + } + return 1; +} +//д װ +static SQInteger SetCharacterAttribute(HSQUIRRELVM v) +{ + SQInteger n1, n2,n3; + sq_getinteger(v, 2, &n1); + sq_getinteger(v, 3, &n2); + sq_getinteger(v, 4, &n3); + + std::cout << n1 << std::endl; + std::cout << n2 << std::endl; + std::cout << n3 << std::endl; + + int CharAddr = *(int*)(0x1AB7CDC); + if (n1 > 0 && n2 > 0 && n3 > 0) + { + int TValue = *(int*)(CharAddr + GetEquAddr(n2)); + int SValue = (TValue + n1); + if (n1 != 0x8 && n1 != 0x1C && n1 != 0xF4) + //sq_pushinteger(v, (SQInteger)(DNFDeCode(SValue))); + DNFEnCode(SValue, n3); + else + //sq_pushinteger(v, (SQInteger)(*(int*)(SValue))); + *(int*)SValue = n3; + sq_pushinteger(v, (SQInteger)1); + } + else if (n1 > 0 && n2 >0) + { + int Value = (CharAddr + n1); + DNFEnCode(Value, n2); + sq_pushinteger(v, (SQInteger)1); + } + else + { + sq_pushinteger(v, -1); + } + + sq_pushinteger(v, -1); + return 1; +} +//ȡ +static SQInteger GetTownIndex(HSQUIRRELVM v) +{ + sq_pushinteger(v, GetHook(0x1A5E258, "0xAC+0xD4+")); + return 1; +} +//ȡ +static SQInteger GetRegionIndex(HSQUIRRELVM v) +{ + sq_pushinteger(v, *(int*)(GetHook(0x1A5E258, "0xAC+0xD8+"))); + return 1; +} +//ȡX +static SQInteger GetTownXpos(HSQUIRRELVM v) +{ + sq_pushinteger(v, GetHook(0x1AB7CE0, "0x2BC+")); + return 1; +} +//ȡY +static SQInteger GetTownYpos(HSQUIRRELVM v) +{ + sq_pushinteger(v, GetHook(0x1AB7CE0, "0x2C0+")); + return 1; +} + +// +static SQInteger SendPackType(HSQUIRRELVM v) +{ + SQInteger n1; + sq_getinteger(v, 2, &n1); + _SendpacksType(*_SendClass, 0, n1); + + sq_pushinteger(v, 1); + return 1; +} + +//Byte +static SQInteger SendPackByte(HSQUIRRELVM v) +{ + SQInteger n1; + sq_getinteger(v, 2, &n1); + _SendPacksByte(*_SendClass, 0, n1); + + sq_pushinteger(v, 1); + return 1; +} + +//Word +static SQInteger SendPackWord(HSQUIRRELVM v) +{ + SQInteger n1; + sq_getinteger(v, 2, &n1); + _SendPacksWord(*_SendClass, 0, n1); + + sq_pushinteger(v, 1); + return 1; +} + +//DWord +static SQInteger SendPackDWord(HSQUIRRELVM v) +{ + SQInteger n1; + sq_getinteger(v, 2, &n1); + _SendPacksDWord(*_SendClass, 0, n1); + + sq_pushinteger(v, 1); + return 1; +} + +// +static SQInteger SendPack(HSQUIRRELVM v) +{ + _SendPacks(); + sq_pushinteger(v, 1); + return 1; +} + +void RegisterNut() +{ + RegisterNutApi(L"L_sq_GetCharacterAttribute", GetCharacterAttribute); + RegisterNutApi(L"L_sq_SetCharacterAttribute", SetCharacterAttribute); + RegisterNutApi(L"L_sq_GetTownIndex", GetTownIndex); + RegisterNutApi(L"L_sq_GetRegionIndex", GetRegionIndex); + RegisterNutApi(L"L_sq_GetTownXpos", GetTownXpos); + RegisterNutApi(L"L_sq_GetTownYpos", GetTownYpos); + RegisterNutApi(L"L_sq_SendPackType", SendPackType); + RegisterNutApi(L"L_sq_SendPackByte", SendPackByte); + RegisterNutApi(L"L_sq_SendPackWord", SendPackWord); + RegisterNutApi(L"L_sq_SendPackDWord", SendPackDWord); + RegisterNutApi(L"L_sq_SendPack", SendPack); +} + + + + +