You last visited: Today at 03:34
Advertisement
Help to find offsets
Discussion on Help to find offsets within the Metin2 forum part of the Popular Games category.
07/23/2026, 11:34
#1
elite*gold: 0
Join Date: Oct 2019
Posts: 10
Received Thanks: 0
Help to find offsets
Hello, i found some old python code to metin2. Do you think it will work if i found offsets? Where do i found offsets? I have even source files from the server. Thanks
Code:
import frida
import customtkinter as ctk
import keyboard
from tkinter import messagebox
ctk.set_appearance_mode("dark")
ctk.set_default_color_theme("blue")
class App(ctk.CTk):
def __init__(self):
super().__init__()
self.title("Správce Target Damage")
self.geometry("420x380")
self.resizable(False, False)
self.grid_columnconfigure(1, weight=1)
ctk.CTkLabel(self, text="Název procesu:").grid(row=0, column=0, padx=10, pady=(20, 5), sticky="e")
self.process_entry = ctk.CTkEntry(self)
self.process_entry.grid(row=0, column=1, padx=10, pady=(20, 5), sticky="we")
self.process_entry.insert(0, "GalaxyWorld.exe")
ctk.CTkLabel(self, text="NET_POINTER_ADDRESS offset (hex):").grid(row=1, column=0, padx=10, pady=5, sticky="e")
self.net_pointer_entry = ctk.CTkEntry(self)
self.net_pointer_entry.grid(row=1, column=1, padx=10, pady=5, sticky="we")
self.net_pointer_entry.insert(0, "0x458044")
ctk.CTkLabel(self, text="BATTLE_CALL_ADDRESS offset (hex):").grid(row=2, column=0, padx=10, pady=5, sticky="e")
self.battle_call_entry = ctk.CTkEntry(self)
self.battle_call_entry.grid(row=2, column=1, padx=10, pady=5, sticky="we")
self.battle_call_entry.insert(0, "0xDF970")
ctk.CTkLabel(self, text="TARGET_BASE_ADDRESS offset (hex):").grid(row=3, column=0, padx=10, pady=5, sticky="e")
self.target_base_entry = ctk.CTkEntry(self)
self.target_base_entry.grid(row=3, column=1, padx=10, pady=5, sticky="we")
self.target_base_entry.insert(0, "0x4580AC")
ctk.CTkLabel(self, text="TARGET_OFFSET (hex):").grid(row=4, column=0, padx=10, pady=5, sticky="e")
self.target_offset_entry = ctk.CTkEntry(self)
self.target_offset_entry.grid(row=4, column=1, padx=10, pady=5, sticky="we")
self.target_offset_entry.insert(0, "0x4E3E8")
self.start_button = ctk.CTkButton(self, text="Spustit", command=self.start_attack)
self.start_button.grid(row=5, column=0, padx=20, pady=20, sticky="we")
self.stop_button = ctk.CTkButton(self, text="Zastavit", command=self.stop_attack, state="disabled")
self.stop_button.grid(row=5, column=1, padx=20, pady=20, sticky="we")
self.status_label = ctk.CTkLabel(self, text="Stav: Zastaveno", font=ctk.CTkFont(size=14, weight="bold"))
self.status_label.grid(row=6, column=0, columnspan=2, pady=(10, 20))
self.session = None
self.script = None
keyboard.on_press_key("insert", lambda e: self.after(0, self.toggle_attack))
self.bind('<Insert>', self.toggle_attack)
self.protocol("WM_DELETE_WINDOW", self.close)
def build_script_code(self, process_name, net_ptr_offset, battle_call_offset, target_base_offset, target_offset):
return f'''
const base = Process.getModuleByName("{process_name}").base;
const NET_POINTER_ADDRESS = base.add({net_ptr_offset});
const BATTLE_CALL_ADDRESS = base.add({battle_call_offset});
const TARGET_BASE_ADDRESS = base.add({target_base_offset});
const TARGET_OFFSET = {target_offset};
var running = false;
function getTargetVID() {{
try {{
var basePtr = TARGET_BASE_ADDRESS.readPointer();
if (basePtr.isNull && basePtr.isNull()) {{
return 0;
}}
var targetAddress = basePtr.add(TARGET_OFFSET);
if (typeof targetAddress.readInt !== "function") {{
return 0;
}}
var targetId = targetAddress.readInt();
return (typeof targetId === "number" && targetId > 0) ? targetId : 0;
}} catch (e) {{
return 0;
}}
}}
function sendBattleAttack(targetId) {{
if (targetId <= 0) return false;
try {{
var netPointer = NET_POINTER_ADDRESS.readPointer();
if ((typeof netPointer.isNull === "function" && netPointer.isNull()) || netPointer.equals(ptr('0x0'))) {{
return false;
}}
var codeSize = 64;
var codePtr = Memory.alloc(codeSize);
Memory.patchCode(codePtr, codeSize, function(code) {{
var writer = new X86Writer(code);
writer.putMovRegAddress('ecx', netPointer);
writer.putPushU32(targetId);
writer.putPushU32(0);
writer.putCallAddress(BATTLE_CALL_ADDRESS);
writer.putRet();
writer.flush();
}});
var execFunc = new NativeFunction(codePtr, 'void', []);
execFunc();
return true;
}} catch (e) {{
return false;
}}
}}
function attackLoop() {{
if (!running) return;
var targetId = getTargetVID();
if (targetId > 0) {{
sendBattleAttack(targetId);
}}
setTimeout(attackLoop, 60);
}}
rpc.exports = {{
start: function() {{
if (!running) {{
running = true;
attackLoop();
return "started";
}}
return "already running";
}},
stop: function() {{
running = false;
return "stopped";
}},
isrunning: function() {{
return running;
}}
}};
'''
def on_message(self, message, data):
if message['type'] == 'send':
print("[*]", message['payload'])
elif message['type'] == 'error':
print("[!][CHYBA]", message['stack'])
def start_attack(self):
if self.session:
messagebox.showwarning("Upozornění", "Proces je již připojen!")
return
process_name = self.process_entry.get().strip()
net_ptr = self.net_pointer_entry.get().strip()
battle_call = self.battle_call_entry.get().strip()
target_base = self.target_base_entry.get().strip()
target_offset = self.target_offset_entry.get().strip()
def norm_hex(s):
return s if s.startswith("0x") else "0x" + s
net_ptr = norm_hex(net_ptr)
battle_call = norm_hex(battle_call)
target_base = norm_hex(target_base)
target_offset = norm_hex(target_offset)
try:
script_code = self.build_script_code(process_name, net_ptr, battle_call, target_base, target_offset)
self.session = frida.attach(process_name)
self.script = self.session.create_script(script_code)
self.script.on('message', self.on_message)
self.script.load()
result = self.script.exports_sync.start()
if result == "started":
self.status_label.configure(text="Stav: Běží")
self.start_button.configure(state="disabled")
self.stop_button.configure(state="normal")
else:
self.status_label.configure(text="Stav: Již běží")
except Exception as e:
messagebox.showerror("Chyba", f"Spuštění selhalo: {e}")
self.cleanup()
def stop_attack(self):
if not self.session:
messagebox.showinfo("Informace", "Není spuštěn žádný proces.")
return
try:
result = self.script.exports_sync.stop()
if result == "stopped":
self.status_label.configure(text="Stav: Zastaveno")
self.start_button.configure(state="normal")
self.stop_button.configure(state="disabled")
else:
self.status_label.configure(text="Stav: Již zastaveno")
except Exception as e:
messagebox.showerror("Chyba", f"Chyba při zastavování: {e}")
self.cleanup()
def cleanup(self):
try:
if self.script:
self.script.unload()
if self.session:
self.session.detach()
except:
pass
self.script = None
self.session = None
def toggle_attack(self, event=None):
if self.session and self.script:
try:
running = self.script.exports_sync.isrunning()
if running:
self.stop_attack()
else:
self.start_attack()
except Exception as e:
self.after(0, lambda: messagebox.showerror("Chyba", f"Chyba kontroly stavu: {e}"))
else:
self.start_attack()
def close(self):
self.stop_attack()
self.destroy()
if __name__ == "__main__":
app = App()
app.mainloop()
07/28/2026, 14:33
#2
elite*gold: 63
Join Date: Apr 2010
Posts: 1,530
Received Thanks: 1,090
If you ask this question, no.
Also depends on the server. Some use other Python functions. The easiest server is probably Gameforge itself. Most pservers are way harder to reverse engineer.
Also just a quick tip: Some servers have some specific tresholds how often you are able to send a specific packet to the server. If this packet gets send send within a too close time, it gets logged.
Probably not a auto-ban, but this log will stack up until it's clear that you use a bot. Jitters & humanized Rate Limiting is in my eyes one of the most needed features.
Otherwise you just get banned. Also read-only attempts on the functions after disassambly.
Depending on your knowledge you can AI coding to get specific parts via Ghidra offline-analyses. So you don't have to start a debugger while connected.
Similar Threads
Help! How Find This offsets?
11/23/2017 - PW Hacks, Bots, Cheats, Exploits - 2 Replies
How to find this offsets for 1.5.3 client?
BaseAdress
SendPacket
Target
Help to find offsets pls (Epic pw)
05/01/2016 - PW Hacks, Bots, Cheats, Exploits - 0 Replies
I need :
BaseAdress
SendPacket
Thank you :handsdown:
Please help find Prophet Offsets for PW Vietnam!!
12/28/2011 - PW Hacks, Bots, Cheats, Exploits - 5 Replies
Hi all professionals,
pls. help a noob player finding the custom-offset.ini for Prophet bot working for the vietnamese version of PW calls The Gioi Hoan My.
I appreciate any help that can be offered.
Great thanks.
Choi
(Email: [email protected] )
Range Help (can't find offsets?)
07/07/2009 - Dekaron - 5 Replies
I am trying to get range hack put into my CT, but I cannot seem to find the correct offset. I've used both the Array of Bytes scan and the Assembly scan with no luck. What am I doing wrong?
Help me how to find offsets (ajarin cari offset)
06/30/2009 - Perfect World - 1 Replies
im playing pw-indo.
i want to learn how to find offset on pw.
aku main di ow indo server emas..
ajarin dunk kk cari offset di pw...
All times are GMT +2. The time now is 03:35 .