Skip to content

Instantly share code, notes, and snippets.

@Ouroboros
Last active October 21, 2021 16:05
Show Gist options
  • Save Ouroboros/a5e7649c4457059fbd6638904bec0101 to your computer and use it in GitHub Desktop.
Save Ouroboros/a5e7649c4457059fbd6638904bec0101 to your computer and use it in GitHub Desktop.
diablo ii update pos
const D2Modules = {
D2Net : Process.getModuleByName('D2Net.dll'),
Storm : Process.getModuleByName('Storm.dll'),
D2Client: Process.getModuleByName('D2Client.dll'),
};
const KERNEL32 = Process.getModuleByName('KERNEL32.dll');
const GetProcAddress = new NativeFunction(KERNEL32.findExportByName("GetProcAddress"), "pointer", ['pointer', 'int']);
const D2GAME_WALKTOLOCATION = 0x01;
const D2GAME_WALKTOENTITY = 0x02;
const D2GAME_RUNTOLOCATION = 0x03;
const D2GAME_RUNTOENTITY = 0x04;
const D2GAME_LEFTSKILLONLOCATION = 0x05;
const D2GAME_LEFTSKILLONENTITY = 0x06;
const D2GAME_LEFTSKILLONENTITYEX = 0x07;
const D2GAME_LEFTSKILLONLOCATIONEX = 0x08;
const D2GAME_LEFTSKILLONENTITYEX2 = 0x09;
const D2GAME_LEFTSKILLONENTITYEX3 = 0x0A;
const D2GAME_SKILLUNK1 = 0x0B;
const D2GAME_RIGHTSKILLONLOCATION = 0x0C;
const D2GAME_RIGHTSKILLONENTITY = 0x0D;
const D2GAME_RIGHTSKILLONENTITYEX = 0x0E;
const D2GAME_RIGHTSKILLONLOCATIONEX = 0x0F;
const D2GAME_RIGHTSKILLONENTITYEX2 = 0x10;
const D2GAME_RIGHTSKILLONENTITYEX3 = 0x11;
const D2GAME_SKILLUNK2 = 0x12;
const D2GAME_INTERACTWITHENTITY = 0x13;
const D2GAME_OVERHEADMESSAGE = 0x14;
const D2GAME_CHATMESSAGE = 0x15;
const D2GAME_PICKUPITEM = 0x16;
const D2GAME_DROPITEM = 0x17;
const D2GAME_ITEMTOBUFFER = 0x18;
const D2GAME_PICKUPBUFFERITEM = 0x19;
const D2GAME_ITEMTOBODY = 0x1A;
const D2GAME_SWAP2HANDEDITEM = 0x1B;
const D2GAME_PICKUPBODYITEM = 0x1C;
const D2GAME_SWITCHBODYITEM = 0x1D;
const D2GAME_SWITCHBODYITEM2 = 0x1E;
const D2GAME_SWITCHINVENTORYITEM = 0x1F;
const D2GAME_USEITEM = 0x20;
const D2GAME_STACKITEM = 0x21;
const D2GAME_REMOVESTACKITEM = 0x22;
const D2GAME_ITEMTOBELT = 0x23;
const D2GAME_REMOVEBELTITEM = 0x24;
const D2GAME_SWITCHBELTITEM = 0x25;
const D2GAME_USEBELTITEM = 0x26;
const D2GAME_IDENTIFYITEM = 0x27;
const D2GAME_INSERTSOCKETITEM = 0x28;
const D2GAME_SCROLLTOTOME = 0x29;
const D2GAME_ITEMTOCUBE = 0x2A;
const D2GAME_UNSELECTOBJ = 0x2D;
const D2GAME_CHATUNK1 = 0x2E;
const D2GAME_NPCINIT = 0x2F;
const D2GAME_NPCCANCEL = 0x30;
const D2GAME_QUESTMESSAGE = 0x31;
const D2GAME_NPCBUY = 0x32;
const D2GAME_NPCSELL = 0x33;
const D2GAME_CAINIDENTIFY = 0x34;
const D2GAME_REPAIR = 0x35;
const D2GAME_HIRE = 0x36;
const D2GAME_GAMBLED = 0x37;
const D2GAME_NPCTRADE = 0x38;
const D2GAME_BUYHEALTH = 0x39;
const D2GAME_STATPOINT = 0x3A;
const D2GAME_SKILLPOINT = 0x3B;
const D2GAME_SWITCHSKILL = 0x3C;
const D2GAME_CLOSEDOOR = 0x3D;
const D2GAME_UPDATEITEMSTAT = 0x3E;
const D2GAME_CHARACTERPHRASE = 0x3F;
const D2GAME_QUESTLOG = 0x40;
const D2GAME_RESPAWN = 0x41;
const D2GAME_UNK2 = 0x48;
const D2GAME_PUTSLOT = 0x44;
const D2GAME_CHANGETP = 0x45;
const D2GAME_MERCINTER = 0x46;
const D2GAME_MOVEMERC = 0x47;
const D2GAME_WAYPOINT = 0x49;
const D2GAME_REASSIGN = 0x4B;
const D2GAME_DISAPPEARITEM = 0x4C;
const D2GAME_UNK1 = 0x4D;
const D2GAME_TRADE = 0x4F;
const D2GAME_DROPGOLD = 0x50;
const D2GAME_ASSIGNMENT = 0x51;
const D2GAME_STAON = 0x53;
const D2GAME_STAOFF = 0x54;
const D2GAME_CLOSEQUEST = 0x58;
const D2GAME_TOWNFOLK = 0x59;
const D2GAME_RELATION = 0x5d;
const D2GAME_PARTY = 0x5E;
const D2GAME_UPDATEPOSITION = 0x5F;
const D2GAME_SWITCHEQUIP = 0x60;
const D2GAME_POTIONTOMERCENARY = 0x61;
const D2GAME_RESURRECTMERC = 0x62;
const D2GAME_INVENTORYTOBELT = 0x63;
const D2GAME_GAMELOGON = 0x68;
const D2GAME_GAMEEXIT = 0x69;
const D2GAME_ENTERGAMEENVIRONMENT = 0x6B;
const D2GAME_PING = 0x6D;
const Logging = false;
Number.prototype.pad = Number.prototype.pad || function (base) {
let nr = this, len = (String(base).length - String(nr).length)+1;
return len > 0? new Array(len).join('0')+nr : nr;
};
Number.prototype.hex = Number.prototype.hex || function () {
let prefix = '';
if (this < 0x10)
prefix = '0';
return '0x' + prefix + this.toString(16);
};
function log(s) {
if (Logging == false)
return;
const now = new Date;
const time = `[${(now.getHours() + 8).pad(10)}:${now.getMinutes().pad(10)}:${now.getSeconds().pad(10)}.${now.getMilliseconds().pad(100)}]`;
console.log(`${time} ${s}`);
}
function getCurrnetPos() {
const invalidPos = {
x: 0,
y: 0,
};
const char = D2Modules.D2Client.base.add(0x11D050).readPointer();
if (char.isNull())
return invalidPos;
const type = char.readU32();
const pos = char.add(0x2C).readPointer();
if (pos.isNull())
return invalidPos;
switch (type) {
case 2:
case 4:
case 5:
return invalidPos;
}
return {
x: Number(pos.add(2).readU16()),
y: Number(pos.add(6).readU16()),
};
}
function hook_d2net() {
const D2Net_SendPacket = GetProcAddress(D2Modules.D2Net.base, 10015);
log('D2Net_SendPacket = ' + D2Net_SendPacket);
const extraUpdateCountInitial = 2;
let retaddr = 0;
let updatePosCounter = 0;
let extraUpdateCount = extraUpdateCountInitial;
let lastPos = {x:0, y:0};
const _D2Net_SendPacket = new NativeFunction(D2Net_SendPacket, "void", ['int', 'int', 'pointer']);
function updatePosInternal() {
const pos = getCurrnetPos();
if (pos.x == 0 && pos.y == 0)
return false
if (pos.x == lastPos.x && pos.y == lastPos.y) {
if (extraUpdateCount == 0) {
return false;
}
extraUpdateCount--;
} else {
extraUpdateCount = extraUpdateCountInitial;
}
lastPos = pos;
log('updatePos');
const b = Memory.alloc(5);
b.writeU8(D2GAME_UPDATEPOSITION);
b.add(1).writeU32(pos.x | (pos.y << 16));
_D2Net_SendPacket(5, 1, b);
return true;
}
function updatePos() {
if (++updatePosCounter != 100)
return false;
updatePosCounter = 0;
return updatePosInternal();
}
const extraUpdatePosInitial = 2;
let extraUpdatePos = extraUpdatePosInitial;
setInterval(function() {
updatePosInternal();
}, 200);
// Interceptor.attach(ptr(0x6FAD7BC0), {
// Interceptor.attach(D2Modules.D2Client.base.add(0x27bc0), {
// // on run
// onLeave: function (retval) {
// if (retval != 0) {
// if (extraUpdatePos != 0) {
// extraUpdatePos--;
// // updatePos();
// }
// return;
// }
// updatePos();
// extraUpdatePos = extraUpdatePosInitial;
// },
// });
Interceptor.attach(D2Net_SendPacket, {
onEnter: function (args) {
const size = Number(args[0]);
const unknown = Number(args[1]);
const buf = ptr(args[2]);
const type = buf.readU8();
this.type = type;
function log(s) {
if (Logging == false)
return;
const now = new Date;
const time = `[${(now.getHours() + 8).pad(10)}:${now.getMinutes().pad(10)}:${now.getSeconds().pad(10)}.${now.getMilliseconds().pad(100)}]`;
console.log(`${time} <${type.hex()}> <len:${size.hex()}> <unk:${unknown.hex()}> ${s}`);
}
switch (type) {
case D2GAME_RUNTOLOCATION:
{
const x = buf.add(1).readU16();
const y = buf.add(3).readU16();
log(`run to location: x = ${x}, y = ${y}`);
break;
}
case D2GAME_RUNTOENTITY:
{
const type = buf.add(1).readU32();
const id = buf.add(5).readU32();
log(`run to entity: type = ${type}, id = ${id}`);
break;
}
case D2GAME_LEFTSKILLONLOCATION:
{
const x = buf.add(1).readU16();
const y = buf.add(3).readU16();
log(`left skill on location: x = ${x}, y = ${y}`);
break;
}
case D2GAME_LEFTSKILLONENTITY:
{
const type = buf.add(1).readU32();
const id = buf.add(5).readU32();
log(`left skill on entity: type = ${type}, id = ${id}`);
break;
}
case D2GAME_LEFTSKILLONENTITYEX:
{
const type = buf.add(1).readU32();
const id = buf.add(5).readU32();
log(`left skill on entity ex: type = ${type}, id = ${id}`);
break;
}
case D2GAME_LEFTSKILLONLOCATIONEX:
{
const x = buf.add(1).readU16();
const y = buf.add(3).readU16();
log(`left skill on location ex: x = ${x}, y = ${y}`);
break;
}
case D2GAME_LEFTSKILLONENTITYEX2:
{
const type = buf.add(1).readU32();
const id = buf.add(5).readU32();
log(`left skill on entity ex 2: type = ${type}, id = ${id}`);
break;
}
case D2GAME_LEFTSKILLONENTITYEX3:
{
const type = buf.add(1).readU32();
const id = buf.add(5).readU32();
log(`left skill on entity ex 3: type = ${type}, id = ${id}`);
break;
}
case D2GAME_RIGHTSKILLONLOCATION:
{
const x = buf.add(1).readU16();
const y = buf.add(3).readU16();
log(`right click on location: x = ${x}, y = ${y}`);
break;
}
case D2GAME_RIGHTSKILLONENTITY:
{
const type = buf.add(1).readU32();
const id = buf.add(5).readU32();
log(`right skill on entity: type = ${type}, id = ${id}`);
break;
}
case D2GAME_RIGHTSKILLONLOCATIONEX:
{
const x = buf.add(1).readU16();
const y = buf.add(3).readU16();
log(`right click on location ex: x = ${x}, y = ${y}`);
break;
}
case D2GAME_RIGHTSKILLONENTITYEX2:
{
const type = buf.add(1).readU32();
const id = buf.add(5).readU32();
log(`right skill on entity ex 2: type = ${type}, id = ${id}`);
break;
}
case D2GAME_INTERACTWITHENTITY:
{
const type = buf.add(1).readU32();
const id = buf.add(5).readU32();
log(`interact with entity: type = ${type}, id = ${id}`);
break;
}
case D2GAME_PICKUPITEM:
{
const type = buf.add(1).readU32();
const unit = buf.add(5).readU32();
const action = buf.add(9).readU32();
log(`pickup item: type = ${type}, unit = ${unit}, action = ${action}`);
break;
}
case D2GAME_DROPITEM:
{
const id = buf.add(1).readU32();
log(`drop item: id = ${id}`);
break;
}
case D2GAME_ITEMTOBUFFER:
{
const id = buf.add(1).readU32();
const x = buf.add(5).readU32();
const y = buf.add(9).readU32();
const type = buf.add(13).readU32();
log(`item to buffer: id = ${id}, x = ${x}, y = ${y}, type = ${type}`);
break;
}
case D2GAME_PICKUPBUFFERITEM:
{
const id = buf.add(1).readU32();
log(`pickup buffer item: id = ${id}`);
break;
}
case D2GAME_SWITCHINVENTORYITEM:
{
const id_inventory = buf.add(1).readU32();
const id_replace = buf.add(5).readU32();
const x = buf.add(9).readU32();
const y = buf.add(13).readU32();
log(`switch inventory item: id_inventory = ${id_inventory}, id_replace = ${id_replace}, x = ${x}, y = ${y}`);
break;
}
case D2GAME_USEITEM:
{
const id = buf.add(1).readU32();
const x = buf.add(5).readU32();
const y = buf.add(9).readU32();
log(`use item: id = ${id}, x = ${x}, y = ${y}`);
break;
}
case D2GAME_NPCINIT:
{
const type = buf.add(1).readU32();
const id = buf.add(5).readU32();
log(`npc init: type = ${type}, id = ${id}`);
break;
}
case D2GAME_NPCCANCEL:
{
const type = buf.add(1).readU32();
const id = buf.add(5).readU32();
log(`npc cancel: type = ${type}, id = ${id}`);
break;
}
case D2GAME_NPCSELL:
{
const id_npc = buf.add(1).readU32();
const id_item = buf.add(5).readU32();
const type = buf.add(9).readU32();
const cost = buf.add(13).readU32();
log(`npc sell: id_npc = ${id_npc}, id_item = ${id_item}, type = ${type}, cost = ${cost}`);
break;
}
case D2GAME_CAINIDENTIFY:
{
const id = buf.add(1).readU32();
log(`cain identify: id = ${id}`);
break;
}
case D2GAME_REPAIR:
{
const id1 = buf.add(1).readU32();
const id2 = buf.add(5).readU32();
const id3 = buf.add(9).readU32();
const id4 = buf.add(13).readU32();
log(`repair: id1 = ${id1}, id2 = ${id2}, id3 = ${id3}, id4 = ${id4}`);
break;
}
case D2GAME_NPCTRADE:
{
const type = buf.add(1).readU32();
const id = buf.add(5).readU32();
const unk1 = buf.add(9).readU32();
log(`npc rade: type = ${type}, id = ${id}, unk1 = ${unk1.hex()}`);
break;
}
case D2GAME_SWITCHSKILL:
{
const id = buf.add(1).readU32();
const unk2 = buf.add(5).readU32();
log(`switch skill: id = ${id.hex()}, unk2 = ${unk2.hex()}`);
break;
}
case D2GAME_CHARACTERPHRASE:
{
const id = buf.add(1).readU16();
log(`character phrase: id = ${id.hex()}`);
break;
}
case D2GAME_WAYPOINT:
{
const id = buf.add(1).readU8();
const unk1 = buf.add(2).readU8();
const unk2 = buf.add(3).readU16();
const level = buf.add(5).readU8();
const unk3 = buf.add(6).readU16();
const unk4 = buf.add(8).readU8();
log(`way point: id = ${id.hex()}, unk1 = ${unk1.hex()}, unk2 = ${unk2.hex()}, level = ${level.hex()}, unk3 = ${unk3.hex()}, unk4 = ${unk4.hex()}`);
break;
}
case D2GAME_TOWNFOLK:
{
const unk1 = buf.add(1).readU32();
const unk2 = buf.add(5).readU32();
const unk3 = buf.add(9).readU32();
const unk4 = buf.add(13).readU32();
log(`town folk: unk1 = ${unk1.hex()}, unk2 = ${unk2.hex()}, unk3 = ${unk3.hex()}, unk4 = ${unk4.hex()}`);
break;
}
case D2GAME_UPDATEPOSITION:
{
const pos = buf.add(1).readU32();
const x = pos & 0xFFFF;
const y = pos >> 16;
log(`update position: pos = ${pos.hex()} x = ${x}, y = ${y}`);
break;
}
case D2GAME_SWITCHEQUIP:
{
log('switch equip');
break;
}
case D2GAME_GAMELOGON:
{
const hash = buf.add(1).readU32();
const token = buf.add(5).readU16();
const charid = buf.add(7).readU8();
const ver = buf.add(8).readU32();
const unk1 = buf.add(12).readU32();
const unk2 = buf.add(16).readU32();
const unk3 = buf.add(20).readU8();
const charname = buf.add(21).readUtf8String();
log(`game logon: hash = ${hash.hex()}, token = ${token.hex()}, charid = ${charid.hex()}, ver = ${ver.hex()}, unk1 = ${unk1.hex()}, unk2 = ${unk2.hex()}, unk3 = ${unk3.hex()}, charname = ${charname}`);
break;
}
case D2GAME_GAMEEXIT:
{
log('game exit');
break;
}
case D2GAME_ENTERGAMEENVIRONMENT:
{
log('enter game environment');
break;
}
case D2GAME_PING:
{
// log('ping');
break;
}
default:
{
const buf2 = buf.readByteArray(size);
if (Logging) {
log(` unknown = ${unknown.hex()}, size = ${size}`);
console.log(buf2);
}
break;
}
}
},
onLeave: function (retval) {
switch (this.type) {
case D2GAME_RUNTOLOCATION:
// updatePosInternal();
break;
}
}
});
// const Storm_WndProc = GetProcAddress(D2Modules.Storm.base, 412);
// console.log('Storm_WndProc = ' + Storm_WndProc);
// Interceptor.attach(Storm_WndProc, {
// onEnter: function (args) {
// const msg = Number(args[1]);
// // console.log(`msg = ${msg.hex()}`);
// // switch (msg) {
// // case 0x201: // WM_LBUTTONDOWN
// // {
// // const esp = this.context['esp'];
// // const retaddr = esp.readPointer();
// // console.log(`msg = ${msg.hex()}, ${retaddr}`);
// // break;
// // }
// // }
// },
// });
// log(D2Modules.D2Client.base.add(0x27d6e));
// Memory.patchCode(D2Modules.D2Client.base.add(0x27d6e), 1, function (code) {
// code.writeU8(1);
// });
}
hook_d2net();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment