86号“出席活动”的研究心得
活动的服务端基址是0x081DAFFA,经过研究发现签到按钮的亮灭(疑似)不在服务端控制。isSetBit_Uint(v26, today_time_day - 1)没研究明白。而setBit_Uint(&v25, 1, today_time_day - 1)是控制活动是否结束,大于0时活动结束。Dispatcher_FatigueAttendance::check_error返回99是在副本不可签到,返回7是不在活动范围,返回0时才可以签到领取奖励。下面是frida的一些函数,只是可以得到一些相关信息,目前就搞到这里。
调试输出
"check_error result:"返回99,7,0。
"today_time_day:"返回当月的第几天。
"server_fatigue_count:"账号今天签到时消耗的疲劳。
"event_entity:"不知道什么东西。
"Event time:" PVF写的活动开始,结束时间,以及当天时间。
"pass_day"今天前面过了几天。
"db_fatigue_count:"数据库疲劳数量,这个不知道怎么搞的,有时候有有时候无。
"total_fatigue:" server_fatigue_count+db_fatigue_count。
"fatigue_condition:" PVF里写的要求消耗疲劳数,如下图我写的1,打印读取的就是1。
活动时长要大于91天,小于的时候每天都会变成已签到并且无奖励。
上图可以看到95天也可以正常领取。
数据库
这个图不知道为什么没上传到上面,这个代码没实现什么功能,就是为了打印调试用的。
受教了 数据记录要角色下线才会把数据传到数据库 测试过程时不时就遇到自动签到的情况。而服务端目前没有发现能控制他的地方,服务端目前只知道能控制活动结束,或者控制发放道具次数,其他的没深究。
以前签到过就会领不了 // Frida脚本 - 游戏限购商品发布功能(生产环境版)// 目标函数: Inter_ItemLimitEdition_Sell_Start::dispatch_sig// 编译环境: Frida 15+
function sendItemLimitEdition(userPtr, itemIndex, endTimestamp) { const dispatchSigAddr = ptr('0x084DB878'); // 需替换实际地址
//▼▼▼ 参数验证 ▼▼▼ const MIN_ITEM_ID = 1; const MAX_ITEM_ID = 10000; if (itemIndex < MIN_ITEM_ID || itemIndex > MAX_ITEM_ID) { console.error(` Invalid itemIndex: ${itemIndex}, allowed range [${MIN_ITEM_ID}-${MAX_ITEM_ID}]`); return; }
//▼▼▼ 计算结构尺寸 ▼▼▼ const HEADER_SIZE = 15; // 头结构尺寸 const ITEM_SIZE = 72; // 单个商品块尺寸 const totalSize = HEADER_SIZE + ITEM_SIZE;
//▼▼▼ 安全构建参数结构 ▼▼▼ const buildParams = () => { const buf = Memory.alloc(totalSize); // 头结构 (0x00-0x0E) buf.writeByteArray(new Array(10).fill(0)); buf.add(0x0A).writeU8(1); buf.add(0x0B).writeU32(1);
// 商品块 (0x0F开始) const itemBlock = buf.add(0x0F); //不填代码0x0F时,商城限购会错乱 itemBlock.add(0x00).writeU32(1); //此代码添加后物品数量正常了,没有这条时,物品会显示9999999个 itemBlock.add(0x01).writeU32(1); //礼包限购,并且0x04失效了;0x09存在时,此行不生效 itemBlock.add(0x02).writeU32(1); // itemBlock.add(0x03).writeU32(1); //
itemBlock.add(0x04).writeU32(21); //---限购物品ID--- 4 itemBlock.add(0x05).writeU32(0); //---礼包限购相关--- itemBlock.add(0x06).writeU32(0); //---礼包限购相关--- itemBlock.add(0x07).writeU32(0); //---礼包限购相关---
itemBlock.add(0x08).writeU32(22); //---限购物品数量---8 itemBlock.add(0x09).writeU32(0); //---道具数量翻倍--- 数值1=256;2=512;如果是填1,那么加上08的55,那就显示311个 itemBlock.add(0x0A).writeU32(0); //---道具数量翻倍--- itemBlock.add(0x0B).writeU32(0); //---道具数量翻倍---
itemBlock.add(0x0C).writeU32(1); //12,不能超过999 itemBlock.add(0x0D).writeU32(0); // itemBlock.add(0x0E).writeU32(0); // itemBlock.add(0x0F).writeU32(0);
itemBlock.add(0x10).writeU32(0); //---点券基本价格--- 16 itemBlock.add(0x11).writeU32(0); //---点券价格翻倍--- 1;价格不变填2;256 itemBlock.add(0x12).writeU32(0); //---点券价格翻倍--- itemBlock.add(0x13).writeU32(0); //---点券价格翻倍---
itemBlock.add(0x14).writeU32(0); //---金币基本价格--- 20 itemBlock.add(0x15).writeU32(0); //---金币价格翻倍--- itemBlock.add(0x16).writeU32(0); //---金币价格翻倍--- itemBlock.add(0x17).writeU32(0); //---金币价格翻倍---
itemBlock.add(0x18).writeU32(2); //24 itemBlock.add(0x19).writeU32(1); // itemBlock.add(0x1A).writeU32(1); // itemBlock.add(0x1B).writeU32(1); //
// itemBlock.add(0x1C).writeU32(1); //28 // itemBlock.add(0x1D).writeU32(1); // // itemBlock.add(0x1E).writeU32(1); // // itemBlock.add(0x1F).writeU32(1); //
// itemBlock.add(0x20).writeU32(1743423690); //32 // itemBlock.add(0x21).writeU32(1743423690); // // itemBlock.add(0x22).writeU32(1743423690); // itemBlock.add(0x23).writeU32(1743423690);
// itemBlock.add(0x24).writeU32(1743423690); //36 // itemBlock.add(0x25).writeU32(1743423690); // itemBlock.add(0x26).writeU32(1743423690); // itemBlock.add(0x27).writeU32(1743423690);
itemBlock.add(0x28).writeU32(1743423690); //40 itemBlock.add(0x29).writeU32(0); itemBlock.add(0x2A).writeU32(0); itemBlock.add(0x2B).writeU32(0);
// itemBlock.add(0x2C).writeU32(1743423690); //44 // itemBlock.add(0x2D).writeU32(1743423690); // itemBlock.add(0x2E).writeU32(1743423690); // itemBlock.add(0x2F).writeU32(1743423690);
// itemBlock.add(0x30).writeU32(1743423690); //48 // itemBlock.add(0x31).writeU32(1743423690); // itemBlock.add(0x32).writeU32(1743423690); // itemBlock.add(0x33).writeU32(1743423690);
// itemBlock.add(0x34).writeU32(1743423690); //52 // itemBlock.add(0x35).writeU32(1743423690); // itemBlock.add(0x36).writeU32(1743423690); // itemBlock.add(0x37).writeU32(1743423690);
// itemBlock.add(0x38).writeU32(1743423690); //56 // itemBlock.add(0x39).writeU32(1743423690); // itemBlock.add(0x3A).writeU32(1743423690); // itemBlock.add(0x3B).writeU32(1743423690);
// itemBlock.add(0x3C).writeU32(1743423690); //60 // itemBlock.add(0x3D).writeU32(1743423690); // itemBlock.add(0x3E).writeU32(1743423690); // itemBlock.add(0x3F).writeU32(1743423690);
// itemBlock.add(0x38).writeU32(11); //itemBlock.add(0x40).writeU32(0); //itemBlock.add(0x68).writeU32(0); return buf; };
//▼▼▼ 调用原生函数 ▼▼▼ try { const thisPtr = ptr("0xD7A24B8"); // 需替换实际地址 if (thisPtr.isNull() || userPtr.isNull()) { console.error(" Invalid pointers!"); return; }
const params = buildParams(); const dispatchSig = new NativeFunction( dispatchSigAddr, 'int', ['pointer', 'pointer', 'pointer'], { abi: 'sysv' } );
const result = dispatchSig(thisPtr, userPtr, params); console.log(` Dispatch result: ${result}`); } catch (e) { console.error(` Native call failed: ${e.message}`); }}
//▼▼▼ 使用示例 ▼▼▼(function main() { const userPtr = ptr(0x86C4D40); // 替换实际地址 const targetItemId = 900; const endTime = Math.floor(Date.now() / 1000) + 3600; sendItemLimitEdition(userPtr, targetItemId, endTime);})(); 服务端的基址怎么找啊楼主
页:
[1]