#include "import.h" #include "controller.hpp" char szGamePath[256]; int n_sleep_time = 10000; int bGMMode = 0, bFairPVP = 0, bPickupRout = 0; //SUBHOOK_INIT(PacketGuard, 0x0858DD4C); SUBHOOK_INIT(GetVectorUserCharacInfo, 0x081A0BB8); SUBHOOK_INIT(doDispatch, 0x08594922); SUBHOOK_INIT(addServerHackCnt, 0x080F8C7E); SUBHOOK_INIT(put_header, 0x080CB8FC); SUBHOOK_INIT(IsRoutingItem, 0x08150F18); SUBHOOK_INIT(setCharacInfoDetail, 0x0864AC1A); SUBHOOK_INIT(IsGameMasterMode, 0x0811EDEE); SUBHOOK_INIT(isGMUser, 0x0814589C); SUBHOOK_INIT(GetPvPTeamCount, 0x08568CE0); SUBHOOK_INIT(isGM, 0x08109346); SUBHOOK_INIT(isGM1, 0x0829948C); SUBHOOK_INIT(set_add_info, 0x080CB884); SUBHOOK_INIT(get_dispatcher, 0x085948E2); SUBHOOK_INIT(dispatch_template, 0x081258B6); SUBHOOK_INIT(isSocketAvatar, 0x082F9228); SUBHOOK_INIT(reach_game_world, 0x086C4E50); SUBHOOK_INIT(Inter_LoadEtc_dispatch_sig, 0x084C0264); //_setCharacInfoDetail int checkGame(const char* pName) { char path[256]; char* path_end; memset(path, 0, sizeof(path)); if (readlink("/proc/self/exe", path, sizeof(path)) <= 0)return -1; path_end = strrchr(path, '/'); if (!path_end || strlen(path_end) < 9)return -1; return strcmp(pName, ++path_end); } int open_main_module_file() { char path[256]; memset(path, 0, sizeof(path)); if (readlink("/proc/self/exe", path, sizeof(path)) <= 0)return -1; return open(path, O_RDONLY); } int getargs(char*** argv) { size_t buflen = 1024, readlen = 0, maxlen = buflen; int fd = open("/proc/self/cmdline", O_RDONLY); if (fd == -1)return 0; char* buf = (char*)malloc(buflen); while (1) { ssize_t n = read(fd, buf + readlen, buflen - readlen); if (n == -1) { free(buf); close(fd); return 0; } readlen += n; if (!n || readlen < buflen)break; maxlen += buflen; buf = (char*)realloc(buf, maxlen); } close(fd); int argc = 0; char* cp = buf; do { while (*cp != '\0')cp++; argc++; } while (++cp < buf + readlen); *argv = (char**)malloc(argc * sizeof(char*)); argc = 0; cp = buf; do { (*argv)[argc] = (char*)malloc(strlen(cp) + 1); strcpy((*argv)[argc], cp); argc++; while (*cp != '\0')cp++; } while (++cp < buf + readlen); free(buf); return argc; } int getConfigPath(char* pPath, size_t nSize) { if (readlink("/proc/self/exe", pPath, nSize) <= 0)return -1; char** argv = NULL; int argc = getargs(&argv); if (!argv || argc < 2) { if (argv) { for (int i = 0; i < argc; i++) { if (argv[i])free(argv[i]); } free(argv); } return -1; } *strrchr(pPath, '/') = '\0'; sprintf(pPath, "%s/cfg/%s.cfg", pPath, argv[1]); for (int i = 0; i < argc; i++) { if (argv[i])free(argv[i]); } free(argv); return 0; } int GetProfileString(const char* profile, const char* section, const char* key, char** val) { int hFile = open(profile, O_RDONLY); if (hFile == -1)return -1; struct stat st; fstat(hFile, &st); void* pFileData = mmap(0, st.st_size, PROT_READ, MAP_SHARED, hFile, 0); if (!pFileData) { close(hFile); return -1; } unsigned char readSection = 0, readKey = 1, readValue = 0, got = 0, notes = 0; char* cur = (char*)pFileData, * end = (char*)pFileData + st.st_size; char* sectionbuf = (char*)malloc(1024) , * keybuf = (char*)malloc(1024) , * valuebuf = (char*)malloc(1024); memset(sectionbuf, 0, 1024); memset(keybuf, 0, 1024); memset(valuebuf, 0, 1024); int i = 0; do { if (notes && *cur != '\n')continue; switch (*cur) { case '#': notes = 1; break; case ' ': case '\t': //jump space break; case '\n': //new line if (readValue) { valuebuf[i] = '\0'; if (!strcmp(section, sectionbuf) && !strcmp(key, keybuf)) { *val = (char*)malloc(i + 1); memset(*val, 0, i + 1); strcpy(*val, valuebuf); got = 1; } //printf("value:%s\n", valuebuf); } notes = 0, readSection = 0, readKey = 1, readValue = 0, i = 0; break; case '[': //section begin readSection = 1; readKey = 0; readValue = 0; i = 0; break; case ']': //section end if (readSection) { sectionbuf[i] = '\0'; //printf("section:%s\n", sectionbuf); readSection = 0; } break; case '=': if (readKey) { keybuf[i] = '\0'; //printf("key:%s\n", keybuf); readSection = 0; readKey = 0; readValue = 1; i = 0; } break; default: if (readSection) { sectionbuf[i++] = *cur; } else if (readKey) { keybuf[i++] = *cur; } else if (readValue) { valuebuf[i++] = *cur; } break; } } while (++cur != end && !got); free(sectionbuf); free(keybuf); free(valuebuf); munmap(pFileData, st.st_size); return 0; } int GetProfileInt(const char* profile, const char* section, const char* key) { int ival = 0; char* pValue = NULL; if (GetProfileString(profile, section, key, &pValue) || !pValue)return 0; ival = atoi(pValue); free(pValue); return ival; } Elf32_Shdr* get_section_by_type(Elf32_Ehdr* pHeader, Elf32_Shdr* pSectionHeaderTable, Elf32_Word sh_type) { Elf32_Half i = 0; do { if (pSectionHeaderTable[i].sh_type == sh_type) { return &pSectionHeaderTable[i]; } } while (++i < pHeader->e_shnum); return NULL; } Elf32_Shdr* get_section_by_index(Elf32_Ehdr* pHeader, Elf32_Shdr* pSectionHeaderTable, Elf32_Half i) { if (i < pHeader->e_shnum) { return &pSectionHeaderTable[i]; } return NULL; } Elf32_Shdr* get_section_by_name(Elf32_Ehdr* pHeader, Elf32_Shdr* pSectionHeaderTable, const char* pSymStrTbl, const char* pName) { Elf32_Half i = 0; do { if (!strcmp(pName, &pSymStrTbl[pSectionHeaderTable[i].sh_name])) { return &pSectionHeaderTable[i]; } } while (++i < pHeader->e_shnum); return NULL; } int get_symbol_index_by_name(Elf32_Sym* pSymbolTbl, int nSymbols, const char* pSymStrTbl, const char* pName) { int i = 0; do { if (ELF32_ST_TYPE(pSymbolTbl[i].st_info) == STT_FUNC && !strcmp(pName, &pSymStrTbl[pSymbolTbl[i].st_name])) { return i; } } while (++i < nSymbols); return 0; } void* replaceIAT(const char* pName, void* pAddr) { void* pOrgAddr = NULL; int hFile = open_main_module_file(); if (hFile != -1) { struct stat st; fstat(hFile, &st); void* pFileData = mmap(0, st.st_size, PROT_READ, MAP_SHARED, hFile, 0); if (pFileData) { Elf32_Ehdr* pHeader = (Elf32_Ehdr*)pFileData; Elf32_Shdr* pSectionHeaderTable = (Elf32_Shdr*)((char*)pHeader + pHeader->e_shoff); Elf32_Shdr* pSymSection = get_section_by_type(pHeader, pSectionHeaderTable, SHT_DYNSYM); Elf32_Shdr* pSymStrSection = get_section_by_index(pHeader, pSectionHeaderTable, pSymSection->sh_link); Elf32_Sym* pSymbolTbl = (Elf32_Sym*)((char*)pHeader + pSymSection->sh_offset); const char* pSymStrTbl = (const char*)((char*)pHeader + pSymStrSection->sh_offset); unsigned int iSymbol = get_symbol_index_by_name(pSymbolTbl, pSymSection->sh_size / sizeof(Elf32_Sym), pSymStrTbl, pName); Elf32_Shdr* pStrSection = get_section_by_index(pHeader, pSectionHeaderTable, pHeader->e_shstrndx); const char* pStrTbl = (const char*)((char*)pHeader + pStrSection->sh_offset); Elf32_Shdr* pRelPltSection = get_section_by_name(pHeader, pSectionHeaderTable, pStrTbl, ".rel.plt"); Elf32_Shdr* pRelDynSection = get_section_by_name(pHeader, pSectionHeaderTable, pStrTbl, ".rel.dyn"); Elf32_Rel* pRelPlt = (Elf32_Rel*)(0x8047000 + pRelPltSection->sh_offset); Elf32_Rel* pRelDyn = (Elf32_Rel*)(0x8047000 + pRelDynSection->sh_offset); int nRelPlt = pRelPltSection->sh_size / sizeof(Elf32_Rel); int nRelDyn = pRelDynSection->sh_size / sizeof(Elf32_Rel); for (int i = 0; i < nRelPlt; i++) { if (ELF32_R_SYM(pRelPlt[i].r_info) == iSymbol && pRelPlt[i].r_offset) { pOrgAddr = *(void**)pRelPlt[i].r_offset; *(void**)pRelPlt[i].r_offset = pAddr; break; } } if (!pOrgAddr) { for (int i = 0; i < nRelDyn; i++) { if (ELF32_R_SYM(pRelDyn[i].r_info) == iSymbol && pRelDyn[i].r_offset) { void** jmpAddr = (void**)pRelDyn[i].r_offset; //printf("jmpaddr::::::::::::::::::::%X\n", pRelDyn[i].r_offset); pOrgAddr = (void*)((char*)(*jmpAddr) + (int)jmpAddr + sizeof(void*)); CodeHook::WriteBytes(pOrgAddr, &pAddr, sizeof(pAddr)); break; } } } munmap(pFileData, st.st_size); } close(hFile); } return pOrgAddr; } int my_select(int __nfds, fd_set* __restrict __readfds, fd_set* __restrict __writefds, fd_set* __restrict __exceptfds, struct timeval* __restrict __timeout) { if (!__nfds && !__readfds && !__writefds && !__exceptfds) { if (!__timeout->tv_sec && __timeout->tv_usec >= 0 && __timeout->tv_usec <= 1000) { __timeout->tv_usec = n_sleep_time; } } return select(__nfds, __readfds, __writefds, __exceptfds, __timeout); } int my_usleep(__useconds_t __useconds) { if (__useconds >= 0 && __useconds <= 1000) { __useconds = n_sleep_time; } return usleep(__useconds); } /*void* my_malloc (size_t __size) { if (__size > 100 * 1024 * 1024) { char path[256]; memset(path, 0, sizeof(path)); readlink("/proc/self/exe", path, sizeof(path)); printf("**********************************[%s][malloc]: %.2f\n", path, (double)__size / 1024 / 1024); print_backtrace(2); } return malloc(__size); }*/ int _doDispatch(void* pPacketDispatcher, void* pUser, int a3, int a4, void* src, int a6, int a7, int a8)//收包处理 { void* pAction = *get_dispatcher(pPacketDispatcher, a4); if (pAction) { //printf("Recv() cs:%d cmd:%d len:%d callback:%p\t%p\t%p\t%p\t%p\t%p\n" // , a3 // , a4 // , a6 // , *((void**)pAction) // , (void*)*((unsigned int*)pAction + 12) // , (void*)*((unsigned int*)pAction + 16) // , (void*)*((unsigned int*)pAction + 20) // , (void*)*((unsigned int*)pAction + 24) // , (void*)*((unsigned int*)pAction + 28) //); } else { //printf("Recv() cs:%d cmd:%d len:%d\n" // , a3 // , a4 // , a6); } return doDispatch(pPacketDispatcher, pUser, a3, a4, src, a6, a7, a8); } int _dispatch_template(void* pInst, void* pUser, void* pPacketBuf) { char* buf = (char*)(*((unsigned int*)pPacketBuf + 5)); //printf("Recv() cs:%d cmd:%d len:%d callback:%p|%p|%p|%p|%p\n" // , buf[0] // , *((unsigned short*)&buf[1]) // , *((unsigned int*)&buf[3]) // , *((void**)*((unsigned int*)pInst + 12)) // , *((void**)*((unsigned int*)pInst + 16)) // , *((void**)*((unsigned int*)pInst + 20)) // , *((void**)*((unsigned int*)pInst + 24)) // , *((void**)*((unsigned int*)pInst + 28)) //); return dispatch_template(pInst, pUser, pPacketBuf); } int _addServerHackCnt(void* pCHackAnalyzer, void* pCUserCharacInfo, int HackType, int Cnt, int a5, int a6) { //printf("addServerHackCnt() HackType:%d \n", HackType); //char pack_buf[0xC]; //PacketGuard(pack_buf); return addServerHackCnt(pCHackAnalyzer, pCUserCharacInfo, HackType, Cnt, a5, a6); } int _put_header(void* pInterfacePacketBuf, int Type, int Cmd) { //printf("Send() cmd:%d\n", Cmd); return put_header(pInterfacePacketBuf, Type, Cmd); } int _IsRoutingItem(void* pItem) { //拾取掷点 return bPickupRout && (*((unsigned int*)pItem + 14) == 4 || *((unsigned char*)pItem + 189)); } int _setCharacInfoDetail(void* pUser, int a2, int a3, void* pCHARAC_DATA) { //下线位置 unsigned char curArea = *((unsigned char*)pCHARAC_DATA + 34); int ret = setCharacInfoDetail(pUser, a2, a3, pCHARAC_DATA); if (curArea == 12 || curArea == 13) { *((char*)GetVectorUserCharacInfo((char*)pUser + 497384, a2) + 34) = 11; } return ret; } int _IsGameMasterMode(void* pUser) { //gm return bGMMode || *((unsigned char*)pUser + 463320) != 0; } int _isGMUser(void* pUser) { //gm //printf("%s\n", __FUNCTION__); return bGMMode || (*((unsigned char*)pUser + 463320) != 0); } int _isGM(void* pGMAccounts, unsigned int a2) { //gm //printf("%s\n", __FUNCTION__); return bGMMode || isGM(pGMAccounts, a2); } int _isGM1(void* pGM_Manager) { //gm //printf("%s\n", __FUNCTION__); return bGMMode || isGM1(pGM_Manager); } int _GetPvPTeamCount(void* pDataManager) { if (bFairPVP)return 10; return *((unsigned int*)pDataManager + 11540); } void* _set_add_info(void* pInven_Item, int a2) { if ((unsigned int)__builtin_return_address(0) == 0x0820156C) { char* _esp = NULL; __asm__ __volatile__("movl %%esp, %[a1];": [a1] "=m"(_esp)); if (_esp) { for (int i = 0; i < 200; i++) { if (897 == *((unsigned int*)&_esp[i])) { //printf("Get !!! %X\n", i); a2 = GetProfileInt(szGamePath, "", "val"); } } } //printf("====================_set_add_info======================%d\n", a2); } return set_add_info(pInven_Item, a2); } int _isSocketAvatar(void* pAvatarItemMgr1, void* pAvatarItemMgr2) { return 1; } int _reach_game_world(void* pThis, void* a2) { return reach_game_world(pThis, a2); } int _Inter_LoadEtc_dispatch_sig(void* pThis, void* pUser, char* a3) { int result = Inter_LoadEtc_dispatch_sig(pThis, pUser, a3); printf("_Inter_LoadEtc_dispatch_sig begin"); //typedef double(__cdecl* FN_sqrt)(_In_ double _X); CUserCharacInfo_getCurCharacNo getCurCharacNo = (CUserCharacInfo_getCurCharacNo)(0x080CBC4E); int CurCharacNo = getCurCharacNo(pUser); printf("CurCharacNo :%d", CurCharacNo); CUserCharacInfo_getCurCharacName getCurCharacName = (CUserCharacInfo_getCurCharacName)0x8101028; char* name = getCurCharacName(pUser); printf("CurCharacName :%s", name); printf("_Inter_LoadEtc_dispatch_sig end"); return result; } void loga() { if (!checkGame("df_game_r")) { int a = 1; void* buf = malloc(4); CodeHook::WriteBytes(buf, &a, 4); getConfigPath(szGamePath, sizeof(szGamePath)); unsigned int nMaxGrade = 80; bGMMode = 1; //max_level = nMaxGrade; //ServerParameterScript::setDungeonOpen //CodeHook::WriteUChar(MAIN_OFFSET(0x22069B), 0x01); //ServerParameterScript::isDungeonOpen CodeHook::WriteUChar(MAIN_OFFSET(0x220894), 0x01); //Init DataManager CodeHook::WriteUChar(MAIN_OFFSET(0x258E80), 0xEB); //Init Level Exp CodeHook::WriteUChar(MAIN_OFFSET(0x314ECB), 0xEB); //Init Mob Reward CodeHook::WriteUChar(MAIN_OFFSET(0x314FCB), 0xEB); //CDataManager::GetSpAtLevelUp CodeHook::WriteUChar(MAIN_OFFSET(0x318CC8), 0xE6); //fixbug CodeHook::WriteUChar(MAIN_OFFSET(0x31C128), 0x7E); CodeHook::WriteUChar(MAIN_OFFSET(0x31C129), 0x06); CodeHook::WriteUChar(MAIN_OFFSET(0x547005), nMaxGrade); CodeHook::WriteUChar(MAIN_OFFSET(0x61AF55), nMaxGrade); CodeHook::WriteUChar(MAIN_OFFSET(0x61B0F3), nMaxGrade); CodeHook::WriteUChar(MAIN_OFFSET(0x61DD28), nMaxGrade - 1); CodeHook::WriteUChar(MAIN_OFFSET(0x61E86A), nMaxGrade); CodeHook::WriteUChar(MAIN_OFFSET(0x61EE9C), nMaxGrade - 1); CodeHook::WriteUChar(MAIN_OFFSET(0x6224A8), nMaxGrade - 1); CodeHook::WriteUChar(MAIN_OFFSET(0x622929), nMaxGrade); CodeHook::WriteUChar(MAIN_OFFSET(0x641D4B), nMaxGrade - 1); CodeHook::WriteUChar(MAIN_OFFSET(0x647ECE), nMaxGrade); CodeHook::WriteUChar(MAIN_OFFSET(0x647EDA), nMaxGrade); CodeHook::WriteUChar(MAIN_OFFSET(0x647F82), nMaxGrade); CodeHook::WriteUChar(MAIN_OFFSET(0x647F88), nMaxGrade); CodeHook::WriteUChar(MAIN_OFFSET(0x66521D), nMaxGrade); CodeHook::WriteUChar(MAIN_OFFSET(0x665223), nMaxGrade); //SUBHOOK_SETUP(doDispatch); SUBHOOK_SETUP(addServerHackCnt); SUBHOOK_SETUP(put_header); SUBHOOK_SETUP(IsRoutingItem); SUBHOOK_SETUP(setCharacInfoDetail); SUBHOOK_SETUP(IsGameMasterMode); SUBHOOK_SETUP(isGMUser); SUBHOOK_SETUP(isGM); SUBHOOK_SETUP(isGM1); SUBHOOK_SETUP(GetPvPTeamCount); SUBHOOK_SETUP(set_add_info); SUBHOOK_SETUP(reach_game_world); SUBHOOK_SETUP(Inter_LoadEtc_dispatch_sig); Controller::Get()->init(); //SUBHOOK_SETUP(isSocketAvatar); if (nMaxGrade > 70) { //以下需要扩充类大小, 修改偏移 CodeHook::WriteUInt(MAIN_OFFSET(0x87162 + 3), 0xB678 + nMaxGrade * 4 + nMaxGrade * 12); //CDataManager::set_reward_sp CodeHook::WriteUInt(MAIN_OFFSET(0x318C26 + 2), 10836 + 840); CodeHook::WriteUChar(MAIN_OFFSET(0x318C3B), nMaxGrade); CodeHook::WriteUInt(MAIN_OFFSET(0x318C68 + 2), 10836 + 840); CodeHook::WriteUChar(MAIN_OFFSET(0x318C79), nMaxGrade); //CDataManager::GetSpAtLevelUp CodeHook::WriteUChar(MAIN_OFFSET(0x318CC4), nMaxGrade); CodeHook::WriteUInt(MAIN_OFFSET(0x318CD4 + 2), 10836 + 840); } CodeHook::WriteUChar(MAIN_OFFSET(0x61B8F6), nMaxGrade); CodeHook::WriteUChar(MAIN_OFFSET(0x622659), nMaxGrade); CodeHook::WriteUChar(MAIN_OFFSET(0x622941), nMaxGrade); CodeHook::WriteUChar(MAIN_OFFSET(0x622941), nMaxGrade); } } void PrintTag() { printf("\n"); printf("**********************************************************\n"); printf("* DNF Server Plugin V%d.%02d *\n", Ver, Patch); printf("* *\n"); printf("* /\\ /\\ *\n"); printf("* *\n"); printf("* __ Auther:Larva *\n"); printf("* QQ Group:81411049 *\n"); printf("**********************************************************\n"); } void __attribute__((constructor)) my_init(void) { PrintTag(); //patchGame(); loga(); }