首先是找到出售物品的call
007A97E7 898D 0AD8FFFF MOV DWORD PTR SS:[EBP-27F6],ECX
007A97ED 8B0D 8048F300 MOV ECX,DWORD PTR DS:[F34880]
007A97F3 52 PUSH EDX
007A97F4 C785 EED7FFFF 0>MOV DWORD PTR SS:[EBP-2812],2
007A97FE 8985 1ED8FFFF MOV DWORD PTR SS:[EBP-27E2],EAX
007A9804 8985 FED7FFFF MOV DWORD PTR SS:[EBP-2802],EAX
007A980A E8 D102D0FF CALL Client.004A9AE0 ; 出售物品的call
007A980F 8BCB MOV ECX,EBX
007A9811 E8 FA9AFEFF CALL Client.00793310
007A9816 E9 92060000 JMP Client.007A9EAD
007A981B A1 9C5BF300 MOV EAX,DWORD PTR DS:[F35B9C]
007A9820 05 3C010000 ADD EAX,13C
007A9825 50 PUSH EAX
007A9826 E8 C5BD1900 CALL Client.009455F0
007A982B 83C4 04 ADD ESP,4
007A982E 8983 1C170000 MOV DWORD PTR DS:[EBX+171C],EAX
dd edx查看缓冲区 会找到以下的数据:
出售 金创药(小) 1
$ ==> >00 00 92 00 80 00 02 00 00 00 26 0F 1B 28 65 CA ..?€....&(e?
$+10 >9A 3B 00 00 00 00 01 00 00 00 00 00 00 00 9B 16 ?...........?
$+20 >00 00 00 00 00 00 CD DD B3 A1 29 67 F0 0B 65 CA ......洼场)g?e?
$+30 >9A 3B 00 00 00 00 01 00 00 00 00 00 00 00 01 00 ?............
$+40 >00 00 01 00 14 23 00 00 00 00 00 00 00 00 00 00 ...#..........
$+50 >00 00 00 00 00 00 00 00 00 00 00 00 00 9A 00 00 .............?.
$+60 >00 00 00 00 00 00 00 00 5E 9A 00 00 00 00 00 00 ........^?.....
$+70 >00 00 00 00 00 00 00 52 87 C2 00 00 00 00 97 CF .......R嚶....椣
$+80 >5E 94 CE 53 73 9E 00 00 00 00 00 00 00 00 00 00 ^斘Ss?.........
3个
$ ==> >00 00 92 00 80 00 02 00 00 00 26 0F 1B 28 65 CA ..?€....&(e?
$+10 >9A 3B 00 00 00 00 03 00 00 00 00 00 00 00 9A 17 ?...........?
$+20 >00 00 00 00 00 00 CD DD B3 A1 29 67 F0 0B 65 CA ......洼场)g?e?
$+30 >9A 3B 00 00 00 00 03 00 00 00 00 00 00 00 01 00 ?............
$+40 >00 00 01 00 14 23 00 00 00 00 00 00 00 00 00 00 ...#..........
$+50 >00 00 00 00 00 00 00 00 00 00 00 00 00 9A 00 00 .............?.
$+60 >00 00 00 00 00 00 00 00 5E 9A 00 00 00 00 00 00 ........^?.....
$+70 >00 00 00 00 00 00 00 52 87 C2 00 00 00 00 97 CF .......R嚶....椣
$+80 >5E 94 CE 53 73 9E 00 00 00 00 00 00 00 00 00 00 ^斘Ss?.........
出售雪原参 1
$ ==> >00 00 92 00 80 00 02 00 00 00 26 0F 1B 28 6A CA ..?€....&(j?
$+10 >9A 3B 00 00 00 00 01 00 00 00 00 00 00 00 B3 16 ?...........?
$+20 >00 00 00 00 00 00 D9 5C 1E CD 2C 67 B0 0B 6A CA ......賊?g?j?
$+30 >9A 3B 00 00 00 00 01 00 00 00 00 00 00 00 01 01 ?...........
$+40 >00 00 01 00 14 23 00 00 00 00 00 00 00 00 00 00 ...#..........
$+50 >00 00 00 00 00 00 00 00 00 00 00 00 00 9A 00 00 .............?.
$+60 >00 00 00 00 00 00 00 00 5E 9A 00 00 00 00 00 00 ........^?.....
$+70 >00 00 00 00 00 00 00 52 87 C2 00 00 00 00 97 CF .......R嚶....椣
$+80 >5E 94 CE 53 73 9E 00 00 00 00 00 00 00 00 00 00 ^斘Ss?.........
出售 人参 1
$ ==> >00 00 92 00 80 00 02 00 00 00 26 0F 1B 28 68 CA ..?€....&(h?
$+10 >9A 3B 00 00 00 00 01 00 00 00 00 00 00 00 43 17 ?...........C
$+20 >00 00 00 00 00 00 1F C0 12 41 92 67 70 0B 68 CA ......?A抔ph?
$+30 >9A 3B 00 00 00 00 01 00 00 00 00 00 00 00 01 02 ?...........
$+40 >00 00 01 00 14 23 00 00 00 00 00 00 00 00 00 00 ...#..........
$+50 >00 00 00 00 00 00 00 00 00 00 00 00 00 9A 00 00 .............?.
$+60 >00 00 00 00 00 00 00 00 5E 9A 00 00 00 00 00 00 ........^?.....
$+70 >00 00 00 00 00 00 00 52 87 C2 00 00 00 00 97 CF .......R嚶....椣
$+80 >5E 94 CE 53 73 9E 00 00 00 00 00 00 00 00 00 00 ^斘Ss?.........
出售 金创药(大) 1
$ ==> >00 00 92 00 80 00 02 00 00 00 26 0F 1B 28 66 CA ..?€....&(f?
$+10 >9A 3B 00 00 00 00 01 00 00 00 00 00 00 00 5E 17 ?...........^
$+20 >00 00 00 00 00 00 8B 15 E2 BD 97 68 30 0B 66 CA ......?饨梙0f?
$+30 >9A 3B 00 00 00 00 01 00 00 00 00 00 00 00 01 03 ?...........
$+40 >00 00 01 00 14 23 00 00 00 00 00 00 00 00 00 00 ...#..........
$+50 >00 00 00 00 00 00 00 00 00 00 00 00 00 9A 00 00 .............?.
$+60 >00 00 00 00 00 00 00 00 5E 9A 00 00 00 00 00 00 ........^?.....
$+70 >00 00 00 00 00 00 00 52 87 C2 00 00 00 00 97 CF .......R嚶....椣
+2 (DWORD) 指令
+A 出售物品特征码
+E 物品类型 来源于 背包+4C
+16 (BYTE) 物品数量
+1E ....
+26 8字节 物品信息 来源于物品+54
+2E 物品类型
+36 物品数量
+3F 物品下表 1字节
以上就是对出售物品封包的分析,下面要做的就是对数据进行结构化和函数的封装
#define nSizePackBack 36
typedef struct TBACKPACK_LIST
{
TBACK_PACK_OBJ mtGoodList[nSizePackBack];
TBACKPACK_LIST* GetData();
int UseGoodsForIndex(DWORD Index);
int GetGoodsIndexForName(char* szpGoodsName);
BOOL UseGoodsForName(char* szpGoodsName);
void DbgPrint();
DWORD SelGoods(DWORD ndIndex); //选中背包中的某一格中的物品
BOOL MoveGoodsToDepot(DWORD ndIndex = 1);//移动选中物品到仓库中的某一格
BOOL MoveGoodsToDepot(char* szpName);//移动选中物品到仓库中的某一格
BOOL TBACKPACK_LIST::MoveGoodsToEquipm(char* szpName, int EquipmPos); //移动装备到身上的装备栏
BOOL TBACKPACK_LIST::SaveGoodsTpDepot(CHAR* szpName, DWORD ndNum); //封装存物品call
BOOL TBACKPACK_LIST::SellGoodsForName(char* szpName, DWORD ndNum);
}_TBACKPACK_LIST;
#pragma pack(1)
#define ndBuyType 1
#define ndSelType 2
typedef struct _tBuyGoodsData{
BYTE nd111[2];
DWORD ndSendCmdType;
DWORD ndBuySelType;
DWORD nd1111;
DWORD ndGoodsType;
DWORD nd2222;
DWORD ndNum;
BYTE nd16[0x0C];
//+26 8字节
QWORD nqGoodsId;
//
DWORD ndGoodsType2;
BYTE nbTemp333[13];
BYTE nbIndexForBackpack;
BYTE nb[0x50];
}_tBuyGoodsData;
#pragma pack()
BOOL TBACKPACK_LIST::SellGoodsForName(char* szpName, DWORD ndNum){
DWORD ndIndex = GetGoodsIndexForName(szpName);
if (ndIndex == -1){
return FALSE;
}
BYTE nbData[0x90] = {
0x00, 0x00, 0x92, 0x00, 0x80, 0x00, 0x02, 0x00, 0x00, 0x00, 0x26, 0x0F, 0x1B, 0x28, 0x65, 0xCA,
0x9A, 0x3B, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x9B, 0x16,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xCD, 0xDD, 0xB3, 0xA1, 0x29, 0x67, 0xF0, 0x0B, 0x65, 0xCA,
0x9A, 0x3B, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00,
0x00, 0x00, 0x01, 0x00, 0x14, 0x23, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x9A, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5E, 0x9A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x52, 0x87, 0xC2, 0x00, 0x00, 0x00, 0x00, 0x97, 0xCF,
0x5E, 0x94, 0xCE, 0x53, 0x73, 0x9E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
_tBuyGoodsData *ptBuyGoodsData = (_tBuyGoodsData*)nbData;
ptBuyGoodsData->ndSendCmdType = 0x00800092;
ptBuyGoodsData->ndBuySelType = ndSelType;
ptBuyGoodsData->ndGoodsType = mtGoodList[ndIndex].ndID1;
ptBuyGoodsData->ndGoodsType2 = mtGoodList[ndIndex].ndID1;
ptBuyGoodsData->ndNum = ndNum;
ptBuyGoodsData->nqGoodsId = mtGoodList[ndIndex].ndID2;
ptBuyGoodsData->nbIndexForBackpack = mtGoodList[ndIndex].ndIndexForPack;
__try
{
__asm{
mov eax, ptBuyGoodsData
//mov DWORD ptr[ecx + 0x2], 0x3B9ACA65
//mov WORD ptr[ecx+0x6] ,2
//mov DWORD ptr[ecx + 0x16], 0x0B65E0FD
//mov DWORD ptr[ecx + 0x26], 0x0BF007A8
//mov DWORD ptr[ecx + 0x26+ 4], 0x3B9ACA65
//mov DWORD ptr[ecx + 0x0e], 0x000000B2
//mov BYTE ptr[ecx + 0x2e],0x00
//mov BYTE ptr[ecx + 0x3f], 0x00
push 0x86
push eax
MOV ECX, DWORD PTR DS : [Base_CallSendDataEcx]
mov eax ,Base_CallSendDataCALL
call eax
}
}
__except (1){
DbgPrintf_Mine("BOOL TBACKPACK_LIST::SellGoodsForName(char* szpName, DWORD ndNum) 出现异常");
}
return TRUE;
}
以上代码就完成了对物品出售的封装,跟以前分析的存入仓库和购买物品都有类似之处,所以还是很简单的