void PLH::AbstractDetour::RelocateASM(BYTE* Code, DWORD& CodeSize, DWORD64 From, DWORD64 To) { cs_insn* InstructionInfo; size_t InstructionCount = cs_disasm(m_CapstoneHandle, Code, CodeSize, (uint64_t)Code, 0, &InstructionInfo); XTrace("\nTrampoline:\n"); for (int i = 0; i < InstructionCount; i++) { cs_insn* CurIns = (cs_insn*)&InstructionInfo[i]; cs_x86* x86 = &(CurIns->detail->x86); XTrace("%I64X: ", CurIns->address); for (int j = 0; j < CurIns->size; j++) XTrace("%02X ", CurIns->bytes[j]); XTrace("%s %s\n", CurIns->mnemonic,CurIns->op_str); for (int j = 0; j < x86->op_count; j++) { cs_x86_op* op = &(x86->operands[j]); if (op->type == X86_OP_MEM) { //MEM are types like lea rcx,[rip+0xdead] if (op->mem.base == X86_REG_INVALID) continue; //Are we relative to instruction pointer? if (op->mem.base != GetIpReg()) continue; _Relocate(CurIns, From, To, x86->offsets.displacement_size, x86->offsets.displacement_offset); }else if (op->type == X86_OP_IMM) { //IMM types are like call 0xdeadbeef if (x86->op_count > 1) //exclude types like sub rsp,0x20 continue; char* mnemonic = CurIns->mnemonic; if (m_ASMInfo.IsConditionalJump(CurIns->bytes,CurIns->size)) { RelocateConditionalJMP(CurIns, CodeSize, From, To, x86->offsets.imm_size, x86->offsets.imm_offset); continue; } //types like push 0x20 slip through, check mnemonic if (strcmp(mnemonic, "call") != 0 && strcmp(mnemonic, "jmp") != 0) //probably more types than just these, update list as they're found continue; _Relocate(CurIns, From, To, x86->offsets.imm_size, x86->offsets.imm_offset); } } } XTrace("\nFixed Trampoline\n"); InstructionCount = cs_disasm(m_CapstoneHandle, Code, CodeSize, (uint64_t)Code, 0, &InstructionInfo); for (int i = 0; i < InstructionCount; i++) { cs_insn* CurIns = (cs_insn*)&InstructionInfo[i]; XTrace("%I64X: ", CurIns->address); for (int j = 0; j < CurIns->size; j++) XTrace("%02X ", CurIns->bytes[j]); XTrace("%s %s\n", CurIns->mnemonic, CurIns->op_str); } cs_free(InstructionInfo, InstructionCount); }
int WorldSession::Update(uint32 diff, int32 mapId) { m_currMsTime += diff; WorldPacket *packet; uint32 i =0; uint16 opcode =0; if(mapId != m_MapId) { _Relocate(); return 2; } if (!_socket) { LogoutPlayer(true); return 1; } while (_recvQueue.size()) { if(m_MapId != mapId) { _Relocate(); return 2; } packet = _recvQueue.next(); if(packet==NULL) continue; opcode = packet->GetOpcode(); if(opcode >= NUM_MSG_TYPES) sLog.outDebug("[Session] Received out of range packet with opcode 0x%.4X", opcode); else { OpcodeHandler * Handler = &WorldPacketHandlers[opcode]; if(Handler->status == STATUS_LOGGEDIN && !_player && Handler->handler != 0) { sLog.outDebug("[Session] Received unexpected/wrong state packet with opcode %s (0x%.4X)", LookupName(opcode, g_worldOpcodeNames), opcode); } else { // Valid Packet :> if(Handler->handler == 0) { sLog.outDebug("[Session] Received unhandled packet with opcode %s (0x%.4X)", LookupName(opcode, g_worldOpcodeNames), opcode); } else { (this->*Handler->handler)(*packet); } } } delete packet; } if( _logoutTime && (m_currMsTime >= _logoutTime) && m_MapId == mapId) LogoutPlayer(true); if(m_lastPing + WORLDSOCKET_TIMEOUT < time(NULL)) { // ping timeout! Disconnect(); return 1; } if(m_MapId != mapId) { // we have relocated. _Relocate(); return 2; } return 0; }