富易行 发表于 2013-11-3 13:20:14

3D玄战网游圣王数据找法

资料很久了由于忙碌实业一段时间没跟这个游戏了。
把找到的数据分享一次

这个游戏有个很大的特征有holyking.map 这个文件
这个文件会有所有函数的名字和地址例如发包CALL
0001:002063f0       ??1UBI_CCSAcceptQuestPacket@@UAE@XZ 006073f0 f i SH_NpcQuestDialogData.obj、
06073f0这个地址就是发包CALL
MAP 文件可以用记事本打开 找功能非常爽的一个游戏
map文件可以转IDA的脚本文件。具体可以找百度解决。转到IDA脚本的话看函数就非常方便了

至于控件遍历也非常简单的使用 熟悉下CEGUI
然后直接动态库的方式操作调用cegui.dll直接操作游戏内所有控件
例如


void OutChilWndInfo(CEGUI::Window* wnd,int pos)
{
    const char *name = (((CEGUI::String*)((DWORD)wnd + 0xf0)))->c_str(); //childWnd->getName().c_str();
    const char *text = wnd->getText().c_str();
    wstring sTempW;

    wstring gR;
    for (int i=0;i<pos;i++)
    {
      gR.append(TEXT("\r"));
    }
    TraceOut(TEXT("%s [%S][%s]"),gR.c_str(),name,Utf8ToUnicode(text,sTempW).c_str());
    for (size_t i = 0; i < wnd->getChildCount(); ++i)
    {
      OutChilWndInfo(wnd->getChildAtIdx(i),i);
    }
    TraceOut(TEXT("%s [%S]"),gR.c_str(),name);
}


void CInfoWnd::OnBnClickedButton()
{
OutChilWndInfo(CEGUI::System::getSingleton().getGUISheet(),0);   //这样调用就可以遍里游戏内所有游戏窗口的标题和名字了
}

你得到CEGUI的CEGUI::Window 然后就可以得到标题的内容了。如果想下按某一个控件 就要移动鼠标 然后下按一次就OK

//             CEGUI::Rect wndRec = childWnd->getInnerRectClipper();
//             sprintf_s(buf,"[%f][%f]\n[%f][%f]",wndRec.d_left, wndRec.d_top, wndRec.d_right, wndRec.d_bottom);
//             MessageBoxA(NULL,buf,"",MB_OK);
//
//
//             float wndWidth =wndRec.d_right - wndRec.d_left;
//             float wndHigh = wndRec.d_bottom - wndRec.d_top;
//
//             //SetCursorPos(wndRec.d_left+wndWidth/2,wndRec.d_top+wndHigh/2+20);
//
//             CEGUI::System::getSingleton().injectMousePosition(wndRec.d_left+wndWidth/2,wndRec.d_top+wndHigh/2);
//
//             CEGUI::System::getSingleton().injectMouseButtonDown(CEGUI::LeftButton);
//
//             CEGUI::System::getSingleton().injectMouseButtonUp(CEGUI::LeftButton);

以上代码就是将鼠标移动到某一个窗口的中心点然后下按一次

使用CEGUI就是这么简单   

至于要得到游戏内的数据还是很简单的。比如遍里包裹。移动到某一个点。
这些操作全部可以使用LUA实现
lua直接使用游戏自身注册函数


int LuaDoString(const char *cmd)
{
    try
    {
      _asm
      {
            pushad
            mov      eax,call_GetLuaState_A
            call    eax
            mov      ecx,eax
            push   
            mov      eax,call_DoString_A
            call    eax
            popad
      }
    }
    catch (...)
    {
      TraceOut(TEXT("CGameFunc::LuaDoString 异常"));
    }

}

LuaDoStringd("ofile(c:\\\\1.lua);"); 这样调用就可以实现让游戏执行c:\1.lua 这个lua脚本了

lua脚本函数内可以自由使用游戏注册的lua函数
例如移动到某个NPC
SceneMapData:MoveToNPC(0x313d);
这样就可以移动到某个NPC了

注意切换类环境例如
setfenv(1,SceneMap);-- 功能描述 : 场景大地图

setfenv(1,Quest_Management);-- 功能描述:任务管理界面信息
setfenv(1,Activity);-- 活动
这些环境切换错误会导致调用无效或者变量获取不正常

至于怎么加自己的LUA函数接口就自己思考下了。很简单就能实现的



local FrontTask = GetFrontTask();--GetFrontTask()是智辅函数
if (FrontTask == 0) then return end;

local QuestName = MyselfQuestData:GetQuestName(FrontTask);--获得任务名字


TraceOut(tostring(QuestName));-- TraceOut智辅函数
if (QuestName == nil) then
TraceOut("AcceptQuest:"..FrontTask);
AcceptQuest(FrontTask);--AcceptQuest接任务接任务是可以远程接的。。交任务没测试
return;
end



SceneMapData:MoveToNPC(taskData_CQ["MoveToNpc"]);

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////


开始挂机
param0:
setfenv(1,AutoMachine);AutoMachine_StarAutoMachine();

关闭挂机
param0:
setfenv(1,AutoMachine);AutoMachine_StopAutoMachine();

关闭任务窗口
param0:
setfenv(1,NPCDialog);NPCDialog_Hide();

param0
param1
param2
。。。。。。
上面这些是可以通过 LuaDoString这个函数来使用的   LuaDoString(“setfenv(1,NPCDialog);NPCDialog_Hide();”); 这样调用
但是param0 param1 这些参数需要挂钩游戏调用才能捕获到
param0 是lua的一个全局变量param1 param2 依次类推 是游戏lua参数通讯
就是游戏调用脚本的时候用的
比如分解装备 选择NPC对话第几项都需要设置这个参数 全是文本类型的
设置函数

.text:00419C50 E8 4B DA 00 00                call    ?GetSingleton@UBI_ScriptSystem@@SAAAV1@XZ ; UBI_ScriptSystem::GetSingleton(void)
.text:00419C55 E8 46 DD 00 00                call    ?__GetLuaState@UBI_ScriptSystem@@KAPAVLuaState@LuaPlus@@XZ ; UBI_ScriptSystem::__GetLuaState(void)
.text:00419C5A 8D 8D 10 FD FF FF             lea   ecx,
.text:00419C60 51                            push    ecx
.text:00419C61 8B C8                         mov   ecx, eax
.text:00419C63 E8 F8 55 2F 00                call    ?GetGlobals@LuaState@LuaPlus@@QAE?AVLuaObject@2@XZ ; LuaPlus::LuaState::GetGlobals(void)
.text:00419C68 C6 45 FC 01                   mov   byte ptr , 1
.text:00419C6C 68 63 27 79 00                push    offset ??_C@_00CNPNBAHC@?$AA@ ; Str
.text:00419C71 68 5C 27 79 00                push    offset ??_C@_06NCJCGBBM@param0?$AA@ ; "param0"
.text:00419C76 8B C8                         mov   ecx, eax
.text:00419C78 E8 E3 DE 2E 00                call    ?SetString@LuaObject@LuaPlus@@QAEAAV12@PBD0@Z ; LuaPlus::LuaObject::SetString(char const *,char const *)
.text:00419C7D C6 45 FC 00                   mov   byte ptr , 0

至于怎么获得游戏脚本。,这个只能DUMP游戏内存。你直接搜索 lua的关键字 然后找到文件的启始位置DUMP 保存成文本。加上UTF8的标志头就可以看到中文的注释和LUA代码了
页: [1]
查看完整版本: 3D玄战网游圣王数据找法