初版
This commit is contained in:
170
src/CConnectPool.cpp
Normal file
170
src/CConnectPool.cpp
Normal file
@@ -0,0 +1,170 @@
|
||||
#include "CConnectPool.h"
|
||||
#include <iostream>
|
||||
|
||||
#define POOL_SAFE_DELETE(ptr) \
|
||||
if (ptr != NULL) \
|
||||
{ \
|
||||
delete ptr; \
|
||||
ptr = NULL; \
|
||||
}
|
||||
|
||||
CConnectPool *CConnectPool::s_pInstance = NULL;
|
||||
|
||||
CConnectPool::CConnectPool()
|
||||
{
|
||||
pthread_mutex_init(&m_mutex, NULL);
|
||||
pthread_cond_init(&m_cond, NULL);
|
||||
// 初始化连接数
|
||||
// 此处由主线程调用初始化,无需考虑锁问题
|
||||
for (int i = 0; i < My_Info.MaxConnectCount; ++i)
|
||||
{
|
||||
MYSQL *pConn = _CreateConnect();
|
||||
if (NULL == pConn)
|
||||
{
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
m_queueFree.push(pConn);
|
||||
}
|
||||
}
|
||||
|
||||
CConnectPool::~CConnectPool()
|
||||
{
|
||||
pthread_mutex_destroy(&m_mutex);
|
||||
pthread_cond_destroy(&m_cond);
|
||||
MYSQL *pConn = NULL;
|
||||
while (m_queueFree.size() > 0)
|
||||
{
|
||||
pConn = m_queueFree.front();
|
||||
POOL_SAFE_DELETE(pConn);
|
||||
m_queueFree.pop();
|
||||
}
|
||||
std::set<MYSQL *>::iterator it = m_setBusy.begin();
|
||||
while (it != m_setBusy.end())
|
||||
{
|
||||
pConn = *it;
|
||||
POOL_SAFE_DELETE(pConn);
|
||||
// it = m_setBusy.erase(it);
|
||||
it++;
|
||||
}
|
||||
}
|
||||
|
||||
void CConnectPool::CreatePool(int MinConnectCount, int MaxConnectCount, const char *Host, int Port, const char *Account, const char *Passwd)
|
||||
{
|
||||
if (NULL == s_pInstance)
|
||||
{
|
||||
s_pInstance = new CConnectPool;
|
||||
s_pInstance->My_Info.MinConnectCount = MinConnectCount;
|
||||
s_pInstance->My_Info.MaxConnectCount = MaxConnectCount;
|
||||
s_pInstance->My_Info.Host = Host;
|
||||
s_pInstance->My_Info.Port = Port;
|
||||
s_pInstance->My_Info.Account = Account;
|
||||
s_pInstance->My_Info.Passwd = Passwd;
|
||||
s_pInstance->My_Info.KName = "taiwan_cain";
|
||||
}
|
||||
}
|
||||
|
||||
void CConnectPool::FreePool()
|
||||
{
|
||||
if (NULL != s_pInstance)
|
||||
{
|
||||
delete s_pInstance;
|
||||
s_pInstance = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
MYSQL *CConnectPool::GetConnect()
|
||||
{
|
||||
return s_pInstance->_GetConnect(false);
|
||||
}
|
||||
|
||||
MYSQL *CConnectPool::TryGetConnect()
|
||||
{
|
||||
return s_pInstance->_GetConnect(true);
|
||||
}
|
||||
|
||||
void CConnectPool::PutConnect(MYSQL *pConn)
|
||||
{
|
||||
s_pInstance->_PutConnect(pConn);
|
||||
}
|
||||
|
||||
MYSQL *CConnectPool::_CreateConnect()
|
||||
{
|
||||
MYSQL *pConn = new MYSQL;
|
||||
mysql_init(pConn);
|
||||
if (!mysql_real_connect(pConn, My_Info.Host, My_Info.Account, My_Info.Passwd, My_Info.KName, MYSQL_PORT, NULL, CLIENT_FOUND_ROWS))
|
||||
{
|
||||
printf("connect error:%s\n", mysql_error(pConn));
|
||||
delete pConn;
|
||||
pConn = NULL;
|
||||
}
|
||||
return pConn;
|
||||
}
|
||||
|
||||
MYSQL *CConnectPool::_GetConnect(bool bTry)
|
||||
{
|
||||
static bool bCheck;
|
||||
MYSQL *pRet = NULL;
|
||||
pthread_mutex_lock(&m_mutex);
|
||||
// 取出来还要检查一下是否能正常使用
|
||||
bCheck = true;
|
||||
if (m_queueFree.size() > 0)
|
||||
{
|
||||
pRet = m_queueFree.front();
|
||||
m_queueFree.pop();
|
||||
}
|
||||
else
|
||||
{
|
||||
// 连接数不足,继续创建
|
||||
if (m_queueFree.size() + m_setBusy.size() < My_Info.MinConnectCount)
|
||||
{
|
||||
pRet = _CreateConnect();
|
||||
bCheck = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!bTry)
|
||||
{
|
||||
// 阻塞等待空闲连接
|
||||
pthread_cond_wait(&m_cond, &m_mutex);
|
||||
// 肯定会有空闲连接的
|
||||
if (m_queueFree.size() > 0)
|
||||
{
|
||||
pRet = m_queueFree.front();
|
||||
m_queueFree.pop();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// 检查连接是否可用
|
||||
if (NULL != pRet && true == bCheck && 0 != mysql_ping(pRet))
|
||||
{
|
||||
mysql_close(pRet);
|
||||
pRet = _CreateConnect();
|
||||
}
|
||||
// 加入busy队列
|
||||
if (NULL != pRet)
|
||||
{
|
||||
m_setBusy.insert(pRet);
|
||||
}
|
||||
pthread_mutex_unlock(&m_mutex);
|
||||
return pRet;
|
||||
}
|
||||
|
||||
void CConnectPool::_PutConnect(MYSQL *pConn)
|
||||
{
|
||||
if (NULL == pConn)
|
||||
return;
|
||||
pthread_mutex_lock(&m_mutex);
|
||||
std::set<MYSQL *>::iterator it = m_setBusy.find(pConn);
|
||||
if (it != m_setBusy.end())
|
||||
{
|
||||
m_setBusy.erase(it);
|
||||
}
|
||||
m_queueFree.push(pConn);
|
||||
if (1 == m_queueFree.size())
|
||||
{
|
||||
// 唤醒等待线程
|
||||
pthread_cond_signal(&m_cond);
|
||||
}
|
||||
pthread_mutex_unlock(&m_mutex);
|
||||
}
|
||||
@@ -22,7 +22,7 @@ file(GLOB_RECURSE DIR_ASMJIT_LIB_SRCS
|
||||
)
|
||||
|
||||
#添加头文件目录
|
||||
include_directories(${PROJECT_SOURCE_DIR}/include)
|
||||
include_directories(${PROJECT_SOURCE_DIR}/include /home/asio/asio-1.28.0/include/ ${PROJECT_SOURCE_DIR}/src/ ${PROJECT_SOURCE_DIR}/src/sdk/)
|
||||
add_compile_definitions(ASMJIT_STATIC)
|
||||
|
||||
# 添加库源文件
|
||||
@@ -30,18 +30,24 @@ set(LIB_SOURCE
|
||||
"dispatch.cpp"
|
||||
"controller.cpp"
|
||||
"df_main.cpp"
|
||||
|
||||
"Tool.cpp"
|
||||
"l_squirrel.cpp"
|
||||
"l_socket.cpp"
|
||||
"CConnectPool.cpp"
|
||||
)
|
||||
|
||||
# 添加动态库,关键词为shared
|
||||
ADD_LIBRARY(hook_shared SHARED ${DIR_ASMJIT_LIB_SRCS} ${LIB_SOURCE})
|
||||
ADD_LIBRARY(hook_aurora SHARED ${DIR_ASMJIT_LIB_SRCS} ${LIB_SOURCE})
|
||||
|
||||
# 指定动态库的输出名称
|
||||
SET_TARGET_PROPERTIES(hook_shared PROPERTIES OUTPUT_NAME "hook")
|
||||
SET_TARGET_PROPERTIES(hook_aurora PROPERTIES OUTPUT_NAME "Aurora")
|
||||
|
||||
|
||||
|
||||
target_link_libraries(hook_aurora libstdc++.a -L/home/dnf_project/dnf_project/build/lib/squirrel -lsqstdlib_static -L/home/dnf_project/dnf_project/build/lib/squirrel -lsquirrel_static -L/home/dnf_project/dnf_project/build/lib/mysql/lib libmysqlclient.a -lpthread)
|
||||
# 指定动态库版本, 视需求而定,可不加
|
||||
# VERSION:动态库版本,SOVERSION:API版本
|
||||
#SET_TARGET_PROPERTIES(hook_shared PROPERTIES VERSION 0.1.1 SOVERSION 0)
|
||||
#SET_TARGET_PROPERTIES(hook_aurora PROPERTIES VERSION 0.1.1 SOVERSION 0)
|
||||
|
||||
# 指定库编译输出目录
|
||||
SET(LIBRARY_OUTPUT_PATH ${PROJECT_BINARY_DIR}/lib)
|
||||
SET(LIBRARY_OUTPUT_PATH ${PROJECT_BINARY_DIR}/lib)
|
||||
|
||||
@@ -47,14 +47,13 @@ public:
|
||||
|
||||
bool get_rand_cera_shop_bonus_item(CeraShopBonusItemType* res = NULL)
|
||||
{
|
||||
int size = get_random_item_num();
|
||||
for (int i = 0; i < size; i++)
|
||||
int rand_ = Utils::Rand(0, get_random_item_num() - 1);
|
||||
int i = 0;
|
||||
for (auto it = cera_shop_bonus_item_map_rand.Begin(); it != cera_shop_bonus_item_map_rand.End(); it++, i++)
|
||||
{
|
||||
int random_value = Utils::Rand(1, size - 1);
|
||||
CeraShopBonusItemType cera_shop_bonusi_temt = cera_shop_bonus_item_map_rand.Map.at(random_value);
|
||||
if (cera_shop_bonusi_temt.is_random == true)
|
||||
if (rand_ == i)
|
||||
{
|
||||
if (res != NULL) *res = cera_shop_bonusi_temt;
|
||||
if (res) *res = it->second;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
125
src/Tool.cpp
Normal file
125
src/Tool.cpp
Normal file
@@ -0,0 +1,125 @@
|
||||
#include "Tool.h"
|
||||
#include <string.h>
|
||||
#include <chrono>
|
||||
#include <ctime>
|
||||
using namespace std;
|
||||
|
||||
Tool::Tool(/* args */)
|
||||
{
|
||||
}
|
||||
|
||||
Tool::~Tool()
|
||||
{
|
||||
}
|
||||
|
||||
int Tool::ByteLittleToInt(unsigned char *Count)
|
||||
{
|
||||
int int1 = Count[0] & 0xff;
|
||||
int int2 = (Count[1] & 0xff) << 8;
|
||||
int int3 = (Count[2] & 0xff) << 16;
|
||||
int int4 = (Count[3] & 0xff) << 24;
|
||||
|
||||
return int1 | int2 | int3 | int4;
|
||||
}
|
||||
|
||||
unsigned char *Tool::IntToByteLittle(int Count)
|
||||
{
|
||||
unsigned char *b = new unsigned char[4];
|
||||
b[0] = (Count & 0xff);
|
||||
b[1] = (Count & 0xff00) >> 8;
|
||||
b[2] = (Count & 0xff0000) >> 16;
|
||||
b[3] = (Count & 0xff000000) >> 24;
|
||||
|
||||
return b;
|
||||
}
|
||||
|
||||
unsigned char *Tool::StringToByte(std::string str)
|
||||
{
|
||||
char *cstr = (char *)str.c_str();
|
||||
int Count = strlen(cstr);
|
||||
unsigned char *temp = IntToByteLittle(Count);
|
||||
unsigned char *buffer = new unsigned char[Count + 4];
|
||||
for (size_t i = 0; i < 4; i++)
|
||||
{
|
||||
buffer[i] = temp[i];
|
||||
}
|
||||
delete[] temp;
|
||||
for (size_t z = 4; z < Count + 4; z++)
|
||||
{
|
||||
buffer[z] = cstr[z - 4];
|
||||
}
|
||||
return buffer;
|
||||
}
|
||||
|
||||
void Tool::Error(std::string O)
|
||||
{
|
||||
#ifdef Development_mode
|
||||
std::cout << "\n----[ERROR]----\n";
|
||||
std::cout << "\n----[By "
|
||||
<< "YosinLenheart"
|
||||
<< "]----\n";
|
||||
std::cout << O << std::endl;
|
||||
std::cout << "\n----------------\n";
|
||||
#endif
|
||||
}
|
||||
void Tool::Warring(std::string W)
|
||||
{
|
||||
#ifdef Development_mode
|
||||
std::cout << "\n----[WARRING]----\n";
|
||||
std::cout << "\n----[By "
|
||||
<< "YosinLenheart"
|
||||
<< "]----\n";
|
||||
std::cout << W << std::endl;
|
||||
std::cout << "\n----------------\n";
|
||||
#endif
|
||||
}
|
||||
void Tool::Logger(std::string L)
|
||||
{
|
||||
#ifdef Development_mode
|
||||
std::cout << "\n----[LOGGER]----\n";
|
||||
std::cout << "\n----[By "
|
||||
<< "YosinLenheart"
|
||||
<< "]----\n";
|
||||
std::cout << L << std::endl;
|
||||
std::cout << "\n----------------\n";
|
||||
#endif
|
||||
}
|
||||
|
||||
long long Tool::get_cur_time()
|
||||
{
|
||||
// 获取操作系统当前时间点(精确到微秒)
|
||||
chrono::time_point<chrono::system_clock, chrono::microseconds> tpMicro = chrono::time_point_cast<chrono::microseconds>(chrono::system_clock::now());
|
||||
// (微秒精度的)时间点 => (微秒精度的)时间戳
|
||||
time_t totalMicroSeconds = tpMicro.time_since_epoch().count();
|
||||
|
||||
long long currentTime = ((long long)totalMicroSeconds) / 1000;
|
||||
|
||||
return currentTime;
|
||||
}
|
||||
|
||||
int Tool::UTF8ToGB2312(char *szSrc, size_t iSrcLen, char *szDst, size_t iDstLen)
|
||||
{
|
||||
iconv_t cd = iconv_open("gb2312//IGNORE", "utf-8//IGNORE"); // take care of "//IGNORE", it will ignore those invalid code
|
||||
if (0 == cd)
|
||||
return -2;
|
||||
memset(szDst, 0, iDstLen);
|
||||
char **src = &szSrc;
|
||||
char **dst = &szDst;
|
||||
if (-1 == (int)iconv(cd, src, &iSrcLen, dst, &iDstLen))
|
||||
return -1;
|
||||
iconv_close(cd);
|
||||
return 0;
|
||||
}
|
||||
int Tool::GB2312ToUTF8(char *szSrc, size_t iSrcLen, char *szDst, size_t iDstLen)
|
||||
{
|
||||
iconv_t cd = iconv_open("utf-8//IGNORE", "gb2312//IGNORE");
|
||||
if (0 == cd)
|
||||
return -2;
|
||||
memset(szDst, 0, iDstLen);
|
||||
char **src = &szSrc;
|
||||
char **dst = &szDst;
|
||||
if (-1 == (int)iconv(cd, src, &iSrcLen, dst, &iDstLen))
|
||||
return -1;
|
||||
iconv_close(cd);
|
||||
return 0;
|
||||
}
|
||||
@@ -7,40 +7,40 @@
|
||||
//************************************
|
||||
|
||||
#include "controller.h"
|
||||
extern HSQUIRRELVM v;
|
||||
extern std::recursive_mutex SqMtx;
|
||||
|
||||
Controller::Controller() :
|
||||
assembler(Arch::kX86),
|
||||
Asm(NULL)
|
||||
Controller::Controller() : assembler(Arch::kX86),
|
||||
Asm(NULL)
|
||||
{
|
||||
Asm = assembler.GetAssembler();
|
||||
}
|
||||
|
||||
Controller::~Controller()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void Controller::init()
|
||||
{
|
||||
CMem::WriteUChar((void*)(base::GlobalData::Init_fix_1 - 0x1), 0);
|
||||
CMem::WriteUChar((void *)(base::GlobalData::Init_fix_1 - 0x1), 0);
|
||||
//.text:085BDE9D 83 F8 0A cmp eax, 10
|
||||
CMem::WriteUChar((void*)(base::CParty::addDungeonClear_fix_1 + 2), 0x7E); //普通被击
|
||||
CMem::WriteUChar((void *)(base::CParty::addDungeonClear_fix_1 + 2), 0x7E); // 普通被击
|
||||
//.text:085BDF30 83 F8 1E cmp eax, 30
|
||||
CMem::WriteUChar((void*)(base::CParty::addDungeonClear_fix_2 + 2), 0x7E); //远古被击
|
||||
CMem::WriteUChar((void *)(base::CParty::addDungeonClear_fix_2 + 2), 0x7E); // 远古被击
|
||||
//.text:085BDFC3 83 F8 32 cmp eax, 50
|
||||
CMem::WriteUChar((void*)(base::CParty::addDungeonClear_fix_3 + 2), 0x7E); //异界被击
|
||||
|
||||
CMem::WriteUChar((void *)(base::CParty::addDungeonClear_fix_3 + 2), 0x7E); // 异界被击
|
||||
CMem::WriteUChar((void *)(0x081C025F + 1), 0x0B);
|
||||
CMem::WriteUChar((void *)(0x081C029E + 1), 0x0B);
|
||||
|
||||
/* 修正使用代币增加积分
|
||||
地址 长度 原始字节 已修补字节
|
||||
08179043 0x1 97 B8
|
||||
0817904E 0x1 8C AD
|
||||
*/
|
||||
CMem::WriteUChar((void*)(0x08179043), 0xB8);
|
||||
CMem::WriteUChar((void*)(0x0817904E), 0xAD);
|
||||
CMem::WriteUChar((void *)(0x08179043), 0xB8);
|
||||
CMem::WriteUChar((void *)(0x0817904E), 0xAD);
|
||||
|
||||
|
||||
//mov dword ptr [esp+4], 8E0F448h
|
||||
// mov dword ptr [esp+4], 8E0F448h
|
||||
Asm->lea(eax, dword_ptr(ebp, -0x84));
|
||||
Asm->mov(dword_ptr(esp), eax);
|
||||
Asm->mov(eax, int(&hook_importCashShopItemList));
|
||||
@@ -49,9 +49,9 @@ void Controller::init()
|
||||
Asm->mov(eax, base::importCashShopItemList_hook_end);
|
||||
Asm->jmp(eax);
|
||||
auto code_importCashShopItemList = assembler.GetBytes(true);
|
||||
void* new_importCashShopItemList_addr = Utils::alloc(code_importCashShopItemList.size());
|
||||
void *new_importCashShopItemList_addr = Utils::alloc(code_importCashShopItemList.size());
|
||||
CMem::WriteBytes(new_importCashShopItemList_addr, code_importCashShopItemList.data(), code_importCashShopItemList.size());
|
||||
LOG("code :%s", Utils::ToHexString((const unsigned char*)code_importCashShopItemList.data(), code_importCashShopItemList.size()).c_str());
|
||||
LOG("code :%s", Utils::ToHexString((const unsigned char *)code_importCashShopItemList.data(), code_importCashShopItemList.size()).c_str());
|
||||
LOG("code_addr :%p", new_importCashShopItemList_addr);
|
||||
|
||||
CMem::HookJmp(base::importCashShopItemList_hook_begin, (int)new_importCashShopItemList_addr);
|
||||
@@ -59,7 +59,7 @@ void Controller::init()
|
||||
/************************************************************************/
|
||||
/* HOOK 商城购买物品成功处理 */
|
||||
/************************************************************************/
|
||||
//mov dword ptr [ebp-0FCh], 0FFFFFFFFh
|
||||
// mov dword ptr [ebp-0FCh], 0FFFFFFFFh
|
||||
|
||||
Asm->lea(eax, dword_ptr(ebp, -0xEC));
|
||||
Asm->mov(dword_ptr(esp, 0x10), eax);
|
||||
@@ -79,20 +79,18 @@ void Controller::init()
|
||||
Asm->mov(eax, int(&hook_ProcessIPG_ResultOutput));
|
||||
Asm->call(eax);
|
||||
|
||||
|
||||
Asm->mov(dword_ptr(ebp, -0xfc), 0x0FFFFFFFF);
|
||||
Asm->mov(eax, base::ItemVendingMachine::ProcessIPG_ResultOutput_hook_end);
|
||||
Asm->jmp(eax);
|
||||
auto code_ProcessIPG_ResultOutput = assembler.GetBytes(true);
|
||||
void* new_ProcessIPG_ResultOutput_addr = Utils::alloc(code_ProcessIPG_ResultOutput.size());
|
||||
void *new_ProcessIPG_ResultOutput_addr = Utils::alloc(code_ProcessIPG_ResultOutput.size());
|
||||
CMem::WriteBytes(new_ProcessIPG_ResultOutput_addr, code_ProcessIPG_ResultOutput.data(), code_ProcessIPG_ResultOutput.size());
|
||||
LOG("code_2 :%s", Utils::ToHexString((const unsigned char*)code_ProcessIPG_ResultOutput.data(), code_ProcessIPG_ResultOutput.size()).c_str());
|
||||
LOG("code_2 :%s", Utils::ToHexString((const unsigned char *)code_ProcessIPG_ResultOutput.data(), code_ProcessIPG_ResultOutput.size()).c_str());
|
||||
LOG("code_addr_2 :%p", new_ProcessIPG_ResultOutput_addr);
|
||||
|
||||
|
||||
CMem::HookJmp(base::ItemVendingMachine::ProcessIPG_ResultOutput_hook_begin, (int)new_ProcessIPG_ResultOutput_addr);
|
||||
|
||||
//HOOK_SETUP(IPacketDispatcher_ParamBase_dispatch_template);
|
||||
// HOOK_SETUP(IPacketDispatcher_ParamBase_dispatch_template);
|
||||
|
||||
HOOK_SETUP(UseJewel_dispatch_sig);
|
||||
|
||||
@@ -109,7 +107,11 @@ void Controller::init()
|
||||
HOOK_SETUP(Init);
|
||||
|
||||
LOG("Controller::init()");
|
||||
}
|
||||
|
||||
void Controller::Jinit()
|
||||
{
|
||||
// HOOK_SETUP(LenDispatcher_New_Gmdebug_Command);
|
||||
}
|
||||
|
||||
int Controller::hook_IPacketDispatcher_ParamBase_dispatch_template(int a1, int a2, int a3)
|
||||
@@ -120,16 +122,15 @@ int Controller::hook_IPacketDispatcher_ParamBase_dispatch_template(int a1, int a
|
||||
// [DNF_PROJECT] + 20 0x8bd8d5c : Dispatcher_ModItemAttr::read(PacketBuf &,MSG_BASE &)
|
||||
// [DNF_PROJECT] + 24 0x8bd8d60 : Dispatcher_ModItemAttr::process(CUser *,MSG_BASE &,ParamBase &)
|
||||
// [DNF_PROJECT] + 28 0x8bd8d64 : IPacketDispatcher<MSG_BASE,ParamBase,(ch_state)0>::send(CUser *,ParamBase&)
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
// [DNF_PROJECT] + 12 0x8bd7dd4 : Dispatcher_Antibot::dispatch_sig
|
||||
// [DNF_PROJECT] + 16 0x8bd7dd8 : IPacketDispatcher<MSG_BASE,ParamBase,(ch_state)0>::check_state(CUser *,PacketBuf &)
|
||||
// [DNF_PROJECT] + 20 0x8bd7ddc : Dispatcher_Antibot::read(PacketBuf &,MSG_BASE &)
|
||||
// [DNF_PROJECT] + 24 0x8bd7de0 : Dispatcher_Antibot::process(CUser *,MSG_BASE &,ParamBase &)
|
||||
// [DNF_PROJECT] + 28 0x8bd7de4 : IPacketDispatcher<MSG_BASE,ParamBase,(ch_state)0>::send(CUser *,ParamBase&)
|
||||
|
||||
|
||||
//LOG("ParamBase_dispatch_template[ +12 :%p +16 :%p +20 :%p +24 :%p +28 :%p ]"
|
||||
// LOG("ParamBase_dispatch_template[ +12 :%p +16 :%p +20 :%p +24 :%p +28 :%p ]"
|
||||
// , *(int*)a1 + 12
|
||||
// , *(int*)a1 + 16
|
||||
// , *(int*)a1 + 20
|
||||
@@ -139,7 +140,7 @@ int Controller::hook_IPacketDispatcher_ParamBase_dispatch_template(int a1, int a
|
||||
Controller::Get()->old_IPacketDispatcher_ParamBase_dispatch_template(a1, a2, a3);
|
||||
}
|
||||
|
||||
int Controller::hook_UseJewel_dispatch_sig(void* pDispatcher_UseJewel, CUser* user, PacketBuf* pBuf)
|
||||
int Controller::hook_UseJewel_dispatch_sig(void *pDispatcher_UseJewel, CUser *user, PacketBuf *pBuf)
|
||||
{
|
||||
ENUM_PACK_RET_TYPE ret = CDispatch::Get()->UseJewel_dispatch_sig(pDispatcher_UseJewel, user, pBuf);
|
||||
int result = (ret == PAK_ERROR) ? 1 : 0;
|
||||
@@ -147,7 +148,7 @@ int Controller::hook_UseJewel_dispatch_sig(void* pDispatcher_UseJewel, CUser* us
|
||||
return result;
|
||||
}
|
||||
|
||||
int Controller::hook_Dispatcher_ModItemAttr_dispatch_sig(Dispatcher_ModItemAttr* dis_mod, CUser* user, PacketBuf* pBuf)
|
||||
int Controller::hook_Dispatcher_ModItemAttr_dispatch_sig(Dispatcher_ModItemAttr *dis_mod, CUser *user, PacketBuf *pBuf)
|
||||
{
|
||||
PacketBuf new_buf;
|
||||
memcpy(&new_buf, pBuf, sizeof(PacketBuf));
|
||||
@@ -155,16 +156,13 @@ int Controller::hook_Dispatcher_ModItemAttr_dispatch_sig(Dispatcher_ModItemAttr*
|
||||
int equipment_id = 0;
|
||||
short item_pos = 0;
|
||||
|
||||
if ((unsigned __int8)new_buf.get_short(&equipment_pos) != 1
|
||||
|| (unsigned __int8)new_buf.get_int(&equipment_id) != 1
|
||||
|| (unsigned __int8)new_buf.get_short(&item_pos) != 1)
|
||||
if ((unsigned __int8)new_buf.get_short(&equipment_pos) != 1 || (unsigned __int8)new_buf.get_int(&equipment_id) != 1 || (unsigned __int8)new_buf.get_short(&item_pos) != 1)
|
||||
{
|
||||
user->SendCmdErrorPacket(84, -1);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
CInventory* CurCharacInvenW = user->getCurCharacInvenR();
|
||||
CInventory *CurCharacInvenW = user->getCurCharacInvenR();
|
||||
|
||||
auto item_inven = CurCharacInvenW->GetInvenRef(CInventory::INVENTORY_TYPE_ITEM, item_pos);
|
||||
|
||||
@@ -177,43 +175,35 @@ int Controller::hook_Dispatcher_ModItemAttr_dispatch_sig(Dispatcher_ModItemAttr*
|
||||
return Get()->old_Dispatcher_ModItemAttr_dispatch_sig(dis_mod, user, pBuf);
|
||||
}
|
||||
|
||||
int Controller::hook_PacketDispatcher_doDispatch(PacketDispatcher* a1, CUser* user, int packet_class, int packet_id, char* packet_src, int packet_len, int a7, int a8)
|
||||
int Controller::hook_PacketDispatcher_doDispatch(PacketDispatcher *a1, CUser *user, int packet_class, int packet_id, char *packet_src, int packet_len, int a7, int a8)
|
||||
{
|
||||
int(***dispatcher)(int, CUser*, char*) = (int(***)(int, CUser*, char*))a1->get_dispatcher(packet_id);
|
||||
int (***dispatcher)(int, CUser *, char *) = (int (***)(int, CUser *, char *))a1->get_dispatcher(packet_id);
|
||||
if (dispatcher)
|
||||
{
|
||||
//v32 = (**dispatcher)(dispatcher, user, v25);
|
||||
LOG("Recv() class:%d id:%d len:%d %p [ +00 :%p +12 :%p +16 :%p +20 :%p +24 :%p +28 :%p ]"
|
||||
, packet_class
|
||||
, packet_id
|
||||
, packet_len
|
||||
, (**dispatcher)
|
||||
, *(int*)dispatcher
|
||||
, *(int*)dispatcher + 12
|
||||
, *(int*)dispatcher + 16
|
||||
, *(int*)dispatcher + 20
|
||||
, *(int*)dispatcher + 24
|
||||
, *(int*)dispatcher + 28
|
||||
);
|
||||
|
||||
// v32 = (**dispatcher)(dispatcher, user, v25);
|
||||
// LOG("Recv() class:%d id:%d len:%d %p [ +00 :%p +12 :%p +16 :%p +20 :%p +24 :%p +28 :%p ]"
|
||||
// , packet_class
|
||||
// , packet_id
|
||||
// , packet_len
|
||||
// , (**dispatcher)
|
||||
// , *(int*)dispatcher
|
||||
// , *(int*)dispatcher + 12
|
||||
// , *(int*)dispatcher + 16
|
||||
// , *(int*)dispatcher + 20
|
||||
// , *(int*)dispatcher + 24
|
||||
// , *(int*)dispatcher + 28
|
||||
// );
|
||||
}
|
||||
|
||||
// LOG("Recv() class:%d id:%d len:%d packet_data :%s ", packet_class, packet_id, packet_len, Utils::ToHexString((const unsigned char *)packet_src, packet_len).c_str());
|
||||
|
||||
if (packet_id == PACKET_ID_ITEM_USE_EQUIPMENT_MOVEITEM)
|
||||
{
|
||||
int result = 0;
|
||||
PacketBuf* v25 = PacketBuf::NewPacketBuf();
|
||||
PacketBuf *v25 = PacketBuf::NewPacketBuf();
|
||||
user->setLastPacketID(packet_id);
|
||||
v25->bind_packet(packet_src, packet_len);
|
||||
|
||||
|
||||
|
||||
LOG("Recv() class:%d id:%d len:%d packet_data :%s "
|
||||
, packet_class
|
||||
, packet_id
|
||||
, packet_len
|
||||
, Utils::ToHexString((const unsigned char*)packet_src, packet_len).c_str()
|
||||
);
|
||||
LOG("Recv() class:%d id:%d len:%d packet_data :%s ", packet_class, packet_id, packet_len, Utils::ToHexString((const unsigned char *)packet_src, packet_len).c_str());
|
||||
|
||||
if (v25)
|
||||
{
|
||||
@@ -225,51 +215,177 @@ int Controller::hook_PacketDispatcher_doDispatch(PacketDispatcher* a1, CUser* us
|
||||
}
|
||||
return result;
|
||||
}
|
||||
// 区域移动
|
||||
else if (packet_id == 38)
|
||||
{
|
||||
std::lock_guard<std::recursive_mutex> lock(SqMtx);
|
||||
SQBool R;
|
||||
// 执行虚拟机Main函数
|
||||
SQInteger top = sq_gettop(v); // saves the stack size before the call
|
||||
sq_pushroottable(v); // pushes the global table
|
||||
sq_pushstring(v, _SC("Cb_move_area"), -1);
|
||||
if (SQ_SUCCEEDED(sq_get(v, -2)))
|
||||
{ // gets the fie123oo' from the global table
|
||||
sq_pushroottable(v); // push the 'this' (in this case is the global table)
|
||||
sq_pushuserpointer(v, user);
|
||||
sq_pushinteger(v, int(*(unsigned char *)(packet_src + 0x0D)));
|
||||
sq_pushinteger(v, int(*(unsigned char *)(packet_src + 0x0E)));
|
||||
sq_call(v, 4, SQTrue, SQTrue); // calls the function
|
||||
sq_getbool(v, -1, &R);
|
||||
}
|
||||
sq_settop(v, top); // restores the original stack size
|
||||
if (!R)
|
||||
return 0;
|
||||
}
|
||||
// 普通输入
|
||||
else if (packet_id == 17)
|
||||
{
|
||||
std::string str = Utils::PackToHexString((const unsigned char *)packet_src, 20);
|
||||
std::lock_guard<std::recursive_mutex> lock(SqMtx);
|
||||
SQBool R;
|
||||
// 执行虚拟机Main函数
|
||||
SQInteger top = sq_gettop(v); // saves the stack size before the call
|
||||
sq_pushroottable(v); // pushes the global table
|
||||
sq_pushstring(v, _SC("Cb_base_input"), -1);
|
||||
if (SQ_SUCCEEDED(sq_get(v, -2)))
|
||||
{ // gets the fie123oo' from the global table
|
||||
sq_pushroottable(v); // push the 'this' (in this case is the global table)
|
||||
sq_pushuserpointer(v, user);
|
||||
sq_pushstring(v, _SC(str.c_str()), -1);
|
||||
sq_call(v, 3, SQTrue, SQTrue); // calls the function
|
||||
sq_getbool(v, -1, &R);
|
||||
}
|
||||
sq_settop(v, top); // restores the original stack size
|
||||
if (!R)
|
||||
return 0;
|
||||
}
|
||||
// GM输入
|
||||
else if (packet_id == 179)
|
||||
{
|
||||
// std::cout << "传入的: " << std::hex << (int)user << std::endl;
|
||||
std::string str = Utils::PackToHexString((const unsigned char *)packet_src, 13);
|
||||
str = str.substr(2);
|
||||
std::lock_guard<std::recursive_mutex> lock(SqMtx);
|
||||
// 执行虚拟机Main函数
|
||||
SQInteger top = sq_gettop(v); // saves the stack size before the call
|
||||
sq_pushroottable(v); // pushes the global table
|
||||
sq_pushstring(v, _SC("Cb_gm_input"), -1);
|
||||
if (SQ_SUCCEEDED(sq_get(v, -2)))
|
||||
{ // gets the fie123oo' from the global table
|
||||
sq_pushroottable(v); // push the 'this' (in this case is the global table)
|
||||
sq_pushuserpointer(v, user);
|
||||
sq_pushstring(v, _SC(str.c_str()), -1);
|
||||
sq_call(v, 3, SQFalse, SQTrue); // calls the function
|
||||
}
|
||||
sq_settop(v, top); // restores the original stack size
|
||||
}
|
||||
// 特殊道具使用
|
||||
else if (packet_id == 255)
|
||||
{
|
||||
std::lock_guard<std::recursive_mutex> lock(SqMtx);
|
||||
// 执行虚拟机Main函数
|
||||
SQInteger top = sq_gettop(v); // saves the stack size before the call
|
||||
sq_pushroottable(v); // pushes the global table
|
||||
sq_pushstring(v, _SC("Cb_use_item_sp"), -1);
|
||||
if (SQ_SUCCEEDED(sq_get(v, -2)))
|
||||
{ // gets the fie123oo' from the global table
|
||||
sq_pushroottable(v); // push the 'this' (in this case is the global table)
|
||||
sq_pushuserpointer(v, user);
|
||||
sq_pushinteger(v, int(*(int *)(packet_src + 0x0D)));
|
||||
sq_call(v, 3, SQFalse, SQTrue); // calls the function
|
||||
}
|
||||
sq_settop(v, top); // restores the original stack size
|
||||
}
|
||||
// 自定义包
|
||||
else if (packet_id == 130)
|
||||
{
|
||||
std::string str = Utils::PackToHexString((const unsigned char *)packet_src, 13);
|
||||
std::lock_guard<std::recursive_mutex> lock(SqMtx);
|
||||
// 执行虚拟机Main函数
|
||||
SQInteger top = sq_gettop(v); // saves the stack size before the call
|
||||
sq_pushroottable(v); // pushes the global table
|
||||
sq_pushstring(v, _SC("OnClientSocketMsg"), -1);
|
||||
if (SQ_SUCCEEDED(sq_get(v, -2)))
|
||||
{ // gets the fie123oo' from the global table
|
||||
sq_pushroottable(v); // push the 'this' (in this case is the global table)
|
||||
sq_pushuserpointer(v, user);
|
||||
sq_pushstring(v, _SC(str.c_str()), -1);
|
||||
sq_call(v, 3, SQFalse, SQTrue); // calls the function
|
||||
}
|
||||
sq_settop(v, top); // restores the original stack size
|
||||
}
|
||||
return Get()->old_PacketDispatcher_doDispatch(a1, user, packet_class, packet_id, packet_src, packet_len, a7, a8);
|
||||
}
|
||||
|
||||
int Controller::hook_DisPatcher_MoveMap_dispatch_sig(void* a1, CUser* pUser, PacketBuf* pBuf)
|
||||
int Controller::hook_LenDispatcher_New_Gmdebug_Command(void *Command, void *CUser, void *PacketBuf)
|
||||
{
|
||||
//ENUM_PACK_RET_TYPE ret = CDispatch::Get()->MoveMap_dispatch_sig(a1, pUser, pBuf);
|
||||
//int result = (ret == PAK_ERROR) ? 1 : 0;
|
||||
|
||||
void *Pck = (void *)((*(int *)(PacketBuf + 20)) + 13);
|
||||
int msg_len = *(int *)(Pck);
|
||||
std::string msg((char *)(Pck + 4), msg_len);
|
||||
msg = msg.substr(2);
|
||||
|
||||
std::lock_guard<std::recursive_mutex> lock(SqMtx);
|
||||
// 执行虚拟机Main函数
|
||||
SQInteger top = sq_gettop(v); // saves the stack size before the call
|
||||
sq_pushroottable(v); // pushes the global table
|
||||
sq_pushstring(v, _SC("Cb_gm_input"), -1);
|
||||
if (SQ_SUCCEEDED(sq_get(v, -2)))
|
||||
{ // gets the fie123oo' from the global table
|
||||
sq_pushroottable(v); // push the 'this' (in this case is the global table)
|
||||
sq_pushuserpointer(v, Command);
|
||||
sq_pushuserpointer(v, CUser);
|
||||
sq_pushstring(v, _SC(msg.c_str()), -1);
|
||||
sq_call(v, 4, SQFalse, SQTrue); // calls the function
|
||||
}
|
||||
sq_settop(v, top); // restores the original stack size
|
||||
|
||||
int Ret = Get()->old_LenDispatcher_New_Gmdebug_Command(Command, CUser, PacketBuf);
|
||||
|
||||
return Ret;
|
||||
}
|
||||
|
||||
int Controller::hook_DisPatcher_MoveMap_dispatch_sig(void *a1, CUser *pUser, PacketBuf *pBuf)
|
||||
{
|
||||
// ENUM_PACK_RET_TYPE ret = CDispatch::Get()->MoveMap_dispatch_sig(a1, pUser, pBuf);
|
||||
// int result = (ret == PAK_ERROR) ? 1 : 0;
|
||||
return Get()->old_DisPatcher_MoveMap_dispatch_sig(a1, pUser, pBuf);
|
||||
}
|
||||
|
||||
int Controller::hook_Inter_LoadEtc_dispatch_sig(void* a1, CUser* pUser, char* a3)
|
||||
int Controller::hook_Inter_LoadEtc_dispatch_sig(void *a1, CUser *pUser, char *a3)
|
||||
{
|
||||
CDispatch::Get()->Inter_LoadEtc_dispatch_sig(a1, pUser, a3);
|
||||
return Get()->old_Inter_LoadEtc_dispatch_sig(a1, pUser, a3);
|
||||
}
|
||||
|
||||
int Controller::hook_DisPatcher_ReturnToSelectCharacter_dispatch_sig(void* a1, CUser* pUser, char* a3)
|
||||
int Controller::hook_DisPatcher_ReturnToSelectCharacter_dispatch_sig(void *a1, CUser *pUser, char *a3)
|
||||
{
|
||||
CDispatch::Get()->DisPatcher_ReturnToSelectCharacter_dispatch_sig(a1, pUser, a3);
|
||||
return Get()->old_DisPatcher_ReturnToSelectCharacter_dispatch_sig(a1, pUser, a3);
|
||||
}
|
||||
|
||||
void Controller::hook_importCashShopItemList(const std::string* str)
|
||||
void Controller::hook_importCashShopItemList(const std::string *str)
|
||||
{
|
||||
if (str != NULL)
|
||||
CDispatch::Get()->importCashShopItemList(str);
|
||||
}
|
||||
|
||||
void Controller::hook_ProcessIPG_ResultOutput(CUser* user, int Goods_No, int item_id, int Cera_Type, InterfacePacketBuf* pbuf)
|
||||
void Controller::hook_ProcessIPG_ResultOutput(CUser *user, int Goods_No, int item_id, int Cera_Type, InterfacePacketBuf *pbuf)
|
||||
{
|
||||
CDispatch::Get()->ProcessIPG_ResultOutput(user, Goods_No, item_id, Cera_Type, pbuf);
|
||||
}
|
||||
|
||||
int Controller::hook_Dispatcher_BuyCeraShopItem_dispatch_sig(void* a1, CUser* pUser, PacketBuf* pBuf)
|
||||
int Controller::hook_Dispatcher_BuyCeraShopItem_dispatch_sig(void *a1, CUser *pUser, PacketBuf *pBuf)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool Controller::hook_Init(int a1, char** a2)
|
||||
bool Controller::hook_Init(int a1, char **a2)
|
||||
{
|
||||
auto result = Get()->old_Init(a1, a2);
|
||||
if (result)
|
||||
{
|
||||
CDispatch::Get()->Init_done(a1, (const char**)a2);
|
||||
CDispatch::Get()->Init_done(a1, (const char **)a2);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,17 +1,18 @@
|
||||
#pragma once
|
||||
#include "dispatch.h"
|
||||
#include "Assembler.h"
|
||||
|
||||
#include "l_squirrel.h"
|
||||
|
||||
#define MAIN_OFFSET(offset) ((void *)((0x8048000) + (offset)))
|
||||
#define SUBHOOK_INIT(func, addr) \
|
||||
fn##func func = (fn##func)addr; \
|
||||
FuncHook h##func
|
||||
fn##func func = (fn##func)addr; \
|
||||
FuncHook h##func
|
||||
|
||||
#define SUBHOOK_SETUP(func) h##func.Hook((void **)&func, (void *)_##func)
|
||||
|
||||
#define INIT_HOOK(func, addr) \
|
||||
using Type_##func = decltype(hook_##func); \
|
||||
Type_##func * old_##func = (Type_##func *)addr; \
|
||||
#define INIT_HOOK(func, addr) \
|
||||
using Type_##func = decltype(hook_##func); \
|
||||
Type_##func *old_##func = (Type_##func *)addr; \
|
||||
FuncHook mhook_##func
|
||||
|
||||
#define HOOK_SETUP(func) mhook_##func.Hook((void **)&old_##func, (void *)hook_##func)
|
||||
@@ -24,12 +25,12 @@ public:
|
||||
private:
|
||||
Controller();
|
||||
~Controller();
|
||||
|
||||
public:
|
||||
void init();
|
||||
|
||||
void Jinit();
|
||||
|
||||
private:
|
||||
|
||||
static int hook_IPacketDispatcher_ParamBase_dispatch_template(int a1, int a2, int a3);
|
||||
/**
|
||||
* @brief hook修复镶嵌徽章
|
||||
@@ -37,12 +38,11 @@ private:
|
||||
* @param pUser
|
||||
* @param pBuf
|
||||
* @return
|
||||
*/
|
||||
static int hook_UseJewel_dispatch_sig(void* pDispatcher_UseJewel, CUser* pUser, PacketBuf* pBuf);
|
||||
|
||||
//使用蜜蜡
|
||||
static int hook_Dispatcher_ModItemAttr_dispatch_sig(Dispatcher_ModItemAttr* dis_mod, CUser* user, PacketBuf* pBuf);
|
||||
*/
|
||||
static int hook_UseJewel_dispatch_sig(void *pDispatcher_UseJewel, CUser *pUser, PacketBuf *pBuf);
|
||||
|
||||
// 使用蜜蜡
|
||||
static int hook_Dispatcher_ModItemAttr_dispatch_sig(Dispatcher_ModItemAttr *dis_mod, CUser *user, PacketBuf *pBuf);
|
||||
|
||||
/**
|
||||
* @brief hook收包处理
|
||||
@@ -55,25 +55,26 @@ private:
|
||||
* @param a7
|
||||
* @param a8
|
||||
* @return
|
||||
*/
|
||||
static int hook_PacketDispatcher_doDispatch(PacketDispatcher* a1, CUser* a2, int a3, int packet_id, char* packet_src, int pecakt_len, int a7, int a8);
|
||||
*/
|
||||
static int hook_PacketDispatcher_doDispatch(PacketDispatcher *a1, CUser *a2, int a3, int packet_id, char *packet_src, int pecakt_len, int a7, int a8);
|
||||
|
||||
static int hook_DisPatcher_MoveMap_dispatch_sig(void* a1, CUser* pUser, PacketBuf* pBuf);
|
||||
static int hook_LenDispatcher_New_Gmdebug_Command(void *a1, void *pUser, void *pBuf);
|
||||
|
||||
static int hook_Inter_LoadEtc_dispatch_sig(void* a1, CUser* pUser, char* a3);
|
||||
static int hook_DisPatcher_MoveMap_dispatch_sig(void *a1, CUser *pUser, PacketBuf *pBuf);
|
||||
|
||||
static int hook_DisPatcher_ReturnToSelectCharacter_dispatch_sig(void* a1, CUser* pUser, char* a3);
|
||||
static int hook_Inter_LoadEtc_dispatch_sig(void *a1, CUser *pUser, char *a3);
|
||||
|
||||
static void hook_importCashShopItemList(const std::string* str);
|
||||
static int hook_DisPatcher_ReturnToSelectCharacter_dispatch_sig(void *a1, CUser *pUser, char *a3);
|
||||
|
||||
static void hook_ProcessIPG_ResultOutput(CUser* user, int Goods_No, int item_id, int Cera_Type, InterfacePacketBuf* pbuf);
|
||||
static void hook_importCashShopItemList(const std::string *str);
|
||||
|
||||
static int hook_Dispatcher_BuyCeraShopItem_dispatch_sig(void* a1, CUser* pUser, PacketBuf* pBuf);
|
||||
static void hook_ProcessIPG_ResultOutput(CUser *user, int Goods_No, int item_id, int Cera_Type, InterfacePacketBuf *pbuf);
|
||||
|
||||
static bool hook_Init(int a1, char** a2);
|
||||
static int hook_Dispatcher_BuyCeraShopItem_dispatch_sig(void *a1, CUser *pUser, PacketBuf *pBuf);
|
||||
|
||||
static bool hook_Init(int a1, char **a2);
|
||||
|
||||
private:
|
||||
|
||||
INIT_HOOK(IPacketDispatcher_ParamBase_dispatch_template, base::IPacketDispatcher::ParamBase::dispatch_template);
|
||||
INIT_HOOK(PacketDispatcher_doDispatch, base::PacketDispatcher::doDispatch);
|
||||
INIT_HOOK(Dispatcher_ModItemAttr_dispatch_sig, base::Dispatcher_ModItemAttr::dispatch_sig);
|
||||
@@ -83,9 +84,9 @@ private:
|
||||
INIT_HOOK(DisPatcher_ReturnToSelectCharacter_dispatch_sig, base::DisPatcher_ReturnToSelectCharacter::dispatch_sig);
|
||||
INIT_HOOK(Init, base::Init);
|
||||
|
||||
INIT_HOOK(LenDispatcher_New_Gmdebug_Command, 0x820BBDE);
|
||||
|
||||
private:
|
||||
CAssembler assembler;
|
||||
Assembler* Asm;
|
||||
|
||||
Assembler *Asm;
|
||||
};
|
||||
585
src/df_main.cpp
585
src/df_main.cpp
@@ -1,12 +1,16 @@
|
||||
#include "import.h"
|
||||
#include "l_squirrel.h"
|
||||
#include "l_socket.h"
|
||||
#include "controller.h"
|
||||
#include "CConnectPool.h"
|
||||
extern HSQUIRRELVM v;
|
||||
extern std::recursive_mutex SqMtx;
|
||||
#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(PacketGuard, 0x0858DD4C);
|
||||
SUBHOOK_INIT(GetVectorUserCharacInfo, 0x081A0BB8);
|
||||
SUBHOOK_INIT(doDispatch, 0x08594922);
|
||||
SUBHOOK_INIT(addServerHackCnt, 0x080F8C7E);
|
||||
@@ -25,17 +29,32 @@ SUBHOOK_INIT(isSocketAvatar, 0x082F9228);
|
||||
SUBHOOK_INIT(reach_game_world, 0x086C4E50);
|
||||
SUBHOOK_INIT(Inter_LoadEtc_dispatch_sig, 0x084C0264);
|
||||
|
||||
SUBHOOK_INIT(Inter_LoadGeolocation_dispatch_sig, 0x0816088A);
|
||||
|
||||
SUBHOOK_INIT(Leninsert_user, 0x086C25A6);
|
||||
SUBHOOK_INIT(LenGameWorld_move_position, 0x086C5706);
|
||||
SUBHOOK_INIT(LenGetTimerMess, 0x08630ECC);
|
||||
SUBHOOK_INIT(Lengetareauseridlist, 0x086C305E);
|
||||
SUBHOOK_INIT(ReqDBSendNewSystemMultiMail, 0x08556B68);
|
||||
SUBHOOK_INIT(AddItem, 0x0867B6D4);
|
||||
SUBHOOK_INIT(InterSelectMobileAuthReward, 0x0816132A);
|
||||
SUBHOOK_INIT(CreateSkill, 0x084024E6);
|
||||
SUBHOOK_INIT(CreateEquip, 0x084023AC);
|
||||
|
||||
|
||||
//_setCharacInfoDetail
|
||||
|
||||
int checkGame(const char* pName)
|
||||
int checkGame(const char *pName)
|
||||
{
|
||||
char path[256];
|
||||
char* path_end;
|
||||
char *path_end;
|
||||
|
||||
memset(path, 0, sizeof(path));
|
||||
if (readlink("/proc/self/exe", path, sizeof(path)) <= 0)return -1;
|
||||
if (readlink("/proc/self/exe", path, sizeof(path)) <= 0)
|
||||
return -1;
|
||||
path_end = strrchr(path, '/');
|
||||
if (!path_end || strlen(path_end) < 9)return -1;
|
||||
if (!path_end || strlen(path_end) < 9)
|
||||
return -1;
|
||||
return strcmp(pName, ++path_end);
|
||||
}
|
||||
|
||||
@@ -43,103 +62,35 @@ int open_main_module_file()
|
||||
{
|
||||
char path[256];
|
||||
memset(path, 0, sizeof(path));
|
||||
if (readlink("/proc/self/exe", path, sizeof(path)) <= 0)return -1;
|
||||
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 GetProfileString(const char *profile, const char *section, const char *key, char **val)
|
||||
{
|
||||
int hFile = open(profile, O_RDONLY);
|
||||
if (hFile == -1)return -1;
|
||||
if (hFile == -1)
|
||||
return -1;
|
||||
struct stat st;
|
||||
fstat(hFile, &st);
|
||||
void* pFileData = mmap(0, st.st_size, PROT_READ, MAP_SHARED, hFile, 0);
|
||||
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);
|
||||
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;
|
||||
if (notes && *cur != '\n')
|
||||
continue;
|
||||
switch (*cur)
|
||||
{
|
||||
case '#':
|
||||
@@ -147,37 +98,37 @@ int GetProfileString(const char* profile, const char* section, const char* key,
|
||||
break;
|
||||
case ' ':
|
||||
case '\t':
|
||||
//jump space
|
||||
// jump space
|
||||
break;
|
||||
case '\n':
|
||||
//new line
|
||||
// new line
|
||||
if (readValue)
|
||||
{
|
||||
valuebuf[i] = '\0';
|
||||
if (!strcmp(section, sectionbuf) && !strcmp(key, keybuf))
|
||||
{
|
||||
*val = (char*)malloc(i + 1);
|
||||
*val = (char *)malloc(i + 1);
|
||||
memset(*val, 0, i + 1);
|
||||
strcpy(*val, valuebuf);
|
||||
got = 1;
|
||||
}
|
||||
//printf("value:%s\n", valuebuf);
|
||||
// printf("value:%s\n", valuebuf);
|
||||
}
|
||||
notes = 0, readSection = 0, readKey = 1, readValue = 0, i = 0;
|
||||
break;
|
||||
case '[':
|
||||
//section begin
|
||||
// section begin
|
||||
readSection = 1;
|
||||
readKey = 0;
|
||||
readValue = 0;
|
||||
i = 0;
|
||||
break;
|
||||
case ']':
|
||||
//section end
|
||||
// section end
|
||||
if (readSection)
|
||||
{
|
||||
sectionbuf[i] = '\0';
|
||||
//printf("section:%s\n", sectionbuf);
|
||||
// printf("section:%s\n", sectionbuf);
|
||||
readSection = 0;
|
||||
}
|
||||
break;
|
||||
@@ -185,7 +136,7 @@ int GetProfileString(const char* profile, const char* section, const char* key,
|
||||
if (readKey)
|
||||
{
|
||||
keybuf[i] = '\0';
|
||||
//printf("key:%s\n", keybuf);
|
||||
// printf("key:%s\n", keybuf);
|
||||
readSection = 0;
|
||||
readKey = 0;
|
||||
readValue = 1;
|
||||
@@ -215,17 +166,18 @@ int GetProfileString(const char* profile, const char* section, const char* key,
|
||||
return 0;
|
||||
}
|
||||
|
||||
int GetProfileInt(const char* profile, const char* section, const char* key)
|
||||
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;
|
||||
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_Shdr *get_section_by_type(Elf32_Ehdr *pHeader, Elf32_Shdr *pSectionHeaderTable, Elf32_Word sh_type)
|
||||
{
|
||||
Elf32_Half i = 0;
|
||||
do
|
||||
@@ -238,7 +190,7 @@ Elf32_Shdr* get_section_by_type(Elf32_Ehdr* pHeader, Elf32_Shdr* pSectionHeaderT
|
||||
return NULL;
|
||||
}
|
||||
|
||||
Elf32_Shdr* get_section_by_index(Elf32_Ehdr* pHeader, Elf32_Shdr* pSectionHeaderTable, Elf32_Half i)
|
||||
Elf32_Shdr *get_section_by_index(Elf32_Ehdr *pHeader, Elf32_Shdr *pSectionHeaderTable, Elf32_Half i)
|
||||
{
|
||||
if (i < pHeader->e_shnum)
|
||||
{
|
||||
@@ -247,7 +199,7 @@ Elf32_Shdr* get_section_by_index(Elf32_Ehdr* pHeader, Elf32_Shdr* pSectionHeader
|
||||
return NULL;
|
||||
}
|
||||
|
||||
Elf32_Shdr* get_section_by_name(Elf32_Ehdr* pHeader, Elf32_Shdr* pSectionHeaderTable, const char* pSymStrTbl, const char* pName)
|
||||
Elf32_Shdr *get_section_by_name(Elf32_Ehdr *pHeader, Elf32_Shdr *pSectionHeaderTable, const char *pSymStrTbl, const char *pName)
|
||||
{
|
||||
Elf32_Half i = 0;
|
||||
do
|
||||
@@ -260,7 +212,7 @@ Elf32_Shdr* get_section_by_name(Elf32_Ehdr* pHeader, Elf32_Shdr* pSectionHeaderT
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int get_symbol_index_by_name(Elf32_Sym* pSymbolTbl, int nSymbols, const char* pSymStrTbl, const char* pName)
|
||||
int get_symbol_index_by_name(Elf32_Sym *pSymbolTbl, int nSymbols, const char *pSymStrTbl, const char *pName)
|
||||
{
|
||||
int i = 0;
|
||||
do
|
||||
@@ -273,39 +225,39 @@ int get_symbol_index_by_name(Elf32_Sym* pSymbolTbl, int nSymbols, const char* pS
|
||||
return 0;
|
||||
}
|
||||
|
||||
void* replaceIAT(const char* pName, void* pAddr)
|
||||
void *replaceIAT(const char *pName, void *pAddr)
|
||||
{
|
||||
void* pOrgAddr = NULL;
|
||||
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);
|
||||
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);
|
||||
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);
|
||||
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;
|
||||
pOrgAddr = *(void **)pRelPlt[i].r_offset;
|
||||
*(void **)pRelPlt[i].r_offset = pAddr;
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -315,9 +267,9 @@ void* replaceIAT(const char* pName, void* pAddr)
|
||||
{
|
||||
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*));
|
||||
void **jmpAddr = (void **)pRelDyn[i].r_offset;
|
||||
// printf("jmpaddr::::::::::::::::::::%X\n", pRelDyn[i].r_offset);
|
||||
pOrgAddr = (void *)((char *)(*jmpAddr) + (int)jmpAddr + sizeof(void *));
|
||||
CMem::WriteBytes(pOrgAddr, &pAddr, sizeof(pAddr));
|
||||
break;
|
||||
}
|
||||
@@ -330,10 +282,10 @@ void* replaceIAT(const char* pName, void* pAddr)
|
||||
return pOrgAddr;
|
||||
}
|
||||
|
||||
int my_select(int __nfds, fd_set* __restrict __readfds,
|
||||
fd_set* __restrict __writefds,
|
||||
fd_set* __restrict __exceptfds,
|
||||
struct timeval* __restrict __timeout)
|
||||
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)
|
||||
{
|
||||
@@ -367,39 +319,24 @@ int my_usleep(__useconds_t __useconds)
|
||||
return malloc(__size);
|
||||
}*/
|
||||
|
||||
int _doDispatch(void* pPacketDispatcher, void* pUser, int a3, int a4, void* src, int a6, int a7, int a8)//收包处理
|
||||
int _doDispatch(void *pPacketDispatcher, void *pUser, int a3, int a4, void *src, int a6, int a7, int a8) // 收包处理
|
||||
{
|
||||
void* pAction = *get_dispatcher(pPacketDispatcher, a4);
|
||||
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)
|
||||
//);
|
||||
// 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);
|
||||
// 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)
|
||||
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"
|
||||
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])
|
||||
@@ -412,109 +349,123 @@ int _dispatch_template(void* pInst, void* pUser, void* pPacketBuf)
|
||||
return dispatch_template(pInst, pUser, pPacketBuf);
|
||||
}
|
||||
|
||||
int _addServerHackCnt(void* pCHackAnalyzer, void* pCUserCharacInfo, int HackType, int Cnt, int a5, int a6)
|
||||
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);
|
||||
// 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)
|
||||
int _put_header(void *pInterfacePacketBuf, int Type, int Cmd)
|
||||
{
|
||||
//printf("Send() cmd:%d\n", Cmd);
|
||||
printf("Send() cmd:%d\n", Cmd);
|
||||
return put_header(pInterfacePacketBuf, Type, Cmd);
|
||||
}
|
||||
|
||||
int _IsRoutingItem(void* pItem)
|
||||
int _IsRoutingItem(void *pItem)
|
||||
{
|
||||
//拾取掷点
|
||||
return bPickupRout && (*((unsigned int*)pItem + 14) == 4 || *((unsigned char*)pItem + 189));
|
||||
// 拾取掷点
|
||||
return bPickupRout && (*((unsigned int *)pItem + 14) == 4 || *((unsigned char *)pItem + 189));
|
||||
}
|
||||
|
||||
int _setCharacInfoDetail(void* pUser, int a2, int a3, void* pCHARAC_DATA)
|
||||
int _setCharacInfoDetail(void *pUser, int a2, int a3, void *pCHARAC_DATA)
|
||||
{
|
||||
//下线位置
|
||||
unsigned char curArea = *((unsigned char*)pCHARAC_DATA + 34);
|
||||
// 下线位置
|
||||
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;
|
||||
*((char *)GetVectorUserCharacInfo((char *)pUser + 497384, a2) + 34) = 11;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
int _IsGameMasterMode(void* pUser)
|
||||
int _IsGameMasterMode(void *pUser)
|
||||
{
|
||||
//gm
|
||||
return bGMMode || *((unsigned char*)pUser + 463320) != 0;
|
||||
// gm
|
||||
return bGMMode || *((unsigned char *)pUser + 463320) != 0;
|
||||
}
|
||||
|
||||
int _isGMUser(void* pUser)
|
||||
int _isGMUser(void *pUser)
|
||||
{
|
||||
//gm
|
||||
//printf("%s\n", __FUNCTION__);
|
||||
return bGMMode || (*((unsigned char*)pUser + 463320) != 0);
|
||||
// gm
|
||||
// printf("%s\n", __FUNCTION__);
|
||||
return bGMMode || (*((unsigned char *)pUser + 463320) != 0);
|
||||
}
|
||||
|
||||
int _isGM(void* pGMAccounts, unsigned int a2)
|
||||
int _isGM(void *pGMAccounts, unsigned int a2)
|
||||
{
|
||||
//gm
|
||||
//printf("%s\n", __FUNCTION__);
|
||||
// gm
|
||||
// printf("%s\n", __FUNCTION__);
|
||||
return bGMMode || isGM(pGMAccounts, a2);
|
||||
}
|
||||
|
||||
int _isGM1(void* pGM_Manager)
|
||||
int _isGM1(void *pGM_Manager)
|
||||
{
|
||||
//gm
|
||||
//printf("%s\n", __FUNCTION__);
|
||||
// gm
|
||||
// printf("%s\n", __FUNCTION__);
|
||||
return bGMMode || isGM1(pGM_Manager);
|
||||
}
|
||||
|
||||
int _GetPvPTeamCount(void* pDataManager)
|
||||
int _GetPvPTeamCount(void *pDataManager)
|
||||
{
|
||||
if (bFairPVP)return 10;
|
||||
return *((unsigned int*)pDataManager + 11540);
|
||||
if (bFairPVP)
|
||||
return 10;
|
||||
return *((unsigned int *)pDataManager + 11540);
|
||||
}
|
||||
|
||||
void* _set_add_info(void* pInven_Item, int a2)
|
||||
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]))
|
||||
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);
|
||||
// printf("Get !!! %X\n", i);
|
||||
a2 = GetProfileInt(szGamePath, "", "val");
|
||||
}
|
||||
}
|
||||
}
|
||||
//printf("====================_set_add_info======================%d\n", a2);
|
||||
// printf("====================_set_add_info======================%d\n", a2);
|
||||
}
|
||||
return set_add_info(pInven_Item, a2);
|
||||
}
|
||||
|
||||
int _isSocketAvatar(void* pAvatarItemMgr1, void* pAvatarItemMgr2)
|
||||
int _isSocketAvatar(void *pAvatarItemMgr1, void *pAvatarItemMgr2)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
int _reach_game_world(void* pThis, void* a2)
|
||||
int _reach_game_world(void *pThis, void *a2)
|
||||
{
|
||||
std::lock_guard<std::recursive_mutex> lock(SqMtx);
|
||||
|
||||
SQInteger top = sq_gettop(v); // saves the stack size before the call
|
||||
sq_pushroottable(v); // pushes the global table
|
||||
sq_pushstring(v, _SC("Cb_reach_game_world"), -1);
|
||||
if (SQ_SUCCEEDED(sq_get(v, -2)))
|
||||
{ // gets the field 'foo' from the global table
|
||||
sq_pushroottable(v); // push the 'this' (in this case is the global table)
|
||||
sq_pushuserpointer(v, a2);
|
||||
sq_call(v, 2, SQFalse, SQTrue); // calls the function
|
||||
}
|
||||
sq_settop(v, top); // restores the original stack size
|
||||
|
||||
return reach_game_world(pThis, a2);
|
||||
}
|
||||
|
||||
int _Inter_LoadEtc_dispatch_sig(void* pThis, void* pUser, char* a3)
|
||||
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);
|
||||
|
||||
|
||||
// typedef double(__cdecl* FN_sqrt)(_In_ double _X);
|
||||
|
||||
CUserCharacInfo_getCurCharacNo getCurCharacNo = (CUserCharacInfo_getCurCharacNo)(0x080CBC4E);
|
||||
int CurCharacNo = getCurCharacNo(pUser);
|
||||
@@ -522,59 +473,187 @@ int _Inter_LoadEtc_dispatch_sig(void* pThis, void* pUser, char* a3)
|
||||
|
||||
CUserCharacInfo_getCurCharacName getCurCharacName = (CUserCharacInfo_getCurCharacName)0x8101028;
|
||||
|
||||
char* name = getCurCharacName(pUser);
|
||||
char *name = getCurCharacName(pUser);
|
||||
LOG("CurCharacName :%s", name);
|
||||
|
||||
LOG("_Inter_LoadEtc_dispatch_sig end");
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void PrintTag()
|
||||
void _Leninsert_user(void *Area, void *CUser)
|
||||
{
|
||||
printf("\n");
|
||||
LOG("**********************************************************");
|
||||
LOG(" DNF Server Plugin %s ", MY_VERSION);
|
||||
LOG(" ");
|
||||
LOG(" /\\ /\\ ");
|
||||
LOG(" ");
|
||||
LOG(" __ ");
|
||||
LOG(" By:Vance ");
|
||||
LOG("**********************************************************");
|
||||
// *(int *)(Area + 0x68) = 1; // 让这个区域的所有玩家互相看不见123
|
||||
// *(int *)(Area + 26) = 1;
|
||||
std::lock_guard<std::recursive_mutex> lock(SqMtx);
|
||||
// 执行虚拟机Main函数
|
||||
SQInteger top = sq_gettop(v); // saves the stack size before the call
|
||||
sq_pushroottable(v); // pushes the global table
|
||||
sq_pushstring(v, _SC("Cb_insert_user"), -1);
|
||||
if (SQ_SUCCEEDED(sq_get(v, -2)))
|
||||
{ // gets the field 'foo' from the global table
|
||||
sq_pushroottable(v); // push the 'this' (in this case is the global table)
|
||||
sq_pushuserpointer(v, Area);
|
||||
sq_pushuserpointer(v, CUser);
|
||||
sq_call(v, 3, SQFalse, SQTrue); // calls the function
|
||||
}
|
||||
sq_settop(v, top); // restores the original stack size
|
||||
Leninsert_user(Area, CUser);
|
||||
}
|
||||
void _LenGameWorld_move_position(void *GameWorld, void *CUser, int a3, int a4, int a5, short a6)
|
||||
{
|
||||
std::lock_guard<std::recursive_mutex> lock(SqMtx);
|
||||
// 执行虚拟机Main函数
|
||||
SQInteger top = sq_gettop(v); // saves the stack size before the call
|
||||
sq_pushroottable(v); // pushes the global table
|
||||
sq_pushstring(v, _SC("Cb_GameWorld_move_position"), -1);
|
||||
if (SQ_SUCCEEDED(sq_get(v, -2)))
|
||||
{ // gets the field 'foo' from the global table
|
||||
sq_pushroottable(v); // push the 'this' (in this case is the global table)
|
||||
sq_pushuserpointer(v, CUser);
|
||||
sq_pushinteger(v, a3);
|
||||
sq_pushinteger(v, a4);
|
||||
sq_pushinteger(v, a5);
|
||||
sq_pushinteger(v, a6);
|
||||
sq_call(v, 6, SQFalse, SQTrue); // calls the function
|
||||
}
|
||||
sq_settop(v, top); // restores the original stack size
|
||||
LenGameWorld_move_position(GameWorld, CUser, a3, a4, a5, a6);
|
||||
}
|
||||
|
||||
void loga()
|
||||
int _LenGetTimerMess(void *TimerQueue, void *TimerEntry)
|
||||
{
|
||||
if (l_socket::getInstance().InitState)
|
||||
l_socket::getInstance().Logic();
|
||||
return LenGetTimerMess(TimerQueue, TimerEntry);
|
||||
}
|
||||
|
||||
void PrintAuroraTag()
|
||||
{
|
||||
printf("\n");
|
||||
|
||||
LOG("**********************************************************");
|
||||
LOG(" DNF_Server Plugin S%s ", MY_VERSION);
|
||||
LOG(" By:Rindro-Aurora ");
|
||||
LOG(" PowerBy:Vance ");
|
||||
LOG("**********************************************************");
|
||||
LOG("DP_S插件已加载*************************************凌众-极光");
|
||||
LOG("DP_S插件已加载*************************************凌众-极光");
|
||||
LOG("DP_S插件已加载*************************************凌众-极光");
|
||||
LOG("DP_S插件已加载*************************************凌众-极光");
|
||||
LOG("DP_S插件已加载*************************************凌众-极光");
|
||||
LOG("DP_S插件已加载*************************************凌众-极光");
|
||||
}
|
||||
|
||||
void *SocketThread_function(void *arg)
|
||||
{
|
||||
l_socket::getInstance().Init();
|
||||
|
||||
// 在这里编写线程的具体操作
|
||||
|
||||
pthread_exit(NULL);
|
||||
}
|
||||
|
||||
int _Inter_LoadGeolocation_dispatch_sig(void *pThis, void *pUser, char *a3)
|
||||
{
|
||||
int Ret = Inter_LoadGeolocation_dispatch_sig(pThis, pUser, a3);
|
||||
PrintAuroraTag();
|
||||
// 初始化松鼠
|
||||
InitSquirrel();
|
||||
|
||||
pthread_t SocketThread;
|
||||
int id1 = 1;
|
||||
// 创建线程1
|
||||
if (pthread_create(&SocketThread, NULL, SocketThread_function, &id1) != 0)
|
||||
{
|
||||
std::cerr << "Error creating thread 1" << std::endl;
|
||||
}
|
||||
|
||||
Controller::Get()->Jinit();
|
||||
// SUBHOOK_SETUP(LenDispatcher_New_Gmdebug_Command);
|
||||
return Ret;
|
||||
}
|
||||
|
||||
int _ReqDBSendNewSystemMultiMail(char *src, int a2, unsigned int a3, int a4, int a5, char *a6, int a7, int a8, int a9, char a10)
|
||||
{
|
||||
int Ret = ReqDBSendNewSystemMultiMail(src, a2, a3, a4, a5, a6, a7, a8, a9, a10);
|
||||
std::cout << 111 << std::endl;
|
||||
return Ret;
|
||||
}
|
||||
|
||||
int _AddItem(void *CUser, int a2, int a3, int a4, int *a5, int a6)
|
||||
{
|
||||
int Ret = AddItem(CUser, a2, a3, a4, a5, a6);
|
||||
std::cout << 111 << std::endl;
|
||||
return Ret;
|
||||
}
|
||||
|
||||
int _InterSelectMobileAuthReward(void *InterSelect, void *CUser, char *a3)
|
||||
{
|
||||
int Ret = InterSelectMobileAuthReward(InterSelect, CUser, a3);
|
||||
std::cout << 111 << std::endl;
|
||||
return Ret;
|
||||
}
|
||||
|
||||
bool _CreateSkill(int a1, int a2)
|
||||
{
|
||||
char *Str = (char *)(a2 + 121);
|
||||
char *Str1 = (char *)(a2 + 529);
|
||||
// Str[6] = 8;
|
||||
// Str[7] = 1;
|
||||
// Str1[6] = 8;
|
||||
// Str1[7] = 1;
|
||||
// Str[8] = 36;
|
||||
// Str[9] = 1;
|
||||
// Str1[8] = 36;
|
||||
// Str1[9] = 1;
|
||||
std::cout << "Str: " << Str << std::endl;
|
||||
std::cout << "Str1: " << Str1 << std::endl;
|
||||
|
||||
bool Ret = CreateSkill(a1, a2);
|
||||
return Ret;
|
||||
}
|
||||
|
||||
// 贪玩需求
|
||||
bool _CreateEquip(void *a1, unsigned int a2, void *a3)
|
||||
{
|
||||
char *Str = (char *)(a3);
|
||||
for (int i = 0; i < (30 * 11); i++)
|
||||
{
|
||||
Str[i] = 0x0;
|
||||
}
|
||||
|
||||
bool Ret = CreateEquip(a1, a2, a3);
|
||||
return Ret;
|
||||
}
|
||||
|
||||
void Lenheart()
|
||||
{
|
||||
|
||||
if (!checkGame("df_game_r"))
|
||||
{
|
||||
PrintTag();
|
||||
|
||||
int a = 1;
|
||||
void* buf = malloc(4);
|
||||
void *buf = malloc(4);
|
||||
CMem::WriteBytes(buf, &a, 4);
|
||||
getConfigPath(szGamePath, sizeof(szGamePath));
|
||||
unsigned int nMaxGrade = 80;
|
||||
unsigned int nMaxGrade = 85;
|
||||
bGMMode = 1;
|
||||
|
||||
// max_level = nMaxGrade;
|
||||
|
||||
//max_level = nMaxGrade;
|
||||
// ServerParameterScript::setDungeonOpen
|
||||
|
||||
//ServerParameterScript::setDungeonOpen
|
||||
|
||||
//CodeHook::WriteUChar(MAIN_OFFSET(0x22069B), 0x01);
|
||||
//ServerParameterScript::isDungeonOpen
|
||||
// CodeHook::WriteUChar(MAIN_OFFSET(0x22069B), 0x01);
|
||||
// ServerParameterScript::isDungeonOpen
|
||||
CMem::WriteUChar(MAIN_OFFSET(0x220894), 0x01);
|
||||
//Init DataManager
|
||||
// Init DataManager
|
||||
CMem::WriteUChar(MAIN_OFFSET(0x258E80), 0xEB);
|
||||
//Init Level Exp
|
||||
// Init Level Exp
|
||||
CMem::WriteUChar(MAIN_OFFSET(0x314ECB), 0xEB);
|
||||
//Init Mob Reward
|
||||
// Init Mob Reward
|
||||
CMem::WriteUChar(MAIN_OFFSET(0x314FCB), 0xEB);
|
||||
//CDataManager::GetSpAtLevelUp
|
||||
// CDataManager::GetSpAtLevelUp
|
||||
CMem::WriteUChar(MAIN_OFFSET(0x318CC8), 0xE6);
|
||||
//fixbug
|
||||
// fixbug
|
||||
CMem::WriteUChar(MAIN_OFFSET(0x31C128), 0x7E);
|
||||
CMem::WriteUChar(MAIN_OFFSET(0x31C129), 0x06);
|
||||
|
||||
@@ -593,31 +672,54 @@ void loga()
|
||||
CMem::WriteUChar(MAIN_OFFSET(0x647F88), nMaxGrade);
|
||||
CMem::WriteUChar(MAIN_OFFSET(0x66521D), nMaxGrade);
|
||||
CMem::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);
|
||||
// SUBHOOK_SETUP(addServerHackCnt);
|
||||
// SUBHOOK_SETUP(put_header);
|
||||
// SUBHOOK_SETUP(IsCurCharacVisible);
|
||||
// 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(Leninsert_user);
|
||||
SUBHOOK_SETUP(LenGetTimerMess);
|
||||
SUBHOOK_SETUP(LenGameWorld_move_position);
|
||||
// SUBHOOK_SETUP(Lengetareauseridlist);
|
||||
// SUBHOOK_SETUP(Inter_LoadEtc_dispatch_sig);
|
||||
// SUBHOOK_SETUP(send_area_users);
|
||||
SUBHOOK_SETUP(Inter_LoadGeolocation_dispatch_sig);
|
||||
// 发送邮件HOOK
|
||||
// SUBHOOK_SETUP(ReqDBSendNewSystemMultiMail);
|
||||
// 发送道具
|
||||
// SUBHOOK_SETUP(AddItem);
|
||||
// 账号首角色送成长契约
|
||||
// SUBHOOK_SETUP(InterSelectMobileAuthReward);
|
||||
// 创建角色创建技能
|
||||
// SUBHOOK_SETUP(CreateSkill);
|
||||
// 创建角色创建装备
|
||||
SUBHOOK_SETUP(CreateEquip);
|
||||
|
||||
|
||||
// SUBHOOK_SETUP(doDispatch); // 收包注册
|
||||
|
||||
// CMem::HookJmp(0x86c2994, (int)insert_user_send_to_all);
|
||||
|
||||
Controller::Get()
|
||||
->init();
|
||||
// SUBHOOK_SETUP(isSocketAvatar);
|
||||
if (nMaxGrade > 70)
|
||||
{
|
||||
//以下需要扩充类大小, 修改偏移
|
||||
// 以下需要扩充类大小, 修改偏移
|
||||
CMem::WriteUInt(MAIN_OFFSET(0x87162 + 3), 0xB678 + nMaxGrade * 4 + nMaxGrade * 12);
|
||||
//CDataManager::set_reward_sp
|
||||
// CDataManager::set_reward_sp
|
||||
CMem::WriteUInt(MAIN_OFFSET(0x318C26 + 2), 10836 + 840);
|
||||
CMem::WriteUChar(MAIN_OFFSET(0x318C3B), nMaxGrade);
|
||||
CMem::WriteUInt(MAIN_OFFSET(0x318C68 + 2), 10836 + 840);
|
||||
CMem::WriteUChar(MAIN_OFFSET(0x318C79), nMaxGrade);
|
||||
//CDataManager::GetSpAtLevelUp
|
||||
// CDataManager::GetSpAtLevelUp
|
||||
CMem::WriteUChar(MAIN_OFFSET(0x318CC4), nMaxGrade);
|
||||
CMem::WriteUInt(MAIN_OFFSET(0x318CD4 + 2), 10836 + 840);
|
||||
}
|
||||
@@ -625,19 +727,10 @@ void loga()
|
||||
CMem::WriteUChar(MAIN_OFFSET(0x622659), nMaxGrade);
|
||||
CMem::WriteUChar(MAIN_OFFSET(0x622941), nMaxGrade);
|
||||
CMem::WriteUChar(MAIN_OFFSET(0x622941), nMaxGrade);
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
void __attribute__((constructor)) my_init(void)
|
||||
void __attribute__((constructor)) lenheart_init(void)
|
||||
{
|
||||
//patchGame();
|
||||
loga();
|
||||
|
||||
Lenheart();
|
||||
}
|
||||
|
||||
|
||||
|
||||
237
src/dispatch.cpp
237
src/dispatch.cpp
@@ -8,18 +8,15 @@
|
||||
|
||||
#include "dispatch.h"
|
||||
|
||||
CDispatch::CDispatch() :
|
||||
last_move_map_tickcount(0)
|
||||
CDispatch::CDispatch() : last_move_map_tickcount(0)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
CDispatch::~CDispatch()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
ENUM_PACK_RET_TYPE CDispatch::UseEquipmentMoveItem(CUser* user, PacketBuf* pBuf)
|
||||
ENUM_PACK_RET_TYPE CDispatch::UseEquipmentMoveItem(CUser *user, PacketBuf *pBuf)
|
||||
{
|
||||
|
||||
if (user->get_state() != 3)
|
||||
@@ -34,41 +31,39 @@ ENUM_PACK_RET_TYPE CDispatch::UseEquipmentMoveItem(CUser* user, PacketBuf* pBuf)
|
||||
return PAK_IGNORE;
|
||||
}
|
||||
|
||||
LOG(u8"UseEquipmentMoveItem :%s ", Utils::ToHexString((const unsigned char*)pBuf->get_buf_ptr(0), 40).c_str());
|
||||
LOG(u8"UseEquipmentMoveItem :%s ", Utils::ToHexString((const unsigned char *)pBuf->get_buf_ptr(0), 40).c_str());
|
||||
|
||||
short equipment_pos = 0;
|
||||
int equipment_id = 0;
|
||||
short item_pos = 0;
|
||||
|
||||
if ((unsigned __int8)pBuf->get_short(&equipment_pos) != 1
|
||||
|| (unsigned __int8)pBuf->get_int(&equipment_id) != 1
|
||||
|| (unsigned __int8)pBuf->get_short(&item_pos) != 1)
|
||||
if ((unsigned __int8)pBuf->get_short(&equipment_pos) != 1 || (unsigned __int8)pBuf->get_int(&equipment_id) != 1 || (unsigned __int8)pBuf->get_short(&item_pos) != 1)
|
||||
{
|
||||
user->SendCmdErrorPacket(84, -1);
|
||||
return PAK_IGNORE;
|
||||
}
|
||||
|
||||
//1 物品栏 2 时装
|
||||
// 1 物品栏 2 时装
|
||||
if (user->CheckItemLock(1, equipment_pos))
|
||||
{
|
||||
user->SendCmdErrorPacket(84, 0xD5);
|
||||
return PAK_IGNORE;
|
||||
}
|
||||
|
||||
CInventory* invenR = user->getCurCharacInvenR();
|
||||
CInventory *invenR = user->getCurCharacInvenR();
|
||||
if (!invenR)
|
||||
{
|
||||
LOG(u8"user->getCurCharacInvenW : error \n");
|
||||
return PAK_IGNORE;
|
||||
}
|
||||
|
||||
Inven_Item* equipment_InvenRef = invenR->GetInvenRef(CInventory::INVENTORY_TYPE_ITEM, equipment_pos);
|
||||
Inven_Item *equipment_InvenRef = invenR->GetInvenRef(CInventory::INVENTORY_TYPE_ITEM, equipment_pos);
|
||||
if (!equipment_InvenRef)
|
||||
{
|
||||
LOG(u8"inven->GetInvenRef : error \n");
|
||||
return PAK_IGNORE;
|
||||
}
|
||||
Inven_Item* item_avartar = invenR->GetInvenRef(CInventory::INVENTORY_TYPE_ITEM, item_pos);
|
||||
Inven_Item *item_avartar = invenR->GetInvenRef(CInventory::INVENTORY_TYPE_ITEM, item_pos);
|
||||
if (!item_avartar)
|
||||
{
|
||||
LOG(u8"inven->GetInvenRef : error \n");
|
||||
@@ -95,7 +90,7 @@ ENUM_PACK_RET_TYPE CDispatch::UseEquipmentMoveItem(CUser* user, PacketBuf* pBuf)
|
||||
|
||||
int item_id = item_avartar->getKey();
|
||||
|
||||
CDataManager* DataManager = CDataManager::G_CDataManager();
|
||||
CDataManager *DataManager = CDataManager::G_CDataManager();
|
||||
|
||||
if (!DataManager)
|
||||
{
|
||||
@@ -103,11 +98,9 @@ ENUM_PACK_RET_TYPE CDispatch::UseEquipmentMoveItem(CUser* user, PacketBuf* pBuf)
|
||||
return PAK_IGNORE;
|
||||
}
|
||||
|
||||
CEquipItem* equipment_citem = (CEquipItem*)DataManager->find_item(equipment_id);
|
||||
CStackableItem* item_citem = (CStackableItem*)DataManager->find_item(item_id);
|
||||
LOG(u8"equipment_citem +12: %p"
|
||||
, *(int*)equipment_citem + 12
|
||||
);
|
||||
CEquipItem *equipment_citem = (CEquipItem *)DataManager->find_item(equipment_id);
|
||||
CStackableItem *item_citem = (CStackableItem *)DataManager->find_item(item_id);
|
||||
LOG(u8"equipment_citem +12: %p", *(int *)equipment_citem + 12);
|
||||
|
||||
if (!equipment_citem || !item_citem)
|
||||
{
|
||||
@@ -115,28 +108,17 @@ ENUM_PACK_RET_TYPE CDispatch::UseEquipmentMoveItem(CUser* user, PacketBuf* pBuf)
|
||||
return PAK_IGNORE;
|
||||
}
|
||||
|
||||
LOG(u8"UseEquipmentMoveItem [ equipment_pos:%d equipment_id:%d item_pos:%d item_id:%d ]"
|
||||
, equipment_pos
|
||||
, equipment_id
|
||||
, item_pos
|
||||
, item_id
|
||||
);
|
||||
LOG(u8"UseEquipmentMoveItem [ equipment_pos:%d equipment_id:%d item_pos:%d item_id:%d ]", equipment_pos, equipment_id, item_pos, item_id);
|
||||
|
||||
//Data: equipment_citem->GetItemType=147418664 item_citem->is_stackable=1 item_citem->GetItemType=11
|
||||
int equipment_Type = ((CEquipItem*)equipment_citem)->GetItemType();
|
||||
// Data: equipment_citem->GetItemType=147418664 item_citem->is_stackable=1 item_citem->GetItemType=11
|
||||
int equipment_Type = ((CEquipItem *)equipment_citem)->GetItemType();
|
||||
int rarity = equipment_citem->get_rarity();
|
||||
if (rarity != 4)
|
||||
{
|
||||
return PAK_OK;
|
||||
}
|
||||
|
||||
|
||||
LOG(u8"Data: equipment_citem->GetItemType=%d item_citem->is_stackable=%d item_citem->GetItemType=%d"
|
||||
, equipment_Type
|
||||
, item_citem->is_stackable()
|
||||
, item_citem->GetItemType()
|
||||
);
|
||||
|
||||
LOG(u8"Data: equipment_citem->GetItemType=%d item_citem->is_stackable=%d item_citem->GetItemType=%d", equipment_Type, item_citem->is_stackable(), item_citem->GetItemType());
|
||||
|
||||
if (equipment_Type <= 9 || equipment_Type > 21 || equipment_Type == 11)
|
||||
{
|
||||
@@ -149,17 +131,15 @@ ENUM_PACK_RET_TYPE CDispatch::UseEquipmentMoveItem(CUser* user, PacketBuf* pBuf)
|
||||
{
|
||||
LOG(u8"item_citem->is_stackable() != true || item_citem->GetItemType() != ITEM_TYPE_CONSUMABLES");
|
||||
|
||||
//没有镜像手机认证,无法使用该功能
|
||||
// 没有镜像手机认证,无法使用该功能
|
||||
user->SendCmdErrorPacket(205, 209);
|
||||
return PAK_IGNORE;
|
||||
}
|
||||
|
||||
|
||||
Inven_Item new_equipment_item = {};
|
||||
invenR->GetInvenSlot(&new_equipment_item, CInventory::INVENTORY_TYPE_ITEM, equipment_pos);
|
||||
|
||||
|
||||
int v9 = 0; //返回给客户端的错误码
|
||||
int v9 = 0; // 返回给客户端的错误码
|
||||
if (item_id == ITEM_ID_KUAJIESHI)
|
||||
{
|
||||
LOG(u8"user->CheckInTrade:%d", user->CheckInTrade());
|
||||
@@ -175,8 +155,7 @@ ENUM_PACK_RET_TYPE CDispatch::UseEquipmentMoveItem(CUser* user, PacketBuf* pBuf)
|
||||
}
|
||||
else
|
||||
{
|
||||
CAccountCargo* AccountCargo = user->GetAccountCargo();
|
||||
|
||||
CAccountCargo *AccountCargo = user->GetAccountCargo();
|
||||
|
||||
LOG(u8"ins_item.IsTradeLimitAttachTypeItem :%d", new_equipment_item.IsTradeLimitAttachTypeItem());
|
||||
LOG(u8"AccountCargo->CheckInsertCondition :%d", AccountCargo->CheckInsertCondition(&new_equipment_item));
|
||||
@@ -193,9 +172,9 @@ ENUM_PACK_RET_TYPE CDispatch::UseEquipmentMoveItem(CUser* user, PacketBuf* pBuf)
|
||||
}
|
||||
}
|
||||
LOG(u8"empty_slot :%d", empty_slot);
|
||||
//inven->delete_item(1, emblem_inven_slot, 1, 8, 1);
|
||||
// inven->delete_item(1, emblem_inven_slot, 1, 8, 1);
|
||||
auto invenW = user->getCurCharacInvenW();
|
||||
InterfacePacketBuf* packet_guard = (InterfacePacketBuf*)PacketGuard::NewPacketGuard();
|
||||
InterfacePacketBuf *packet_guard = (InterfacePacketBuf *)PacketGuard::NewPacketGuard();
|
||||
LOG("%p", invenW);
|
||||
if (invenW->delete_item(CInventory::INVENTORY_TYPE_ITEM, equipment_pos, 1, 37, 1) && invenW->delete_item(CInventory::INVENTORY_TYPE_ITEM, item_pos, 1, 37, 1))
|
||||
{
|
||||
@@ -207,8 +186,8 @@ ENUM_PACK_RET_TYPE CDispatch::UseEquipmentMoveItem(CUser* user, PacketBuf* pBuf)
|
||||
packet_guard->put_header(1, 2000);
|
||||
packet_guard->put_int(1);
|
||||
packet_guard->finalize(1);
|
||||
user->Send((PacketGuard*)packet_guard);
|
||||
PacketGuard::DelPacketGuard((PacketGuard*)packet_guard);
|
||||
user->Send((PacketGuard *)packet_guard);
|
||||
PacketGuard::DelPacketGuard((PacketGuard *)packet_guard);
|
||||
SendNoti(user, "已完成装备跨界");
|
||||
|
||||
return PAK_OK;
|
||||
@@ -218,8 +197,8 @@ ENUM_PACK_RET_TYPE CDispatch::UseEquipmentMoveItem(CUser* user, PacketBuf* pBuf)
|
||||
packet_guard->put_header(1, 2000);
|
||||
packet_guard->put_int(0);
|
||||
packet_guard->finalize(0);
|
||||
user->Send((PacketGuard*)packet_guard);
|
||||
PacketGuard::DelPacketGuard((PacketGuard*)packet_guard);
|
||||
user->Send((PacketGuard *)packet_guard);
|
||||
PacketGuard::DelPacketGuard((PacketGuard *)packet_guard);
|
||||
SendNoti(user, "装备跨界失败");
|
||||
}
|
||||
return PAK_IGNORE;
|
||||
@@ -233,10 +212,10 @@ ENUM_PACK_RET_TYPE CDispatch::UseEquipmentMoveItem(CUser* user, PacketBuf* pBuf)
|
||||
密钥Call (物品位置,2)
|
||||
发包Call ()
|
||||
*/
|
||||
return PAK_OK;
|
||||
return PAK_OK;
|
||||
}
|
||||
|
||||
ENUM_PACK_RET_TYPE CDispatch::Dispatcher_ModItemAttr_dispatch_sig(Dispatcher_ModItemAttr* dis_mod, CUser* user, PacketBuf* pBuf)
|
||||
ENUM_PACK_RET_TYPE CDispatch::Dispatcher_ModItemAttr_dispatch_sig(Dispatcher_ModItemAttr *dis_mod, CUser *user, PacketBuf *pBuf)
|
||||
{
|
||||
if (user->get_state() != 3 || !user->getCurCharacR())
|
||||
{
|
||||
@@ -247,15 +226,13 @@ ENUM_PACK_RET_TYPE CDispatch::Dispatcher_ModItemAttr_dispatch_sig(Dispatcher_Mod
|
||||
int equipment_id = 0;
|
||||
short item_pos = 0;
|
||||
|
||||
if ((unsigned __int8)pBuf->get_short(&equipment_pos) != 1
|
||||
|| (unsigned __int8)pBuf->get_int(&equipment_id) != 1
|
||||
|| (unsigned __int8)pBuf->get_short(&item_pos) != 1)
|
||||
if ((unsigned __int8)pBuf->get_short(&equipment_pos) != 1 || (unsigned __int8)pBuf->get_int(&equipment_id) != 1 || (unsigned __int8)pBuf->get_short(&item_pos) != 1)
|
||||
{
|
||||
user->SendCmdErrorPacket(84, -1);
|
||||
return PAK_IGNORE;
|
||||
}
|
||||
|
||||
auto CurCharacInvenW = (CInventory*)user->getCurCharacInvenW();
|
||||
auto CurCharacInvenW = (CInventory *)user->getCurCharacInvenW();
|
||||
Inven_Item equipment_inven = {};
|
||||
CurCharacInvenW->GetInvenSlot(&equipment_inven, CInventory::INVENTORY_TYPE_ITEM, equipment_pos);
|
||||
|
||||
@@ -264,12 +241,12 @@ ENUM_PACK_RET_TYPE CDispatch::Dispatcher_ModItemAttr_dispatch_sig(Dispatcher_Mod
|
||||
user->SendCmdErrorPacket(84, 4);
|
||||
return PAK_IGNORE;
|
||||
}
|
||||
CEquipItem* equipment_item = (CEquipItem*)CDataManager::G_CDataManager()->find_item(equipment_id);
|
||||
CEquipItem *equipment_item = (CEquipItem *)CDataManager::G_CDataManager()->find_item(equipment_id);
|
||||
|
||||
LOG("(*(int(**)(CItem*))(*(_DWORD*)equipment_item + 12)) :%p %p"
|
||||
|
||||
, (*(int(**)(CItem*))(*(_DWORD*)equipment_item + 12))
|
||||
, ((int(**)(CItem*))(*(_DWORD*)equipment_item + 12))
|
||||
,
|
||||
(*(int (**)(CItem *))(*(_DWORD *)equipment_item + 12)), ((int (**)(CItem *))(*(_DWORD *)equipment_item + 12))
|
||||
|
||||
);
|
||||
|
||||
@@ -307,8 +284,8 @@ ENUM_PACK_RET_TYPE CDispatch::Dispatcher_ModItemAttr_dispatch_sig(Dispatcher_Mod
|
||||
return PAK_IGNORE;
|
||||
}
|
||||
|
||||
int grade = equipment_item->get_grade(); //掉落等级
|
||||
int rarity = equipment_item->get_rarity(); //稀有
|
||||
int grade = equipment_item->get_grade(); // 掉落等级
|
||||
int rarity = equipment_item->get_rarity(); // 稀有
|
||||
int attach_type = equipment_item->GetAttachType();
|
||||
auto add_info = item_inven.get_add_info();
|
||||
|
||||
@@ -339,7 +316,7 @@ ENUM_PACK_RET_TYPE CDispatch::Dispatcher_ModItemAttr_dispatch_sig(Dispatcher_Mod
|
||||
return PAK_IGNORE;
|
||||
}
|
||||
|
||||
ENUM_PACK_RET_TYPE CDispatch::UseJewel_dispatch_sig(void* pDispatcher_UseJewel, CUser* user, PacketBuf* pBuf)
|
||||
ENUM_PACK_RET_TYPE CDispatch::UseJewel_dispatch_sig(void *pDispatcher_UseJewel, CUser *user, PacketBuf *pBuf)
|
||||
{
|
||||
printf("getCurCharacName :%s \n", user->getCurCharacName().c_str());
|
||||
printf("getCurCharacNo :%d \n", user->getCurCharacNo());
|
||||
@@ -349,22 +326,20 @@ ENUM_PACK_RET_TYPE CDispatch::UseJewel_dispatch_sig(void* pDispatcher_UseJewel,
|
||||
// printf("pBuf :%s \n", Util::ToHexString((const unsigned char*)pBuf->get_buf_ptr(0),40).c_str());
|
||||
int state = user->get_state();
|
||||
LOG("state :%d \n", state);
|
||||
//校验角色状态是否允许镶嵌
|
||||
// 校验角色状态是否允许镶嵌
|
||||
if (state != 3)
|
||||
return PAK_IGNORE;
|
||||
|
||||
int isEnableAvatarSocketAction = user->isEnableAvatarSocketAction();
|
||||
if (isEnableAvatarSocketAction)
|
||||
user->SendCmdErrorPacket(205, (unsigned char)isEnableAvatarSocketAction);
|
||||
//解析packet_buf
|
||||
// 解析packet_buf
|
||||
|
||||
short avartar_inven_slot = 0; //时装所在的背包槽
|
||||
int avartar_item_id = 0; //时装item_id
|
||||
char emblem_cnt = 0; //本次镶嵌徽章数量
|
||||
short avartar_inven_slot = 0; // 时装所在的背包槽
|
||||
int avartar_item_id = 0; // 时装item_id
|
||||
char emblem_cnt = 0; // 本次镶嵌徽章数量
|
||||
|
||||
if ((unsigned __int8)pBuf->get_short(&avartar_inven_slot) != 1
|
||||
|| (unsigned __int8)pBuf->get_int(&avartar_item_id) != 1
|
||||
|| (unsigned __int8)pBuf->get_byte(&emblem_cnt) != 1)
|
||||
if ((unsigned __int8)pBuf->get_short(&avartar_inven_slot) != 1 || (unsigned __int8)pBuf->get_int(&avartar_item_id) != 1 || (unsigned __int8)pBuf->get_byte(&emblem_cnt) != 1)
|
||||
{
|
||||
user->SendCmdErrorPacket(205, -1);
|
||||
return PAK_IGNORE;
|
||||
@@ -376,31 +351,31 @@ ENUM_PACK_RET_TYPE CDispatch::UseJewel_dispatch_sig(void* pDispatcher_UseJewel,
|
||||
return PAK_IGNORE;
|
||||
}
|
||||
|
||||
//获取时装道具
|
||||
CInventory* CurCharacInvenW = user->getCurCharacInvenW();
|
||||
// 获取时装道具
|
||||
CInventory *CurCharacInvenW = user->getCurCharacInvenW();
|
||||
if (!CurCharacInvenW)
|
||||
{
|
||||
LOG("pUser->getCurCharacInvenW : error \n");
|
||||
return PAK_IGNORE;
|
||||
}
|
||||
Inven_Item* avartar_inven_item = CurCharacInvenW->GetInvenRef(CInventory::INVENTORY_TYPE_AVARTAR, avartar_inven_slot);
|
||||
Inven_Item *avartar_inven_item = CurCharacInvenW->GetInvenRef(CInventory::INVENTORY_TYPE_AVARTAR, avartar_inven_slot);
|
||||
if (!avartar_inven_item)
|
||||
{
|
||||
LOG("inven->GetInvenRef : error \n");
|
||||
return PAK_IGNORE;
|
||||
}
|
||||
//校验时装 数据是否合法
|
||||
// 校验时装 数据是否合法
|
||||
if (avartar_inven_item->isEmpty() || (avartar_inven_item->getKey() != avartar_item_id) || user->CheckItemLock(2, avartar_inven_slot))
|
||||
{
|
||||
|
||||
LOG("avartar->isEmpty() || avartar->getKey() || pUser->CheckItemLock() : error \n");
|
||||
return PAK_IGNORE;
|
||||
}
|
||||
//获取时装插槽数据
|
||||
// 获取时装插槽数据
|
||||
auto avartar_add_info = avartar_inven_item->get_add_info();
|
||||
auto inven_avartar_mgr = (WongWork::CAvatarItemMgr*)CurCharacInvenW->GetAvatarItemMgrW();
|
||||
auto inven_avartar_mgr = (WongWork::CAvatarItemMgr *)CurCharacInvenW->GetAvatarItemMgrW();
|
||||
|
||||
stAvatarEmblemInfo_t* JewelSocketData = (stAvatarEmblemInfo_t*)inven_avartar_mgr->getJewelSocketData(avartar_add_info);
|
||||
stAvatarEmblemInfo_t *JewelSocketData = (stAvatarEmblemInfo_t *)inven_avartar_mgr->getJewelSocketData(avartar_add_info);
|
||||
|
||||
if (!JewelSocketData)
|
||||
{
|
||||
@@ -408,27 +383,27 @@ ENUM_PACK_RET_TYPE CDispatch::UseJewel_dispatch_sig(void* pDispatcher_UseJewel,
|
||||
return PAK_IGNORE;
|
||||
}
|
||||
|
||||
LOG("jewel_socket_data 1:%s \n", Utils::ToHexString((const unsigned char*)JewelSocketData, 30).c_str());
|
||||
LOG("jewel_socket_data 1:%s \n", Utils::ToHexString((const unsigned char *)JewelSocketData, 30).c_str());
|
||||
if (emblem_cnt <= 3)
|
||||
{
|
||||
std::map<int, std::pair<int, int>> emblems;
|
||||
for (int i = 0; i < emblem_cnt; i++)
|
||||
{
|
||||
//徽章所在的背包槽
|
||||
// 徽章所在的背包槽
|
||||
short emblem_inven_slot = 0;
|
||||
pBuf->get_short(&emblem_inven_slot);
|
||||
//徽章item_id
|
||||
// 徽章item_id
|
||||
int emblem_item_id = 0;
|
||||
pBuf->get_int(&emblem_item_id);
|
||||
//该徽章镶嵌的时装插槽id
|
||||
// 该徽章镶嵌的时装插槽id
|
||||
char avartar_socket_slot = 0;
|
||||
pBuf->get_byte(&avartar_socket_slot);
|
||||
|
||||
LOG("emblem_inven_slot :%d emblem_item_id :%d avartar_socket_slot :%d", emblem_inven_slot, emblem_item_id, avartar_socket_slot);
|
||||
|
||||
//获取徽章道具
|
||||
Inven_Item* emblem = CurCharacInvenW->GetInvenRef(CInventory::INVENTORY_TYPE_ITEM, emblem_inven_slot);
|
||||
//校验徽章及插槽数据是否合法
|
||||
// 获取徽章道具
|
||||
Inven_Item *emblem = CurCharacInvenW->GetInvenRef(CInventory::INVENTORY_TYPE_ITEM, emblem_inven_slot);
|
||||
// 校验徽章及插槽数据是否合法
|
||||
if (emblem->isEmpty() || (emblem->getKey() != emblem_item_id) || (avartar_socket_slot >= 3))
|
||||
{
|
||||
LOG("emblem->isEmpty() || (emblem->getKey() : error \n");
|
||||
@@ -436,17 +411,17 @@ ENUM_PACK_RET_TYPE CDispatch::UseJewel_dispatch_sig(void* pDispatcher_UseJewel,
|
||||
return PAK_IGNORE;
|
||||
}
|
||||
|
||||
//校验徽章是否满足时装插槽颜色要求
|
||||
// 校验徽章是否满足时装插槽颜色要求
|
||||
|
||||
//获取徽章pvf数据
|
||||
CDataManager* DataManager = CDataManager::G_CDataManager();
|
||||
// 获取徽章pvf数据
|
||||
CDataManager *DataManager = CDataManager::G_CDataManager();
|
||||
if (!DataManager)
|
||||
{
|
||||
LOG("CDataManager::G_CDataManager() : error \n");
|
||||
user->SendCmdErrorPacket(205, 209);
|
||||
return PAK_IGNORE;
|
||||
}
|
||||
CStackableItem* citem = (CStackableItem*)DataManager->find_item(emblem_item_id);
|
||||
CStackableItem *citem = (CStackableItem *)DataManager->find_item(emblem_item_id);
|
||||
if (!citem)
|
||||
{
|
||||
LOG("DataManager->find_item() : error \n");
|
||||
@@ -454,7 +429,7 @@ ENUM_PACK_RET_TYPE CDispatch::UseJewel_dispatch_sig(void* pDispatcher_UseJewel,
|
||||
return PAK_IGNORE;
|
||||
}
|
||||
|
||||
//校验徽章类型
|
||||
// 校验徽章类型
|
||||
if (!citem->is_stackable() || (citem->GetItemType() != 20))
|
||||
{
|
||||
LOG("citem->is_stackable() || (citem->GetItemType() : error \n");
|
||||
@@ -462,21 +437,19 @@ ENUM_PACK_RET_TYPE CDispatch::UseJewel_dispatch_sig(void* pDispatcher_UseJewel,
|
||||
return PAK_IGNORE;
|
||||
}
|
||||
|
||||
//获取徽章支持的插槽
|
||||
// 获取徽章支持的插槽
|
||||
int emblem_socket_type = citem->getJewelTargetSocket();
|
||||
|
||||
//01 00 C4 25 26 00 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
|
||||
//获取要镶嵌的时装插槽类型
|
||||
// 01 00 C4 25 26 00 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
|
||||
// 获取要镶嵌的时装插槽类型
|
||||
|
||||
sizeof(stAvatarEmblemInfo_t);
|
||||
|
||||
|
||||
|
||||
int avartar_socket_type = JewelSocketData->EmblemSocketData[avartar_socket_slot].slot_type;
|
||||
LOG("emblem_socket_type :%d avartar_socket_type :%d", emblem_socket_type, avartar_socket_type);
|
||||
if (!(emblem_socket_type & avartar_socket_type))
|
||||
{
|
||||
//插槽类型不匹配
|
||||
// 插槽类型不匹配
|
||||
LOG("emblem_socket_type & avartar_socket_type\n");
|
||||
user->SendCmdErrorPacket(205, 209);
|
||||
return PAK_IGNORE;
|
||||
@@ -490,30 +463,29 @@ ENUM_PACK_RET_TYPE CDispatch::UseJewel_dispatch_sig(void* pDispatcher_UseJewel,
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
LOG("jewel_socket_data 2:%s \n", Utils::ToHexString((const unsigned char*)JewelSocketData, 30).c_str());
|
||||
LOG("jewel_socket_data 2:%s \n", Utils::ToHexString((const unsigned char *)JewelSocketData, 30).c_str());
|
||||
|
||||
inven_avartar_mgr->setEmblemSocketData(avartar_add_info, JewelSocketData);
|
||||
//时装插槽数据存档
|
||||
DB_UpdateAvatarJewelSlot::makeRequest(user->getCurCharacNo(), (unsigned int)avartar_add_info, (void*)JewelSocketData);
|
||||
// 时装插槽数据存档
|
||||
DB_UpdateAvatarJewelSlot::makeRequest(user->getCurCharacNo(), (unsigned int)avartar_add_info, (void *)JewelSocketData);
|
||||
|
||||
//通知客户端时装数据已更新
|
||||
// 通知客户端时装数据已更新
|
||||
user->SendUpdateItemList(1, 1, avartar_inven_slot);
|
||||
//回包给客户端
|
||||
InterfacePacketBuf* packet_guard = (InterfacePacketBuf*)PacketGuard::NewPacketGuard();
|
||||
// 回包给客户端
|
||||
InterfacePacketBuf *packet_guard = (InterfacePacketBuf *)PacketGuard::NewPacketGuard();
|
||||
|
||||
packet_guard->put_header(1, 204);
|
||||
packet_guard->put_int(1);
|
||||
packet_guard->finalize(1);
|
||||
user->Send((PacketGuard*)packet_guard);
|
||||
PacketGuard::DelPacketGuard((PacketGuard*)packet_guard);
|
||||
user->Send((PacketGuard *)packet_guard);
|
||||
PacketGuard::DelPacketGuard((PacketGuard *)packet_guard);
|
||||
SendNoti(user, "已完成徽章镶嵌");
|
||||
return PAK_OK;
|
||||
}
|
||||
return PAK_IGNORE;
|
||||
}
|
||||
|
||||
ENUM_PACK_RET_TYPE CDispatch::MoveMap_dispatch_sig(void* a1, CUser* user, PacketBuf* pBuf)
|
||||
ENUM_PACK_RET_TYPE CDispatch::MoveMap_dispatch_sig(void *a1, CUser *user, PacketBuf *pBuf)
|
||||
{
|
||||
USER_DATA data;
|
||||
if (user_map.Find(user, &data))
|
||||
@@ -531,7 +503,7 @@ ENUM_PACK_RET_TYPE CDispatch::MoveMap_dispatch_sig(void* a1, CUser* user, Packet
|
||||
|
||||
user_map.Change(user, data);
|
||||
|
||||
//判断异常次数是否大于等于3
|
||||
// 判断异常次数是否大于等于3
|
||||
if (data.abnormal_data_count >= 3)
|
||||
{
|
||||
return PAK_ERROR;
|
||||
@@ -540,7 +512,7 @@ ENUM_PACK_RET_TYPE CDispatch::MoveMap_dispatch_sig(void* a1, CUser* user, Packet
|
||||
return PAK_OK;
|
||||
}
|
||||
|
||||
ENUM_PACK_RET_TYPE CDispatch::Inter_LoadEtc_dispatch_sig(void* a1, CUser* user, char* a3)
|
||||
ENUM_PACK_RET_TYPE CDispatch::Inter_LoadEtc_dispatch_sig(void *a1, CUser *user, char *a3)
|
||||
{
|
||||
user->getCurCharacNo();
|
||||
user->getCurCharacName();
|
||||
@@ -549,17 +521,17 @@ ENUM_PACK_RET_TYPE CDispatch::Inter_LoadEtc_dispatch_sig(void* a1, CUser* user,
|
||||
return PAK_OK;
|
||||
}
|
||||
|
||||
ENUM_PACK_RET_TYPE CDispatch::DisPatcher_ReturnToSelectCharacter_dispatch_sig(void* a1, CUser* user, char* a3)
|
||||
ENUM_PACK_RET_TYPE CDispatch::DisPatcher_ReturnToSelectCharacter_dispatch_sig(void *a1, CUser *user, char *a3)
|
||||
{
|
||||
|
||||
user_map.Erase(user);
|
||||
return PAK_OK;
|
||||
}
|
||||
|
||||
ENUM_PACK_RET_TYPE CDispatch::ProcessIPG_ResultOutput(CUser* user, int Goods_No, int item_id, int Cera_Type, InterfacePacketBuf* pbuf)
|
||||
ENUM_PACK_RET_TYPE CDispatch::ProcessIPG_ResultOutput(CUser *user, int Goods_No, int item_id, int Cera_Type, InterfacePacketBuf *pbuf)
|
||||
{
|
||||
|
||||
if (Cera_Type == 0) //0是点券 1是代币
|
||||
if (Cera_Type == 0) // 0是点券 1是代币
|
||||
{
|
||||
CeraShopBonusCodeType cera_shop_bonus_code_;
|
||||
if (CGameDataManager::Get()->is_cera_shop_bonus_code(Goods_No, &cera_shop_bonus_code_))
|
||||
@@ -596,33 +568,31 @@ ENUM_PACK_RET_TYPE CDispatch::ProcessIPG_ResultOutput(CUser* user, int Goods_No,
|
||||
auto item = CDataManager::G_CDataManager()->find_item(BonusItem.item_id);
|
||||
if (item)
|
||||
{
|
||||
//if (item->is_stackable()
|
||||
// if (item->is_stackable()
|
||||
// && ((*(int(**)(CItem*))(*(_DWORD*)item + 12))(item) == 16 // GetItemType
|
||||
// || (*(int(**)(CItem*))(*(_DWORD*)item + 12))(item) == 34)) // GetItemType
|
||||
{
|
||||
int inserted = -1;
|
||||
Inven_Item v60 = {};
|
||||
*(_DWORD*)((char*)&v60 + 2) = BonusItem.item_id;
|
||||
*(_DWORD*)((char*)&v60 + 7) = BonusItem.item_num;
|
||||
*(_DWORD *)((char *)&v60 + 2) = BonusItem.item_id;
|
||||
*(_DWORD *)((char *)&v60 + 7) = BonusItem.item_num;
|
||||
|
||||
(*(void(**)(CItem*, Inven_Item*))(*(_DWORD*)item + 8))(item, &v60);
|
||||
(*(void (**)(CItem *, Inven_Item *))(*(_DWORD *)item + 8))(item, &v60);
|
||||
|
||||
auto CurCharacInvenW = user->getCurCharacInvenW();
|
||||
auto CurCharacInvenW = user->getCurCharacInvenW();
|
||||
|
||||
inserted = CurCharacInvenW->insertItemIntoInventory(v60, 15, 1, 0);
|
||||
if (inserted == -1)
|
||||
{
|
||||
auto CurCharacNo = user->getCurCharacNo();
|
||||
|
||||
((WongWork::CMailBoxHelper*)(user))->ReqDBSendNewMailCashShop(&v60, 0, CurCharacNo, 1, 0, 0);
|
||||
|
||||
((WongWork::CMailBoxHelper *)(user))->ReqDBSendNewMailCashShop(&v60, 0, CurCharacNo, 1, 0, 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
user->SendUpdateItemList(1, 0, inserted);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -630,34 +600,32 @@ ENUM_PACK_RET_TYPE CDispatch::ProcessIPG_ResultOutput(CUser* user, int Goods_No,
|
||||
pbuf->put_int(BonusItem.item_id);
|
||||
pbuf->put_int(BonusItem.item_num);
|
||||
|
||||
std::vector <unsigned char> code;
|
||||
std::vector<unsigned char> code;
|
||||
for (int i = 0; i < 0x30; i++)
|
||||
{
|
||||
code.push_back(0x90);
|
||||
}
|
||||
//0817964F 0817967F
|
||||
CMem::WriteBytes((void*)0x0817964F, code.data(), code.size());
|
||||
// 0817964F 0817967F
|
||||
CMem::WriteBytes((void *)0x0817964F, code.data(), code.size());
|
||||
return PAK_OK;
|
||||
}
|
||||
}
|
||||
IPG_END:
|
||||
std::vector <unsigned char> code = {
|
||||
0x8B, 0x85, 0x04, 0xFF, 0xFF, 0xFF, 0x89, 0x44, 0x24, 0x04, 0x8D, 0x85, 0x14, 0xFF, 0xFF, 0xFF,
|
||||
0x89, 0x04, 0x24, 0xE8, 0xD5, 0x22, 0xF5, 0xFF, 0x8B, 0x85, 0x00, 0xFF, 0xFF, 0xFF, 0x89, 0x44,
|
||||
0x24, 0x04, 0x8D, 0x85, 0x14, 0xFF, 0xFF, 0xFF, 0x89, 0x04, 0x24, 0xE8, 0xBD, 0x22, 0xF5, 0xFF
|
||||
};
|
||||
CMem::WriteBytes((void*)0x0817964F, code.data(), code.size());
|
||||
std::vector<unsigned char> code = {
|
||||
0x8B, 0x85, 0x04, 0xFF, 0xFF, 0xFF, 0x89, 0x44, 0x24, 0x04, 0x8D, 0x85, 0x14, 0xFF, 0xFF, 0xFF,
|
||||
0x89, 0x04, 0x24, 0xE8, 0xD5, 0x22, 0xF5, 0xFF, 0x8B, 0x85, 0x00, 0xFF, 0xFF, 0xFF, 0x89, 0x44,
|
||||
0x24, 0x04, 0x8D, 0x85, 0x14, 0xFF, 0xFF, 0xFF, 0x89, 0x04, 0x24, 0xE8, 0xBD, 0x22, 0xF5, 0xFF};
|
||||
CMem::WriteBytes((void *)0x0817964F, code.data(), code.size());
|
||||
return PAK_OK;
|
||||
}
|
||||
|
||||
ENUM_PACK_RET_TYPE CDispatch::Init_done(int argc, const char** argv)
|
||||
ENUM_PACK_RET_TYPE CDispatch::Init_done(int argc, const char **argv)
|
||||
{
|
||||
|
||||
|
||||
return PAK_OK;
|
||||
}
|
||||
|
||||
ENUM_PACK_RET_TYPE CDispatch::importCashShopItemList(const std::string* str)
|
||||
ENUM_PACK_RET_TYPE CDispatch::importCashShopItemList(const std::string *str)
|
||||
{
|
||||
/**
|
||||
|
||||
@@ -698,7 +666,7 @@ ENUM_PACK_RET_TYPE CDispatch::importCashShopItemList(const std::string* str)
|
||||
int is_random = ScanInt();
|
||||
if (is_random == 1)
|
||||
{
|
||||
CGameDataManager::Get()->get_cera_shop_bonus_item_map_rand()->Push(index_, { item_id, item_num, true });
|
||||
CGameDataManager::Get()->get_cera_shop_bonus_item_map_rand()->Push(index_, {item_id, item_num, true});
|
||||
}
|
||||
CGameDataManager::Get()->add_cera_shop_bonus_item(index_, item_id, item_num, is_random);
|
||||
}
|
||||
@@ -706,25 +674,24 @@ ENUM_PACK_RET_TYPE CDispatch::importCashShopItemList(const std::string* str)
|
||||
return PAK_OK;
|
||||
}
|
||||
|
||||
void CDispatch::SendMsg(CUser* user, int pack_id, int status, const std::string& str)
|
||||
void CDispatch::SendMsg(CUser *user, int pack_id, int status, const std::string &str)
|
||||
{
|
||||
char out_str[0xff] = {};
|
||||
memset(out_str, 0, sizeof(out_str));
|
||||
DNFFLib::ConvertGBKtoUTF8((char*)str.c_str(), out_str);
|
||||
InterfacePacketBuf* packet_guard = (InterfacePacketBuf*)PacketGuard::NewPacketGuard();
|
||||
DNFFLib::ConvertGBKtoUTF8((char *)str.c_str(), out_str);
|
||||
InterfacePacketBuf *packet_guard = (InterfacePacketBuf *)PacketGuard::NewPacketGuard();
|
||||
packet_guard->put_header(1, pack_id);
|
||||
packet_guard->put_int(status);
|
||||
packet_guard->put_int(strlen(out_str));
|
||||
packet_guard->put_str(out_str, strlen(out_str));
|
||||
user->Send((PacketGuard*)packet_guard);
|
||||
PacketGuard::DelPacketGuard((PacketGuard*)packet_guard);
|
||||
user->Send((PacketGuard *)packet_guard);
|
||||
PacketGuard::DelPacketGuard((PacketGuard *)packet_guard);
|
||||
}
|
||||
|
||||
void CDispatch::SendNoti(CUser* user, const std::string& str, NOTI_PACKETMESSAGE_TYPE type)
|
||||
void CDispatch::SendNoti(CUser *user, const std::string &str, NOTI_PACKETMESSAGE_TYPE type)
|
||||
{
|
||||
char out_str[0xff] = {};
|
||||
memset(out_str, 0, sizeof(out_str));
|
||||
DNFFLib::ConvertGBKtoUTF8((char*)str.c_str(), out_str);
|
||||
DNFFLib::ConvertGBKtoUTF8((char *)str.c_str(), out_str);
|
||||
user->SendNotiPacketMessage(out_str, type);
|
||||
}
|
||||
|
||||
|
||||
83
src/import.h
83
src/import.h
@@ -1,3 +1,4 @@
|
||||
#pragma once
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <fcntl.h>
|
||||
@@ -5,66 +6,90 @@
|
||||
#include <execinfo.h>
|
||||
#include <elf.h>
|
||||
|
||||
|
||||
#define PADALIGN(x,mask) ((x+mask)&(~(x%mask)))
|
||||
#define PADALIGN(x, mask) ((x + mask) & (~(x % mask)))
|
||||
|
||||
#define Ver 1
|
||||
#define Patch 2
|
||||
|
||||
__BEGIN_DECLS
|
||||
|
||||
typedef int(*fnPacketGuard)(void *pInst);
|
||||
typedef int (*fnPacketGuard)(void *pInst);
|
||||
|
||||
typedef int(*fnaddServerHackCnt)(void *pCHackAnalyzer, void *pCUserCharacInfo, int HackType, int Cnt, int a5, int a6);
|
||||
typedef int (*fnaddServerHackCnt)(void *pCHackAnalyzer, void *pCUserCharacInfo, int HackType, int Cnt, int a5, int a6);
|
||||
|
||||
typedef int(*fnParsing)(void *pUser, int nSize);
|
||||
typedef int (*fnParsing)(void *pUser, int nSize);
|
||||
|
||||
typedef int(*fnput_header)(void *pInterfacePacketBuf, int Type, int Cmd);
|
||||
typedef int (*fnput_header)(void *pInterfacePacketBuf, int Type, int Cmd);
|
||||
|
||||
typedef int(*fnIsRoutingItem)(void *pItem);
|
||||
typedef void (*fnLeninsert_user)(void *Area, void *CUser);
|
||||
|
||||
typedef int(*fnsetCharacInfoDetail)(void *pUser, int a2, int a3, void *pCHARAC_DATA);
|
||||
typedef void (*fnLenGameWorld_move_position)(void *GameWorld, void *CUser, int a3, int a4, int a5, short a6);
|
||||
|
||||
typedef void* (*fnGetVectorUserCharacInfo)(void *pUser, int a2);
|
||||
typedef int (*fnLenGetTimerMess)(void *TimerQueue, void *TimerEntry);
|
||||
|
||||
typedef int(*fnIsGameMasterMode)(void *pUser);
|
||||
typedef int (*fnLengetareauseridlist)(int a1, int a2);
|
||||
|
||||
typedef int(*fnisGMUser)(void *pUser);
|
||||
typedef int (*fnInter_LoadGeolocation_dispatch_sig)(void *A, void *B, char *C);
|
||||
|
||||
typedef int(*fnGetPvPTeamCount)(void *pDataManager);
|
||||
typedef int (*fnLenDispatcher_New_Gmdebug_Command)(void *Command, void *CUser, void *PacketBuf);
|
||||
|
||||
typedef int(*fnisGM)(void *pGMAccounts, unsigned int a2);
|
||||
typedef int (*fnIsRoutingItem)(void *pItem);
|
||||
|
||||
typedef int(*fnisGM1)(void *pGM_Manager);
|
||||
typedef int (*fnsetCharacInfoDetail)(void *pUser, int a2, int a3, void *pCHARAC_DATA);
|
||||
|
||||
typedef void* (*fnset_add_info)(void *pInven_Item, int a2);
|
||||
typedef void *(*fnGetVectorUserCharacInfo)(void *pUser, int a2);
|
||||
|
||||
typedef int(*fndoDispatch)(void *pPacketDispatcher, void *pUser, int a3, int a4, void *src, int a6, int a7, int a8);
|
||||
typedef int (*fnIsGameMasterMode)(void *pUser);
|
||||
|
||||
typedef void** (*fnget_dispatcher)(void *pPacketDispatcher, int a2);
|
||||
typedef int (*fnisGMUser)(void *pUser);
|
||||
|
||||
typedef int(*fnisSocketAvatar)(void *pAvatarItemMgr1, void *pAvatarItemMgr2);
|
||||
typedef int (*fnGetPvPTeamCount)(void *pDataManager);
|
||||
|
||||
typedef int(*fndispatch_template)(void *pInst, void *pUser, void *pPacketBuf);
|
||||
typedef int (*fnisGM)(void *pGMAccounts, unsigned int a2);
|
||||
|
||||
typedef int(*fnreach_game_world)(void *pThis, void *a2);
|
||||
typedef int (*fnisGM1)(void *pGM_Manager);
|
||||
|
||||
typedef int(*fnInter_LoadEtc_dispatch_sig)(void *pThis, void * pUser, char*a3);
|
||||
typedef void *(*fnset_add_info)(void *pInven_Item, int a2);
|
||||
|
||||
typedef int(* CUserCharacInfo_getCurCharacNo)(void* pUser);
|
||||
typedef int (*fndoDispatch)(void *pPacketDispatcher, void *pUser, int a3, int a4, void *src, int a6, int a7, int a8);
|
||||
|
||||
typedef char*(* CUserCharacInfo_getCurCharacName)(void* pUser);
|
||||
typedef void **(*fnget_dispatcher)(void *pPacketDispatcher, int a2);
|
||||
|
||||
typedef int(*fnselect) (int __nfds, fd_set *__restrict __readfds,
|
||||
fd_set *__restrict __writefds,
|
||||
fd_set *__restrict __exceptfds,
|
||||
struct timeval *__restrict __timeout);
|
||||
typedef int (*fnisSocketAvatar)(void *pAvatarItemMgr1, void *pAvatarItemMgr2);
|
||||
|
||||
typedef int(*fnusleep) (__useconds_t __useconds);
|
||||
typedef int (*fndispatch_template)(void *pInst, void *pUser, void *pPacketBuf);
|
||||
|
||||
typedef void* (*fnmalloc) (size_t __size);
|
||||
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);
|
||||
|
||||
// 发送邮件
|
||||
typedef int (*fnReqDBSendNewSystemMultiMail)(char *src, int a2, unsigned int a3, int a4, int a5, char *a6, int a7, int a8, int a9, char a10);
|
||||
|
||||
// 发送道具
|
||||
typedef int (*fnAddItem)(void *CUser, int a2, int a3, int a4, int *a5, int a6);
|
||||
|
||||
// 首次创建角色送契约
|
||||
typedef int (*fnInterSelectMobileAuthReward)(void *InterSelect, void *CUser, char *a3);
|
||||
|
||||
// 创建角色创建技能
|
||||
typedef int (*fnCreateSkill)(int a1, int a2);
|
||||
// 创建角色创建装备
|
||||
typedef int (*fnCreateEquip)(void *a1, unsigned int a2, void *a3);
|
||||
|
||||
typedef int (*fnInitSkill)(int a1, int a2, int a3);
|
||||
|
||||
__END_DECLS
|
||||
@@ -9,13 +9,14 @@
|
||||
#include <map>
|
||||
#include <list>
|
||||
|
||||
#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)))
|
||||
#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 {
|
||||
enum flags
|
||||
{
|
||||
MODRM = 1,
|
||||
PLUS_R = 1 << 1,
|
||||
REG_OPCODE = 1 << 2,
|
||||
@@ -24,7 +25,8 @@ enum flags {
|
||||
IMM32 = 1 << 5,
|
||||
RELOC = 1 << 6
|
||||
};
|
||||
struct opcode_info {
|
||||
struct opcode_info
|
||||
{
|
||||
unsigned char opcode;
|
||||
unsigned char reg_opcode;
|
||||
unsigned int flags;
|
||||
@@ -36,171 +38,190 @@ static unsigned char prefixes[] = {
|
||||
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 }
|
||||
};
|
||||
/* 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)
|
||||
static size_t GetCodeLen(void *Addr)
|
||||
{
|
||||
unsigned char* code = (unsigned char*)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]) {
|
||||
for (i = 0; i < sizeof(prefixes); i++)
|
||||
{
|
||||
if (code[len] == prefixes[i])
|
||||
{
|
||||
len++;
|
||||
if (prefixes[i] == 0x66) {
|
||||
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) {
|
||||
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 {
|
||||
else
|
||||
{
|
||||
found_opcode = true;
|
||||
}
|
||||
}
|
||||
|
||||
if ((opcodes[i].flags & PLUS_R) && (code[len] & 0xF8) == opcodes[i].opcode) {
|
||||
if ((opcodes[i].flags & PLUS_R) && (code[len] & 0xF8) == opcodes[i].opcode)
|
||||
{
|
||||
found_opcode = true;
|
||||
}
|
||||
|
||||
if (found_opcode) {
|
||||
if (found_opcode)
|
||||
{
|
||||
len++;
|
||||
//opcode = code[len++];
|
||||
// opcode = code[len++];
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!found_opcode) {
|
||||
if (!found_opcode)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (opcodes[i].flags & MODRM) {
|
||||
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) {
|
||||
if (mod != 3 && rm == 4)
|
||||
{
|
||||
uint8_t sib = code[len++]; /* +1 for SIB byte */
|
||||
uint8_t base = sib & 7;
|
||||
|
||||
if (base == 5) {
|
||||
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) {
|
||||
* Otherwise, disp8 or disp32 + [EBP].
|
||||
*/
|
||||
if (mod == 1)
|
||||
{
|
||||
len += 1; /* for disp8 */
|
||||
}
|
||||
else {
|
||||
else
|
||||
{
|
||||
len += 4; /* for disp32 */
|
||||
}
|
||||
}
|
||||
}
|
||||
if (mod == 1) {
|
||||
if (mod == 1)
|
||||
{
|
||||
len += 1; /* for disp8 */
|
||||
}
|
||||
if (mod == 2 || (mod == 0 && rm == 5)) {
|
||||
if (mod == 2 || (mod == 0 && rm == 5))
|
||||
{
|
||||
len += 4; /* for disp32 */
|
||||
}
|
||||
}
|
||||
|
||||
if (opcodes[i].flags & IMM8) {
|
||||
if (opcodes[i].flags & IMM8)
|
||||
{
|
||||
len += 1;
|
||||
}
|
||||
if (opcodes[i].flags & IMM16) {
|
||||
if (opcodes[i].flags & IMM16)
|
||||
{
|
||||
len += 2;
|
||||
}
|
||||
if (opcodes[i].flags & IMM32) {
|
||||
if (opcodes[i].flags & IMM32)
|
||||
{
|
||||
len += operand_size;
|
||||
}
|
||||
|
||||
@@ -212,14 +233,16 @@ class CMemPool
|
||||
{
|
||||
private:
|
||||
size_t SysPageSize;
|
||||
void* MemPool;
|
||||
std::map<void*, size_t> AllocMap;
|
||||
std::map<void*, size_t> FreeMap;
|
||||
void *MemPool;
|
||||
std::map<void *, size_t> AllocMap;
|
||||
std::map<void *, size_t> FreeMap;
|
||||
|
||||
public:
|
||||
static CMemPool* GetInstance()
|
||||
static CMemPool *GetInstance()
|
||||
{
|
||||
static CMemPool* pInst = NULL;
|
||||
if (!pInst)pInst = new CMemPool();
|
||||
static CMemPool *pInst = NULL;
|
||||
if (!pInst)
|
||||
pInst = new CMemPool();
|
||||
return pInst;
|
||||
}
|
||||
CMemPool()
|
||||
@@ -234,28 +257,28 @@ public:
|
||||
{
|
||||
munmap(MemPool, SysPageSize * 10);
|
||||
}
|
||||
bool SetPageProtect(void* Address, int Protect)
|
||||
bool SetPageProtect(void *Address, int Protect)
|
||||
{
|
||||
return SetAddressProtect(Addr_Align(Address, SysPageSize), SysPageSize, Protect);
|
||||
}
|
||||
static bool SetAddressProtect(void* Address, size_t Size, int 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)
|
||||
static void MakeJmp(void *Src, void *Dst, int nNop = 0)
|
||||
{
|
||||
unsigned char* code = (unsigned char*)Src;
|
||||
unsigned char *code = (unsigned char *)Src;
|
||||
code[0] = '\xE9';
|
||||
*((unsigned long*)&code[1]) = (unsigned long)Dst - (unsigned long)&code[1] - 4;
|
||||
*((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 *alloc(size_t _size)
|
||||
{
|
||||
void* pBuf = NULL;
|
||||
for (std::map<void*, size_t>::iterator iter = FreeMap.begin(); iter != FreeMap.end(); iter++)
|
||||
void *pBuf = NULL;
|
||||
for (std::map<void *, size_t>::iterator iter = FreeMap.begin(); iter != FreeMap.end(); iter++)
|
||||
{
|
||||
if (iter->second >= _size)
|
||||
{
|
||||
@@ -271,7 +294,7 @@ public:
|
||||
}
|
||||
return pBuf;
|
||||
}
|
||||
void free(void* _ptr)
|
||||
void free(void *_ptr)
|
||||
{
|
||||
size_t _size = AllocMap[_ptr];
|
||||
AllocMap.erase(_ptr);
|
||||
@@ -283,7 +306,6 @@ public:
|
||||
}
|
||||
void sortMem()
|
||||
{
|
||||
|
||||
}
|
||||
};
|
||||
|
||||
@@ -291,39 +313,35 @@ class FuncHook
|
||||
{
|
||||
public:
|
||||
FuncHook()
|
||||
: Actived(false)
|
||||
, Src(NULL)
|
||||
, SrcPtr(NULL)
|
||||
, Dst(NULL)
|
||||
, SrcCodeSize(0)
|
||||
, HookCodeSize(5)
|
||||
: Actived(false), Src(NULL), SrcPtr(NULL), Dst(NULL), SrcCodeSize(0), HookCodeSize(5)
|
||||
{
|
||||
}
|
||||
~FuncHook()
|
||||
{
|
||||
this->Restore();
|
||||
}
|
||||
void Hook(void** SrcAddr, void* DstAddr)
|
||||
void Hook(void **SrcAddr, void *DstAddr)
|
||||
{
|
||||
if (!SrcAddr || !*SrcAddr || !DstAddr)return;
|
||||
//恢复上次HOOK
|
||||
if (!SrcAddr || !*SrcAddr || !DstAddr)
|
||||
return;
|
||||
// 恢复上次HOOK
|
||||
this->Restore();
|
||||
//填充数据
|
||||
// 填充数据
|
||||
this->HookCodeSize = 5;
|
||||
this->SrcCodeSize = 0;
|
||||
this->SrcPtr = SrcAddr;
|
||||
this->Src = *SrcAddr;
|
||||
this->Dst = DstAddr;
|
||||
//计算HOOK代码大小
|
||||
// 计算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);
|
||||
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;
|
||||
@@ -333,10 +351,10 @@ public:
|
||||
{
|
||||
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;
|
||||
@@ -348,12 +366,13 @@ public:
|
||||
this->HookCode = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
bool Actived;
|
||||
void* Src;
|
||||
void** SrcPtr;
|
||||
void* Dst;
|
||||
unsigned char* HookCode;
|
||||
void *Src;
|
||||
void **SrcPtr;
|
||||
void *Dst;
|
||||
unsigned char *HookCode;
|
||||
size_t SrcCodeSize;
|
||||
size_t HookCodeSize;
|
||||
};
|
||||
@@ -361,19 +380,19 @@ private:
|
||||
class CMem
|
||||
{
|
||||
public:
|
||||
static void WriteUChar(void* Addr, unsigned char Value)
|
||||
static void WriteUChar(void *Addr, unsigned char Value)
|
||||
{
|
||||
WriteBytes(Addr, &Value, 1);
|
||||
}
|
||||
static void WriteUShort(void* Addr, unsigned short Value)
|
||||
static void WriteUShort(void *Addr, unsigned short Value)
|
||||
{
|
||||
WriteBytes(Addr, &Value, 2);
|
||||
}
|
||||
static void WriteUInt(void* Addr, unsigned int Value)
|
||||
static void WriteUInt(void *Addr, unsigned int Value)
|
||||
{
|
||||
WriteBytes(Addr, &Value, 4);
|
||||
}
|
||||
static void WriteBytes(void* Addr, void* Data, size_t Len)
|
||||
static void WriteBytes(void *Addr, void *Data, size_t Len)
|
||||
{
|
||||
CMemPool::GetInstance()->SetPageProtect(Addr, PROT_READ | PROT_WRITE | PROT_EXEC);
|
||||
memcpy(Addr, Data, Len);
|
||||
@@ -382,26 +401,25 @@ public:
|
||||
static void HookJmp(int base, int func_)
|
||||
{
|
||||
char Jmp[5] = {};
|
||||
*((char*)Jmp) = 0xE9;
|
||||
*((int*)(Jmp + 1)) = func_ - base - 5;
|
||||
WriteBytes((void*)base, Jmp, 5);
|
||||
*((char *)Jmp) = 0xE9;
|
||||
*((int *)(Jmp + 1)) = func_ - base - 5;
|
||||
WriteBytes((void *)base, Jmp, 5);
|
||||
}
|
||||
|
||||
static void HookCall(int base, int func_)
|
||||
{
|
||||
char Jmp[5] = {};
|
||||
*((char*)Jmp) = 0xE8;
|
||||
*((int*)(Jmp + 1)) = func_ - base - 5;
|
||||
WriteBytes((void*)base, Jmp, 5);
|
||||
*((char *)Jmp) = 0xE8;
|
||||
*((int *)(Jmp + 1)) = func_ - base - 5;
|
||||
WriteBytes((void *)base, Jmp, 5);
|
||||
}
|
||||
|
||||
static void HookCall_6(int base, int func_)
|
||||
{
|
||||
char Jmp[6] = {};
|
||||
*((char*)Jmp) = 0xE8;
|
||||
*((int*)(Jmp + 1)) = func_ - base - 5;
|
||||
*((char*)(Jmp + 5)) = 0x90;
|
||||
WriteBytes((void*)base, Jmp, 5);
|
||||
*((char *)Jmp) = 0xE8;
|
||||
*((int *)(Jmp + 1)) = func_ - base - 5;
|
||||
*((char *)(Jmp + 5)) = 0x90;
|
||||
WriteBytes((void *)base, Jmp, 5);
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
82
src/l_socket.cpp
Normal file
82
src/l_socket.cpp
Normal file
@@ -0,0 +1,82 @@
|
||||
#include "l_socket.h"
|
||||
|
||||
static SQInteger SquirrelSendMsg(HSQUIRRELVM v)
|
||||
{
|
||||
const SQChar *Str;
|
||||
sq_getstring(v, 2, &Str);
|
||||
|
||||
l_socket::getInstance().Send(Str);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void l_socket::InitSqr()
|
||||
{
|
||||
std::lock_guard<std::recursive_mutex> lock(SqMtx);
|
||||
sq_pushroottable(v);
|
||||
sq_pushstring(v, _SC("Sq_SendPackToGateway"), -1);
|
||||
sq_newclosure(v, SquirrelSendMsg, 0); // create a new function
|
||||
sq_newslot(v, -3, SQFalse);
|
||||
sq_pop(v, 1); // pops the root table
|
||||
}
|
||||
|
||||
static void *PackLogicThread(void *arg)
|
||||
{
|
||||
while (true)
|
||||
{
|
||||
usleep(100);
|
||||
l_socket::getInstance().Logic();
|
||||
}
|
||||
|
||||
// 在这里编写线程的具体操作
|
||||
|
||||
pthread_exit(NULL);
|
||||
}
|
||||
|
||||
void l_socket::InitPackLogic()
|
||||
{
|
||||
pthread_t PackLogicT;
|
||||
int id1 = 1;
|
||||
// 创建线程1
|
||||
if (pthread_create(&PackLogicT, NULL, PackLogicThread, &id1) != 0)
|
||||
{
|
||||
std::cerr << "Error creating thread 1" << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
void l_socket::Init()
|
||||
{
|
||||
InitSqr();
|
||||
asio::io_context io_context;
|
||||
ClientObj = new Client(io_context);
|
||||
ClientObj->start();
|
||||
InitState = true;
|
||||
// InitPackLogic();
|
||||
io_context.run();
|
||||
}
|
||||
|
||||
void l_socket::IntToByteLittle(unsigned char *b, int Count)
|
||||
{
|
||||
b[0] = (Count & 0xff);
|
||||
b[1] = (Count & 0xff00) >> 8;
|
||||
b[2] = (Count & 0xff0000) >> 16;
|
||||
b[3] = (Count & 0xff000000) >> 24;
|
||||
}
|
||||
|
||||
void l_socket::Send(const SQChar *Pck)
|
||||
{
|
||||
if (ClientObj->ConnectState == false)
|
||||
return;
|
||||
int Length = strlen(Pck);
|
||||
unsigned char *PckData = new unsigned char[Length + 4];
|
||||
IntToByteLittle(PckData, Length);
|
||||
memcpy(PckData + 4, Pck, Length);
|
||||
ClientObj->send(PckData, Length + 4);
|
||||
delete[] PckData;
|
||||
}
|
||||
|
||||
void l_socket::Logic()
|
||||
{
|
||||
if (ClientObj->ConnectState == false)
|
||||
return;
|
||||
ClientObj->PackLogic();
|
||||
}
|
||||
147
src/l_squirrel.cpp
Normal file
147
src/l_squirrel.cpp
Normal file
@@ -0,0 +1,147 @@
|
||||
#include "l_squirrel.h"
|
||||
// 虚拟机对象
|
||||
HSQUIRRELVM v;
|
||||
// Lock
|
||||
std::recursive_mutex SqMtx;
|
||||
|
||||
static void printfunc(HSQUIRRELVM v, const SQChar *s, ...)
|
||||
{
|
||||
fflush(stdout);
|
||||
va_list vl;
|
||||
va_start(vl, s);
|
||||
scvprintf(stdout, s, vl);
|
||||
va_end(vl);
|
||||
printf("\n");
|
||||
fflush(stdout);
|
||||
}
|
||||
|
||||
static void errorfunc(HSQUIRRELVM v, const SQChar *s, ...)
|
||||
{
|
||||
fflush(stderr);
|
||||
va_list vl;
|
||||
va_start(vl, s);
|
||||
scvprintf(stderr, s, vl);
|
||||
va_end(vl);
|
||||
printf("\n");
|
||||
fflush(stderr);
|
||||
}
|
||||
|
||||
static void ReloadingScript(HSQUIRRELVM v)
|
||||
{
|
||||
// 爬取出所有的脚本文件
|
||||
std::vector<std::string> vec = Tool::GetListFilesR("/Dnf_Sqr");
|
||||
std::map<std::string, std::string> SquirrelFilePath;
|
||||
|
||||
for (auto it = vec.cbegin(); it != vec.cend(); ++it)
|
||||
{
|
||||
std::string FileName = "/Dnf_Sqr/" + *it;
|
||||
if (FileName.find(".nut") == std::string::npos)
|
||||
continue;
|
||||
std::fstream F;
|
||||
F.open((FileName).c_str(), std::ios::in);
|
||||
std::stringstream ContentStringStream;
|
||||
ContentStringStream << F.rdbuf();
|
||||
std::string ContentString(ContentStringStream.str());
|
||||
F.close();
|
||||
SquirrelFilePath[FileName] = ContentString;
|
||||
}
|
||||
|
||||
std::map<std::string, std::string> SquirrelLastFilePath;
|
||||
|
||||
for (auto it = SquirrelFilePath.begin(); it != SquirrelFilePath.end(); it++)
|
||||
{
|
||||
std::string Sourcename = it->first;
|
||||
std::string ContentString = it->second;
|
||||
if (SQ_SUCCEEDED(sq_compilebuffer(v, (SQChar *)(ContentString.c_str()), ContentString.length(), (SQChar *)(Sourcename.c_str()), true)))
|
||||
{
|
||||
sq_pushroottable(v);
|
||||
sq_call(v, 1, 1, 1);
|
||||
sq_pop(v, 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
SquirrelLastFilePath[Sourcename] = ContentString;
|
||||
}
|
||||
}
|
||||
|
||||
while (SquirrelLastFilePath.size() > 0)
|
||||
{
|
||||
std::map<std::string, std::string> FailMapBuffer;
|
||||
for (auto it = SquirrelLastFilePath.begin(); it != SquirrelLastFilePath.end(); it++)
|
||||
{
|
||||
std::string Sourcename = it->first;
|
||||
std::string ContentString = it->second;
|
||||
|
||||
if (SQ_SUCCEEDED(sq_compilebuffer(v, (SQChar *)(ContentString.c_str()), ContentString.length(), (SQChar *)(Sourcename.c_str()), true)))
|
||||
{
|
||||
sq_pushroottable(v);
|
||||
if (SQ_FAILED(sq_call(v, 1, 1, 1)))
|
||||
{
|
||||
FailMapBuffer[Sourcename] = ContentString;
|
||||
};
|
||||
sq_pop(v, 1);
|
||||
};
|
||||
}
|
||||
|
||||
SquirrelLastFilePath.clear();
|
||||
if (FailMapBuffer.size() > 0)
|
||||
{
|
||||
for (auto it = FailMapBuffer.begin(); it != FailMapBuffer.end(); it++)
|
||||
{
|
||||
std::string Sourcename = it->first;
|
||||
std::string ContentString = it->second;
|
||||
SquirrelLastFilePath[Sourcename] = ContentString;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static SQInteger SqReloadScript(HSQUIRRELVM v)
|
||||
{
|
||||
ReloadingScript(v);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void InitSquirrel()
|
||||
{
|
||||
std::lock_guard<std::recursive_mutex> lock(SqMtx);
|
||||
|
||||
v = sq_open(4096); // 创建虚拟机,其栈的初始大小为1024
|
||||
|
||||
sq_pushroottable(v);
|
||||
|
||||
sqstd_register_bloblib(v);
|
||||
sqstd_register_iolib(v);
|
||||
sqstd_register_systemlib(v);
|
||||
sqstd_register_mathlib(v);
|
||||
sqstd_register_stringlib(v);
|
||||
sqstd_seterrorhandlers(v);
|
||||
|
||||
sq_setprintfunc(v, printfunc, errorfunc); // sets the print function
|
||||
|
||||
// 输出版本信息
|
||||
// scfprintf(stdout, _SC("%s %s (%d bits)\n"), SQUIRREL_VERSION, SQUIRREL_COPYRIGHT, (int)sizeof(SQInteger) * 8);
|
||||
|
||||
// 注册全局NutApi
|
||||
GlobaRegisterSquirrel(v);
|
||||
|
||||
// 加载基础脚本文件
|
||||
ReloadingScript(v);
|
||||
|
||||
// 执行虚拟机Main函数
|
||||
SQInteger top = sq_gettop(v); // saves the stack size before the call
|
||||
sq_pushroottable(v); // pushes the global table
|
||||
sq_pushstring(v, _SC("main"), -1);
|
||||
if (SQ_SUCCEEDED(sq_get(v, -2)))
|
||||
{ // gets the field 'foo' from the global table
|
||||
sq_pushroottable(v); // push the 'this' (in this case is the global table)
|
||||
sq_call(v, 1, SQFalse, SQTrue); // calls the function
|
||||
}
|
||||
sq_settop(v, top); // restores the original stack size
|
||||
|
||||
sq_pushroottable(v);
|
||||
sq_pushstring(v, "sq_ReloadScript", -1);
|
||||
sq_newclosure(v, SqReloadScript, 0); // create a new function
|
||||
sq_newslot(v, -3, SQFalse);
|
||||
sq_pop(v, 1); // pops the root table
|
||||
}
|
||||
@@ -3,17 +3,16 @@
|
||||
#define __PACKETBUF_H__
|
||||
#pragma pack(push, 0x01)
|
||||
|
||||
|
||||
class PacketBuf
|
||||
{
|
||||
public:
|
||||
unsigned char UnknownData_0000[0x20000];
|
||||
unsigned char UnknownData_0000[0x20000];
|
||||
|
||||
public:
|
||||
PacketBuf()
|
||||
{
|
||||
memset(UnknownData_0000, 0, sizeof(UnknownData_0000));
|
||||
CallT<PacketBuf*>(base::PacketBuf::PacketBuf_make, this);
|
||||
CallT<PacketBuf *>(base::PacketBuf::PacketBuf_make, this);
|
||||
}
|
||||
|
||||
~PacketBuf()
|
||||
@@ -21,14 +20,15 @@ public:
|
||||
CallT<int>(base::PacketBuf::PacketBuf_destroy, this);
|
||||
}
|
||||
|
||||
static PacketBuf* NewPacketBuf()
|
||||
static PacketBuf *NewPacketBuf()
|
||||
{
|
||||
void* v62 = malloc(0x20000);
|
||||
if (!v62) return NULL;
|
||||
return CallT<PacketBuf*>(base::PacketBuf::PacketBuf_make, v62);
|
||||
void *v62 = malloc(0x20000);
|
||||
if (!v62)
|
||||
return NULL;
|
||||
return CallT<PacketBuf *>(base::PacketBuf::PacketBuf_make, v62);
|
||||
}
|
||||
|
||||
static void DelPacketBuf(PacketBuf* a1)
|
||||
static void DelPacketBuf(PacketBuf *a1)
|
||||
{
|
||||
CallT<int>(base::PacketBuf::PacketBuf_destroy, a1);
|
||||
free(a1);
|
||||
@@ -39,7 +39,7 @@ public:
|
||||
return CallT<int>(base::PacketBuf::at, this, a2);
|
||||
}
|
||||
|
||||
int bind_packet(char* a2, int a3)
|
||||
int bind_packet(char *a2, int a3)
|
||||
{
|
||||
return CallT<int>(base::PacketBuf::bind_packet, this, a2, a3);
|
||||
}
|
||||
@@ -59,7 +59,7 @@ public:
|
||||
return CallT<int>(base::PacketBuf::compress_packet, this);
|
||||
}
|
||||
|
||||
int copy(PacketBuf const& a2)
|
||||
int copy(PacketBuf const &a2)
|
||||
{
|
||||
return CallT<int>(base::PacketBuf::copy, this, a2);
|
||||
}
|
||||
@@ -84,7 +84,7 @@ public:
|
||||
return CallT<int>(base::PacketBuf::getLastError, this);
|
||||
}
|
||||
|
||||
int get_binary(char* a2, int a3)
|
||||
int get_binary(char *a2, int a3)
|
||||
{
|
||||
return CallT<int>(base::PacketBuf::get_binary, this, a2, a3);
|
||||
}
|
||||
@@ -94,12 +94,12 @@ public:
|
||||
return CallT<int>(base::PacketBuf::get_buf_ptr, this, a2);
|
||||
}
|
||||
|
||||
int get_byte(char* a2)
|
||||
int get_byte(char *a2)
|
||||
{
|
||||
return CallT<int>(base::PacketBuf::get_byte, this, a2);
|
||||
}
|
||||
|
||||
int get_byte_u(uchar* a2)
|
||||
int get_byte_u(uchar *a2)
|
||||
{
|
||||
return CallT<int>(base::PacketBuf::get_byte_u, this, a2);
|
||||
}
|
||||
@@ -109,22 +109,22 @@ public:
|
||||
return CallT<int>(base::PacketBuf::get_index, this);
|
||||
}
|
||||
|
||||
int get_int(int* a2)
|
||||
int get_int(int *a2)
|
||||
{
|
||||
return CallT<int>(base::PacketBuf::get_int, this, a2);
|
||||
}
|
||||
|
||||
int get_int_u(uint* a2)
|
||||
int get_int_u(uint *a2)
|
||||
{
|
||||
return CallT<int>(base::PacketBuf::get_int_u, this, a2);
|
||||
}
|
||||
|
||||
int get_int_ul(ulong* a2)
|
||||
int get_int_ul(ulong *a2)
|
||||
{
|
||||
return CallT<int>(base::PacketBuf::get_int_ul, this, a2);
|
||||
}
|
||||
|
||||
int get_item_idx(ulong* a2)
|
||||
int get_item_idx(ulong *a2)
|
||||
{
|
||||
return CallT<int>(base::PacketBuf::get_item_idx, this, a2);
|
||||
}
|
||||
@@ -139,22 +139,22 @@ public:
|
||||
return CallT<int>(base::PacketBuf::get_packet, this, a2);
|
||||
}
|
||||
|
||||
int get_short(short* a2)
|
||||
int get_short(short *a2)
|
||||
{
|
||||
return CallT<int>(base::PacketBuf::get_short, this, a2);
|
||||
}
|
||||
|
||||
int get_short_u(ushort* a2)
|
||||
int get_short_u(ushort *a2)
|
||||
{
|
||||
return CallT<int>(base::PacketBuf::get_short_u, this, a2);
|
||||
}
|
||||
|
||||
int get_str(char* a2, int a3, int a4)
|
||||
int get_str(char *a2, int a3, int a4)
|
||||
{
|
||||
return CallT<int>(base::PacketBuf::get_str, this, a2, a3, a4);
|
||||
}
|
||||
|
||||
int isCompressRequired(char* a2)
|
||||
int isCompressRequired(char *a2)
|
||||
{
|
||||
return CallT<int>(base::PacketBuf::isCompressRequired, this, a2);
|
||||
}
|
||||
@@ -179,12 +179,12 @@ public:
|
||||
return CallT<int>(base::PacketBuf::is_ptr_end, this, a2, a3);
|
||||
}
|
||||
|
||||
int put_binary(char* a2, int a3)
|
||||
int put_binary(char *a2, int a3)
|
||||
{
|
||||
return CallT<int>(base::PacketBuf::put_binary, this, a2, a3);
|
||||
}
|
||||
|
||||
int put_binary_c(char const* a2, int a3)
|
||||
int put_binary_c(char const *a2, int a3)
|
||||
{
|
||||
return CallT<int>(base::PacketBuf::put_binary_c, this, a2, a3);
|
||||
}
|
||||
@@ -194,7 +194,7 @@ public:
|
||||
return CallT<int>(base::PacketBuf::put_byte, this, a2);
|
||||
}
|
||||
|
||||
int put_header(int a2, int a3)
|
||||
int put_header(char a2, short a3)
|
||||
{
|
||||
return CallT<int>(base::PacketBuf::put_header, this, a2, a3);
|
||||
}
|
||||
@@ -209,7 +209,7 @@ public:
|
||||
return CallT<int>(base::PacketBuf::put_item_idx, this, a2);
|
||||
}
|
||||
|
||||
int put_packet(Inven_Item const& a2)
|
||||
int put_packet(Inven_Item const &a2)
|
||||
{
|
||||
return CallT<int>(base::PacketBuf::put_packet, this, a2);
|
||||
}
|
||||
@@ -219,12 +219,12 @@ public:
|
||||
return CallT<int>(base::PacketBuf::put_short, this, a2);
|
||||
}
|
||||
|
||||
int put_str(char* a2, int a3)
|
||||
int put_str(char *a2, int a3)
|
||||
{
|
||||
return CallT<int>(base::PacketBuf::put_str, this, a2, a3);
|
||||
}
|
||||
|
||||
int put_str_c(char const* a2, int a3)
|
||||
int put_str_c(char const *a2, int a3)
|
||||
{
|
||||
return CallT<int>(base::PacketBuf::put_str_c, this, a2, a3);
|
||||
}
|
||||
@@ -239,18 +239,15 @@ public:
|
||||
return CallT<int>(base::PacketBuf::set_index, this, a2);
|
||||
}
|
||||
|
||||
int set_packet(char const* a2, int a3)
|
||||
int set_packet(char const *a2, int a3)
|
||||
{
|
||||
return CallT<int>(base::PacketBuf::set_packet, this, a2, a3);
|
||||
}
|
||||
|
||||
|
||||
};
|
||||
|
||||
class InterfacePacketBuf :public PacketBuf
|
||||
class InterfacePacketBuf : public PacketBuf
|
||||
{
|
||||
public:
|
||||
|
||||
InterfacePacketBuf()
|
||||
{
|
||||
CallT<int>(base::InterfacePacketBuf::InterfacePacketBuf_make, this);
|
||||
@@ -261,12 +258,12 @@ public:
|
||||
CallT<int>(base::InterfacePacketBuf::InterfacePacketBuf_destroy, this);
|
||||
}
|
||||
|
||||
int AcquirePacketBuf(PacketBuf* a2)
|
||||
int AcquirePacketBuf(PacketBuf *a2)
|
||||
{
|
||||
return CallT<int>(base::InterfacePacketBuf::AcquirePacketBuf, this, a2);
|
||||
}
|
||||
|
||||
int bind_packet(char* a2, int a3)
|
||||
int bind_packet(char *a2, int a3)
|
||||
{
|
||||
return CallT<int>(base::InterfacePacketBuf::bind_packet, this, a2, a3);
|
||||
}
|
||||
@@ -291,7 +288,7 @@ public:
|
||||
return CallT<int>(base::InterfacePacketBuf::getLastError, this);
|
||||
}
|
||||
|
||||
int get_binary(char* a2, int a3)
|
||||
int get_binary(char *a2, int a3)
|
||||
{
|
||||
return CallT<int>(base::InterfacePacketBuf::get_binary, this, a2, a3);
|
||||
}
|
||||
@@ -301,7 +298,7 @@ public:
|
||||
return CallT<int>(base::InterfacePacketBuf::get_index, this);
|
||||
}
|
||||
|
||||
int get_int(int* a2)
|
||||
int get_int(int *a2)
|
||||
{
|
||||
return CallT<int>(base::InterfacePacketBuf::get_int, this, a2);
|
||||
}
|
||||
@@ -316,7 +313,7 @@ public:
|
||||
return CallT<int>(base::InterfacePacketBuf::get_packet, this, a2);
|
||||
}
|
||||
|
||||
int get_short(short* a2)
|
||||
int get_short(short *a2)
|
||||
{
|
||||
return CallT<int>(base::InterfacePacketBuf::get_short, this, a2);
|
||||
}
|
||||
@@ -326,12 +323,12 @@ public:
|
||||
return CallT<int>(base::InterfacePacketBuf::is_finallized, this);
|
||||
}
|
||||
|
||||
int put_binary(char* a2, int a3)
|
||||
int put_binary(char *a2, int a3)
|
||||
{
|
||||
return CallT<int>(base::InterfacePacketBuf::put_binary, this, a2, a3);
|
||||
}
|
||||
|
||||
int put_binary_c(char const* a2, int a3)
|
||||
int put_binary_c(char const *a2, int a3)
|
||||
{
|
||||
return CallT<int>(base::InterfacePacketBuf::put_binary_c, this, a2, a3);
|
||||
}
|
||||
@@ -356,7 +353,7 @@ public:
|
||||
return CallT<int>(base::InterfacePacketBuf::put_item_idx, this, a2);
|
||||
}
|
||||
|
||||
int put_packet(Inven_Item const& a2)
|
||||
int put_packet(Inven_Item const &a2)
|
||||
{
|
||||
return CallT<int>(base::InterfacePacketBuf::put_packet, this, a2);
|
||||
}
|
||||
@@ -366,12 +363,12 @@ public:
|
||||
return CallT<int>(base::InterfacePacketBuf::put_short, this, a2);
|
||||
}
|
||||
|
||||
int put_str(char* a2, int a3)
|
||||
int put_str(char *a2, int a3)
|
||||
{
|
||||
return CallT<int>(base::InterfacePacketBuf::put_str, this, a2, a3);
|
||||
}
|
||||
|
||||
int put_str_c(char const* a2, int a3)
|
||||
int put_str_c(char const *a2, int a3)
|
||||
{
|
||||
return CallT<int>(base::InterfacePacketBuf::put_str_c, this, a2, a3);
|
||||
}
|
||||
@@ -380,24 +377,23 @@ public:
|
||||
{
|
||||
return CallT<int>(base::InterfacePacketBuf::set_index, this, a2);
|
||||
}
|
||||
|
||||
|
||||
};
|
||||
|
||||
class PacketGuard
|
||||
{
|
||||
public:
|
||||
static PacketGuard* NewPacketGuard()
|
||||
static PacketGuard *NewPacketGuard()
|
||||
{
|
||||
void* v62 = malloc(0x20000);
|
||||
typedef int (*__func)(void* a1);
|
||||
if (!v62) return NULL;
|
||||
void *v62 = malloc(0x20000);
|
||||
typedef int (*__func)(void *a1);
|
||||
if (!v62)
|
||||
return NULL;
|
||||
((__func)base::PacketGuard::PacketGuard_make)(v62);
|
||||
return (PacketGuard*)v62;
|
||||
return (PacketGuard *)v62;
|
||||
}
|
||||
static void DelPacketGuard(PacketGuard* a1)
|
||||
static void DelPacketGuard(PacketGuard *a1)
|
||||
{
|
||||
typedef int (*__func)(void* a1);
|
||||
typedef int (*__func)(void *a1);
|
||||
((__func)base::PacketGuard::PacketGuard_destroy)(a1);
|
||||
free(a1);
|
||||
}
|
||||
@@ -408,13 +404,13 @@ class PacketDispatcher
|
||||
public:
|
||||
int getDispatcher(int a2)
|
||||
{
|
||||
typedef int (*__func)(PacketDispatcher* a1, int a2);
|
||||
typedef int (*__func)(PacketDispatcher *a1, int a2);
|
||||
return ((__func)base::PacketDispatcher::getDispatcher)(this, a2);
|
||||
}
|
||||
|
||||
void** get_dispatcher(int a2)
|
||||
void **get_dispatcher(int a2)
|
||||
{
|
||||
typedef void** (*__func)(PacketDispatcher* a1, int a2);
|
||||
typedef void **(*__func)(PacketDispatcher *a1, int a2);
|
||||
return ((__func)base::PacketDispatcher::get_dispatcher)(this, a2);
|
||||
}
|
||||
};
|
||||
@@ -422,4 +418,3 @@ public:
|
||||
#pragma pack(pop)
|
||||
|
||||
#endif // __PACKETBUF_H__
|
||||
|
||||
|
||||
@@ -8,14 +8,13 @@ namespace base
|
||||
|
||||
const int Init = 0x082A08F4;
|
||||
|
||||
|
||||
const int importCashShopItemList = 0x088FDCB5;
|
||||
const int importCashShopItemList_hook_begin = 0x088FDD59;
|
||||
const int importCashShopItemList_hook_end = 0x088FDD61;
|
||||
|
||||
namespace ItemVendingMachine
|
||||
{
|
||||
//08178676
|
||||
// 08178676
|
||||
const int ProcessIPG_ResultOutput_hook_begin = 0x08179398;
|
||||
const int ProcessIPG_ResultOutput_hook_end = 0x081793A2;
|
||||
}
|
||||
@@ -42,7 +41,6 @@ namespace base
|
||||
const int CSystemTime_destroy = 0x082A6986;
|
||||
}
|
||||
|
||||
|
||||
namespace Dispatcher_BuyCeraShopItem
|
||||
{
|
||||
const int dispatch_sig = 0x081FD396;
|
||||
@@ -52,7 +50,6 @@ namespace base
|
||||
{
|
||||
const int dispatch_sig = 0x8217BD6;
|
||||
|
||||
|
||||
}
|
||||
|
||||
namespace DisPatcher_MoveMap
|
||||
@@ -76,13 +73,12 @@ namespace base
|
||||
const int Init = 0x08299FA0;
|
||||
const int Init_fix_1 = 0x0829C075;
|
||||
|
||||
|
||||
//base
|
||||
const int s_pSecuProtectionField = 0x0941F7CC; //0x18
|
||||
const int s_pItemVendingMachine = 0x0941F760; //0x20
|
||||
const int s_db_mgr = 0x0940BDAC; //0x38
|
||||
const int s_pCeraShop = 0x0941F744; //0x8
|
||||
const int s_pLogGameChannel = 0x0941F740; //0x10
|
||||
// base
|
||||
const int s_pSecuProtectionField = 0x0941F7CC; // 0x18
|
||||
const int s_pItemVendingMachine = 0x0941F760; // 0x20
|
||||
const int s_db_mgr = 0x0940BDAC; // 0x38
|
||||
const int s_pCeraShop = 0x0941F744; // 0x8
|
||||
const int s_pLogGameChannel = 0x0941F740; // 0x10
|
||||
const int s_systemTime_ = 0x0941F714;
|
||||
}
|
||||
|
||||
@@ -104,10 +100,9 @@ namespace base
|
||||
namespace CParty
|
||||
{
|
||||
const int addDungeonClear = 0x085BDDFC;
|
||||
const int addDungeonClear_fix_1 = 0x085BDE9D; //ÆÕͨ±»»÷
|
||||
const int addDungeonClear_fix_2 = 0x085BDF30; //Ô¶¹Å±»»÷
|
||||
const int addDungeonClear_fix_3 = 0x085BDFC3; //Òì½ç±»»÷
|
||||
|
||||
const int addDungeonClear_fix_1 = 0x085BDE9D; // ÆÕͨ±»»÷
|
||||
const int addDungeonClear_fix_2 = 0x085BDF30; // Ô¶¹Å±»»÷
|
||||
const int addDungeonClear_fix_3 = 0x085BDFC3; // Òì½ç±»»÷
|
||||
|
||||
}
|
||||
|
||||
@@ -292,7 +287,6 @@ namespace base
|
||||
const int set_index = 0x081252BA;
|
||||
const int set_packet = 0x0858D462;
|
||||
|
||||
|
||||
}
|
||||
|
||||
namespace InterfacePacketBuf
|
||||
@@ -332,12 +326,12 @@ namespace base
|
||||
const int PacketGuard_destroy = 0x0858DE80;
|
||||
}
|
||||
|
||||
namespace PacketDispatcher
|
||||
namespace PacketDispatcher // U
|
||||
{
|
||||
const int getDispatcher = 0x08231F2E;
|
||||
const int server_load_monitoring = 0x0825F658;
|
||||
const int log_recv_packet = 0x0825F72E;
|
||||
const int PacketDispatcher_make = 0x08590A2E;
|
||||
const int PacketDispatcher_make = 0x08590A2E;//???
|
||||
const int PacketDispatcher_destroy = 0x08594840;
|
||||
const int get_dispatcher = 0x085948E2;
|
||||
const int doDispatch = 0x08594922;
|
||||
@@ -356,7 +350,6 @@ namespace base
|
||||
const int ReqDBSendNewMailCashShop = 0x08556D5C;
|
||||
}
|
||||
|
||||
|
||||
namespace CHackAnalyzer
|
||||
{
|
||||
const int addServerHackCnt = 0x080F8C7E;
|
||||
@@ -464,10 +457,8 @@ namespace base
|
||||
const int update = 0x083F4718;
|
||||
const int MySQL_destroy = 0x083F3AEA;
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
namespace CGM_Manager
|
||||
{
|
||||
const int isGM = 0x0829948C;
|
||||
@@ -481,8 +472,7 @@ namespace base
|
||||
|
||||
namespace DisPatcher_MoveItem
|
||||
{
|
||||
const int process = 0x081C5904; //int __cdecl DisPatcher_MoveItem::process(DisPatcher_MoveItem *this, CUser *a2, MSG_BASE *a3, ParamBase *a4)
|
||||
|
||||
const int process = 0x081C5904; // int __cdecl DisPatcher_MoveItem::process(DisPatcher_MoveItem *this, CUser *a2, MSG_BASE *a3, ParamBase *a4)
|
||||
|
||||
}
|
||||
|
||||
@@ -564,14 +554,10 @@ namespace base
|
||||
namespace Dispatcher_ModItemAttr
|
||||
{
|
||||
const int dispatch_sig = 0x08200B08;
|
||||
const int dispatch_sig_hook = 0x08201119; //.text:08201119 cmp eax, 28D14Eh
|
||||
const int dispatch_sig_ret = 0x0820111E; //.text:0820111E ja short loc_820113E
|
||||
const int dispatch_sig_hook = 0x08201119; //.text:08201119 cmp eax, 28D14Eh
|
||||
const int dispatch_sig_ret = 0x0820111E; //.text:0820111E ja short loc_820113E
|
||||
const int _SendResult = 0x08201938;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
133
src/utils.h
133
src/utils.h
@@ -1,14 +1,18 @@
|
||||
#ifndef utils_h__
|
||||
#define utils_h__
|
||||
#include <string>
|
||||
#include <sstream>
|
||||
#include <iostream>
|
||||
#include <iomanip>
|
||||
#include <stdarg.h>
|
||||
#include <iconv.h>
|
||||
#include <stdio.h>
|
||||
#include <random>
|
||||
|
||||
#define BUFFCOUNT (3196)
|
||||
#define SET_TEXTW(X) L#X
|
||||
#define SET_TEXTA(X) #X
|
||||
|
||||
|
||||
namespace Utils
|
||||
{
|
||||
static int Rand(int v_min, int v_max)
|
||||
@@ -20,10 +24,10 @@ namespace Utils
|
||||
return v_min + rNum % (v_max - v_min + 1);
|
||||
}
|
||||
|
||||
static void* alloc(size_t len)
|
||||
static void *alloc(size_t len)
|
||||
{
|
||||
int fd = open("/dev/zero", O_RDONLY);
|
||||
void* code_addr = mmap(NULL, len, PROT_READ | PROT_WRITE | PROT_EXEC, MAP_PRIVATE, fd, 0);
|
||||
void *code_addr = mmap(NULL, len, PROT_READ | PROT_WRITE | PROT_EXEC, MAP_PRIVATE, fd, 0);
|
||||
close(fd);
|
||||
return code_addr;
|
||||
}
|
||||
@@ -31,7 +35,7 @@ namespace Utils
|
||||
class NLock
|
||||
{
|
||||
public:
|
||||
typedef pthread_mutex_t OSLockType;
|
||||
typedef pthread_mutex_t OSLockType;
|
||||
|
||||
NLock()
|
||||
{
|
||||
@@ -65,7 +69,7 @@ namespace Utils
|
||||
}
|
||||
|
||||
// Return the native underlying lock. Not supported for Windows builds.
|
||||
OSLockType* os_lock() { return &os_lock_; }
|
||||
OSLockType *os_lock() { return &os_lock_; }
|
||||
|
||||
private:
|
||||
OSLockType os_lock_;
|
||||
@@ -74,7 +78,7 @@ namespace Utils
|
||||
class NAutoLock
|
||||
{
|
||||
public:
|
||||
NAutoLock(NLock* lock)
|
||||
NAutoLock(NLock *lock)
|
||||
{
|
||||
lock_ = lock;
|
||||
lock_->Lock();
|
||||
@@ -87,13 +91,13 @@ namespace Utils
|
||||
}
|
||||
|
||||
private:
|
||||
NLock* lock_;
|
||||
NLock *lock_;
|
||||
};
|
||||
|
||||
class NAutoUnlock
|
||||
{
|
||||
public:
|
||||
NAutoUnlock(NLock* lock)
|
||||
NAutoUnlock(NLock *lock)
|
||||
{
|
||||
lock_ = lock;
|
||||
lock_->Unlock();
|
||||
@@ -106,10 +110,9 @@ namespace Utils
|
||||
}
|
||||
|
||||
private:
|
||||
NLock* lock_;
|
||||
NLock *lock_;
|
||||
};
|
||||
|
||||
|
||||
template <class V1, class V2, class V3 = std::less<V1>>
|
||||
class TMap
|
||||
{
|
||||
@@ -119,7 +122,7 @@ namespace Utils
|
||||
* @param key
|
||||
* @param data
|
||||
* @return
|
||||
*/
|
||||
*/
|
||||
bool Push(V1 key, V2 data)
|
||||
{
|
||||
NAutoLock auto_lock(&Lock);
|
||||
@@ -136,7 +139,7 @@ namespace Utils
|
||||
* @brief 删除
|
||||
* @param key
|
||||
* @return
|
||||
*/
|
||||
*/
|
||||
bool Erase(V1 key)
|
||||
{
|
||||
NAutoLock auto_lock(&Lock);
|
||||
@@ -151,7 +154,7 @@ namespace Utils
|
||||
|
||||
/**
|
||||
* @brief 清空
|
||||
*/
|
||||
*/
|
||||
void Clear()
|
||||
{
|
||||
NAutoLock auto_lock(&Lock);
|
||||
@@ -161,7 +164,7 @@ namespace Utils
|
||||
/**
|
||||
* @brief 大小
|
||||
* @return
|
||||
*/
|
||||
*/
|
||||
size_t Size()
|
||||
{
|
||||
return Map.size();
|
||||
@@ -170,7 +173,7 @@ namespace Utils
|
||||
/**
|
||||
* @brief 迭代器头
|
||||
* @return
|
||||
*/
|
||||
*/
|
||||
typename std::map<V1, V2>::iterator Begin()
|
||||
{
|
||||
return Map.begin();
|
||||
@@ -179,7 +182,7 @@ namespace Utils
|
||||
/**
|
||||
* @brief 迭代器尾
|
||||
* @return
|
||||
*/
|
||||
*/
|
||||
typename std::map<V1, V2>::iterator End()
|
||||
{
|
||||
return Map.end();
|
||||
@@ -190,8 +193,8 @@ namespace Utils
|
||||
* @param key
|
||||
* @param data
|
||||
* @return
|
||||
*/
|
||||
bool Find(V1 key, V2* data = NULL)
|
||||
*/
|
||||
bool Find(V1 key, V2 *data = NULL)
|
||||
{
|
||||
NAutoLock auto_lock(&Lock);
|
||||
auto itr = Map.find(key);
|
||||
@@ -211,7 +214,7 @@ namespace Utils
|
||||
* @param key
|
||||
* @param data
|
||||
* @return
|
||||
*/
|
||||
*/
|
||||
bool Change(V1 key, V2 data)
|
||||
{
|
||||
NAutoLock auto_lock(&Lock);
|
||||
@@ -223,17 +226,23 @@ namespace Utils
|
||||
}
|
||||
return false;
|
||||
}
|
||||
std::map<V1, V2, V3>Map;
|
||||
|
||||
V2 at(const V1 &__k)
|
||||
{
|
||||
return Map.at(__k);
|
||||
}
|
||||
|
||||
std::map<V1, V2, V3> Map;
|
||||
NLock Lock;
|
||||
};
|
||||
/**
|
||||
* @brief 到16进制Hex文本
|
||||
* @param buf
|
||||
* @param len
|
||||
* @param tok
|
||||
* @return
|
||||
*/
|
||||
static std::string ToHexString(const unsigned char* buf, int len, std::string tok = " ")
|
||||
* @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];
|
||||
@@ -248,7 +257,67 @@ namespace Utils
|
||||
return output;
|
||||
}
|
||||
|
||||
static void _Log(const char* formatstring, ...)
|
||||
static int ByteLittleToInt(unsigned char *Count)
|
||||
{
|
||||
int int1 = Count[0] & 0xff;
|
||||
int int2 = (Count[1] & 0xff) << 8;
|
||||
int int3 = (Count[2] & 0xff) << 16;
|
||||
int int4 = (Count[3] & 0xff) << 24;
|
||||
|
||||
return int1 | int2 | int3 | int4;
|
||||
}
|
||||
|
||||
static std::string utf8_to_gbk(const char *utf8String, int length)
|
||||
{
|
||||
// Open a conversion descriptor
|
||||
iconv_t cd = iconv_open("GBK", "UTF-8");
|
||||
if (cd == (iconv_t)(-1))
|
||||
{
|
||||
std::cerr << "Failed to open iconv" << std::endl;
|
||||
return std::string(); // Return empty string on failure
|
||||
}
|
||||
|
||||
// Prepare buffers
|
||||
size_t inbytesleft = length;
|
||||
size_t outbytesleft = length * 2; // Assuming worst case for expansion
|
||||
char outbuf[outbytesleft + 1]; // +1 for null termination
|
||||
char *inbuf = const_cast<char *>(utf8String);
|
||||
char *outptr = outbuf;
|
||||
|
||||
// Perform the conversion
|
||||
size_t result = iconv(cd, &inbuf, &inbytesleft, &outptr, &outbytesleft);
|
||||
if (result == (size_t)(-1))
|
||||
{
|
||||
std::cerr << "Conversion failed" << std::endl;
|
||||
iconv_close(cd);
|
||||
return std::string(); // Return empty string on failure
|
||||
}
|
||||
|
||||
// Null-terminate the output buffer
|
||||
*outptr = '\0';
|
||||
|
||||
// Close the conversion descriptor
|
||||
iconv_close(cd);
|
||||
|
||||
// Return the converted string
|
||||
return std::string(outbuf);
|
||||
}
|
||||
|
||||
static std::string PackToHexString(const unsigned char *buf, int Offset)
|
||||
{
|
||||
int Len = ByteLittleToInt((unsigned char *)((int)buf + Offset));
|
||||
// char *Buffer = new char[Len + 1];
|
||||
// memcpy(Buffer, buf + 17, Len);
|
||||
// utf8_to_gbk(Buffer, Len);
|
||||
// Buffer[Len] = '\0';
|
||||
// std::cout << Buffer << std::endl;
|
||||
std::string str((char *)(buf + Offset + 4), Len);
|
||||
// std::cout << str << std::endl;
|
||||
// delete[] Buffer;
|
||||
return str;
|
||||
}
|
||||
|
||||
static void _Log(const char *formatstring, ...)
|
||||
{
|
||||
int nSize = 0;
|
||||
char buff[BUFFCOUNT];
|
||||
@@ -257,15 +326,13 @@ namespace Utils
|
||||
va_start(args, formatstring);
|
||||
nSize = vsnprintf(buff, sizeof(buff), formatstring, args);
|
||||
va_end(args);
|
||||
char szPrINT32[BUFFCOUNT + 50] = { 0 };
|
||||
sprintf(szPrINT32, "[DNF_PROJECT] %s \n", buff);//wsprintfA
|
||||
char szPrINT32[BUFFCOUNT + 50] = {0};
|
||||
sprintf(szPrINT32, "[DPS_PLUGIN] %s \n", buff); // wsprintfA
|
||||
printf(szPrINT32);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
#define LOG(format,...) Utils::_Log(format,##__VA_ARGS__)
|
||||
|
||||
#define LOG(format, ...) Utils::_Log(format, ##__VA_ARGS__)
|
||||
|
||||
#endif // utils_h__
|
||||
Reference in New Issue
Block a user