首先 还是通过发包函数来判断取物品call
发现 存取物品都是同一个call
007A98DD 8DB3 8C170000 LEA ESI,DWORD PTR DS:[EBX+178C] ; ebx+178C+2a-0a
007A98E3 A1 BCA31C03 MOV EAX,DWORD PTR DS:[31CA3BC]
007A98E8 8B15 24EEF902 MOV EDX,DWORD PTR DS:[2F9EE24]
007A98EE 8985 EED7FFFF MOV DWORD PTR SS:[EBP-2812],EAX
007A98F4 A1 28EEF902 MOV EAX,DWORD PTR DS:[2F9EE28]
007A98F9 B9 20000000 MOV ECX,20
007A98FE 8DBD F2D7FFFF LEA EDI,DWORD PTR SS:[EBP-280E] ; +A
007A9904 C785 EAD7FFFF 9>MOV DWORD PTR SS:[EBP-2816],Client.00840>; +2
007A990E F3:A5 REP MOVS DWORD PTR ES:[EDI],DWORD PTR DS>
007A9910 8995 0AD8FFFF MOV DWORD PTR SS:[EBP-27F6],EDX ; +22
007A9916 8985 0ED8FFFF MOV DWORD PTR SS:[EBP-27F2],EAX ; +26
007A991C 68 86000000 PUSH 86
007A9921 8D8D E8D7FFFF LEA ECX,DWORD PTR SS:[EBP-2818]
007A9927 51 PUSH ECX
007A9928 8B0D 8048F300 MOV ECX,DWORD PTR DS:[F34880]
007A992E E8 AD01D0FF CALL Client.004A9AE0 ; 存取物品call
dd [esp]
取金创要 11
$ ==> >00 00 94 00 84 00 01 00 00 00 05 00 00 00 00 00 ..??........
$+10 >00 00 65 CA 9A 3B 00 00 00 00 0B 00 00 00 00 00 ..e蕷;.........
$+20 >00 00 A3 31 00 00 00 00 00 00 FB A3 FC F4 98 60 ..?......榒
$+30 >F0 0B 65 CA 9A 3B 00 00 00 00 39 01 00 00 00 00 ?e蕷;....9....
$+40 >00 00 08 02 00 00 01 00 00 00 00 00 00 00 00 00 .............
$+50 >00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
$+60 >00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
$+70 >00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
$+80 >00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
取人参 11
$ ==> >00 00 94 00 84 00 01 00 00 00 05 00 00 00 00 00 ..??........
$+10 >00 00 68 CA 9A 3B 00 00 00 00 0B 00 00 00 00 00 ..h蕷;.........
$+20 >00 00 3F 31 00 00 00 00 00 00 4B 38 DD 68 9A 4F ..?1......K8輍歄
$+30 >30 0B 68 CA 9A 3B 00 00 00 00 26 00 00 00 00 00 0h蕷;....&.....
$+40 >00 00 08 01 00 00 01 00 00 00 00 00 00 00 00 00 .............
$+50 >00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
$+60 >00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
$+70 >00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
$+80 >00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+1A的来源: (2字节) 物品数量
+2A的来源:(8字节) db [[物品背包基址]+410+ 4*1]+54
+3A: 物品最大上限 db [[物品背包基址]+410+ 4*1]+c44
+12的来源:(4字节) db [[物品背包基址]+410+ 4*1]+4c
+32的来源:(4字节) db [[物品背包基址]+410+ 4*1]+4c
+43的来源:(1字节) 物品下表db [[物品背包基址]+410+ 4*1]+1f4
存金疮药 11
$ ==> >00 00 94 00 84 00 01 00 00 00 03 00 00 00 2B 0C ..??......+.
$+10 >17 24 65 CA 9A 3B 00 00 00 00 0B 00 00 00 00 00 $e蕷;.........
$+20 >00 00 4D 00 00 00 00 00 00 00 FD E0 65 0B A8 07 ..M.......e?
$+30 >F0 0B 65 CA 9A 3B 00 00 00 00 81 00 00 00 00 00 ?e蕷;....?....
$+40 >00 00 01 00 00 00 01 00 4F 90 00 00 00 00 00 00 ......O?.....
$+50 >00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
$+60 >00 AB 00 00 00 00 00 00 00 00 00 00 27 3A 00 00 .?.........':..
$+70 >00 00 00 00 00 00 00 00 00 00 00 0F 1C 28 00 00 ...........(..
$+80 >00 00 1C 29 12 20 2D 0E 1A 26 00 00 00 00 00 00 ..) -&......
存人参 11
$ ==> >00 00 94 00 84 00 01 00 00 00 03 00 00 00 2B 0C ..??......+.
$+10 >17 24 6A CA 9A 3B 00 00 00 00 0B 00 00 00 00 00 $j蕷;.........
$+20 >00 00 4D 00 00 00 00 00 00 00 53 06 3B B7 99 4F ..M.......S;窓O
$+30 >70 0B 6A CA 9A 3B 00 00 00 00 17 00 00 00 00 00 pj蕷;.........
$+40 >00 00 01 01 00 00 01 00 4F 90 00 00 00 00 00 00 .....O?.....
$+50 >00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
$+60 >00 AB 00 00 00 00 00 00 00 00 00 00 27 3A 00 00 .?.........':..
$+70 >00 00 00 00 00 00 00 00 00 00 00 0F 1C 28 00 00 ...........(..
$+80 >00 00 1C 29 12 20 2D 0E 1A 26 00 00 00 00 00 00 ..) -&......
0b704f99b73b0653
//分析出来的数据 关键数据就是 +0E :0x24170c2b 就表示为存仓库
数据来源:仓库列表基址0x31CA294
+1A的来源: (2字节) 物品数量
+2A的来源:(8字节) db [[仓库列表基址]+410+ 4*1]+54
+3A: 物品最大上限 db [[仓库列表基址]+410+ 4*1]+c44
+12的来源:(4字节) db [[仓库列表基址]+410+ 4*1]+4c
+32的来源:(4字节) db [[仓库列表基址]+410+ 4*1]+4c
+43的来源:(1字节) 物品下表db [[仓库列表基址]+410+ 4*1]+1f4
首先是数据封包定义:
BYTE nbData[0x90] = {
0x00, 0x00, 0x94, 0x00, 0x84, 0x00, 0x01, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0xb2, 0xc6,
0xb3, 0xa4, 0x68, 0xCA, 0x9A, 0x3B, 0x00, 0x00, 0x00, 0x00, 0x0B, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x3F, 0x31, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4B, 0x38, 0xDD, 0x68, 0x9A, 0x4F,
0x30, 0x0B, 0x68, 0xCA, 0x9A, 0x3B, 0x00, 0x00, 0x00, 0x00, 0x26, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x08, 0x01, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
然后数据填充到结构体中:
PtSaveDepotData pSaveData = (PtSaveDepotData)nbData;
//pSaveData->ndID1_A = 0x3B9ACA6A;
//pSaveData->ndID1_B = 0x3B9ACA6A;
//pSaveData->nqID2 = 0x0b704f99b73b0653;
//pSaveData->ndGoodsSaveNum = 3;
//pSaveData->nwCurGoodsNum = 0x000000B2;
//pSaveData->ndIndexForpacket = 0x01;
__asm{
mov ecx , pSaveData
push 0x86
push ecx
MOV ECX, DWORD PTR DS : [0xF34880]
mov eax, 0x004A9AE0
CALL eax
}
以上代码就完成了对取出仓库数据的测试。
具体实现代码应该封装在一个函数中
BOOL GetGoodsFromDepot(char* szpName , DWORD ndNum){
BYTE nbData[0x90] = {
0x00, 0x00, 0x94, 0x00, 0x84, 0x00, 0x01, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0xb2, 0xc6,
0xb3, 0xa4, 0x68, 0xCA, 0x9A, 0x3B, 0x00, 0x00, 0x00, 0x00, 0x0B, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x3F, 0x31, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4B, 0x38, 0xDD, 0x68, 0x9A, 0x4F,
0x30, 0x0B, 0x68, 0xCA, 0x9A, 0x3B, 0x00, 0x00, 0x00, 0x00, 0x26, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x08, 0x01, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
DWORD ndIndex = GetGoodsIndexByName(szpName);
PtSaveDepotData pSaveData = (PtSaveDepotData)nbData;
pSaveData->ndID1_A = mtGoodsList[ndIndex].ID1;
pSaveData->ndID1_B = mtGoodsList[ndIndex].ID1;
pSaveData->nqID2 = mtGoodsList[ndIndex].ID2;
pSaveData->ndGoodsSaveNum = ndNum;
pSaveData->nwCurGoodsNum = mtGoodsList[ndIndex].ndCurNum;
pSaveData->ndIndexForpacket = mtGoodsList[ndIndex].ndIndexForPacket;
__asm{
mov ecx, pSaveData
push 0x86
push ecx
mov ecx, DWORD PTR DS:[0XF34880]
mov eax , 0x004a9ae0
call eax
}
}$ ==> >00 00 94 00 84 00 01 00 00 00 05 00 00 00 00 00 ..??........
$+10 >00 00 66 CA 9A 3B 00 00 00 00 01 00 00 00 00 00 ..f蕷;.........
$+20 >00 00 BD 66 00 00 00 00 00 00 93 0F EA B1 AD 66 ..絝......?瓯璮
$+30 >F0 01 66 CA 9A 3B 00 00 00 00 31 00 00 00 00 00 ?f蕷;....1.....
$+40 >00 00 08 00 00 00 01 00 00 00 00 00 00 00 00 00 ..............
$+50 >00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
$+60 >00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
$+70 >00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
$+80 >00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
具体分析就是这样,
还有一些关键数据:
+A 5代表取 3代表存
+22 来源人物属性基址
这两个地方数据的来源,所以我们需要重新来写结构体
#pragma pack(1)
typedef struct _tSaveDepotData{
//BYTE nb1[0x0A]; //未知数据
//DWORD ndCmd;
//DWORD ndID1_A;//0x16 ID1
//BYTE nb2[4];
////+1A 2字节存放物品数量
//WORD ndGoodsSaveNum; //0x1c
//BYTE nb3[0x6]; //
//DWORD nd22; //+26
//BYTE nb7[0x4];
////+2a 8字节 来源背包对象+54
//QWORD nqID2;
////+32 +4c
//DWORD ndID1_B;
//BYTE nb4[4];
////+3a
//WORD nwCurGoodsNum;
//BYTE nb5[7];
//BYTE ndIndexForpacket;
//BYTE nb6[0x4c];
BYTE nb1[0x0A]; //未知数据
DWORD ndCmd;//4字节 指令//存物品指令3 //取物品指令5
BYTE nb9[4];//
//+12 //4byte 来源于 物品对象+4C //OK
DWORD ndGoodType_A;//0x16 ID1
BYTE nb2[4];//
//+1A //2字节 存放的物品数量 //OK
WORD nwGoodSaveNum;//0x1C
BYTE nb3[0x6];//
DWORD nd22; //+26
BYTE nb7[0x4];
//+2A //8字节 来源于 背包物品对象+54 // OK
QWORD nqId2;//
//+32 //4byte 来源于 物品对象+4C
DWORD ndGoodType_B;
BYTE nb4[4];
//+3A //当前物品数量 2字节 //物品对象+0C44
WORD nwCurGoodsNum;//3C
BYTE nb5[7];//
//+43 //1字节 物品在背包里的下标 //1字节 //背包对象+1F4 背包下标 OK
BYTE nbIndexForBackPack;
//其它数据
BYTE nb6[0x4C]; //0x90
}tSaveDepotData, *PtSaveDepotData;
#pragma pack()
为结构体添加了一些数据,并且与封包结构进行了数据对其,然后我们要做的就是定义一个结构体来进行仓库列表的遍历和取出物品函数的封装
具体实现如下:
#define nSizeDepotList 60
typedef struct TDEPOT_LIST{
TBACK_PACK_OBJ mtGoodList[nSizeDepotList];
TDEPOT_LIST* GetData();
int TDEPOT_LIST::GetGoodsIndexForName(char* szpGoodsName);
BOOL TDEPOT_LIST::OutPutGoodsFromDepot(CHAR* szpName, DWORD ndNum); //从仓库取出物品
}_DEPOT_LIST;
BOOL TDEPOT_LIST::OutPutGoodsFromDepot(CHAR* szpName, DWORD ndNum) //从仓库取出物品
{
GetData();
int niIndex = GetGoodsIndexForName(szpName);
if (niIndex == -1){
return FALSE;
}
BYTE nbData[0x90] = {
0x00, 0x00, 0x94, 0x00, 0x84, 0x00, 0x01, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x2B, 0x0C,
0x17, 0x24, 0x68, 0xCA, 0x9A, 0x3B, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x15, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3D, 0x9E, 0x64, 0xE1, 0x20, 0x05,
0xB0, 0x0B, 0x68, 0xCA, 0x9A, 0x3B, 0x00, 0x00, 0x00, 0x00, 0x1F, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x01, 0x06, 0x00, 0x00, 0x01, 0x00, 0x4F, 0x90, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
PtSaveDepotData pSaveData = (PtSaveDepotData)nbData;
pSaveData->nd22 = *(DWORD*)(Base_CALLSendDataEDX);
pSaveData->ndCmd = 05;
pSaveData->ndGoodType_A = mtGoodList[niIndex].ndID1;
pSaveData->ndGoodType_B = pSaveData->ndGoodType_A;
pSaveData->nqId2 = mtGoodList[niIndex].ndID2;
pSaveData->nwGoodSaveNum = ndNum;
pSaveData->nwCurGoodsNum = mtGoodList[niIndex].ndGoodNum;
pSaveData->nbIndexForBackPack = mtGoodList[niIndex].ndIndexForPack;
__try{
__asm{
//lea ecx, nbData
//mov DWORD ptr[ecx + 0x12], 0x3B9ACA65
//mov WORD ptr[ecx+0x1a] ,2
//mov DWORD ptr[ecx + 0x2a], 0x0B65E0FD
//mov DWORD ptr[ecx + 0x2a + 4], 0x0BF007A8
//mov DWORD ptr[ecx + 0x32], 0x3B9ACA65
//mov DWORD ptr[ecx + 0x3a], 0x000000B2
//mov BYTE ptr[ecx + 0x43], 0x00
mov ecx, pSaveData
push 0x86
push ecx
MOV ECX, DWORD PTR DS : [Base_CallSendDataEcx]
mov eax, Base_CallSendDataCALL
CALL eax
}
}
__except (1){
DbgPrintf_Mine("存放%s 物品出现异常", szpName);
return FALSE;
}
return TRUE;
}
具体代码就是上面的那样,但是好像还有一些BUG,估计估计就是+22数据对其的问题 ,因为那个字符是从人物属性取出来的,估计就是动作一类的。
这里就不做具体分析了