diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 0000000..df41c50 --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,12 @@ +# 声明编译要求cmake最低版本 +CMAKE_MINIMUM_REQUIRED(VERSION 3.0) + +# ADD_DEFINITIONS(-std=c++11) + +# 声明一个cmake工程 +PROJECT(Dnf_Projet) + +# 添加子目录, 并指定指定中间二进制和目标二进制存放的位置 +ADD_SUBDIRECTORY(src) +ADD_SUBDIRECTORY(test) + diff --git a/CMakeSettings.json b/CMakeSettings.json new file mode 100644 index 0000000..3ece806 --- /dev/null +++ b/CMakeSettings.json @@ -0,0 +1,86 @@ +{ + "configurations": [ + { + "name": "WSL-GCC-Debug", + "generator": "Unix Makefiles", + "configurationType": "Debug", + "buildRoot": "${projectDir}\\out\\build\\${name}", + "installRoot": "${projectDir}\\out\\install\\${name}", + "cmakeExecutable": "cmake", + "cmakeCommandArgs": "", + "ctestCommandArgs": "", + "inheritEnvironments": [ "linux_x64" ], + "wslPath": "Debian", + "buildCommandArgs": "-j3" + }, + { + "name": "WSL-GCC-Release", + "generator": "Unix Makefiles", + "configurationType": "Release", + "buildRoot": "${projectDir}\\out\\build\\${name}", + "installRoot": "${projectDir}\\out\\install\\${name}", + "cmakeExecutable": "cmake", + "cmakeCommandArgs": "", + "ctestCommandArgs": "", + "inheritEnvironments": [ "linux_x64" ], + "wslPath": "Debian", + "buildCommandArgs": "-j3" + }, + { + "name": "Linux-GCC-Release", + "generator": "Unix Makefiles", + "configurationType": "RelWithDebInfo", + "cmakeExecutable": "cmake", + "remoteCopySourcesExclusionList": [ ".vs", ".git", "out" ], + "buildCommandArgs": "-j3", + "inheritEnvironments": [ "linux_x64" ], + "remoteMachineName": "${defaultRemoteMachineName}", + "remoteCMakeListsRoot": "$HOME/.vs/${projectDirName}/${workspaceHash}/src", + "remoteBuildRoot": "$HOME/.vs/${projectDirName}/${workspaceHash}/out/build/${name}", + "remoteInstallRoot": "$HOME/.vs/${projectDirName}/${workspaceHash}/out/install/${name}", + "remoteCopySources": true, + "rsyncCommandArgs": "-t --delete", + "remoteCopyBuildOutput": false, + "remoteCopySourcesMethod": "rsync", + "addressSanitizerEnabled": false + }, + { + "name": "Linux-GCC-Debug", + "generator": "Unix Makefiles", + "configurationType": "Debug", + "cmakeExecutable": "cmake", + "remoteCopySourcesExclusionList": [ ".vs", ".git", "out" ], + "buildCommandArgs": "-j3", + "ctestCommandArgs": "", + "inheritEnvironments": [ "linux_x64" ], + "remoteMachineName": "${defaultRemoteMachineName}", + "remoteCMakeListsRoot": "$HOME/.vs/${projectDirName}/${workspaceHash}/src", + "remoteBuildRoot": "$HOME/.vs/${projectDirName}/${workspaceHash}/out/build/${name}", + "remoteInstallRoot": "$HOME/.vs/${projectDirName}/${workspaceHash}/out/install/${name}", + "remoteCopySources": true, + "rsyncCommandArgs": "-t --delete", + "remoteCopyBuildOutput": false, + "remoteCopySourcesMethod": "rsync" + }, + { + "name": "x86-Linux-GCC-Release", + "generator": "Unix Makefiles", + "configurationType": "RelWithDebInfo", + "cmakeExecutable": "cmake", + "remoteCopySourcesExclusionList": [ ".vs", ".git", "out" ], + "cmakeCommandArgs": "", + "buildCommandArgs": "-j3", + "ctestCommandArgs": "", + "inheritEnvironments": [ "linux_x86" ], + "remoteMachineName": "${defaultRemoteMachineName}", + "remoteCMakeListsRoot": "$HOME/.vs/${projectDirName}/${workspaceHash}/src", + "remoteBuildRoot": "$HOME/.vs/${projectDirName}/${workspaceHash}/out/build/${name}", + "remoteInstallRoot": "$HOME/.vs/${projectDirName}/${workspaceHash}/out/install/${name}", + "remoteCopySources": true, + "rsyncCommandArgs": "-t --delete", + "remoteCopyBuildOutput": false, + "remoteCopySourcesMethod": "rsync", + "variables": [] + } + ] +} \ No newline at end of file diff --git a/include/Singleton.hpp b/include/Singleton.hpp new file mode 100644 index 0000000..91f3b96 --- /dev/null +++ b/include/Singleton.hpp @@ -0,0 +1,15 @@ +#ifndef __SINGLETON_H__ +#define __SINGLETON_H__ + +//饿汉模式 +#define SINGLETON_DEFINE_S(TypeName) \ +static TypeName* Get() \ +{ \ + static TypeName type_instance; \ + return &type_instance; \ +} \ + \ +TypeName(const TypeName&) = delete; \ +TypeName& operator=(const TypeName&) = delete + +#endif // __SINGLETON_H__ diff --git a/src - 副本/CMakeLists.txt b/src - 副本/CMakeLists.txt new file mode 100644 index 0000000..b2190a6 --- /dev/null +++ b/src - 副本/CMakeLists.txt @@ -0,0 +1,31 @@ +# ҪcmakeͰ汾 +CMAKE_MINIMUM_REQUIRED(VERSION 3.0) + +# ֧֣++11 + +set(CMAKE_CXX_STANDARD 11) +set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -m32 -fpic") + +#ͷļĿ¼ +include_directories(${PROJECT_SOURCE_DIR}/include) + +# ӿԴļ +set(LIB_SOURCE + controller.cc + + df_main.cc +) + +# Ӷ̬⣬ؼΪshared +ADD_LIBRARY(hook_shared SHARED ${LIB_SOURCE}) + +# ָ̬ +SET_TARGET_PROPERTIES(hook_shared PROPERTIES OUTPUT_NAME "hook") + +# ָ̬汾, ɲ +# VERSION:̬汾SOVERSION:API汾 +#SET_TARGET_PROPERTIES(hook_shared PROPERTIES VERSION 0.1.1 SOVERSION 0) + +# ָĿ¼ +SET(LIBRARY_OUTPUT_PATH ${PROJECT_BINARY_DIR}/lib) + diff --git a/src - 副本/controller.cc b/src - 副本/controller.cc new file mode 100644 index 0000000..bb98526 --- /dev/null +++ b/src - 副本/controller.cc @@ -0,0 +1,236 @@ +#include "controller.hpp" + + +controller* controller::pThis = NULL; + + +controller::controller() : + old_UseJewel_dispatch_sig((UseJewel_dispatch_sig_Type*)base::Dispatcher_UseJewel::dispatch_sig), + old_PacketDispatcher_doDispatch((PacketDispatcher_doDispatch_Type*)base::PacketDispatcher::doDispatch) +{ + pThis = this; +} + +controller::~controller() +{ + +} + +void controller::init() +{ + CodeHook::WriteUChar((void*)(base::GlobalData::Init_fix_1 - 0x1), 0); + //.text:085BDE9D 83 F8 0A cmp eax, 10 + CodeHook::WriteUChar((void*)(base::CParty::addDungeonClear_fix_1 + 2), 0x7E); //ͨ + //.text:085BDF30 83 F8 1E cmp eax, 30 + CodeHook::WriteUChar((void*)(base::CParty::addDungeonClear_fix_2 + 2), 0x7E); //Զű + //.text:085BDFC3 83 F8 32 cmp eax, 50 + CodeHook::WriteUChar((void*)(base::CParty::addDungeonClear_fix_3 + 2), 0x7E); //类 + + + + mhook_PacketDispatcher_doDispatch.Hook((void**)&old_PacketDispatcher_doDispatch, (void*)hook_PacketDispatcher_doDispatch); + + mhook_UseJewel_dispatch_sig.Hook((void**)&old_UseJewel_dispatch_sig, (void*)hook_UseJewel_dispatch_sig); + + LOG("controller::init()"); + +} + +int controller::hook_UseJewel_dispatch_sig(void* pDispatcher_UseJewel, CUser* pUser, PacketBuf* pBuf) +{ + printf("getCurCharacName :%s \n", pUser->getCurCharacName().c_str()); + printf("getCurCharacNo :%d \n", pUser->getCurCharacNo()); + printf("get_buf_ptr :%p %p \n", pBuf->get_buf_ptr(0)); + printf("get_len :%d \n", pBuf->get_len()); + + // printf("pBuf :%s \n", Util::ToHexString((const unsigned char*)pBuf->get_buf_ptr(0),40).c_str()); + int state = pUser->get_state(); + printf("state :%d \n", state); + //Уɫ״̬ǷǶ + if (state != 3) + return 0; + + int isEnableAvatarSocketAction = pUser->isEnableAvatarSocketAction(); + if (isEnableAvatarSocketAction) + pUser->SendCmdErrorPacket(205, (unsigned char)isEnableAvatarSocketAction); + //packet_buf + + //ʱװڵı + int avartar_inven_slot = pBuf->get_short(); + printf("avartar_inven_slot :%d \n", avartar_inven_slot); + //ʱװitem_id + int avartar_item_id = pBuf->get_int(); + printf("avartar_item_id :%d \n", avartar_item_id); + //Ƕ + int emblem_cnt = pBuf->get_byte(); + printf("emblem_cnt :%d \n", emblem_cnt); + + if (pUser->CheckItemLock(2, avartar_inven_slot)) + { + pUser->SendCmdErrorPacket(205, 213); + return 0; + } + + //ȡʱװ + CInventory* inven = pUser->getCurCharacInvenW(); + if (!inven) + { + printf("pUser->getCurCharacInvenW : error \n"); + return 0; + } + Inven_Item* avartar = inven->GetInvenRef(CInventory::INVENTORY_TYPE_AVARTAR, avartar_inven_slot); + if (!avartar) + { + printf("inven->GetInvenRef : error \n"); + return 0; + } + //Уʱװ ǷϷ + if (avartar->isEmpty() || (avartar->getKey() != avartar_item_id) || pUser->CheckItemLock(2, avartar_inven_slot)) + { + + printf("avartar->isEmpty() || avartar->getKey() || pUser->CheckItemLock() : error \n"); + return 0; + } + //ȡʱװ + WongWork::CAvatarItemMgr* avartar_add_info = avartar->get_add_info(); + WongWork::CAvatarItemMgr* inven_avartar_mgr = inven->GetAvatarItemMgrR(); + int jewel_socket_data = inven_avartar_mgr->getJewelSocketData(avartar_add_info); + if (!jewel_socket_data) + { + printf("jewel_socket_data : error \n"); + return 0; + } + + printf("jewel_socket_data :%s \n", Util::ToHexString((const unsigned char*)jewel_socket_data, 40).c_str()); + if (emblem_cnt <= 3) + { + std::map> emblems; + for (int i = 0; i < emblem_cnt; i++) + { + //ڵı + int emblem_inven_slot = pBuf->get_short(); + //item_id + int emblem_item_id = pBuf->get_int(); + //ûǶʱװid + int avartar_socket_slot = pBuf->get_byte(); + + //ȡµ + Inven_Item* emblem = inven->GetInvenRef(CInventory::INVENTORY_TYPE_ITEM, emblem_inven_slot); + //У¼ǷϷ + if (emblem->isEmpty() || (emblem->getKey() != emblem_item_id) || (avartar_socket_slot >= 3)) + { + printf("emblem->isEmpty() || (emblem->getKey() : error \n"); + pUser->SendCmdErrorPacket(205, 209); + return 0; + } + + //УǷʱװɫҪ + + //ȡpvf + CDataManager* DataManager = CDataManager::G_CDataManager(); + if (!DataManager) + { + printf("CDataManager::G_CDataManager() : error \n"); + pUser->SendCmdErrorPacket(205, 209); + return 0; + } + CItem* citem = DataManager->find_item(emblem_item_id); + if (!citem) + { + printf("DataManager->find_item() : error \n"); + pUser->SendCmdErrorPacket(205, 209); + return 0; + } + + //У + if (!citem->is_stackable() || (citem->GetItemType() != 20)) + { + printf("citem->is_stackable() || (citem->GetItemType() : error \n"); + pUser->SendCmdErrorPacket(205, 209); + return 0; + } + + //ȡֵ֧IJ + int emblem_socket_type = citem->getJewelTargetSocket(); + + //ȡҪǶʱװ + int avartar_socket_type = *(short*)(jewel_socket_data + avartar_socket_slot * 6); + if (!(emblem_socket_type & avartar_socket_type)) + { + //Ͳƥ + printf("emblem_socket_type & avartar_socket_type\n"); + pUser->SendCmdErrorPacket(205, 209); + return 0; + } + printf("avartar_socket_slot:%d emblem_inven_slot:%d emblem_item_id:%d\n", avartar_socket_slot, emblem_inven_slot, emblem_item_id); + emblems[avartar_socket_slot] = std::make_pair(emblem_inven_slot, emblem_item_id); + } + printf("Ѷȡ!!!\n"); + + for (auto& avartar_socket_slot : emblems) + { + //ɾ + int emblem_inven_slot = avartar_socket_slot.second.first; + inven->delete_item(1, emblem_inven_slot, 1, 8, 1); + + //ʱװ + int emblem_item_id = avartar_socket_slot.second.second; + *(int*)(jewel_socket_data + avartar_socket_slot.first * 6 + 2) = emblem_item_id; + printf("item_id=%d ѳɹǶavartar_socket_slot=%d IJ!\n", emblem_item_id, avartar_socket_slot); + } + + //ʱװݴ浵 + DB_UpdateAvatarJewelSlot::makeRequest(pUser->getCurCharacNo(), avartar->get_ui_id(), (void*)jewel_socket_data); + + //֪ͨͻʱװѸ + pUser->SendUpdateItemList(1, 1, avartar_inven_slot); + printf("Ƕ!!!\n"); + //ذͻ + InterfacePacketBuf* packet_guard = (InterfacePacketBuf*)PacketGuard::NewPacketGuard(); + + packet_guard->put_header(1, 204); + packet_guard->put_int(1); + packet_guard->finalize(1); + pUser->Send((PacketGuard*)packet_guard); + PacketGuard::DelPacketGuard((PacketGuard*)packet_guard); + } + + // 08217C06 ֽ + return 0; +} + +int controller::hook_PacketDispatcher_doDispatch(PacketDispatcher* a1, CUser* user, int packet_class, int packet_id, void* packet_src, int pecakt_len, int a7, int a8) +{ + //void* pAction = *a1->get_dispatcher(packet_id); + // + //if (pAction) + //{ + // LOG("Recv() class:%d id:%d len:%d data:%s callback:%p %p %p %p %p %p " + // , packet_class + // , packet_id + // , pecakt_len + // , Util::ToHexString((const unsigned char*)packet_src, pecakt_len).c_str() + // , *((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 + //{ + // LOG("Recv() class:%d id:%d len:%d data:%s " + // , packet_class + // , packet_id + // , pecakt_len + // , Util::ToHexString((const unsigned char*)packet_src, pecakt_len).c_str() + // ); + //} + + if (packet_id == Packet_UseItem) + { + LOG("hook_PacketDispatcher_doDispatch packet_data :%s ", Util::ToHexString((const unsigned char*)packet_src, pecakt_len).c_str()); + } + return pThis->old_PacketDispatcher_doDispatch(a1, user, packet_class, packet_id, packet_src, pecakt_len, a7, a8); +} diff --git a/src - 副本/controller.hpp b/src - 副本/controller.hpp new file mode 100644 index 0000000..08e12ca --- /dev/null +++ b/src - 副本/controller.hpp @@ -0,0 +1,57 @@ +#include "import.h" +#include "sdk_class.hpp" +#include "hook.h" +#include "utils.hpp" + + +class controller +{ +public: + controller(); + + ~controller(); + + void init(); + + +private: + /** + * @brief hook修复镶嵌徽章 + * @param pDispatcher_UseJewel + * @param pUser + * @param pBuf + * @return + */ + static int hook_UseJewel_dispatch_sig(void* pDispatcher_UseJewel, CUser* pUser, PacketBuf* pBuf); + + /** + * @brief hook收包处理 + * @param a1 + * @param a2 + * @param a3 + * @param a4 + * @param src + * @param a6 + * @param a7 + * @param a8 + * @return + */ + static int hook_PacketDispatcher_doDispatch(PacketDispatcher* a1, CUser* a2, int a3, int packet_id, void* packet_src, int pecakt_len, int a7, int a8); + +private: + using UseJewel_dispatch_sig_Type = decltype(hook_UseJewel_dispatch_sig); + UseJewel_dispatch_sig_Type* old_UseJewel_dispatch_sig; + + using PacketDispatcher_doDispatch_Type = decltype(hook_PacketDispatcher_doDispatch); + PacketDispatcher_doDispatch_Type* old_PacketDispatcher_doDispatch; + + +private: + FuncHook mhook_UseJewel_dispatch_sig; + FuncHook mhook_PacketDispatcher_doDispatch; + + + +private: + static controller* pThis; +}; \ No newline at end of file diff --git a/src - 副本/df_main.cc b/src - 副本/df_main.cc new file mode 100644 index 0000000..7bd643b --- /dev/null +++ b/src - 副本/df_main.cc @@ -0,0 +1,912 @@ +#include "controller.hpp" +controller* manager = NULL; + +char szGamePath[256]; +int n_sleep_time = 10000; +int bGMMode = 0, bFairPVP = 0, bPickupRout = 0; + +#define MAIN_OFFSET(offset) ((void *)((0x8048000) + (offset))) +#define SUBHOOK_INIT(func, addr) \ + fn##func func = (fn##func)addr; \ + FuncHook h##func + +#define SUBHOOK_SETUP(func) h##func.Hook((void **)&func, (void *)_##func) + +//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; +} + + +int patchGame() +{ + int a = 1; + void* buf = malloc(4); + CodeHook::WriteBytes(buf, &a, 4); + getConfigPath(szGamePath, sizeof(szGamePath)); + printf("GameConfigPath:%s\n", szGamePath); + + replaceIAT("select", (void*)my_select); + replaceIAT("usleep", (void*)my_usleep); + //replaceIAT("malloc", (void*)my_malloc); + + if (!checkGame("df_coserver_r")) + { + n_sleep_time = 13000; + } + else if (!checkGame("df_game_r")) + { + int nMaxClientNum_Game = GetProfileInt(szGamePath, "", "max_client"); + int bHumanCertify = GetProfileInt(szGamePath, "", "random_human_certify") != 0; + unsigned int nMaxGrade = GetProfileInt(szGamePath, "", "max_grade"); + if (nMaxGrade > 255)nMaxGrade = 255; + //if (nMaxGrade < 70)nMaxGrade = 70; + bGMMode = GetProfileInt(szGamePath, "", "force_gm_mode") != 0; + bFairPVP = GetProfileInt(szGamePath, "", "fair_pvp") != 0; + bPickupRout = GetProfileInt(szGamePath, "", "pickup_rout") != 0; + int bDespirTowerUnlimit = GetProfileInt(szGamePath, "", "despir_tower_unlimit") != 0; + printf("GM Mode: %s\n", bGMMode ? "on" : "off"); + printf("Human Certify: %s\n", bHumanCertify ? "on" : "off"); + printf("Fair PVP: %s\n", bFairPVP ? "on" : "off"); + printf("Pickup Rout: %s\n", bPickupRout ? "on" : "off"); + printf("Despir Tower Unlimit: %s\n", bDespirTowerUnlimit ? "on" : "off"); + if (bGMMode) + { + CodeHook::WriteUChar(MAIN_OFFSET(0x2512DA + 1), 1); + } + /*CodeHook::WriteUChar(MAIN_OFFSET(0x1B954E), 0x68); + CodeHook::WriteBytes_uint(MAIN_OFFSET(0x1B954E + 1), (int)_hook_item_897); + CodeHook::WriteUChar(MAIN_OFFSET(0x1B954E + 5), 0xC3); + CodeHook::WriteUChar(MAIN_OFFSET(0x1B954E), 0xB8); + CodeHook::WriteUChar(MAIN_OFFSET(0x1B954F), 0x64); + CodeHook::WriteUChar(MAIN_OFFSET(0x1B9550), 0x00); + CodeHook::WriteUChar(MAIN_OFFSET(0x1B9551), 0x00); + CodeHook::WriteUChar(MAIN_OFFSET(0x1B9552), 0x00); + CodeHook::WriteBytes_uint(MAIN_OFFSET(0x1B9553), 0x90909090); + CodeHook::WriteUChar(MAIN_OFFSET(0x1B9557), 0x90); + CodeHook::WriteUChar(MAIN_OFFSET(0x1B9558), 0x90); + CodeHook::WriteUChar(MAIN_OFFSET(0x1B9559), 0x90);*/ + if (bDespirTowerUnlimit) + { + CodeHook::WriteUChar(MAIN_OFFSET(0x5FC1AC), 0xEB); + } + CodeHook::WriteBytes((void*)(0x080EE403 + 1), &nMaxClientNum_Game, sizeof(nMaxClientNum_Game)); + CodeHook::WriteBytes((void*)(0x080EE423 + 1), &nMaxClientNum_Game, sizeof(nMaxClientNum_Game)); + CodeHook::WriteBytes((void*)(0x080EE463 + 1), &nMaxClientNum_Game, sizeof(nMaxClientNum_Game)); + CodeHook::WriteBytes((void*)(0x080EE483 + 1), &nMaxClientNum_Game, sizeof(nMaxClientNum_Game)); + CodeHook::WriteBytes((void*)(0x082AE3F1 + 2), &nMaxClientNum_Game, sizeof(nMaxClientNum_Game)); + CodeHook::WriteBytes((void*)(0x082AE88B + 2), &nMaxClientNum_Game, sizeof(nMaxClientNum_Game)); + CodeHook::WriteBytes((void*)(0x082AEAE9 + 2), &nMaxClientNum_Game, sizeof(nMaxClientNum_Game)); + CodeHook::WriteBytes((void*)(0x082AEFB9 + 2), &nMaxClientNum_Game, sizeof(nMaxClientNum_Game)); + int for_num = nMaxClientNum_Game - 1; + CodeHook::WriteBytes((void*)(0x082AE3FF + 1), &for_num, sizeof(for_num)); + CodeHook::WriteBytes((void*)(0x082AE431 + 1), &for_num, sizeof(for_num)); + CodeHook::WriteBytes((void*)(0x082AE4FF + 3), &for_num, sizeof(for_num)); + CodeHook::WriteBytes((void*)(0x082AE899 + 1), &for_num, sizeof(for_num)); + CodeHook::WriteBytes((void*)(0x082AE8CB + 1), &for_num, sizeof(for_num)); + CodeHook::WriteBytes((void*)(0x082AE999 + 3), &for_num, sizeof(for_num)); + CodeHook::WriteBytes((void*)(0x082AEAF7 + 1), &for_num, sizeof(for_num)); + CodeHook::WriteBytes((void*)(0x082AEB29 + 1), &for_num, sizeof(for_num)); + CodeHook::WriteBytes((void*)(0x082AEBF7 + 3), &for_num, sizeof(for_num)); + CodeHook::WriteBytes((void*)(0x082AEFC7 + 1), &for_num, sizeof(for_num)); + CodeHook::WriteBytes((void*)(0x082AEFF9 + 1), &for_num, sizeof(for_num)); + CodeHook::WriteBytes((void*)(0x082AF0C7 + 3), &for_num, sizeof(for_num)); + unsigned int val = 4 + 0x8EC3C * nMaxClientNum_Game; + CodeHook::WriteBytes((void*)(0x082AE3E1 + 3), &val, sizeof(val)); + val = 4 + 0x1B08 * nMaxClientNum_Game; + CodeHook::WriteBytes((void*)(0x082AE87B + 3), &val, sizeof(val)); + val = 4 + 0x6F0 * nMaxClientNum_Game; + CodeHook::WriteBytes((void*)(0x082AEAD9 + 3), &val, sizeof(val)); + val = 4 + 0xB6C * nMaxClientNum_Game; + CodeHook::WriteBytes((void*)(0x082AEFA9 + 3), &val, sizeof(val)); +#if 0 + CodeHook::WriteUChar(MAIN_OFFSET(0x135E32), 0xEB); + CodeHook::WriteUChar(MAIN_OFFSET(0x22069B), 0x01); + CodeHook::WriteUChar(MAIN_OFFSET(0x220894), 0x01); + CodeHook::WriteUChar(MAIN_OFFSET(0x254D78), 0xEB); + CodeHook::WriteUChar(MAIN_OFFSET(0x258E80), 0xEB); + CodeHook::WriteUChar(MAIN_OFFSET(0x314ECB), 0xEB); + CodeHook::WriteUChar(MAIN_OFFSET(0x314FCB), 0xEB); + CodeHook::WriteUChar(MAIN_OFFSET(0x318CC8), 0xE6); + CodeHook::WriteUChar(MAIN_OFFSET(0x31C128), 0x7E); + CodeHook::WriteUChar(MAIN_OFFSET(0x31C129), 0x06); + + CodeHook::WriteUChar(MAIN_OFFSET(0x602DAF), 0x7C); + + CodeHook::WriteUChar(MAIN_OFFSET(0x61AF55), 0x55); + CodeHook::WriteUChar(MAIN_OFFSET(0x61B0F3), 0x55); + CodeHook::WriteUChar(MAIN_OFFSET(0x61DD28), 0x54); + CodeHook::WriteUChar(MAIN_OFFSET(0x61E86A), 0x57); + CodeHook::WriteUChar(MAIN_OFFSET(0x61EE9C), 0x54); + CodeHook::WriteUChar(MAIN_OFFSET(0x6224A8), 0x54); + CodeHook::WriteUChar(MAIN_OFFSET(0x622929), 0x55); + CodeHook::WriteUChar(MAIN_OFFSET(0x641D4B), 0x54); + CodeHook::WriteUChar(MAIN_OFFSET(0x647ECE), 0x55); + CodeHook::WriteUChar(MAIN_OFFSET(0x647EDA), 0x55); + CodeHook::WriteUChar(MAIN_OFFSET(0x647F82), 0x56); + CodeHook::WriteUChar(MAIN_OFFSET(0x647F88), 0x56); + CodeHook::WriteUChar(MAIN_OFFSET(0x66521D), 0x56); + CodeHook::WriteUChar(MAIN_OFFSET(0x665223), 0x56); +#else + //AradAppSystem::AradAppInit + CodeHook::WriteUChar(MAIN_OFFSET(0x135E32), 0xEB); + //ServerParameterScript::setDungeonOpen + CodeHook::WriteUChar(MAIN_OFFSET(0x22069B), 0x01); + //ServerParameterScript::isDungeonOpen + CodeHook::WriteUChar(MAIN_OFFSET(0x220894), 0x01); + //AntiBot init + CodeHook::WriteUChar(MAIN_OFFSET(0x254D78), 0xEB); + //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); + //pickup rout + CodeHook::WriteUChar(MAIN_OFFSET(0x107D53), 0x90); + CodeHook::WriteUChar(MAIN_OFFSET(0x107D54), 0x90); + CodeHook::WriteUChar(MAIN_OFFSET(0x55D6D1), 0x90); + CodeHook::WriteUChar(MAIN_OFFSET(0x55D6D2), 0x90); + CodeHook::WriteUChar(MAIN_OFFSET(0x6382F4), bHumanCertify); + 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); + 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); +#if 0 + //CDataManager::getDailyTrainingQuest + CodeHook::WriteBytes_uint(MAIN_OFFSET(0x31C110 + 1), 0xB678 + nMaxGrade * 4); + //CDataManager::isThereDailyTrainingQuestList + CodeHook::WriteUChar(MAIN_OFFSET(0x31C12D), nMaxGrade); + //CDataManager::reselectDailyTrainingQuest + //ջڴ + unsigned int incsize = (nMaxGrade - 70) * 4 * 6; + CodeHook::WriteBytes_uint(MAIN_OFFSET(0x31BCE6 + 2), 0x70C + incsize); + CodeHook::WriteBytes_uint(MAIN_OFFSET(0x31BD03 + 2), 0xFFFFF91C - incsize); + CodeHook::WriteBytes_uint(MAIN_OFFSET(0x31BD2E + 2), 0xFFFFF914 - incsize); + CodeHook::WriteBytes_uint(MAIN_OFFSET(0x31BD5E + 2), 0xFFFFF914 - incsize); + CodeHook::WriteBytes_uint(MAIN_OFFSET(0x31BD77 + 2), 0xFFFFF91C - incsize); + CodeHook::WriteBytes_uint(MAIN_OFFSET(0x31BDD2 + 2), 0xFFFFF91C - incsize); + CodeHook::WriteBytes_uint(MAIN_OFFSET(0x31BEED + 2), 0xFFFFF91C - incsize); + CodeHook::WriteBytes_uint(MAIN_OFFSET(0x31C098 + 2), 0xFFFFF91C - incsize); + CodeHook::WriteBytes_uint(MAIN_OFFSET(0x31C0AA + 2), 0xFFFFF91C - incsize); + CodeHook::WriteBytes_uint(MAIN_OFFSET(0x31C0B6 + 2), 0xFFFFF91C - incsize); + CodeHook::WriteBytes_uint(MAIN_OFFSET(0x31C0D9 + 2), 0xFFFFF91C - incsize); + + CodeHook::WriteUChar(MAIN_OFFSET(0x31BD0B + 1), nMaxGrade - 1); + CodeHook::WriteUChar(MAIN_OFFSET(0x31BD38 + 1), nMaxGrade - 1); + CodeHook::WriteUChar(MAIN_OFFSET(0x31C084 + 3), nMaxGrade); + CodeHook::WriteBytes_uint(MAIN_OFFSET(0x31BDA4 + 1), 0xB678 + nMaxGrade * 4); + CodeHook::WriteBytes_uint(MAIN_OFFSET(0x31BEBC + 1), 0xB678 + nMaxGrade * 4); + CodeHook::WriteBytes_uint(MAIN_OFFSET(0x31BF4A + 1), 0xB678 + nMaxGrade * 4); + CodeHook::WriteBytes_uint(MAIN_OFFSET(0x31BF82 + 1), 0xB678 + nMaxGrade * 4); + CodeHook::WriteBytes_uint(MAIN_OFFSET(0x31BFAE + 1), 0xB678 + nMaxGrade * 4); + //TrainingQuestScript::getApplyLevel + CodeHook::WriteUChar(MAIN_OFFSET(0xA67AFB + 3), nMaxGrade); + //TrainingQuestScript::suffleTrainingQuests + CodeHook::WriteUChar(MAIN_OFFSET(0xA67DAA + 3), nMaxGrade); + //CDataManager::CDataManager + CodeHook::WriteBytes_uint(MAIN_OFFSET(0x30DF24 + 2), 0xB678 + nMaxGrade * 4); + CodeHook::WriteUChar(MAIN_OFFSET(0x30DF2C + 1), nMaxGrade - 1); + CodeHook::WriteUChar(MAIN_OFFSET(0x30DF56 + 1), nMaxGrade - 1); +#endif + } + CodeHook::WriteUChar(MAIN_OFFSET(0x61B8F6), nMaxGrade); + CodeHook::WriteUChar(MAIN_OFFSET(0x622659), nMaxGrade); + CodeHook::WriteUChar(MAIN_OFFSET(0x622941), nMaxGrade); + CodeHook::WriteUChar(MAIN_OFFSET(0x622941), 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(isSocketAvatar); + +#endif + } + else if (!checkGame("df_channel_r")) + { + int nMaxClientNum_Gate = GetProfileInt(szGamePath, "server", "max_client"); + + int for_num = nMaxClientNum_Gate - 1; + unsigned int val = 4 + 0x1C * nMaxClientNum_Gate; + CodeHook::WriteBytes((void*)(0x0805361E + 3), &val, sizeof(val)); + CodeHook::WriteBytes((void*)(0x0805362E + 2), &nMaxClientNum_Gate, sizeof(nMaxClientNum_Gate)); + CodeHook::WriteBytes((void*)(0x0805363C + 1), &for_num, sizeof(for_num)); + CodeHook::WriteBytes((void*)(0x080536B8 + 4), &nMaxClientNum_Gate, sizeof(nMaxClientNum_Gate)); + CodeHook::WriteBytes((void*)(0x08053783 + 3), &for_num, sizeof(for_num)); + val = 4 + 0x140060 * nMaxClientNum_Gate; + CodeHook::WriteBytes((void*)0x0805380D, &val, sizeof(val)); + CodeHook::WriteBytes((void*)0x0805381C, &nMaxClientNum_Gate, sizeof(nMaxClientNum_Gate)); + CodeHook::WriteBytes((void*)0x08053829, &for_num, sizeof(for_num)); + CodeHook::WriteBytes((void*)0x080538A4, &nMaxClientNum_Gate, sizeof(nMaxClientNum_Gate)); + CodeHook::WriteBytes((void*)0x08053964, &for_num, sizeof(for_num)); + } + else if (!checkGame("df_bridge_r")) + { + int nMaxClientNum_Gate = GetProfileInt(szGamePath, "server", "max_client"); + + int for_num = nMaxClientNum_Gate - 1; + unsigned int val = 4 + 0x1C * nMaxClientNum_Gate; + CodeHook::WriteBytes((void*)(0x08058018 + 3), &val, sizeof(val)); + CodeHook::WriteBytes((void*)(0x08058028 + 2), &nMaxClientNum_Gate, sizeof(nMaxClientNum_Gate)); + CodeHook::WriteBytes((void*)(0x08058036 + 1), &for_num, sizeof(for_num)); + CodeHook::WriteBytes((void*)(0x080580B2 + 4), &nMaxClientNum_Gate, sizeof(nMaxClientNum_Gate)); + CodeHook::WriteBytes((void*)(0x0805817D + 3), &for_num, sizeof(for_num)); + val = 4 + 0x140060 * nMaxClientNum_Gate; + CodeHook::WriteBytes((void*)0x08058207, &val, sizeof(val)); + CodeHook::WriteBytes((void*)0x08058216, &nMaxClientNum_Gate, sizeof(nMaxClientNum_Gate)); + CodeHook::WriteBytes((void*)0x08058223, &for_num, sizeof(for_num)); + CodeHook::WriteBytes((void*)0x0805829E, &nMaxClientNum_Gate, sizeof(nMaxClientNum_Gate)); + CodeHook::WriteBytes((void*)0x0805835E, &for_num, sizeof(for_num)); + } + return 0; +} + + +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 = 70; + 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); + //manager->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) +{ + manager = new controller(); + PrintTag(); + //patchGame(); + loga(); + +} + + diff --git a/src - 副本/hook.h b/src - 副本/hook.h new file mode 100644 index 0000000..e662f43 --- /dev/null +++ b/src - 副本/hook.h @@ -0,0 +1,381 @@ +#pragma once +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define MOVEPOINT(p,i) (void*)((char*)p+i) +#define MAKEPOINTER(t, p, offset) ((t)((unsigned char*)(p) + (long)offset)) +#define PADALIGN(x,mask) ((x+mask)&(~(x%mask))) +#define Addr_Align(addr,mask) ((void*)(((unsigned long)(addr))&(~((mask)-1)))) +#define Move_Ptr(addr,offset) ((void*)((unsigned long)(addr)+(offset))) + +enum flags { + MODRM = 1, + PLUS_R = 1 << 1, + REG_OPCODE = 1 << 2, + IMM8 = 1 << 3, + IMM16 = 1 << 4, + IMM32 = 1 << 5, + RELOC = 1 << 6 +}; +struct opcode_info { + unsigned char opcode; + unsigned char reg_opcode; + unsigned int flags; +}; +static unsigned char prefixes[] = { + 0xF0, 0xF2, 0xF3, + 0x2E, 0x36, 0x3E, 0x26, 0x64, 0x65, + 0x66, /* operand size override */ + 0x67 /* address size override */ +}; +static struct opcode_info opcodes[] = { + /* ADD AL, imm8 */{ 0x04, 0, IMM8 }, + /* ADD EAX, imm32 */{ 0x05, 0, IMM32 }, + /* ADD r/m8, imm8 */{ 0x80, 0, MODRM | REG_OPCODE | IMM8 }, + /* ADD r/m32, imm32 */{ 0x81, 0, MODRM | REG_OPCODE | IMM32 }, + /* ADD r/m32, imm8 */{ 0x83, 0, MODRM | REG_OPCODE | IMM8 }, + /* ADD r/m8, r8 */{ 0x00, 0, MODRM }, + /* ADD r/m32, r32 */{ 0x01, 0, MODRM }, + /* ADD r8, r/m8 */{ 0x02, 0, MODRM }, + /* ADD r32, r/m32 */{ 0x03, 0, MODRM }, + /* AND AL, imm8 */{ 0x24, 0, IMM8 }, + /* AND EAX, imm32 */{ 0x25, 0, IMM32 }, + /* AND r/m8, imm8 */{ 0x80, 4, MODRM | REG_OPCODE | IMM8 }, + /* AND r/m32, imm32 */{ 0x81, 4, MODRM | REG_OPCODE | IMM32 }, + /* AND r/m32, imm8 */{ 0x83, 4, MODRM | REG_OPCODE | IMM8 }, + /* AND r/m8, r8 */{ 0x20, 0, MODRM }, + /* AND r/m32, r32 */{ 0x21, 0, MODRM }, + /* AND r8, r/m8 */{ 0x22, 0, MODRM }, + /* AND r32, r/m32 */{ 0x23, 0, MODRM }, + /* CALL rel32 */{ 0xE8, 0, IMM32 | RELOC }, + /* CALL r/m32 */{ 0xFF, 2, MODRM | REG_OPCODE }, + /* CMP r/m16/32, imm8*/{ 0x83, 7, MODRM | REG_OPCODE | IMM8 }, + /* DEC r/m16/32 */{ 0xFF, 1, MODRM | REG_OPCODE }, + /* ENTER imm16, imm8 */{ 0xC8, 0, IMM16 | IMM8 }, + /* INT 3 */{ 0xCC, 0, 0 }, + /* JMP rel32 */{ 0xE9, 0, IMM32 | RELOC }, + /* JMP r/m32 */{ 0xFF, 4, MODRM | REG_OPCODE }, + /* LEA r32,m */{ 0x8D, 0, MODRM }, + /* LEAVE */{ 0xC9, 0, 0 }, + /* MOV r/m8,r8 */{ 0x88, 0, MODRM }, + /* MOV r/m32,r32 */{ 0x89, 0, MODRM }, + /* MOV r8,r/m8 */{ 0x8A, 0, MODRM }, + /* MOV r32,r/m32 */{ 0x8B, 0, MODRM }, + /* MOV r/m16,Sreg */{ 0x8C, 0, MODRM }, + /* MOV Sreg,r/m16 */{ 0x8E, 0, MODRM }, + /* MOV AL,moffs8 */{ 0xA0, 0, IMM8 }, + /* MOV EAX,moffs32 */{ 0xA1, 0, IMM32 }, + /* MOV moffs8,AL */{ 0xA2, 0, IMM8 }, + /* MOV moffs32,EAX */{ 0xA3, 0, IMM32 }, + /* MOV r8, imm8 */{ 0xB0, 0, PLUS_R | IMM8 }, + /* MOV r32, imm32 */{ 0xB8, 0, PLUS_R | IMM32 }, + /* MOV r/m8, imm8 */{ 0xC6, 0, MODRM | REG_OPCODE | IMM8 }, + /* MOV r/m32, imm32 */{ 0xC7, 0, MODRM | REG_OPCODE | IMM32 }, + /* NOP */{ 0x90, 0, 0 }, + /* OR AL, imm8 */{ 0x0C, 0, IMM8 }, + /* OR EAX, imm32 */{ 0x0D, 0, IMM32 }, + /* OR r/m8, imm8 */{ 0x80, 1, MODRM | REG_OPCODE | IMM8 }, + /* OR r/m32, imm32 */{ 0x81, 1, MODRM | REG_OPCODE | IMM32 }, + /* OR r/m32, imm8 */{ 0x83, 1, MODRM | REG_OPCODE | IMM8 }, + /* OR r/m8, r8 */{ 0x08, 0, MODRM }, + /* OR r/m32, r32 */{ 0x09, 0, MODRM }, + /* OR r8, r/m8 */{ 0x0A, 0, MODRM }, + /* OR r32, r/m32 */{ 0x0B, 0, MODRM }, + /* POP r/m32 */{ 0x8F, 0, MODRM | REG_OPCODE }, + /* POP r32 */{ 0x58, 0, PLUS_R }, + /* PUSH r/m32 */{ 0xFF, 6, MODRM | REG_OPCODE }, + /* PUSH r32 */{ 0x50, 0, PLUS_R }, + /* PUSH imm8 */{ 0x6A, 0, IMM8 }, + /* PUSH imm32 */{ 0x68, 0, IMM32 }, + /* RET */{ 0xC3, 0, 0 }, + /* RET imm16 */{ 0xC2, 0, IMM16 }, + /* SUB AL, imm8 */{ 0x2C, 0, IMM8 }, + /* SUB EAX, imm32 */{ 0x2D, 0, IMM32 }, + /* SUB r/m8, imm8 */{ 0x80, 5, MODRM | REG_OPCODE | IMM8 }, + /* SUB r/m32, imm32 */{ 0x81, 5, MODRM | REG_OPCODE | IMM32 }, + /* SUB r/m32, imm8 */{ 0x83, 5, MODRM | REG_OPCODE | IMM8 }, + /* SUB r/m8, r8 */{ 0x28, 0, MODRM }, + /* SUB r/m32, r32 */{ 0x29, 0, MODRM }, + /* SUB r8, r/m8 */{ 0x2A, 0, MODRM }, + /* SUB r32, r/m32 */{ 0x2B, 0, MODRM }, + /* TEST AL, imm8 */{ 0xA8, 0, IMM8 }, + /* TEST EAX, imm32 */{ 0xA9, 0, IMM32 }, + /* TEST r/m8, imm8 */{ 0xF6, 0, MODRM | REG_OPCODE | IMM8 }, + /* TEST r/m32, imm32 */{ 0xF7, 0, MODRM | REG_OPCODE | IMM32 }, + /* TEST r/m8, r8 */{ 0x84, 0, MODRM }, + /* TEST r/m32, r32 */{ 0x85, 0, MODRM }, + /* XOR AL, imm8 */{ 0x34, 0, IMM8 }, + /* XOR EAX, imm32 */{ 0x35, 0, IMM32 }, + /* XOR r/m8, imm8 */{ 0x80, 6, MODRM | REG_OPCODE | IMM8 }, + /* XOR r/m32, imm32 */{ 0x81, 6, MODRM | REG_OPCODE | IMM32 }, + /* XOR r/m32, imm8 */{ 0x83, 6, MODRM | REG_OPCODE | IMM8 }, + /* XOR r/m8, r8 */{ 0x30, 0, MODRM }, + /* XOR r/m32, r32 */{ 0x31, 0, MODRM }, + /* XOR r8, r/m8 */{ 0x32, 0, MODRM }, + /* XOR r32, r/m32 */{ 0x33, 0, MODRM } +}; + +class Asm +{ +public: + static size_t GetCodeLen(void* Addr) + { + unsigned char* code = (unsigned char*)Addr; + size_t i = 0, len = 0, operand_size = 4; + bool found_opcode = false; + + for (i = 0; i < sizeof(prefixes); i++) { + if (code[len] == prefixes[i]) { + len++; + if (prefixes[i] == 0x66) { + operand_size = 2; + } + } + } + + for (i = 0; i < sizeof(opcodes) / sizeof(*opcodes); i++) { + if (code[len] == opcodes[i].opcode) { + if (opcodes[i].flags & REG_OPCODE) { + found_opcode = ((code[len + 1] >> 3) & 7) == opcodes[i].reg_opcode; + } + else { + found_opcode = true; + } + } + + if ((opcodes[i].flags & PLUS_R) && (code[len] & 0xF8) == opcodes[i].opcode) { + found_opcode = true; + } + + if (found_opcode) { + len++; + //opcode = code[len++]; + break; + } + } + + if (!found_opcode) { + return 0; + } + + if (opcodes[i].flags & MODRM) { + uint8_t modrm = code[len++]; /* +1 for Mod/RM byte */ + uint8_t mod = modrm >> 6; + uint8_t rm = modrm & 7; + + if (mod != 3 && rm == 4) { + uint8_t sib = code[len++]; /* +1 for SIB byte */ + uint8_t base = sib & 7; + + if (base == 5) { + /* The SIB is followed by a disp32 with no base if the MOD is 00B. + * Otherwise, disp8 or disp32 + [EBP]. + */ + if (mod == 1) { + len += 1; /* for disp8 */ + } + else { + len += 4; /* for disp32 */ + } + } + } + if (mod == 1) { + len += 1; /* for disp8 */ + } + if (mod == 2 || (mod == 0 && rm == 5)) { + len += 4; /* for disp32 */ + } + } + + if (opcodes[i].flags & IMM8) { + len += 1; + } + if (opcodes[i].flags & IMM16) { + len += 2; + } + if (opcodes[i].flags & IMM32) { + len += operand_size; + } + + return len; + } +}; + +class Utils +{ +private: + size_t SysPageSize; + void *MemPool; + std::map AllocMap; + std::map FreeMap; +public: + static Utils* GetInstance() + { + static Utils* pInst = NULL; + if (!pInst)pInst = new Utils(); + return pInst; + } + Utils() + { + SysPageSize = sysconf(_SC_PAGESIZE); + int fd = open("/dev/zero", O_RDONLY); + MemPool = mmap(NULL, SysPageSize * 10, PROT_READ | PROT_WRITE | PROT_EXEC, MAP_PRIVATE, fd, 0); + close(fd); + FreeMap[MemPool] = SysPageSize * 10; + } + ~Utils() + { + munmap(MemPool, SysPageSize * 10); + } + bool SetPageProtect(void* Address, int Protect) + { + return SetAddressProtect(Addr_Align(Address, SysPageSize), SysPageSize, Protect); + } + static bool SetAddressProtect(void* Address, size_t Size, int Protect) + { + return !mprotect(Address, Size, Protect); + } + static void MakeJmp(void* Src, void* Dst, int nNop = 0) + { + unsigned char* code = (unsigned char*)Src; + code[0] = '\xE9'; + *((unsigned long*)&code[1]) = (unsigned long)Dst - (unsigned long)&code[1] - 4; + for (int i = 0; i < nNop; i++) + { + code[5 + i] = '\x90'; + } + } + void* alloc(size_t _size) + { + void *pBuf = NULL; + for (std::map::iterator iter = FreeMap.begin(); iter != FreeMap.end(); iter++) + { + if (iter->second >= _size) + { + pBuf = iter->first; + FreeMap.erase(pBuf); + if (iter->second > _size) + { + FreeMap[MOVEPOINT(pBuf, _size)] = iter->second - _size; + } + AllocMap[pBuf] = _size; + break; + } + } + return pBuf; + } + void free(void* _ptr) + { + size_t _size = AllocMap[_ptr]; + AllocMap.erase(_ptr); + FreeMap[_ptr] = _size; + if (FreeMap.size() >= 10) + { + sortMem(); + } + } + void sortMem() + { + + } +}; + +class FuncHook +{ +public: + FuncHook() + : Actived(false) + , Src(NULL) + , SrcPtr(NULL) + , Dst(NULL) + , SrcCodeSize(0) + , HookCodeSize(5) + { + } + ~FuncHook() + { + this->Restore(); + } + void Hook(void** SrcAddr, void* DstAddr) + { + if (!SrcAddr || !*SrcAddr || !DstAddr)return; + //ָϴHOOK + this->Restore(); + // + this->HookCodeSize = 5; + this->SrcCodeSize = 0; + this->SrcPtr = SrcAddr; + this->Src = *SrcAddr; + this->Dst = DstAddr; + //HOOKС + do + { + this->SrcCodeSize += Asm::GetCodeLen(Move_Ptr(this->Src, this->SrcCodeSize)); + } while (this->SrcCodeSize < this->HookCodeSize); + this->HookCode = (unsigned char*)Utils::GetInstance()->alloc(this->SrcCodeSize + 11); + memcpy(this->HookCode, this->Src, this->SrcCodeSize); + //޸ĿַڴȨ + Utils::MakeJmp(&this->HookCode[this->SrcCodeSize], Move_Ptr(this->Src, this->SrcCodeSize), this->SrcCodeSize - this->HookCodeSize); + //޸ԴַڴȨ + Utils::GetInstance()->SetPageProtect(this->Src, PROT_READ | PROT_WRITE | PROT_EXEC); + Utils::MakeJmp(this->Src, this->Dst, this->SrcCodeSize - this->HookCodeSize); + *this->SrcPtr = this->HookCode; + this->Actived = true; + } + void Restore() + { + if (this->Actived) + { + //޸ԴַڴдȨ + Utils::GetInstance()->SetPageProtect(this->Src, PROT_READ | PROT_WRITE); + memcpy(this->Src, this->HookCode, this->SrcCodeSize); + //޸ԴַڴִȨ + Utils::GetInstance()->SetPageProtect(this->Src, PROT_READ | PROT_EXEC); + this->Actived = false; + this->SrcCodeSize = 0; + *this->SrcPtr = this->Src; + if (this->HookCode) + { + Utils::GetInstance()->free(this->HookCode); + } + this->HookCode = NULL; + } + } +private: + bool Actived; + void *Src; + void **SrcPtr; + void *Dst; + unsigned char* HookCode; + size_t SrcCodeSize; + size_t HookCodeSize; +}; + +class CodeHook +{ +public: + static void WriteUChar(void *Addr, unsigned char Value) + { + WriteBytes(Addr, &Value, 1); + } + static void WriteUShort(void *Addr, unsigned short Value) + { + WriteBytes(Addr, &Value, 2); + } + static void WriteUInt(void *Addr, unsigned int Value) + { + WriteBytes(Addr, &Value, 4); + } + static void WriteBytes(void *Addr, void *Data, size_t Len) + { + Utils::GetInstance()->SetPageProtect(Addr, PROT_READ | PROT_WRITE | PROT_EXEC); + memcpy(Addr, Data, Len); + } +}; diff --git a/src - 副本/import.h b/src - 副本/import.h new file mode 100644 index 0000000..ff37687 --- /dev/null +++ b/src - 副本/import.h @@ -0,0 +1,70 @@ +#include +#include +#include +#include +#include +#include + + +#define PADALIGN(x,mask) ((x+mask)&(~(x%mask))) + +#define Ver 1 +#define Patch 2 + +__BEGIN_DECLS + +typedef int(*fnPacketGuard)(void *pInst); + +typedef int(*fnaddServerHackCnt)(void *pCHackAnalyzer, void *pCUserCharacInfo, int HackType, int Cnt, int a5, int a6); + +typedef int(*fnParsing)(void *pUser, int nSize); + +typedef int(*fnput_header)(void *pInterfacePacketBuf, int Type, int Cmd); + +typedef int(*fnIsRoutingItem)(void *pItem); + +typedef int(*fnsetCharacInfoDetail)(void *pUser, int a2, int a3, void *pCHARAC_DATA); + +typedef void* (*fnGetVectorUserCharacInfo)(void *pUser, int a2); + +typedef int(*fnIsGameMasterMode)(void *pUser); + +typedef int(*fnisGMUser)(void *pUser); + +typedef int(*fnGetPvPTeamCount)(void *pDataManager); + +typedef int(*fnisGM)(void *pGMAccounts, unsigned int a2); + +typedef int(*fnisGM1)(void *pGM_Manager); + +typedef void* (*fnset_add_info)(void *pInven_Item, int a2); + +typedef int(*fndoDispatch)(void *pPacketDispatcher, void *pUser, int a3, int a4, void *src, int a6, int a7, int a8); + +typedef void** (*fnget_dispatcher)(void *pPacketDispatcher, int a2); + +typedef int(*fnisSocketAvatar)(void *pAvatarItemMgr1, void *pAvatarItemMgr2); + +typedef int(*fndispatch_template)(void *pInst, void *pUser, void *pPacketBuf); + +typedef int(*fnreach_game_world)(void *pThis, void *a2); + +typedef int(*fnInter_LoadEtc_dispatch_sig)(void *pThis, void * pUser, char*a3); + +typedef int(* CUserCharacInfo_getCurCharacNo)(void* pUser); + +typedef char*(* CUserCharacInfo_getCurCharacName)(void* pUser); + +typedef int(*fnselect) (int __nfds, fd_set *__restrict __readfds, + fd_set *__restrict __writefds, + fd_set *__restrict __exceptfds, +struct timeval *__restrict __timeout); + +typedef int(*fnusleep) (__useconds_t __useconds); + +typedef void* (*fnmalloc) (size_t __size); + + + + +__END_DECLS \ No newline at end of file diff --git a/src - 副本/sdk_class.hpp b/src - 副本/sdk_class.hpp new file mode 100644 index 0000000..b360c78 --- /dev/null +++ b/src - 副本/sdk_class.hpp @@ -0,0 +1,457 @@ +#ifndef USER_CLASS_H +#define USER_CLASS_H +#include "base.h" +#include "enum.h" + +#include + + + +template R CallT(A call_addr, const ARG ... arguments) +{ + if (!call_addr) + { + return R(); + } + const auto control = reinterpret_cast(call_addr); + try + { + return control(arguments ...); + } + catch (...) + { + + } + return R(); +} + +class PacketBuf; +class DB_UpdateAvatarJewelSlot; +class CInventory; +class CStackableItem; +class Inven_Item; +class CItem; +class CUserCharacInfo; +class CUser; +class PacketBuf; +class PacketGuard; +class InterfacePacketBuf; + +namespace WongWork +{ + + class CAvatarItemMgr + { + public: + //获取时装插槽数据 + int getJewelSocketData(WongWork::CAvatarItemMgr* a2) + { + typedef int (*__func)(WongWork::CAvatarItemMgr* a1, void* a2); + return ((__func)base::WongWork::CAvatarItemMgr::getJewelSocketData)(this, a2); + } + }; + + class CHackAnalyzer + { + public: + int addServerHackCnt(CUserCharacInfo* a2, int a3, int a4, int a5, int a6) + { + typedef int (*__func)(WongWork::CHackAnalyzer* a1, CUserCharacInfo* a2, int a3, int a4, int a5, int a6); + + return CallT(base::WongWork::CHackAnalyzer::addServerHackCnt, this, a2, a3, a4, a5, a6); + return ((__func)base::WongWork::CHackAnalyzer::addServerHackCnt)(this, a2, a3, a4, a5, a6); + } + }; +} + +class CUserCharacInfo +{ +public: + //获取角色名字 + std::string getCurCharacName() + { + typedef char* (*__func)(CUserCharacInfo* a1); + return std::string(((__func)base::CUserCharacInfo::getCurCharacName)(this)); + } + + //获取角色编号 + int getCurCharacNo() + { + typedef int (*__func)(CUserCharacInfo* a1); + return int(((__func)base::CUserCharacInfo::getCurCharacNo)(this)); + } + + //获取角色上次退出游戏时间 + int getCurCharacLastPlayTick() + { + typedef int (*__func)(CUserCharacInfo* a1); + return int(((__func)base::CUserCharacInfo::getCurCharacLastPlayTick)(this)); + } + + //获取角色等级 + int get_level_up_exp(int a2) + { + typedef int (*__func)(CUserCharacInfo* a1, int a2); + return int(((__func)base::CUserCharacInfo::get_level_up_exp)(this, a2)); + } + + //获取角色背包 + CInventory* getCurCharacInvenW() + { + typedef CInventory* (*__func)(CUserCharacInfo* a1); + return ((__func)base::CUserCharacInfo::getCurCharacInvenW)(this); + } +}; + +class CUser : public CUserCharacInfo +{ +public: + int get_state() + { + typedef int (*__func)(CUser* a1); + return int(((__func)base::CUser::get_state)(this)); + } + + bool CheckItemLock(int a2, int a3) + { + typedef bool (*__func)(CUser* a1, int a2, int a3); + return int(((__func)base::CUser::CheckItemLock)(this, a2, a3)); + } + + int SendNotiPacketMessage(char* a2, int a3) + { + typedef bool (*__func)(CUser* a1, char* a2, int a3); + return int(((__func)base::CUser::SendNotiPacketMessage)(this, a2, a3)); + } + + //角色增加经验 + int gain_exp_sp(unsigned int a2, int a3, int a4, int a5, int a6, int a7) + { + typedef int (*__func)(CUserCharacInfo* a1, unsigned int a2, int a3, int a4, int a5, int a6, int a7); + return int(((__func)base::CUser::gain_exp_sp)(this, a2, a3, a4, a5, a6, a7)); + } + + //发送道具 + int AddItem(int a2, int a3, int a4, int a5, int a6) + { + typedef int (*__func)(CUser* a1, int a2, int a3, int a4, int a5, int a6); + return int(((__func)base::CUser::AddItem)(this, a2, a3, a4, a5, a6)); + } + + //通知客户端道具更新(客户端指针, 通知方式[仅客户端=1, 世界广播=0, 小队=2, war room=3], itemSpace[装备=0, 时装=1], 道具所在的背包槽) + int SendUpdateItemList(int a2, int a3, int a4) + { + typedef int (*__func)(CUserCharacInfo* a1, int a2, int a3, int a4); + return int(((__func)base::CUser::SendUpdateItemList)(this, a2, a3, a4)); + } + + int SendCmdErrorPacket(int a2, unsigned char a3) + { + typedef int (*__func)(CUser* a1, int a2, unsigned char a3); + return int(((__func)base::CUser::SendCmdErrorPacket)(this, a2, a3)); + } + + int isEnableAvatarSocketAction() + { + typedef int (*__func)(CUser* a1); + return int(((__func)base::CUser::isEnableAvatarSocketAction)(this)); + } + + int Send(PacketGuard* a2) + { + typedef int (*__func)(CUser* a1, PacketGuard* a2); + return int(((__func)base::CUser::Send)(this, a2)); + } +}; + +class CStackableItem +{ +public: + //获取消耗品类型 + int GetItemType() + { + typedef int (*__func)(void* a1); + return ((__func)base::CStackableItem::GetItemType)(this); + } + + //获取徽章支持的镶嵌槽类型 + int getJewelTargetSocket() + { + typedef int (*__func)(CStackableItem* a1); + return ((__func)base::CStackableItem::getJewelTargetSocket)(this); + } +}; + +class CItem : public CStackableItem +{ +public: + //道具是否为消耗品 + int is_stackable() + { + typedef int (*__func)(CItem* a1); + return ((__func)base::CItem::is_stackable)(this); + } + + bool IsRoutingItem() + { + typedef bool (*__func)(CItem* a1); + return ((__func)base::CItem::IsRoutingItem)(this); + } + +private: +}; + +class Inven_Item +{ +public: + //获取道具附加信息 + WongWork::CAvatarItemMgr* get_add_info() + { + typedef WongWork::CAvatarItemMgr* (*__func)(Inven_Item* a1); + return ((__func)base::Inven_Item::get_add_info)(this); + } + + //检查背包中道具是否为空 + bool isEmpty() + { + typedef bool (*__func)(Inven_Item* a1); + return ((__func)base::Inven_Item::isEmpty)(this); + } + //获取背包中道具item_id + int getKey() + { + typedef int (*__func)(Inven_Item* a1); + return ((__func)base::Inven_Item::getKey)(this); + } + //道具是否是装备 + bool isEquipableItemType() + { + typedef bool (*__func)(Inven_Item* a1); + return ((__func)base::Inven_Item::isEquipableItemType)(this); + } + + int get_ui_id() + { + return *(int*)(this + 0x7); + } +}; + +class CDataManager +{ +public: + static CDataManager* G_CDataManager(void) + { + typedef CDataManager* (*__func)(void); + return ((__func)base::CDataManager::G_CDataManager)(); + } + + //获取装备pvf数据 + CItem* find_item(int a2) + { + typedef CItem* (*__func)(CDataManager* a1, int a2); + return ((__func)base::CDataManager::find_item)(this, a2); + } +}; + +class CInventory +{ +public: + enum INVENTORY_TYPE : int + { + INVENTORY_TYPE_BODY = 0, //身上穿的装备 + INVENTORY_TYPE_ITEM = 1, //物品栏 + INVENTORY_TYPE_AVARTAR = 2, //时装栏 + }; + +public: + //获取时装管理器 + WongWork::CAvatarItemMgr* GetAvatarItemMgrR() + { + typedef WongWork::CAvatarItemMgr* (*__func)(void* a1); + return ((__func)base::CInventory::GetAvatarItemMgrR)(this); + } + + int delete_item(int a2, int a3, int a4, int a5, int a6) + { + typedef int (*__func)(CInventory* a1, int a2, int a3, int a4, int a5, int a6); + return ((__func)base::CInventory::delete_item)(this, a2, a3, a4, a5, a6); + } + + //使用金币 + int use_money(int a2, int a3, char a4) + { + typedef int (*__func)(CInventory* a1, int a2, int a3, char a4); + return ((__func)base::CInventory::use_money)(this, a2, a3, a4); + } + + //获得金币 + int gain_money(unsigned int a2, int a3, char a4, int a5) + { + typedef int (*__func)(CInventory* a1, unsigned int a2, int a3, char a4, int a5); + return ((__func)base::CInventory::gain_money)(this, a2, a3, a4, a5); + } + + //获取背包槽中的道具 + Inven_Item* GetInvenRef(INVENTORY_TYPE a2, int a3) + { + typedef Inven_Item* (*__func)(CInventory* a1, INVENTORY_TYPE a2, int a3); + return ((__func)base::CInventory::GetInvenRef)(this, a2, a3); + } +}; + +class DB_UpdateAvatarJewelSlot +{ +public: + static int makeRequest(int a1, unsigned int a2, void* src) + { + typedef int (*__func)(int a1, unsigned int a2, void* src); + return ((__func)base::DB_UpdateAvatarJewelSlot::makeRequest)(a1, a2, src); + } +}; + +class PacketBuf +{ +public: + //取大小 + int get_len() + { + typedef int (*__func)(PacketBuf* a1); + return ((__func)base::PacketBuf::get_len)(this); + } + + //取指针 + int get_buf_ptr(int a2 = 0) + { + typedef int (*__func)(PacketBuf* a1, int a2); + return ((__func)base::PacketBuf::get_buf_ptr)(this, a2); + } + + char get_byte() + { + char result; + typedef int (*__func)(PacketBuf* a1, char* a2); + if (((__func)base::PacketBuf::get_byte)(this, &result) == 1) + { + return result; + } + return 0; + } + + short get_short() + { + short result; + typedef int (*__func)(PacketBuf* a1, short* a2); + if (((__func)base::PacketBuf::get_short)(this, &result) == 1) + { + return result; + } + return 0; + } + + int get_int() + { + int result; + typedef int (*__func)(PacketBuf* a1, int* a2); + if (((__func)base::PacketBuf::get_int)(this, &result) == 1) + { + return result; + } + return 0; + } + + int get_binary(char* a2, int a3) + { + typedef int (*__func)(PacketBuf* a1, char* a2, int a3); + return ((__func)base::PacketBuf::get_binary)(this, a2, a3); + } +}; + +class InterfacePacketBuf +{ +public: + int put_header(int a2, int a3) + { + typedef int (*__func)(InterfacePacketBuf* a1, int a2, int a3); + return ((__func)base::InterfacePacketBuf::put_header)(this, a2, a3); + } + + int put_byte(char a2) + { + typedef int (*__func)(InterfacePacketBuf* a1, char a2); + return ((__func)base::InterfacePacketBuf::put_byte)(this, a2); + } + int put_short(short a2) + { + typedef int (*__func)(InterfacePacketBuf* a1, short a2); + return ((__func)base::InterfacePacketBuf::put_short)(this, a2); + } + + int put_int(int a2) + { + typedef int (*__func)(InterfacePacketBuf* a1, int a2); + return ((__func)base::InterfacePacketBuf::put_int)(this, a2); + } + + int put_binary(char* a2, int a3) + { + typedef int (*__func)(InterfacePacketBuf* a1, char* a2, int a3); + return ((__func)base::InterfacePacketBuf::put_binary)(this, a2, a3); + } + + int finalize(bool a2) + { + typedef int (*__func)(InterfacePacketBuf* a1, bool a2); + return ((__func)base::InterfacePacketBuf::finalize)(this, a2); + } + + int put_str(const char* a2, int a3) + { + typedef int (*__func)(InterfacePacketBuf* a1, const char* a2, int a3); + return ((__func)base::InterfacePacketBuf::put_str)(this, a2, a3); + } + + int put_packet(const Inven_Item* a2) + { + typedef int (*__func)(InterfacePacketBuf* a1, const Inven_Item* a2); + return ((__func)base::InterfacePacketBuf::put_packet)(this, a2); + } +}; + +class PacketGuard +{ +public: + static PacketGuard* NewPacketGuard() + { + void* v62 = malloc(0x20000); + typedef int (*__func)(void* a1); + ((__func)base::PacketGuard::PacketGuard_make)(v62); + return (PacketGuard*)v62; + } + static void DelPacketGuard(PacketGuard* a1) + { + typedef int (*__func)(void* a1); + ((__func)base::PacketGuard::PacketGuard_destroy)(a1); + free(a1); + } +}; + +class PacketDispatcher +{ +public: + int getDispatcher(int a2) + { + typedef int (*__func)(PacketDispatcher* a1, int a2); + return ((__func)base::PacketDispatcher::getDispatcher)(this, a2); + } + + void** get_dispatcher(int a2) + { + typedef void** (*__func)(PacketDispatcher* a1, int a2); + return ((__func)base::PacketDispatcher::get_dispatcher)(this, a2); + } +}; + + + + +#endif // __DXFBASE_H__ diff --git a/src - 副本/utils.hpp b/src - 副本/utils.hpp new file mode 100644 index 0000000..b675d44 --- /dev/null +++ b/src - 副本/utils.hpp @@ -0,0 +1,50 @@ +#include +#include +#include +#define BUFFCOUNT (3196) +#define SET_TEXTW(X) L#X +#define SET_TEXTA(X) #X + +namespace Util +{ + /** + * @brief 到16进制Hex文本 + * @param buf + * @param len + * @param tok + * @return +*/ +static std::string ToHexString(const unsigned char* buf, int len, std::string tok = " ") +{ + std::string output; + char temp[8] ; + for (int i = 0; i < len; ++i) + { + memset(temp,0,sizeof(temp)); + snprintf(temp, sizeof(temp), "%.2X", buf[i]); + output.append(temp, 2); + output.append(tok); + } + + return output; +} + +static void _Log(const char* formatstring, ...) +{ + int nSize = 0; + char buff[BUFFCOUNT]; + memset(buff, 0, sizeof(buff)); + va_list args; + va_start(args, formatstring); + nSize = vsnprintf(buff, sizeof(buff), formatstring, args); + va_end(args); + char szPrINT32[BUFFCOUNT + 50] = { 0 }; + sprintf(szPrINT32, "[GameHelpers] %s \n", buff);//wsprintfA + printf(szPrINT32); +} + + +} + + +#define LOG(format,...) Util::_Log(format,##__VA_ARGS__) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt new file mode 100644 index 0000000..11ef0bf --- /dev/null +++ b/src/CMakeLists.txt @@ -0,0 +1,30 @@ +# ҪcmakeͰ汾 +CMAKE_MINIMUM_REQUIRED(VERSION 3.0) + +# ֧֣++11 + +set(CMAKE_CXX_STANDARD 11) +set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -m32 -fpic") + +#ͷļĿ¼ +include_directories(${PROJECT_SOURCE_DIR}/include) + +# ӿԴļ +set(LIB_SOURCE + "controller.cpp" + "df_main.cpp" + +) + +# Ӷ̬⣬ؼΪshared +ADD_LIBRARY(hook_shared SHARED ${LIB_SOURCE}) + +# ָ̬ +SET_TARGET_PROPERTIES(hook_shared PROPERTIES OUTPUT_NAME "hook") + +# ָ̬汾, ɲ +# VERSION:̬汾SOVERSION:API汾 +#SET_TARGET_PROPERTIES(hook_shared PROPERTIES VERSION 0.1.1 SOVERSION 0) + +# ָĿ¼ +SET(LIBRARY_OUTPUT_PATH ${PROJECT_BINARY_DIR}/lib) diff --git a/src/base.h b/src/base.h new file mode 100644 index 0000000..4f0ae75 --- /dev/null +++ b/src/base.h @@ -0,0 +1,188 @@ +#pragma once + +namespace base +{ + namespace CGameManager + { + const int G_CGameManager = 0x080CC18E; + + } + + namespace Dispatcher_UseJewel + { + const int dispatch_sig = 0x8217BD6; + + + } + + namespace GlobalData + { + const int Init = 0x08299FA0; + const int Init_fix_1 = 0x0829C075; + } + + namespace CParty + { + const int addDungeonClear = 0x085BDDFC; + const int addDungeonClear_fix_1 = 0x085BDE9D; //ͨ + const int addDungeonClear_fix_2 = 0x085BDF30; //Զű + const int addDungeonClear_fix_3 = 0x085BDFC3; //类 + + + } + + namespace CUserCharacInfo + { + const int getCurCharacName = 0x8101028; + const int getCurCharacNo = 0x080CBC4E; + const int getCurCharacLastPlayTick = 0x82A66AA; + const int get_level_up_exp = 0x0864E3BA; + const int getCurCharacInvenW = 0x80DA28E; + } + + namespace CUser + { + const int get_acc_id=0x080DA36E; + const int get_state = 0x080DA38C; + const int CheckItemLock = 0x8646942; + const int SendNotiPacketMessage = 0x86886CE; + const int gain_exp_sp = 0x866A3FE; + const int AddItem = 0x867B6D4; + const int SendUpdateItemList = 0x867C65A; + const int SendCmdErrorPacket = 0x0867BF42; + const int isEnableAvatarSocketAction = 0x086810A8; + const int Send = 0x86485BA; + const int setCharacInfoDetail = 0x0864AC1A; + const int IsGameMasterMode = 0x0811EDEE; + const int isGMUser = 0x0814589C; + const int exchange_interspace = 0x0865F7B0; + } + + namespace CStackableItem + { + const int GetItemType = 0x8514A84; + const int getJewelTargetSocket = 0x0822CA28; + + } + + namespace CItem + { + const int is_stackable = 0x80F12FA; + const int IsRoutingItem = 0x08150F18; + } + + namespace Inven_Item + { + const int get_add_info = 0x80F783A; + const int isEmpty = 0x811ED66; + const int getKey = 0x850D14E; + const int isEquipableItemType = 0x08150812; + } + + namespace CDataManager + { + const int G_CDataManager = 0x80CC19B; + const int find_item = 0x835FA32; + } + + namespace CInventory + { + const int GetAvatarItemMgrR = 0x80DD576; + const int delete_item = 0x850400C; + const int use_money = 0x84FF54C; + const int gain_money = 0x84FF29C; + const int GetInvenRef = 0x84FC1DE; + } + + namespace DB_UpdateAvatarJewelSlot + { + const int makeRequest = 0x843081C; + } + + namespace PacketBuf + { + const int get_len = 0x0858DA52; + const int get_buf_ptr = 0x0858DA38; + const int get_byte = 0x858CF22; + const int get_short = 0x858CFC0; + const int get_int = 0x858D27E; + const int get_binary = 0x858D3B2; + } + + namespace InterfacePacketBuf + { + const int put_header = 0x080CB8FC; + const int put_byte = 0x080CB920; + const int put_short = 0x80D9EA4; + const int put_int = 0x80CB93C; + const int put_binary = 0x811DF08; + const int finalize = 0x80CB958; + const int put_str = 0x0822B770; + const int put_packet = 0x0822B794; + } + + namespace PacketGuard + { + const int PacketGuard_make = 0x0858DD4C; + const int PacketGuard_destroy = 0x0858DE80; + } + + namespace PacketDispatcher + { + const int getDispatcher = 0x08231F2E; + const int server_load_monitoring = 0x0825F658; + const int log_recv_packet = 0x0825F72E; + const int PacketDispatcher_make = 0x08590A2E; + const int PacketDispatcher_destroy = 0x08594840; + const int get_dispatcher = 0x085948E2; + const int doDispatch = 0x08594922; + const int dispatch = 0x08594E52; + } + namespace WongWork + { + namespace CHackAnalyzer + { + const int addServerHackCnt = 0x080F8C7E; + } + + namespace CGMAccounts + { + const int isGM = 0x08109346; + } + + namespace CAvatarItemMgr + { + const int getJewelSocketData = 0x82F98F8; + } + } + + namespace CGM_Manager + { + const int isGM = 0x0829948C; + + } + + namespace CDataManager + { + const int GetPvPTeamCount = 0x08568CE0; + } + + namespace DisPatcher_MoveItem + { + const int process = 0x081C5904; //int __cdecl DisPatcher_MoveItem::process(DisPatcher_MoveItem *this, CUser *a2, MSG_BASE *a3, ParamBase *a4) + + + } + + namespace cMyTrace + { + const int cMyTrace_make =0x0854F746; + const int operator_ = 0x0854F788; + const int cMyTrace_destroy =0x0854F746; + } + + + +} + + diff --git a/src/controller.cpp b/src/controller.cpp new file mode 100644 index 0000000..4915c0f --- /dev/null +++ b/src/controller.cpp @@ -0,0 +1,243 @@ +//************************************ +// FileName: D:\VisualStudioSource\dnf_project\src\controller.cpp +// FullName: D:\VisualStudioSource\dnf_project\src +// Date: 2022/09/01 +// By: Vance +// Copyright (c) 2022. Vance All rights reserved +//************************************ + +#include "controller.hpp" + +Controller::Controller() : + old_UseJewel_dispatch_sig((UseJewel_dispatch_sig_Type*)base::Dispatcher_UseJewel::dispatch_sig), + old_PacketDispatcher_doDispatch((PacketDispatcher_doDispatch_Type*)base::PacketDispatcher::doDispatch) +{ + +} + +Controller::~Controller() +{ + +} + + +void Controller::init() +{ + CodeHook::WriteUChar((void*)(base::GlobalData::Init_fix_1 - 0x1), 0); + //.text:085BDE9D 83 F8 0A cmp eax, 10 + CodeHook::WriteUChar((void*)(base::CParty::addDungeonClear_fix_1 + 2), 0x7E); //ͨ + //.text:085BDF30 83 F8 1E cmp eax, 30 + CodeHook::WriteUChar((void*)(base::CParty::addDungeonClear_fix_2 + 2), 0x7E); //Զű + //.text:085BDFC3 83 F8 32 cmp eax, 50 + CodeHook::WriteUChar((void*)(base::CParty::addDungeonClear_fix_3 + 2), 0x7E); //类 + + + + mhook_PacketDispatcher_doDispatch.Hook((void**)&old_PacketDispatcher_doDispatch, (void*)hook_PacketDispatcher_doDispatch); + + mhook_UseJewel_dispatch_sig.Hook((void**)&old_UseJewel_dispatch_sig, (void*)hook_UseJewel_dispatch_sig); + + LOG("Controller::init()"); + +} + +int Controller::hook_UseJewel_dispatch_sig(void* pDispatcher_UseJewel, CUser* pUser, PacketBuf* pBuf) +{ + printf("getCurCharacName :%s \n", pUser->getCurCharacName().c_str()); + printf("getCurCharacNo :%d \n", pUser->getCurCharacNo()); + printf("get_buf_ptr :%p %p \n", pBuf->get_buf_ptr(0)); + printf("get_len :%d \n", pBuf->get_len()); + + // printf("pBuf :%s \n", Util::ToHexString((const unsigned char*)pBuf->get_buf_ptr(0),40).c_str()); + int state = pUser->get_state(); + printf("state :%d \n", state); + //Уɫ״̬ǷǶ + if (state != 3) + return 0; + + int isEnableAvatarSocketAction = pUser->isEnableAvatarSocketAction(); + if (isEnableAvatarSocketAction) + pUser->SendCmdErrorPacket(205, (unsigned char)isEnableAvatarSocketAction); + //packet_buf + + //ʱװڵı + int avartar_inven_slot = pBuf->get_short(); + printf("avartar_inven_slot :%d \n", avartar_inven_slot); + //ʱװitem_id + int avartar_item_id = pBuf->get_int(); + printf("avartar_item_id :%d \n", avartar_item_id); + //Ƕ + int emblem_cnt = pBuf->get_byte(); + printf("emblem_cnt :%d \n", emblem_cnt); + + if (pUser->CheckItemLock(2, avartar_inven_slot)) + { + pUser->SendCmdErrorPacket(205, 213); + return 0; + } + + //ȡʱװ + CInventory* inven = pUser->getCurCharacInvenW(); + if (!inven) + { + printf("pUser->getCurCharacInvenW : error \n"); + return 0; + } + Inven_Item* avartar = inven->GetInvenRef(CInventory::INVENTORY_TYPE_AVARTAR, avartar_inven_slot); + if (!avartar) + { + printf("inven->GetInvenRef : error \n"); + return 0; + } + //Уʱװ ǷϷ + if (avartar->isEmpty() || (avartar->getKey() != avartar_item_id) || pUser->CheckItemLock(2, avartar_inven_slot)) + { + + printf("avartar->isEmpty() || avartar->getKey() || pUser->CheckItemLock() : error \n"); + return 0; + } + //ȡʱװ + WongWork::CAvatarItemMgr* avartar_add_info = avartar->get_add_info(); + WongWork::CAvatarItemMgr* inven_avartar_mgr = inven->GetAvatarItemMgrR(); + int jewel_socket_data = inven_avartar_mgr->getJewelSocketData(avartar_add_info); + if (!jewel_socket_data) + { + printf("jewel_socket_data : error \n"); + return 0; + } + + printf("jewel_socket_data :%s \n", Util::ToHexString((const unsigned char*)jewel_socket_data, 40).c_str()); + if (emblem_cnt <= 3) + { + std::map> emblems; + for (int i = 0; i < emblem_cnt; i++) + { + //ڵı + int emblem_inven_slot = pBuf->get_short(); + //item_id + int emblem_item_id = pBuf->get_int(); + //ûǶʱװid + int avartar_socket_slot = pBuf->get_byte(); + + //ȡµ + Inven_Item* emblem = inven->GetInvenRef(CInventory::INVENTORY_TYPE_ITEM, emblem_inven_slot); + //У¼ǷϷ + if (emblem->isEmpty() || (emblem->getKey() != emblem_item_id) || (avartar_socket_slot >= 3)) + { + printf("emblem->isEmpty() || (emblem->getKey() : error \n"); + pUser->SendCmdErrorPacket(205, 209); + return 0; + } + + //УǷʱװɫҪ + + //ȡpvf + CDataManager* DataManager = CDataManager::G_CDataManager(); + if (!DataManager) + { + printf("CDataManager::G_CDataManager() : error \n"); + pUser->SendCmdErrorPacket(205, 209); + return 0; + } + CItem* citem = DataManager->find_item(emblem_item_id); + if (!citem) + { + printf("DataManager->find_item() : error \n"); + pUser->SendCmdErrorPacket(205, 209); + return 0; + } + + //У + if (!citem->is_stackable() || (citem->GetItemType() != 20)) + { + printf("citem->is_stackable() || (citem->GetItemType() : error \n"); + pUser->SendCmdErrorPacket(205, 209); + return 0; + } + + //ȡֵ֧IJ + int emblem_socket_type = citem->getJewelTargetSocket(); + + //ȡҪǶʱװ + int avartar_socket_type = *(short*)(jewel_socket_data + avartar_socket_slot * 6); + if (!(emblem_socket_type & avartar_socket_type)) + { + //Ͳƥ + printf("emblem_socket_type & avartar_socket_type\n"); + pUser->SendCmdErrorPacket(205, 209); + return 0; + } + printf("avartar_socket_slot:%d emblem_inven_slot:%d emblem_item_id:%d\n", avartar_socket_slot, emblem_inven_slot, emblem_item_id); + emblems[avartar_socket_slot] = std::make_pair(emblem_inven_slot, emblem_item_id); + } + printf("Ѷȡ!!!\n"); + + for (auto& avartar_socket_slot : emblems) + { + //ɾ + int emblem_inven_slot = avartar_socket_slot.second.first; + inven->delete_item(1, emblem_inven_slot, 1, 8, 1); + + //ʱװ + int emblem_item_id = avartar_socket_slot.second.second; + *(int*)(jewel_socket_data + avartar_socket_slot.first * 6 + 2) = emblem_item_id; + printf("item_id=%d ѳɹǶavartar_socket_slot=%d IJ!\n", emblem_item_id, avartar_socket_slot); + } + + //ʱװݴ浵 + DB_UpdateAvatarJewelSlot::makeRequest(pUser->getCurCharacNo(), avartar->get_ui_id(), (void*)jewel_socket_data); + + //֪ͨͻʱװѸ + pUser->SendUpdateItemList(1, 1, avartar_inven_slot); + printf("Ƕ!!!\n"); + //ذͻ + InterfacePacketBuf* packet_guard = (InterfacePacketBuf*)PacketGuard::NewPacketGuard(); + + packet_guard->put_header(1, 204); + packet_guard->put_int(1); + packet_guard->finalize(1); + pUser->Send((PacketGuard*)packet_guard); + PacketGuard::DelPacketGuard((PacketGuard*)packet_guard); + } + + // 08217C06 ֽ + return 0; +} + +int Controller::hook_PacketDispatcher_doDispatch(PacketDispatcher* a1, CUser* user, int packet_class, int packet_id, void* packet_src, int pecakt_len, int a7, int a8) +{ + void* pAction = *a1->get_dispatcher(packet_id); + + if (pAction) + { + LOG("Recv() class:%d id:%d len:%d data:%s callback:%p %p %p %p %p %p " + , packet_class + , packet_id + , pecakt_len + , Util::ToHexString((const unsigned char*)packet_src, pecakt_len).c_str() + , *((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 + { + LOG("Recv() class:%d id:%d len:%d data:%s " + , packet_class + , packet_id + , pecakt_len + , Util::ToHexString((const unsigned char*)packet_src, pecakt_len).c_str() + ); + } + + if (packet_id == Packet_UseItem) + { + LOG("hook_PacketDispatcher_doDispatch packet_data :%s ", Util::ToHexString((const unsigned char*)packet_src, pecakt_len).c_str()); + } + return Controller::Get()->old_PacketDispatcher_doDispatch(a1, user, packet_class, packet_id, packet_src, pecakt_len, a7, a8); +} + + diff --git a/src/controller.hpp b/src/controller.hpp new file mode 100644 index 0000000..5656211 --- /dev/null +++ b/src/controller.hpp @@ -0,0 +1,62 @@ +#include "import.h" +#include "Singleton.hpp" +#include "sdk_class.hpp" +#include "inline_hook.h" +#include "utils.hpp" + +#define MAIN_OFFSET(offset) ((void *)((0x8048000) + (offset))) +#define SUBHOOK_INIT(func, addr) \ + fn##func func = (fn##func)addr; \ + FuncHook h##func + +#define SUBHOOK_SETUP(func) h##func.Hook((void **)&func, (void *)_##func) + +class Controller +{ +public: + SINGLETON_DEFINE_S(Controller); + +private: + Controller(); + ~Controller(); +public: + void init(); + + +private: + /** + * @brief hook修复镶嵌徽章 + * @param pDispatcher_UseJewel + * @param pUser + * @param pBuf + * @return + */ + static int hook_UseJewel_dispatch_sig(void* pDispatcher_UseJewel, CUser* pUser, PacketBuf* pBuf); + + /** + * @brief hook收包处理 + * @param a1 + * @param a2 + * @param a3 + * @param a4 + * @param src + * @param a6 + * @param a7 + * @param a8 + * @return + */ + static int hook_PacketDispatcher_doDispatch(PacketDispatcher* a1, CUser* a2, int a3, int packet_id, void* packet_src, int pecakt_len, int a7, int a8); + +private: + using UseJewel_dispatch_sig_Type = decltype(hook_UseJewel_dispatch_sig); + UseJewel_dispatch_sig_Type* old_UseJewel_dispatch_sig; + + using PacketDispatcher_doDispatch_Type = decltype(hook_PacketDispatcher_doDispatch); + PacketDispatcher_doDispatch_Type* old_PacketDispatcher_doDispatch; + + +private: + FuncHook mhook_UseJewel_dispatch_sig; + FuncHook mhook_PacketDispatcher_doDispatch; + +}; \ No newline at end of file diff --git a/src/df_main.cpp b/src/df_main.cpp new file mode 100644 index 0000000..baeec75 --- /dev/null +++ b/src/df_main.cpp @@ -0,0 +1,647 @@ +#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(); + +} + + diff --git a/src/enum.h b/src/enum.h new file mode 100644 index 0000000..a1d78a5 --- /dev/null +++ b/src/enum.h @@ -0,0 +1,7 @@ +#pragma once +enum ENUM_PACKET_ID +{ + Packet_UseItem = 84, + + +}; \ No newline at end of file diff --git a/src/import.h b/src/import.h new file mode 100644 index 0000000..ff37687 --- /dev/null +++ b/src/import.h @@ -0,0 +1,70 @@ +#include +#include +#include +#include +#include +#include + + +#define PADALIGN(x,mask) ((x+mask)&(~(x%mask))) + +#define Ver 1 +#define Patch 2 + +__BEGIN_DECLS + +typedef int(*fnPacketGuard)(void *pInst); + +typedef int(*fnaddServerHackCnt)(void *pCHackAnalyzer, void *pCUserCharacInfo, int HackType, int Cnt, int a5, int a6); + +typedef int(*fnParsing)(void *pUser, int nSize); + +typedef int(*fnput_header)(void *pInterfacePacketBuf, int Type, int Cmd); + +typedef int(*fnIsRoutingItem)(void *pItem); + +typedef int(*fnsetCharacInfoDetail)(void *pUser, int a2, int a3, void *pCHARAC_DATA); + +typedef void* (*fnGetVectorUserCharacInfo)(void *pUser, int a2); + +typedef int(*fnIsGameMasterMode)(void *pUser); + +typedef int(*fnisGMUser)(void *pUser); + +typedef int(*fnGetPvPTeamCount)(void *pDataManager); + +typedef int(*fnisGM)(void *pGMAccounts, unsigned int a2); + +typedef int(*fnisGM1)(void *pGM_Manager); + +typedef void* (*fnset_add_info)(void *pInven_Item, int a2); + +typedef int(*fndoDispatch)(void *pPacketDispatcher, void *pUser, int a3, int a4, void *src, int a6, int a7, int a8); + +typedef void** (*fnget_dispatcher)(void *pPacketDispatcher, int a2); + +typedef int(*fnisSocketAvatar)(void *pAvatarItemMgr1, void *pAvatarItemMgr2); + +typedef int(*fndispatch_template)(void *pInst, void *pUser, void *pPacketBuf); + +typedef int(*fnreach_game_world)(void *pThis, void *a2); + +typedef int(*fnInter_LoadEtc_dispatch_sig)(void *pThis, void * pUser, char*a3); + +typedef int(* CUserCharacInfo_getCurCharacNo)(void* pUser); + +typedef char*(* CUserCharacInfo_getCurCharacName)(void* pUser); + +typedef int(*fnselect) (int __nfds, fd_set *__restrict __readfds, + fd_set *__restrict __writefds, + fd_set *__restrict __exceptfds, +struct timeval *__restrict __timeout); + +typedef int(*fnusleep) (__useconds_t __useconds); + +typedef void* (*fnmalloc) (size_t __size); + + + + +__END_DECLS \ No newline at end of file diff --git a/src/inline_hook.h b/src/inline_hook.h new file mode 100644 index 0000000..174b70e --- /dev/null +++ b/src/inline_hook.h @@ -0,0 +1,381 @@ +#pragma once +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define MOVEPOINT(p,i) (void*)((char*)p+i) +#define MAKEPOINTER(t, p, offset) ((t)((unsigned char*)(p) + (long)offset)) +#define PADALIGN(x,mask) ((x+mask)&(~(x%mask))) +#define Addr_Align(addr,mask) ((void*)(((unsigned long)(addr))&(~((mask)-1)))) +#define Move_Ptr(addr,offset) ((void*)((unsigned long)(addr)+(offset))) + +enum flags { + MODRM = 1, + PLUS_R = 1 << 1, + REG_OPCODE = 1 << 2, + IMM8 = 1 << 3, + IMM16 = 1 << 4, + IMM32 = 1 << 5, + RELOC = 1 << 6 +}; +struct opcode_info { + unsigned char opcode; + unsigned char reg_opcode; + unsigned int flags; +}; +static unsigned char prefixes[] = { + 0xF0, 0xF2, 0xF3, + 0x2E, 0x36, 0x3E, 0x26, 0x64, 0x65, + 0x66, /* operand size override */ + 0x67 /* address size override */ +}; +static struct opcode_info opcodes[] = { + /* ADD AL, imm8 */{ 0x04, 0, IMM8 }, + /* ADD EAX, imm32 */{ 0x05, 0, IMM32 }, + /* ADD r/m8, imm8 */{ 0x80, 0, MODRM | REG_OPCODE | IMM8 }, + /* ADD r/m32, imm32 */{ 0x81, 0, MODRM | REG_OPCODE | IMM32 }, + /* ADD r/m32, imm8 */{ 0x83, 0, MODRM | REG_OPCODE | IMM8 }, + /* ADD r/m8, r8 */{ 0x00, 0, MODRM }, + /* ADD r/m32, r32 */{ 0x01, 0, MODRM }, + /* ADD r8, r/m8 */{ 0x02, 0, MODRM }, + /* ADD r32, r/m32 */{ 0x03, 0, MODRM }, + /* AND AL, imm8 */{ 0x24, 0, IMM8 }, + /* AND EAX, imm32 */{ 0x25, 0, IMM32 }, + /* AND r/m8, imm8 */{ 0x80, 4, MODRM | REG_OPCODE | IMM8 }, + /* AND r/m32, imm32 */{ 0x81, 4, MODRM | REG_OPCODE | IMM32 }, + /* AND r/m32, imm8 */{ 0x83, 4, MODRM | REG_OPCODE | IMM8 }, + /* AND r/m8, r8 */{ 0x20, 0, MODRM }, + /* AND r/m32, r32 */{ 0x21, 0, MODRM }, + /* AND r8, r/m8 */{ 0x22, 0, MODRM }, + /* AND r32, r/m32 */{ 0x23, 0, MODRM }, + /* CALL rel32 */{ 0xE8, 0, IMM32 | RELOC }, + /* CALL r/m32 */{ 0xFF, 2, MODRM | REG_OPCODE }, + /* CMP r/m16/32, imm8*/{ 0x83, 7, MODRM | REG_OPCODE | IMM8 }, + /* DEC r/m16/32 */{ 0xFF, 1, MODRM | REG_OPCODE }, + /* ENTER imm16, imm8 */{ 0xC8, 0, IMM16 | IMM8 }, + /* INT 3 */{ 0xCC, 0, 0 }, + /* JMP rel32 */{ 0xE9, 0, IMM32 | RELOC }, + /* JMP r/m32 */{ 0xFF, 4, MODRM | REG_OPCODE }, + /* LEA r32,m */{ 0x8D, 0, MODRM }, + /* LEAVE */{ 0xC9, 0, 0 }, + /* MOV r/m8,r8 */{ 0x88, 0, MODRM }, + /* MOV r/m32,r32 */{ 0x89, 0, MODRM }, + /* MOV r8,r/m8 */{ 0x8A, 0, MODRM }, + /* MOV r32,r/m32 */{ 0x8B, 0, MODRM }, + /* MOV r/m16,Sreg */{ 0x8C, 0, MODRM }, + /* MOV Sreg,r/m16 */{ 0x8E, 0, MODRM }, + /* MOV AL,moffs8 */{ 0xA0, 0, IMM8 }, + /* MOV EAX,moffs32 */{ 0xA1, 0, IMM32 }, + /* MOV moffs8,AL */{ 0xA2, 0, IMM8 }, + /* MOV moffs32,EAX */{ 0xA3, 0, IMM32 }, + /* MOV r8, imm8 */{ 0xB0, 0, PLUS_R | IMM8 }, + /* MOV r32, imm32 */{ 0xB8, 0, PLUS_R | IMM32 }, + /* MOV r/m8, imm8 */{ 0xC6, 0, MODRM | REG_OPCODE | IMM8 }, + /* MOV r/m32, imm32 */{ 0xC7, 0, MODRM | REG_OPCODE | IMM32 }, + /* NOP */{ 0x90, 0, 0 }, + /* OR AL, imm8 */{ 0x0C, 0, IMM8 }, + /* OR EAX, imm32 */{ 0x0D, 0, IMM32 }, + /* OR r/m8, imm8 */{ 0x80, 1, MODRM | REG_OPCODE | IMM8 }, + /* OR r/m32, imm32 */{ 0x81, 1, MODRM | REG_OPCODE | IMM32 }, + /* OR r/m32, imm8 */{ 0x83, 1, MODRM | REG_OPCODE | IMM8 }, + /* OR r/m8, r8 */{ 0x08, 0, MODRM }, + /* OR r/m32, r32 */{ 0x09, 0, MODRM }, + /* OR r8, r/m8 */{ 0x0A, 0, MODRM }, + /* OR r32, r/m32 */{ 0x0B, 0, MODRM }, + /* POP r/m32 */{ 0x8F, 0, MODRM | REG_OPCODE }, + /* POP r32 */{ 0x58, 0, PLUS_R }, + /* PUSH r/m32 */{ 0xFF, 6, MODRM | REG_OPCODE }, + /* PUSH r32 */{ 0x50, 0, PLUS_R }, + /* PUSH imm8 */{ 0x6A, 0, IMM8 }, + /* PUSH imm32 */{ 0x68, 0, IMM32 }, + /* RET */{ 0xC3, 0, 0 }, + /* RET imm16 */{ 0xC2, 0, IMM16 }, + /* SUB AL, imm8 */{ 0x2C, 0, IMM8 }, + /* SUB EAX, imm32 */{ 0x2D, 0, IMM32 }, + /* SUB r/m8, imm8 */{ 0x80, 5, MODRM | REG_OPCODE | IMM8 }, + /* SUB r/m32, imm32 */{ 0x81, 5, MODRM | REG_OPCODE | IMM32 }, + /* SUB r/m32, imm8 */{ 0x83, 5, MODRM | REG_OPCODE | IMM8 }, + /* SUB r/m8, r8 */{ 0x28, 0, MODRM }, + /* SUB r/m32, r32 */{ 0x29, 0, MODRM }, + /* SUB r8, r/m8 */{ 0x2A, 0, MODRM }, + /* SUB r32, r/m32 */{ 0x2B, 0, MODRM }, + /* TEST AL, imm8 */{ 0xA8, 0, IMM8 }, + /* TEST EAX, imm32 */{ 0xA9, 0, IMM32 }, + /* TEST r/m8, imm8 */{ 0xF6, 0, MODRM | REG_OPCODE | IMM8 }, + /* TEST r/m32, imm32 */{ 0xF7, 0, MODRM | REG_OPCODE | IMM32 }, + /* TEST r/m8, r8 */{ 0x84, 0, MODRM }, + /* TEST r/m32, r32 */{ 0x85, 0, MODRM }, + /* XOR AL, imm8 */{ 0x34, 0, IMM8 }, + /* XOR EAX, imm32 */{ 0x35, 0, IMM32 }, + /* XOR r/m8, imm8 */{ 0x80, 6, MODRM | REG_OPCODE | IMM8 }, + /* XOR r/m32, imm32 */{ 0x81, 6, MODRM | REG_OPCODE | IMM32 }, + /* XOR r/m32, imm8 */{ 0x83, 6, MODRM | REG_OPCODE | IMM8 }, + /* XOR r/m8, r8 */{ 0x30, 0, MODRM }, + /* XOR r/m32, r32 */{ 0x31, 0, MODRM }, + /* XOR r8, r/m8 */{ 0x32, 0, MODRM }, + /* XOR r32, r/m32 */{ 0x33, 0, MODRM } +}; + +class Asm +{ +public: + static size_t GetCodeLen(void* Addr) + { + unsigned char* code = (unsigned char*)Addr; + size_t i = 0, len = 0, operand_size = 4; + bool found_opcode = false; + + for (i = 0; i < sizeof(prefixes); i++) { + if (code[len] == prefixes[i]) { + len++; + if (prefixes[i] == 0x66) { + operand_size = 2; + } + } + } + + for (i = 0; i < sizeof(opcodes) / sizeof(*opcodes); i++) { + if (code[len] == opcodes[i].opcode) { + if (opcodes[i].flags & REG_OPCODE) { + found_opcode = ((code[len + 1] >> 3) & 7) == opcodes[i].reg_opcode; + } + else { + found_opcode = true; + } + } + + if ((opcodes[i].flags & PLUS_R) && (code[len] & 0xF8) == opcodes[i].opcode) { + found_opcode = true; + } + + if (found_opcode) { + len++; + //opcode = code[len++]; + break; + } + } + + if (!found_opcode) { + return 0; + } + + if (opcodes[i].flags & MODRM) { + uint8_t modrm = code[len++]; /* +1 for Mod/RM byte */ + uint8_t mod = modrm >> 6; + uint8_t rm = modrm & 7; + + if (mod != 3 && rm == 4) { + uint8_t sib = code[len++]; /* +1 for SIB byte */ + uint8_t base = sib & 7; + + if (base == 5) { + /* The SIB is followed by a disp32 with no base if the MOD is 00B. + * Otherwise, disp8 or disp32 + [EBP]. + */ + if (mod == 1) { + len += 1; /* for disp8 */ + } + else { + len += 4; /* for disp32 */ + } + } + } + if (mod == 1) { + len += 1; /* for disp8 */ + } + if (mod == 2 || (mod == 0 && rm == 5)) { + len += 4; /* for disp32 */ + } + } + + if (opcodes[i].flags & IMM8) { + len += 1; + } + if (opcodes[i].flags & IMM16) { + len += 2; + } + if (opcodes[i].flags & IMM32) { + len += operand_size; + } + + return len; + } +}; + +class CMemPool +{ +private: + size_t SysPageSize; + void *MemPool; + std::map AllocMap; + std::map FreeMap; +public: + static CMemPool* GetInstance() + { + static CMemPool* pInst = NULL; + if (!pInst)pInst = new CMemPool(); + return pInst; + } + CMemPool() + { + SysPageSize = sysconf(_SC_PAGESIZE); + int fd = open("/dev/zero", O_RDONLY); + MemPool = mmap(NULL, SysPageSize * 10, PROT_READ | PROT_WRITE | PROT_EXEC, MAP_PRIVATE, fd, 0); + close(fd); + FreeMap[MemPool] = SysPageSize * 10; + } + ~CMemPool() + { + munmap(MemPool, SysPageSize * 10); + } + bool SetPageProtect(void* Address, int Protect) + { + return SetAddressProtect(Addr_Align(Address, SysPageSize), SysPageSize, Protect); + } + static bool SetAddressProtect(void* Address, size_t Size, int Protect) + { + return !mprotect(Address, Size, Protect); + } + static void MakeJmp(void* Src, void* Dst, int nNop = 0) + { + unsigned char* code = (unsigned char*)Src; + code[0] = '\xE9'; + *((unsigned long*)&code[1]) = (unsigned long)Dst - (unsigned long)&code[1] - 4; + for (int i = 0; i < nNop; i++) + { + code[5 + i] = '\x90'; + } + } + void* alloc(size_t _size) + { + void *pBuf = NULL; + for (std::map::iterator iter = FreeMap.begin(); iter != FreeMap.end(); iter++) + { + if (iter->second >= _size) + { + pBuf = iter->first; + FreeMap.erase(pBuf); + if (iter->second > _size) + { + FreeMap[MOVEPOINT(pBuf, _size)] = iter->second - _size; + } + AllocMap[pBuf] = _size; + break; + } + } + return pBuf; + } + void free(void* _ptr) + { + size_t _size = AllocMap[_ptr]; + AllocMap.erase(_ptr); + FreeMap[_ptr] = _size; + if (FreeMap.size() >= 10) + { + sortMem(); + } + } + void sortMem() + { + + } +}; + +class FuncHook +{ +public: + FuncHook() + : Actived(false) + , Src(NULL) + , SrcPtr(NULL) + , Dst(NULL) + , SrcCodeSize(0) + , HookCodeSize(5) + { + } + ~FuncHook() + { + this->Restore(); + } + void Hook(void** SrcAddr, void* DstAddr) + { + if (!SrcAddr || !*SrcAddr || !DstAddr)return; + //ָϴHOOK + this->Restore(); + // + this->HookCodeSize = 5; + this->SrcCodeSize = 0; + this->SrcPtr = SrcAddr; + this->Src = *SrcAddr; + this->Dst = DstAddr; + //HOOKС + do + { + this->SrcCodeSize += Asm::GetCodeLen(Move_Ptr(this->Src, this->SrcCodeSize)); + } while (this->SrcCodeSize < this->HookCodeSize); + this->HookCode = (unsigned char*)CMemPool::GetInstance()->alloc(this->SrcCodeSize + 11); + memcpy(this->HookCode, this->Src, this->SrcCodeSize); + //޸ĿַڴȨ + CMemPool::MakeJmp(&this->HookCode[this->SrcCodeSize], Move_Ptr(this->Src, this->SrcCodeSize), this->SrcCodeSize - this->HookCodeSize); + //޸ԴַڴȨ + CMemPool::GetInstance()->SetPageProtect(this->Src, PROT_READ | PROT_WRITE | PROT_EXEC); + CMemPool::MakeJmp(this->Src, this->Dst, this->SrcCodeSize - this->HookCodeSize); + *this->SrcPtr = this->HookCode; + this->Actived = true; + } + void Restore() + { + if (this->Actived) + { + //޸ԴַڴдȨ + CMemPool::GetInstance()->SetPageProtect(this->Src, PROT_READ | PROT_WRITE); + memcpy(this->Src, this->HookCode, this->SrcCodeSize); + //޸ԴַڴִȨ + CMemPool::GetInstance()->SetPageProtect(this->Src, PROT_READ | PROT_EXEC); + this->Actived = false; + this->SrcCodeSize = 0; + *this->SrcPtr = this->Src; + if (this->HookCode) + { + CMemPool::GetInstance()->free(this->HookCode); + } + this->HookCode = NULL; + } + } +private: + bool Actived; + void *Src; + void **SrcPtr; + void *Dst; + unsigned char* HookCode; + size_t SrcCodeSize; + size_t HookCodeSize; +}; + +class CodeHook +{ +public: + static void WriteUChar(void *Addr, unsigned char Value) + { + WriteBytes(Addr, &Value, 1); + } + static void WriteUShort(void *Addr, unsigned short Value) + { + WriteBytes(Addr, &Value, 2); + } + static void WriteUInt(void *Addr, unsigned int Value) + { + WriteBytes(Addr, &Value, 4); + } + static void WriteBytes(void *Addr, void *Data, size_t Len) + { + CMemPool::GetInstance()->SetPageProtect(Addr, PROT_READ | PROT_WRITE | PROT_EXEC); + memcpy(Addr, Data, Len); + } +}; diff --git a/src/sdk_class.hpp b/src/sdk_class.hpp new file mode 100644 index 0000000..b360c78 --- /dev/null +++ b/src/sdk_class.hpp @@ -0,0 +1,457 @@ +#ifndef USER_CLASS_H +#define USER_CLASS_H +#include "base.h" +#include "enum.h" + +#include + + + +template R CallT(A call_addr, const ARG ... arguments) +{ + if (!call_addr) + { + return R(); + } + const auto control = reinterpret_cast(call_addr); + try + { + return control(arguments ...); + } + catch (...) + { + + } + return R(); +} + +class PacketBuf; +class DB_UpdateAvatarJewelSlot; +class CInventory; +class CStackableItem; +class Inven_Item; +class CItem; +class CUserCharacInfo; +class CUser; +class PacketBuf; +class PacketGuard; +class InterfacePacketBuf; + +namespace WongWork +{ + + class CAvatarItemMgr + { + public: + //获取时装插槽数据 + int getJewelSocketData(WongWork::CAvatarItemMgr* a2) + { + typedef int (*__func)(WongWork::CAvatarItemMgr* a1, void* a2); + return ((__func)base::WongWork::CAvatarItemMgr::getJewelSocketData)(this, a2); + } + }; + + class CHackAnalyzer + { + public: + int addServerHackCnt(CUserCharacInfo* a2, int a3, int a4, int a5, int a6) + { + typedef int (*__func)(WongWork::CHackAnalyzer* a1, CUserCharacInfo* a2, int a3, int a4, int a5, int a6); + + return CallT(base::WongWork::CHackAnalyzer::addServerHackCnt, this, a2, a3, a4, a5, a6); + return ((__func)base::WongWork::CHackAnalyzer::addServerHackCnt)(this, a2, a3, a4, a5, a6); + } + }; +} + +class CUserCharacInfo +{ +public: + //获取角色名字 + std::string getCurCharacName() + { + typedef char* (*__func)(CUserCharacInfo* a1); + return std::string(((__func)base::CUserCharacInfo::getCurCharacName)(this)); + } + + //获取角色编号 + int getCurCharacNo() + { + typedef int (*__func)(CUserCharacInfo* a1); + return int(((__func)base::CUserCharacInfo::getCurCharacNo)(this)); + } + + //获取角色上次退出游戏时间 + int getCurCharacLastPlayTick() + { + typedef int (*__func)(CUserCharacInfo* a1); + return int(((__func)base::CUserCharacInfo::getCurCharacLastPlayTick)(this)); + } + + //获取角色等级 + int get_level_up_exp(int a2) + { + typedef int (*__func)(CUserCharacInfo* a1, int a2); + return int(((__func)base::CUserCharacInfo::get_level_up_exp)(this, a2)); + } + + //获取角色背包 + CInventory* getCurCharacInvenW() + { + typedef CInventory* (*__func)(CUserCharacInfo* a1); + return ((__func)base::CUserCharacInfo::getCurCharacInvenW)(this); + } +}; + +class CUser : public CUserCharacInfo +{ +public: + int get_state() + { + typedef int (*__func)(CUser* a1); + return int(((__func)base::CUser::get_state)(this)); + } + + bool CheckItemLock(int a2, int a3) + { + typedef bool (*__func)(CUser* a1, int a2, int a3); + return int(((__func)base::CUser::CheckItemLock)(this, a2, a3)); + } + + int SendNotiPacketMessage(char* a2, int a3) + { + typedef bool (*__func)(CUser* a1, char* a2, int a3); + return int(((__func)base::CUser::SendNotiPacketMessage)(this, a2, a3)); + } + + //角色增加经验 + int gain_exp_sp(unsigned int a2, int a3, int a4, int a5, int a6, int a7) + { + typedef int (*__func)(CUserCharacInfo* a1, unsigned int a2, int a3, int a4, int a5, int a6, int a7); + return int(((__func)base::CUser::gain_exp_sp)(this, a2, a3, a4, a5, a6, a7)); + } + + //发送道具 + int AddItem(int a2, int a3, int a4, int a5, int a6) + { + typedef int (*__func)(CUser* a1, int a2, int a3, int a4, int a5, int a6); + return int(((__func)base::CUser::AddItem)(this, a2, a3, a4, a5, a6)); + } + + //通知客户端道具更新(客户端指针, 通知方式[仅客户端=1, 世界广播=0, 小队=2, war room=3], itemSpace[装备=0, 时装=1], 道具所在的背包槽) + int SendUpdateItemList(int a2, int a3, int a4) + { + typedef int (*__func)(CUserCharacInfo* a1, int a2, int a3, int a4); + return int(((__func)base::CUser::SendUpdateItemList)(this, a2, a3, a4)); + } + + int SendCmdErrorPacket(int a2, unsigned char a3) + { + typedef int (*__func)(CUser* a1, int a2, unsigned char a3); + return int(((__func)base::CUser::SendCmdErrorPacket)(this, a2, a3)); + } + + int isEnableAvatarSocketAction() + { + typedef int (*__func)(CUser* a1); + return int(((__func)base::CUser::isEnableAvatarSocketAction)(this)); + } + + int Send(PacketGuard* a2) + { + typedef int (*__func)(CUser* a1, PacketGuard* a2); + return int(((__func)base::CUser::Send)(this, a2)); + } +}; + +class CStackableItem +{ +public: + //获取消耗品类型 + int GetItemType() + { + typedef int (*__func)(void* a1); + return ((__func)base::CStackableItem::GetItemType)(this); + } + + //获取徽章支持的镶嵌槽类型 + int getJewelTargetSocket() + { + typedef int (*__func)(CStackableItem* a1); + return ((__func)base::CStackableItem::getJewelTargetSocket)(this); + } +}; + +class CItem : public CStackableItem +{ +public: + //道具是否为消耗品 + int is_stackable() + { + typedef int (*__func)(CItem* a1); + return ((__func)base::CItem::is_stackable)(this); + } + + bool IsRoutingItem() + { + typedef bool (*__func)(CItem* a1); + return ((__func)base::CItem::IsRoutingItem)(this); + } + +private: +}; + +class Inven_Item +{ +public: + //获取道具附加信息 + WongWork::CAvatarItemMgr* get_add_info() + { + typedef WongWork::CAvatarItemMgr* (*__func)(Inven_Item* a1); + return ((__func)base::Inven_Item::get_add_info)(this); + } + + //检查背包中道具是否为空 + bool isEmpty() + { + typedef bool (*__func)(Inven_Item* a1); + return ((__func)base::Inven_Item::isEmpty)(this); + } + //获取背包中道具item_id + int getKey() + { + typedef int (*__func)(Inven_Item* a1); + return ((__func)base::Inven_Item::getKey)(this); + } + //道具是否是装备 + bool isEquipableItemType() + { + typedef bool (*__func)(Inven_Item* a1); + return ((__func)base::Inven_Item::isEquipableItemType)(this); + } + + int get_ui_id() + { + return *(int*)(this + 0x7); + } +}; + +class CDataManager +{ +public: + static CDataManager* G_CDataManager(void) + { + typedef CDataManager* (*__func)(void); + return ((__func)base::CDataManager::G_CDataManager)(); + } + + //获取装备pvf数据 + CItem* find_item(int a2) + { + typedef CItem* (*__func)(CDataManager* a1, int a2); + return ((__func)base::CDataManager::find_item)(this, a2); + } +}; + +class CInventory +{ +public: + enum INVENTORY_TYPE : int + { + INVENTORY_TYPE_BODY = 0, //身上穿的装备 + INVENTORY_TYPE_ITEM = 1, //物品栏 + INVENTORY_TYPE_AVARTAR = 2, //时装栏 + }; + +public: + //获取时装管理器 + WongWork::CAvatarItemMgr* GetAvatarItemMgrR() + { + typedef WongWork::CAvatarItemMgr* (*__func)(void* a1); + return ((__func)base::CInventory::GetAvatarItemMgrR)(this); + } + + int delete_item(int a2, int a3, int a4, int a5, int a6) + { + typedef int (*__func)(CInventory* a1, int a2, int a3, int a4, int a5, int a6); + return ((__func)base::CInventory::delete_item)(this, a2, a3, a4, a5, a6); + } + + //使用金币 + int use_money(int a2, int a3, char a4) + { + typedef int (*__func)(CInventory* a1, int a2, int a3, char a4); + return ((__func)base::CInventory::use_money)(this, a2, a3, a4); + } + + //获得金币 + int gain_money(unsigned int a2, int a3, char a4, int a5) + { + typedef int (*__func)(CInventory* a1, unsigned int a2, int a3, char a4, int a5); + return ((__func)base::CInventory::gain_money)(this, a2, a3, a4, a5); + } + + //获取背包槽中的道具 + Inven_Item* GetInvenRef(INVENTORY_TYPE a2, int a3) + { + typedef Inven_Item* (*__func)(CInventory* a1, INVENTORY_TYPE a2, int a3); + return ((__func)base::CInventory::GetInvenRef)(this, a2, a3); + } +}; + +class DB_UpdateAvatarJewelSlot +{ +public: + static int makeRequest(int a1, unsigned int a2, void* src) + { + typedef int (*__func)(int a1, unsigned int a2, void* src); + return ((__func)base::DB_UpdateAvatarJewelSlot::makeRequest)(a1, a2, src); + } +}; + +class PacketBuf +{ +public: + //取大小 + int get_len() + { + typedef int (*__func)(PacketBuf* a1); + return ((__func)base::PacketBuf::get_len)(this); + } + + //取指针 + int get_buf_ptr(int a2 = 0) + { + typedef int (*__func)(PacketBuf* a1, int a2); + return ((__func)base::PacketBuf::get_buf_ptr)(this, a2); + } + + char get_byte() + { + char result; + typedef int (*__func)(PacketBuf* a1, char* a2); + if (((__func)base::PacketBuf::get_byte)(this, &result) == 1) + { + return result; + } + return 0; + } + + short get_short() + { + short result; + typedef int (*__func)(PacketBuf* a1, short* a2); + if (((__func)base::PacketBuf::get_short)(this, &result) == 1) + { + return result; + } + return 0; + } + + int get_int() + { + int result; + typedef int (*__func)(PacketBuf* a1, int* a2); + if (((__func)base::PacketBuf::get_int)(this, &result) == 1) + { + return result; + } + return 0; + } + + int get_binary(char* a2, int a3) + { + typedef int (*__func)(PacketBuf* a1, char* a2, int a3); + return ((__func)base::PacketBuf::get_binary)(this, a2, a3); + } +}; + +class InterfacePacketBuf +{ +public: + int put_header(int a2, int a3) + { + typedef int (*__func)(InterfacePacketBuf* a1, int a2, int a3); + return ((__func)base::InterfacePacketBuf::put_header)(this, a2, a3); + } + + int put_byte(char a2) + { + typedef int (*__func)(InterfacePacketBuf* a1, char a2); + return ((__func)base::InterfacePacketBuf::put_byte)(this, a2); + } + int put_short(short a2) + { + typedef int (*__func)(InterfacePacketBuf* a1, short a2); + return ((__func)base::InterfacePacketBuf::put_short)(this, a2); + } + + int put_int(int a2) + { + typedef int (*__func)(InterfacePacketBuf* a1, int a2); + return ((__func)base::InterfacePacketBuf::put_int)(this, a2); + } + + int put_binary(char* a2, int a3) + { + typedef int (*__func)(InterfacePacketBuf* a1, char* a2, int a3); + return ((__func)base::InterfacePacketBuf::put_binary)(this, a2, a3); + } + + int finalize(bool a2) + { + typedef int (*__func)(InterfacePacketBuf* a1, bool a2); + return ((__func)base::InterfacePacketBuf::finalize)(this, a2); + } + + int put_str(const char* a2, int a3) + { + typedef int (*__func)(InterfacePacketBuf* a1, const char* a2, int a3); + return ((__func)base::InterfacePacketBuf::put_str)(this, a2, a3); + } + + int put_packet(const Inven_Item* a2) + { + typedef int (*__func)(InterfacePacketBuf* a1, const Inven_Item* a2); + return ((__func)base::InterfacePacketBuf::put_packet)(this, a2); + } +}; + +class PacketGuard +{ +public: + static PacketGuard* NewPacketGuard() + { + void* v62 = malloc(0x20000); + typedef int (*__func)(void* a1); + ((__func)base::PacketGuard::PacketGuard_make)(v62); + return (PacketGuard*)v62; + } + static void DelPacketGuard(PacketGuard* a1) + { + typedef int (*__func)(void* a1); + ((__func)base::PacketGuard::PacketGuard_destroy)(a1); + free(a1); + } +}; + +class PacketDispatcher +{ +public: + int getDispatcher(int a2) + { + typedef int (*__func)(PacketDispatcher* a1, int a2); + return ((__func)base::PacketDispatcher::getDispatcher)(this, a2); + } + + void** get_dispatcher(int a2) + { + typedef void** (*__func)(PacketDispatcher* a1, int a2); + return ((__func)base::PacketDispatcher::get_dispatcher)(this, a2); + } +}; + + + + +#endif // __DXFBASE_H__ diff --git a/src/utils.hpp b/src/utils.hpp new file mode 100644 index 0000000..74faaaf --- /dev/null +++ b/src/utils.hpp @@ -0,0 +1,56 @@ +#ifndef utils_h__ +#define utils_h__ +#include +#include +#include +#define BUFFCOUNT (3196) +#define SET_TEXTW(X) L#X +#define SET_TEXTA(X) #X + + +namespace Util +{ + /** + * @brief 到16进制Hex文本 + * @param buf + * @param len + * @param tok + * @return + */ + static std::string ToHexString(const unsigned char* buf, int len, std::string tok = " ") + { + std::string output; + char temp[8]; + for (int i = 0; i < len; ++i) + { + memset(temp, 0, sizeof(temp)); + snprintf(temp, sizeof(temp), "%.2X", buf[i]); + output.append(temp, 2); + output.append(tok); + } + + return output; + } + + static void _Log(const char* formatstring, ...) + { + int nSize = 0; + char buff[BUFFCOUNT]; + memset(buff, 0, sizeof(buff)); + va_list args; + va_start(args, formatstring); + nSize = vsnprintf(buff, sizeof(buff), formatstring, args); + va_end(args); + char szPrINT32[BUFFCOUNT + 50] = { 0 }; + sprintf(szPrINT32, "[GameHelpers] %s \n", buff);//wsprintfA + printf(szPrINT32); + } + + +} + + +#define LOG(format,...) Util::_Log(format,##__VA_ARGS__) + + +#endif // utils_h__ \ No newline at end of file diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt new file mode 100644 index 0000000..f8daf86 --- /dev/null +++ b/test/CMakeLists.txt @@ -0,0 +1,13 @@ +# ҪcmakeͰ汾 +CMAKE_MINIMUM_REQUIRED(VERSION 3.0) + +# Դļ +SET(SOURCE main.cc) + +# ָλΪĿĿ¼µlibĿ¼ +LINK_DIRECTORIES(${PROJECT_SOURCE_DIR}/build/lib) +INCLUDE_DIRECTORIES(${PROJECT_SOURCE_DIR}/src) + +# һִг,ƺ͹Ʊһ +ADD_EXECUTABLE(hook-test ${SOURCE}) +TARGET_LINK_LIBRARIES(hook-test SHARED hook) diff --git a/test/main.cc b/test/main.cc new file mode 100644 index 0000000..8fb603f --- /dev/null +++ b/test/main.cc @@ -0,0 +1,9 @@ +#include + +using namespace std; + +int main(int argc, char** argv) +{ + return 0; +} +