Skip to content

Instantly share code, notes, and snippets.

@ZeusAFK
Created August 24, 2012 14:25
Show Gist options
  • Star 5 You must be signed in to star a gist
  • Fork 4 You must be signed in to fork a gist
  • Save ZeusAFK/3451195 to your computer and use it in GitHub Desktop.
Save ZeusAFK/3451195 to your computer and use it in GitHub Desktop.
USKO Knight Online World Multiclient source code in C#.NET by ZeusAFK
// By ZeusAFK
// Multiclient ARP patch source code for knight online
// For fun and learning only
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Runtime.InteropServices;
namespace ZeusAFK_Multiclient
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
protected uint CREATE_SUSPENDED = 0x00000004;
protected IntPtr KO_HANDLE;
protected IntPtr KO_MULTI = new IntPtr(0xA78358);
protected ASCIIEncoding encoder = new ASCIIEncoding();
protected STARTUPINFO sInfo;
protected PROCESS_INFORMATION pInfo;
private Random rnd = new Random();
#region "Library import"
[DllImport("kernel32.dll")]
protected static extern bool CreateProcess(string lpApplicationName, string lpCommandLine, IntPtr lpProcessAttributes, IntPtr lpThreadAttributes, bool bInheritHandles, uint dwCreationFlags, IntPtr lpEnvironment, string lpCurrentDirectory, ref STARTUPINFO lpStartupInfo, out PROCESS_INFORMATION lpProcessInformation);
[DllImport("kernel32.dll")]
protected static extern int WriteProcessMemory(IntPtr hProcess, IntPtr lpBaseAddress, byte[] buffer, long size, uint lpNumberOfBytesWritten);
[DllImport("kernel32.dll")]
protected static extern int ReadProcessMemory(IntPtr hProcess, IntPtr lpBaseAddress, byte[] lpBuffer, long nSize, long lpNumberOfBytesRead);
[DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
protected static extern IntPtr GetModuleHandle(string lpModuleName);
[DllImport("kernel32", CharSet = CharSet.Ansi, ExactSpelling = true, SetLastError = true)]
protected static extern IntPtr GetProcAddress(IntPtr hModule, string lpProcName);
[DllImport("kernel32.dll")]
protected static extern int ResumeThread(IntPtr hThread);
[DllImport("kernel32", CharSet = CharSet.Auto, SetLastError = true, ExactSpelling = true)]
protected internal static extern int CloseHandle(IntPtr hObject);
#endregion
#region "Structures"
public struct PROCESS_INFORMATION
{
public IntPtr hProcess;
public IntPtr hThread;
public uint dwProcessId;
public IntPtr dwThreadId;
}
public struct STARTUPINFO
{
public uint cb;
public string lpReserved;
public string lpDesktop;
public string lpTitle;
public uint dwX;
public uint dwY;
public uint dwXSize;
public uint dwYSize;
public uint dwXCountChars;
public uint dwYCountChars;
public uint dwFillAttribute;
public uint dwFlags;
public short wShowWindow;
public short cbReserved2;
public IntPtr lpReserved2;
public IntPtr hStdInput;
public IntPtr hStdOutput;
public IntPtr hStdError;
}
public struct SECURITY_ATTRIBUTES
{
public int length;
public IntPtr lpSecurityDescriptor;
public bool bInheritHandle;
}
#endregion
protected int WriteMemory(IntPtr Address, byte[] Value, long size)
{
return WriteProcessMemory(KO_HANDLE, Address, Value, size, 0);
}
public int WriteMemory(IntPtr Address, int Value)
{
return WriteProcessMemory(KO_HANDLE, Address, BitConverter.GetBytes(Value), 4L, 0);
}
public byte[] ReadMemory(IntPtr Address, byte[] ReadBytes, long nSize)
{
ReadProcessMemory(KO_HANDLE, Address, ReadBytes, nSize, 0L);
return ReadBytes;
}
protected string ToHex(string pStr)
{
string hex = "";
foreach (char c in pStr)
{
int tmp = c;
hex += String.Format("{0:x2}", (uint)System.Convert.ToUInt32(tmp.ToString()));
}
return hex.ToUpper();
}
public String AlignDWORD(IntPtr word)
{
long ADDWORD;
String ADpStr, ADpStr2, ADresultStr;
ADDWORD = (long)Convert.ToInt32(word.ToString());
ADpStr = Convert.ToString(ADDWORD, 16);
ADpStr2 = "";
Int32 ADpStrLength = ADpStr.Length;
int i = 0;
for (i = 0; i < 8 - ADpStrLength; i++)
ADpStr2 = ADpStr2.Insert(i, "0");
int j = 0;
int t = i;
for (i = t; i < 8; i++)
{
ADpStr2 = ADpStr2.Insert(i, ADpStr[j].ToString());
j++;
}
ADresultStr = "";
ADresultStr = ADresultStr.Insert(0, ADpStr2[6].ToString());
ADresultStr = ADresultStr.Insert(1, ADpStr2[7].ToString());
ADresultStr = ADresultStr.Insert(2, ADpStr2[4].ToString());
ADresultStr = ADresultStr.Insert(3, ADpStr2[5].ToString());
ADresultStr = ADresultStr.Insert(4, ADpStr2[2].ToString());
ADresultStr = ADresultStr.Insert(5, ADpStr2[3].ToString());
ADresultStr = ADresultStr.Insert(6, ADpStr2[0].ToString());
ADresultStr = ADresultStr.Insert(7, ADpStr2[1].ToString());
return ADresultStr.ToUpper();
}
protected void btnOpen_Click(object sender, EventArgs e)
{
try
{
if (!txtWindowsName.Text.Trim().Equals(""))
{
OpenFileDialog OpenDialog = new OpenFileDialog();
OpenDialog.Filter = "KnightOnLine.exe |*KnightOnLine.exe";
if (OpenDialog.ShowDialog() == DialogResult.OK)
{
sInfo = new STARTUPINFO();
pInfo = new PROCESS_INFORMATION();
CreateProcess(null, OpenDialog.FileName.Substring(0, OpenDialog.FileName.LastIndexOf("\\") + 1) + "KnightOnLine.exe USA_KnightOnLine", IntPtr.Zero, IntPtr.Zero, false, CREATE_SUSPENDED, IntPtr.Zero, OpenDialog.FileName.Substring(0, OpenDialog.FileName.LastIndexOf("\\") + 1), ref sInfo, out pInfo);
KO_HANDLE = pInfo.hProcess;
if (KO_HANDLE != IntPtr.Zero)
{
APR_Patch();
Application.DoEvents();
WriteMemory(new IntPtr(0xC4A5D8), 0);
WriteMemory(new IntPtr(0xC4A5F8), 0);
WriteMemory(new IntPtr(0xC43EE4), 0);
CloseHandle(pInfo.hThread);
CloseHandle(pInfo.hProcess);
}
else
MessageBox.Show("Error al crear un handle para el proceso de Knight Online", "Handle Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
else
{
txtWindowsName.Text = "cliente" + rnd.Next(1000, 9999).ToString();
Application.DoEvents();
btnOpen_Click(sender, e);
}
}
catch (Exception Ex) { MessageBox.Show("Ocurrio un error al abrir el cliente Knight Online.\n\nINFORMACION DEL ERROR:\n" + Ex.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error); }
}
protected void APR_Patch()
{
for (int i = 0; i < 3; i++)
{
byte[] bytesName = ToByteArray(ToHex(txtWindowsName.Text.Trim()));
WriteMemory(KO_MULTI, bytesName, 20L);
OpcodePath(GetProcAddress(GetModuleHandle("kernel32.dll"), "SetThreadAffinityMask"), "C20800");
OpcodePath(GetProcAddress(GetModuleHandle("Advapi32.dll"), "OpenSCManagerA"), "B801000000C20C00");
OpcodePath(GetProcAddress(GetModuleHandle("Advapi32.dll"), "CreateServiceA"), "B801000000C23400");
OpcodePath(GetProcAddress(GetModuleHandle("Advapi32.dll"), "StartServiceA"), "68" + AlignDWORD(new IntPtr(0x4FB)) + "BF" + AlignDWORD(GetProcAddress(GetModuleHandle("kernel32.dll"), "SetLastError")) + "FFD7B800000000C20C00");
OpcodePath(GetProcAddress(GetModuleHandle("Advapi32.dll"), "CloseServiceHandle"), "B801000000C20400");
ResumeThread(pInfo.hThread);
System.Threading.Thread.Sleep(1300);
}
}
public void OpcodePath(IntPtr StartAddress, string Opcodes)
{
byte[] pBytes = ToByteArray(Opcodes);
WriteMemory(StartAddress, pBytes, pBytes.LongLength);
}
protected string WindowsName()
{
byte[] pBytes = new byte[25];
string Name = Convert.ToString(ASCIIEncoding.ASCII.GetString(ReadMemory(KO_MULTI, pBytes, 25L)));
for (int i = 0; i < Name.Length; i++)
if ((int)Name[i] == 0)
return Name.Substring(0, i);
return "";
}
public Byte[] ToByteArray(String pStr)
{
Byte[] pByte = new Byte[pStr.Length / 2];
Int32 i, j;
j = -1;
Int32 pStrLength = pStr.Length;
try
{
for (i = 0; i < pStrLength; i += 2)
{
j++;
pByte[j] = Convert.ToByte(Convert.ToInt32("0x" + pStr.Substring(i, 2), 16));
}
}
catch { }
return pByte;
}
}
}
@clauderoy790
Copy link

Nice one man. Stumble upon this while coming back to KO myself. Sent you a tweet. I'd be stoked to show you what I've done on my Genie reproduction.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment