Files
DP_S/src/df_main.cpp
2022-09-12 13:35:16 +08:00

644 lines
17 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#include "import.h"
#include "controller.h"
#define MY_VERSION ("BuildTime " __DATE__ " " __TIME__)
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*));
Mem::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);
LOG("_Inter_LoadEtc_dispatch_sig begin");
//typedef double(__cdecl* FN_sqrt)(_In_ double _X);
CUserCharacInfo_getCurCharacNo getCurCharacNo = (CUserCharacInfo_getCurCharacNo)(0x080CBC4E);
int CurCharacNo = getCurCharacNo(pUser);
LOG("CurCharacNo :%d", CurCharacNo);
CUserCharacInfo_getCurCharacName getCurCharacName = (CUserCharacInfo_getCurCharacName)0x8101028;
char* name = getCurCharacName(pUser);
LOG("CurCharacName :%s", name);
LOG("_Inter_LoadEtc_dispatch_sig end");
return result;
}
void PrintTag()
{
printf("\n");
LOG("**********************************************************");
LOG(" DNF Server Plugin %s ", MY_VERSION);
LOG(" ");
LOG(" /\\ /\\ ");
LOG(" ");
LOG(" __ ");
LOG(" By:Vance ");
LOG("**********************************************************");
}
void loga()
{
if (!checkGame("df_game_r"))
{
PrintTag();
int a = 1;
void* buf = malloc(4);
Mem::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
Mem::WriteUChar(MAIN_OFFSET(0x220894), 0x01);
//Init DataManager
Mem::WriteUChar(MAIN_OFFSET(0x258E80), 0xEB);
//Init Level Exp
Mem::WriteUChar(MAIN_OFFSET(0x314ECB), 0xEB);
//Init Mob Reward
Mem::WriteUChar(MAIN_OFFSET(0x314FCB), 0xEB);
//CDataManager::GetSpAtLevelUp
Mem::WriteUChar(MAIN_OFFSET(0x318CC8), 0xE6);
//fixbug
Mem::WriteUChar(MAIN_OFFSET(0x31C128), 0x7E);
Mem::WriteUChar(MAIN_OFFSET(0x31C129), 0x06);
Mem::WriteUChar(MAIN_OFFSET(0x547005), nMaxGrade);
Mem::WriteUChar(MAIN_OFFSET(0x61AF55), nMaxGrade);
Mem::WriteUChar(MAIN_OFFSET(0x61B0F3), nMaxGrade);
Mem::WriteUChar(MAIN_OFFSET(0x61DD28), nMaxGrade - 1);
Mem::WriteUChar(MAIN_OFFSET(0x61E86A), nMaxGrade);
Mem::WriteUChar(MAIN_OFFSET(0x61EE9C), nMaxGrade - 1);
Mem::WriteUChar(MAIN_OFFSET(0x6224A8), nMaxGrade - 1);
Mem::WriteUChar(MAIN_OFFSET(0x622929), nMaxGrade);
Mem::WriteUChar(MAIN_OFFSET(0x641D4B), nMaxGrade - 1);
Mem::WriteUChar(MAIN_OFFSET(0x647ECE), nMaxGrade);
Mem::WriteUChar(MAIN_OFFSET(0x647EDA), nMaxGrade);
Mem::WriteUChar(MAIN_OFFSET(0x647F82), nMaxGrade);
Mem::WriteUChar(MAIN_OFFSET(0x647F88), nMaxGrade);
Mem::WriteUChar(MAIN_OFFSET(0x66521D), nMaxGrade);
Mem::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)
{
//以下需要扩充类大小, 修改偏移
Mem::WriteUInt(MAIN_OFFSET(0x87162 + 3), 0xB678 + nMaxGrade * 4 + nMaxGrade * 12);
//CDataManager::set_reward_sp
Mem::WriteUInt(MAIN_OFFSET(0x318C26 + 2), 10836 + 840);
Mem::WriteUChar(MAIN_OFFSET(0x318C3B), nMaxGrade);
Mem::WriteUInt(MAIN_OFFSET(0x318C68 + 2), 10836 + 840);
Mem::WriteUChar(MAIN_OFFSET(0x318C79), nMaxGrade);
//CDataManager::GetSpAtLevelUp
Mem::WriteUChar(MAIN_OFFSET(0x318CC4), nMaxGrade);
Mem::WriteUInt(MAIN_OFFSET(0x318CD4 + 2), 10836 + 840);
}
Mem::WriteUChar(MAIN_OFFSET(0x61B8F6), nMaxGrade);
Mem::WriteUChar(MAIN_OFFSET(0x622659), nMaxGrade);
Mem::WriteUChar(MAIN_OFFSET(0x622941), nMaxGrade);
Mem::WriteUChar(MAIN_OFFSET(0x622941), nMaxGrade);
}
}
void __attribute__((constructor)) my_init(void)
{
//patchGame();
loga();
}