重要的事情先说三遍:写服务端的人真菜!写服务端的人真菜!写服务端的人真菜!算是炒个冷饭。
在本文发布的时候,漏洞已经被提交并被网易修复,想做坏事的还是算了。
先提一下网易为了这个天梯系统写的“DzApi”,其实就是仿照jass虚拟机注册函数的方式向jass虚拟机注册自定义函数。
关键函数原型如下:
uintptr_twar3_searcher::search_get_instance()const
{
uintptr_tget_instance;
//=========================================
// (1)
//
// push 493E0h
// push 1
// push 1
// push 0
// mov edx, offset s_Config ; "config"
// mov ecx, esi
// call UnknowFunc <----
//=========================================
get_instance=search_string("config");
get_instance+=sizeofuintptr_t;
get_instance=next_opcode(get_instance, 0xE8, 5);
get_instance=convert_function(get_instance);
//=========================================
// (2)
//
// UnknowFunc:
// push esi
// mov esi, edx
// call jGetVMInstance <---
//=========================================
get_instance=next_opcode(get_instance, 0xE8, 5);
get_instance=convert_function(get_instance);
//=========================================
// (3)
//
// jGetVMInstance:
// jmp jGetVMInstance2 <----
//=========================================
get_instance=convert_function(get_instance);
//=========================================
// (4)
//
// jGetVMInstance2:
// push esi
// mov esi, ecx
// mov ecx, 5
// call GetInstance <----
// push esi
// mov ecx, eax
// call UnknowFunc
// pop esi
// retn
//=========================================
get_instance=next_opcode(get_instance, 0xE8, 5);
get_instance=convert_function(get_instance);
returnget_instance;
uint32_twar3_searcher::get_instance(uint32_tindex)
{
return((uint32_t(_fastcall*)(uint32_t))get_instance_)(index);
hashtable::native_func_table*get_native_function_hashtable()
{
return(hashtable::native_func_table*)(get_war3_searcher().get_instance(5)+0x18);
booltable_hook (constchar*proc_name,uintptr_t*old_proc_ptr,uintptr_tnew_proc)
{
hashtable::native_func_node*node_ptr=get_native_function_hashtable()->get(proc_name);
if(!node_ptr)
returnfalse;
*old_proc_ptr= (uintptr_t)node_ptr->func_address_;
node_ptr->func_address_ = (uint32_t)new_proc;
returntrue;
namespaceDzApi
{
uint32_tget_adress(std::stringdz_api_name);
voidhook(std::stringdz_api_name,uintptr_t*old_proc_ptr,uintptr_tnew_proc);
voidunhook(std::stringdz_api_name,uintptr_t*old_proc_ptr,uintptr_tnew_proc);
}
//native DzAPI_Map_SaveServerValue takesplayer whichPlayer, string key, string value returns boolean
//native DzAPI_Map_GetServerValue takesplayer whichPlayer, string key returns string
//native DzAPI_Map_Ladder_SetStat takesplayer whichPlayer, string key, string value returns nothing
//native DzAPI_Map_IsRPGLobby takesnothing returns boolean
//native DzAPI_Map_IsRPGLadder takesnothing returns boolean
//native DzAPI_Map_GetGameStartTime takesnothing returns integer
//native DzAPI_Map_Stat_SetStat takesplayer whichPlayer, string key, string value returns nothing
//native DzAPI_Map_GetMapLevel takesplayer whichPlayer returns integer
//native DzAPI_Map_MissionComplete takesplayer whichPlayer, string key, string value returns nothing
//native DzAPI_Map_GetActivityData takesnothing returns string
//native DzAPI_Map_GetMatchType takesnothing returns integer
usingbase::warcraft3::jass::jboolean_t;
usingbase::warcraft3::jass::jinteger_t;
usingbase::warcraft3::jass::jnothing_t;
usingbase::warcraft3::jass::jstring_t;
usingbase::warcraft3::jass::jhandle_t;
usingbase::warcraft3::jass::table_hook;
usingbase::warcraft3::jass::async_hook;
usingbase::warcraft3::jass::table_unhook;
usingbase::warcraft3::jass::async_unhook;
typedefbase::warcraft3::hashtable::native_func_nodeDzApiFunc;
namespaceDzApi
{
uint32_tget_adress(std::stringdz_api_name)
{
DzApiFunc*dz_func= base::warcraft3::get_native_function_hashtable()->get(dz_api_name.c_str());
if(dz_func!=nullptr)
{
[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!