#include "pch.h" //获取EXE使用头 号位数据 int GetExeNutWrtNum(int Pos) { int num = *(int*)(0x40079F + (Pos * 4)); return num; } //写EXE使用头 号位数据 void SetExeNutWrtNum(int Pos, int num) { int* p = (int*)(0x40079F + (Pos * 4)); *p = num; } //获取Nut头 号位数据 int GetNutArrNum(int Nut头地址, int Pos ) { int num = *(int*)(Nut头地址 + (Pos * 8)); return num; } //写Nut头 号位数据 void SetNutArrNum(int Nut头地址, int Pos, int num) { int* p = (int*)(Nut头地址 + (Pos * 8)); *p = num; } //读内存偏移地址 int GetHook(int Addr, std::string 地址) { size_t pos = 地址.find("+"); size_t size = 地址.size(); int GetHookArr[] = { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 }; int i = 0; while (pos != std::string::npos) { std::string x = 地址.substr(0, pos); GetHookArr[i] = stoi(x, 0, 16); i++; 地址 = 地址.substr(pos + 1, size); pos = 地址.find("+"); } int num; num = *(int*)(Addr); if (num != 0) { for (int z = 0; z < i; z++) { num = *(int*)(num + GetHookArr[z]); } } 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; } //加载 static int SQloadfile(uint32_t v, const wchar_t* filename, bool printerror) { SQFILE* file = SQfopen(filename, L"rb+"); //FILE* file; //file = fopen(filename, "rb"); int ret; unsigned short us; unsigned char uc; LSQLEXREADFUNC func = SQ_io_file_lexfeed_ASCII; if (file) { ret = SQfread(&us, 1, 2, file); if (ret != 2) { us = 0; } if (us == 0xFAFA) { SQfseek(file, 0, 2); if (SQ_Readclosure(v, SQ_File_read, file) > 0) { SQ__Fclose(file); return SQ_OK; } } else { switch (us) { case 0xFFFE: func = SQ_io_file_lexfeed_UCS2_BE; break;//UTF-16 little endian; case 0xFEFF: func = SQ_io_file_lexfeed_UCS2_LE; break;//UTF-16 big endian; case 0xBBEF: if (SQfread(&uc, 1, sizeof(uc), file) == 0) { SQ__Fclose(file); return 1; } if (uc != 0xBF) { SQ__Fclose(file); return 1; } func = SQ_io_file_lexfeed_UTF8; break;//UTF-8 ; default: SQfseek(file, 0, 2); break; // ascii } SQfseek(file, 0, 1);//定位到尾 int length = SQftell(file);//得到文件长度 SQfseek(file, 0, 2);//定位到头 char* temp = new char[length+4];//new一个新的字符串 SQfread(temp, sizeof(temp), length, file);//把文件读到字符串里 temp[length] = '\0';//给结尾添加结束符号 int key[] = { 5,2,3,5,0 };//定义解密数组 Cutecode(temp, key);//解密 SQFILE* newfile = SQfopen(L"ImagePacks2/sprite_interface_teart_zero.npk", L"wb+");//定义新的文件流 SQwrite(temp, sizeof(temp), strlen(temp), newfile);//写入 SQfseek(file, 0, 2);//定位到头 SQfseek(newfile, 0, 2);//定位到头 if (SQ_Compile(v, func, newfile, filename, printerror) >= 0) { SQ__Fclose(file);//关闭文件流 SQ__Fclose(newfile);//关闭文件流 remove("ImagePacks2/sprite_interface_teart_zero.npk");//删除文件 return SQ_OK; } } SQ__Fclose(file); return -1; } return 1; } static int SQdofile(uint32_t v, const wchar_t* filename, bool retval, bool printerror) { if (SQloadfile(v, filename, printerror) >= 0) { SQPush(v, -2); if ((int)SQ_Call(v, 1, retval, 1) >= 0) { SQ_Remove(v, -(retval != 0) - 1); return 1; } SQPop(v, 1); } return -1; } void ggc(char* str,int type,int color) { int shangdian; int laba; int ggtype; int ggcolor; int ggstr; //ggtype = 16; //ggcolor = 65535; shangdian = 0x1A5FB20; laba = 0x9536c0; ggtype = 16; ggcolor = 65535; ggstr = (int)str; //std::cout << ggstr << std::endl; _asm { pushad mov ecx, dword ptr[ebp - 0x04] mov ecx, dword ptr[ecx] mov ecx, dword ptr[ecx + 0x40] push 0x00000000 push 0x00000000 push 0x00000000 push 0x00000000 push dword ptr[ebp - 0x0c] push dword ptr[ebp - 0x10] push dword ptr[ebp - 0x14] call dword ptr[ebp - 0x08] popad } } //-------------------------------------------------------------------------------------------Squirrel //获取Squirrel v 基址 inline uint32_t GetSqVm() { return *(uint32_t*)0x1AF3544; } //新增nut接口funcName绑定C语言函数funcAddr void RegisterNutApi(const wchar_t* funcName, void* funcAddr, uint32_t v) { if (!v) v = GetSqVm(); SQPushRootTable(v); SQPushString(v, funcName, -1); RealSqNewClosure(v, funcAddr, 0); SQNewSlot(v, -3, false); SQPopTop(v); } //Test static int sq_Test(uint32_t v) { //sq_pushinteger(v, n1); *(char**)0x400F00 = (char*)u"test"; _Noticecall(0x400F00, 65535, 14, 0, 0, 0, 0); return 0; } //读人物 或 装备属性 static int GetCharacterAttribute(uint32_t v) { int n1 ,n2 ; int num = SQGetTop(v); int CharAddr = *(int*)(0x1AB7CDC); if (num == 3) { SQGetInt(v, 2, &n1); SQGetInt(v, 3, &n2); int TValue = *(int*)(CharAddr + GetEquAddr(n2)); int SValue = (TValue + n1); if (n1 != 0x8 && n1 != 0x1C && n1 != 0xF4) SQPushInt(v, (DNFDeCode(SValue))); else SQPushInt(v, (*(int*)(SValue))); } else if (num == 2) { SQGetInt(v, 2, &n1); int Value = (CharAddr + n1); SQPushInt(v, (DNFDeCode(Value))); } else { SQPushString(v, L"parameter error",-1); } return 1; } //写人物 或 装备属性 static int SetCharacterAttribute(uint32_t v) { int n1, n2, n3; int num = SQGetTop(v); int CharAddr = *(int*)(0x1AB7CDC); if (num == 4) { SQGetInt(v, 2, &n1); SQGetInt(v, 3, &n2); SQGetInt(v, 4, &n3); int TValue = *(int*)(CharAddr + GetEquAddr(n2)); int SValue = (TValue + n1); if (n1 != 0x8 && n1 != 0x1C && n1 != 0xF4) DNFEnCode(SValue, n3); else *(int*)SValue = n3; SQPushBool(v, true); } else if (num == 3) { SQGetInt(v, 2, &n1); SQGetInt(v, 3, &n2); int Value = (CharAddr + n1); DNFEnCode(Value, n2); SQPushBool(v, true); } else { SQPushBool(v, false); } return 1; } //获取城镇编号 static int GetTownIndex(uint32_t v) { SQPushInt(v, GetHook(0x1A5E258, "0xAC+0xD4+")); return 1; } //获取城镇区域编号 static int GetRegionIndex(uint32_t v) { SQPushInt(v, *(int*)(GetHook(0x1A5E258, "0xAC+0xD8+"))); return 1; } //获取城镇X坐标 static int GetTownXpos(uint32_t v) { SQPushInt(v, GetHook(0x1AB7CE0, "0x2BC+")); return 1; } //获取城镇Y坐标 static int GetTownYpos(uint32_t v) { SQPushInt(v, GetHook(0x1AB7CE0, "0x2C0+")); return 1; } //发包类型 static int SendPackType(uint32_t v) { int n1; SQGetInt(v, 2, &n1); _SendpacksType(*_SendClass, 0, n1); SQPushInt(v, 1); return 1; } //发包Byte static int SendPackByte(uint32_t v) { int n1; SQGetInt(v, 2, &n1); _SendPacksByte(*_SendClass, 0, n1); SQPushInt(v, 1); return 1; } //发包Word static int SendPackWord(uint32_t v) { int n1; SQGetInt(v, 2, &n1); _SendPacksWord(*_SendClass, 0, n1); SQPushInt(v, 1); return 1; } //发包DWord static int SendPackDWord(uint32_t v) { int n1; SQGetInt(v, 2, &n1); _SendPacksDWord(*_SendClass, 0, n1); SQPushInt(v, 1); return 1; } //发包 static int SendPack(uint32_t v) { _SendPacks(); SQPushInt(v, 1); return 1; } //发物品给玩家 static int GivePlayerItem(uint32_t v) { int n1,n2; int num = SQGetTop(v); if (num == 3) { SQGetInt(v, 2, &n1); SQGetInt(v, 3, &n2); _SendpacksType(*_SendClass, 0, 65); _SendPacksDWord(*_SendClass, 0, 1); _SendPacksDWord(*_SendClass, 0, n1); _SendPacksDWord(*_SendClass, 0, n2); _SendPacks(); SQPushBool(v, true); } else { SQPushBool(v, false); } return 1; } //发装备给玩家 static int GivePlayerEqu(uint32_t v) { int n1, n2; int num = SQGetTop(v); if (num == 3) { SQGetInt(v, 2, &n1); SQGetInt(v, 3, &n2); _SendpacksType(*_SendClass, 0, 65); _SendPacksDWord(*_SendClass, 0, 2); _SendPacksDWord(*_SendClass, 0, n1); _SendPacksDWord(*_SendClass, 0, n2); _SendPacks(); SQPushBool(v, true); } else { SQPushBool(v, false); } return 1; } //去副本 static int GoDungeon(uint32_t v) { int n1 = 0; int n2 = 0; int n3 = 0; int n4 = 0; int num = SQGetTop(v); if (num == 2) { SQGetInt(v, 2, &n1); } else if (num == 5) { SQGetInt(v, 2, &n1); SQGetInt(v, 3, &n2); SQGetInt(v, 4, &n3); SQGetInt(v, 5, &n4); } else { SQPushBool(v, false); return 1; } _SendpacksType(*_SendClass, 0, 15); _SendPacks(); _SendpacksType(*_SendClass, 0, 16); _SendPacksWord(*_SendClass, 0, n1); _SendPacksByte(*_SendClass, 0, n2); _SendPacksByte(*_SendClass, 0, n3); _SendPacksByte(*_SendClass, 0, n4); _SendPacks(); SQPushBool(v, true); return 1; } //Ldofile static int LDofile(uint32_t v) { wchar_t* n1; int num = SQGetTop(v); if (num == 2) { SQGetString(v, 2, &n1); SQPopTop(v); /* size_t len = wcslen(n1) + 1; size_t converted = 0; char* CStr; CStr = (char*)malloc(len * sizeof(char)); wcstombs_s(&converted, CStr, len, n1, _TRUNCATE); */ SQdofile(v, n1, false, false); SQPushBool(v, true); } else { SQPushBool(v, false); } return 1; } void RegisterNut() { RegisterNutApi(L"L_sq_Test", sq_Test); 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); RegisterNutApi(L"L_sq_GivePlayerItem", GivePlayerItem); RegisterNutApi(L"L_sq_GivePlayerEqu", GivePlayerEqu); RegisterNutApi(L"L_sq_GoDungeon", GoDungeon); RegisterNutApi(L"L_sq_Dofile", LDofile); }