public static void Execute( ClientInfo ci, byte param1, byte param2a, byte param2b ) { ci.PrimaryCave[data1offset + 24] = param1; ci.PrimaryCave[data1offset + 28] = param2b; ci.PrimaryCave[data1offset + 29] = param2a; Memory.Write( ci.Handle, ci.CaveAddress, ci.PrimaryCave, true ); }
public static void MemoryInit(ClientInfo ci) { ulong len = (ulong)ci.EntryPoint - (ulong)ci.BaseAddress; NativeMethods.GainMemoryAccessEx(ci.Handle, ci.BaseAddress, len); if (!SetInfoAddresses(ci)) { ci.IsValid = false; } }
public static void Execute( ClientInfo ci, byte param1, byte param2, string param3 ) { ci.PrimaryCave[data1offset + 24] = param1; ci.PrimaryCave[data1offset + 28] = param2; byte[] data2Address = BitConverter.GetBytes( ci.CaveAddress.ToInt32() + data2offset ); Buffer.BlockCopy( data2Address, 0, ci.PrimaryCave, data1offset + 32, 4 ); byte[] unicodeBytes = UnicodeEncoding.Unicode.GetBytes( param3 ); if (unicodeBytes.Length > 256) Buffer.BlockCopy( unicodeBytes, 0, ci.PrimaryCave, data2offset, 256 ); else Buffer.BlockCopy( unicodeBytes, 0, ci.PrimaryCave, data2offset, unicodeBytes.Length ); Memory.Write( ci.Handle, ci.CaveAddress, ci.PrimaryCave, true ); Buffer.BlockCopy( emptyArray, 0, ci.PrimaryCave, data2offset, 256 ); // clear previous data }
private static bool SetInfoAddresses(ClientInfo ci) { byte[] memBytes = new byte[4]; uint playerInfoAddress = 0; for (int x = 0; x < 100; x++) { Memory.Read(ci.Handle, ci.PlayerInfoPointer, memBytes, true); playerInfoAddress = BitConverter.ToUInt32(memBytes, 0); if (playerInfoAddress > 0) break; Thread.Sleep(100); } if (playerInfoAddress == 0) return false; ci.ZAddress = (IntPtr)(playerInfoAddress + 0x28); return true; }
public static bool AddClient(ClientInfo clientInfo, out int instance) { if (Count >= ClientList.Length) { throw new ApplicationException("Maximum number of simultaneous clients exceeded."); } for (int x = 0; x < ClientList.Length; x++) { ClientInfo ci = ThreadHelper.VolatileRead<ClientInfo>(ref ClientList[x]); if (ci == null) { Interlocked.Exchange<ClientInfo>(ref ClientList[x], clientInfo); TreeViewUpdater.AddPlaceHolder(x, clientInfo.ProcessID); Count++; instance = x; return true; } } instance = -1; return false; }
private static bool GetLoginServerAddress(int baseAddress, byte[] buffer, ClientInfo clientInfo) { /* Here we're getting address for server IP as well as preventing client from overwriting our IP * we're also getting port address and protecting it as well */ byte[] sig1 = new byte[] { 0x8B, 0x44, 0x24, 0x0C, 0xC1, 0xE1, 0x08, 0x0B, 0xC8, 0x66, 0x89, 0x15 }; byte[] sig2 = new byte[] { 0xC1, 0xE1, 0x08, 0x0B, 0x4C, 0x24, 0x0C, 0x89, 0x0D }; byte[] sig3 = new byte[] { 0x83, 0XC4, 0X04, 0X50, 0X51, 0X8B, 0XCF, 0XE8 }; int offset; if (FindSignatureOffset(sig1, buffer, out offset)) { byte[] patch = { 0x90, 0x90, 0x90, 0x90, 0x90, 0x90 }; byte[] portPatch = { 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90 }; IntPtr portPatchAddress = (IntPtr)(baseAddress + offset + 0x09); IntPtr patchAddress = (IntPtr)(baseAddress + offset + 0x10); clientInfo.LoginServerAddress = (IntPtr)(BitConverter.ToInt32(buffer, offset + 0x12)); clientInfo.LoginPortAddress = (IntPtr)(BitConverter.ToInt32(buffer, offset + 0x0C)); if (Memory.Write(clientInfo.Handle, patchAddress, patch, true)) { return(Memory.Write(clientInfo.Handle, portPatchAddress, portPatch, true)); } } if (FindSignatureOffset(sig2, buffer, out offset)) { byte[] patch = { 0x90, 0x90, 0x90, 0x90, 0x90, 0x90 }; byte[] portPatch = { 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90 }; IntPtr portPatchAddress = (IntPtr)(baseAddress + offset - 0x07); IntPtr patchAddress = (IntPtr)(baseAddress + offset + 0x07); clientInfo.LoginServerAddress = (IntPtr)(BitConverter.ToInt32(buffer, offset + 0x09)); clientInfo.LoginPortAddress = (IntPtr)(BitConverter.ToInt32(buffer, offset - 0x04)); if (Memory.Write(clientInfo.Handle, patchAddress, patch, true)) { return(Memory.Write(clientInfo.Handle, portPatchAddress, portPatch, true)); } } if (FindSignatureOffset(sig3, buffer, out offset)) { // Tested up to 7.0.46.2 2015-10-22 //.text: 00599FB0 loc_599FB0: ; CODE XREF: sub_599F10 + E5j //.text:00599FB0 push ebx //.text:00599FB1 call sub_595C10 // NOP's here //.text:00599FB6 movzx eax, word_A9A634 // port //.text:00599FBD mov ecx, dword_A9A630 // address //.text:00599FC3 add esp, 4 //.text:00599FC6 push eax; hostshort //.text:00599FC7 push ecx; hostlong //.text:00599FC8 mov ecx, edi byte[] patch = { 0x90, 0x90, 0x90, 0x90, 0x90 }; IntPtr patchAddress = (IntPtr)(baseAddress + offset - 0x12); Memory.Write(clientInfo.Handle, patchAddress, patch, true); clientInfo.LoginServerAddress = (IntPtr)(BitConverter.ToInt32(buffer, offset - 0x04)); clientInfo.LoginPortAddress = (IntPtr)(BitConverter.ToInt32(buffer, offset - 0x0A)); return(true); } return(false); }
public static void PreparePathfindCave(ClientInfo ci) { byte[] cave; int caveAddress = ci.PathFindCaveAddress.ToInt32(); byte[] startWord = BitConverter.GetBytes(caveAddress + 6); byte[] EAXDword = BitConverter.GetBytes(caveAddress - 0x24); byte[] gumpFunction; byte[] RETNDword; byte[] pathFindJMP; switch (ci.PathFindType) { case 0: cave = new byte[] { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x66, 0xA1, 0xFF, 0xFF, 0xFF, 0xFF, 0x66, 0x83, 0xF8, 0x00, 0x75, 0x06, 0x90, 0x90, 0x90, 0x90, 0x90, 0xC3, 0x66, 0x33, 0xC0, 0x66, 0xA3, 0xFF, 0xFF, 0xFF, 0xFF, 0x6A, 0x00, 0x6A, 0x00, 0x68, 0xFF, 0xFF, 0xFF, 0xFF, 0x51, 0x53, 0x55, 0x56, 0x57, 0xB8, 0xFF, 0xFF, 0xFF, 0xFF, 0xE9, 0xFF, 0xFF, 0xFF, 0xFF, 0xC3 }; gumpFunction = ClientHook.CreateCALL(caveAddress + 20, ci.GumpFunctionCaveAddress.ToInt32() + 10, CallType.CALL); pathFindJMP = ClientHook.CreateCALL(caveAddress + 54, ci.PathFindFunction, CallType.JMP); RETNDword = BitConverter.GetBytes(caveAddress + cave.Length - 1); Buffer.BlockCopy(startWord, 0, cave, 10, 4); Buffer.BlockCopy(startWord, 0, cave, 31, 4); Buffer.BlockCopy(gumpFunction, 0, cave, 20, 5); Buffer.BlockCopy(RETNDword, 0, cave, 40, 4); Buffer.BlockCopy(EAXDword, 0, cave, 50, 4); Buffer.BlockCopy(pathFindJMP, 0, cave, 54, 5); Memory.Write(ci.Handle, ci.PathFindCaveAddress, cave, true); break; case 1: /* 004008D1 FFFF ??? ; X * 004008D3 FFFF ??? ; Y * 004008D5 FFFF ??? ; Z * 004008D7 0000 ADD BYTE PTR DS:[EAX],AL ; nonzero = execute * 004008D9 66:A1 D7084000 MOV AX,WORD PTR DS:[4008D7] * 004008DF 66:83F8 00 CMP AX,0 * 004008E3 75 06 JNZ SHORT client.004008EB * 004008E5 90 NOP ; reserved for future * 004008E6 90 NOP ; reserved for future * 004008E7 90 NOP ; reserved for future * 004008E8 90 NOP ; reserved for future * 004008E9 90 NOP ; reserved for future * 004008EA C3 RETN * 004008EB 66:33C0 XOR AX,AX * 004008EE 66:A3 D7084000 MOV WORD PTR DS:[4008D7],AX * 004008F4 6A 00 PUSH 0 * 004008F6 6A 00 PUSH 0 * 004008F8 68 08094000 PUSH client.00400908 ; RETN from pathfind * 004008FD 51 PUSH ECX * 004008FE B8 AD084000 MOV EAX,client.004008AD ; EAX + 0x24 = X word * 00400903 -E9 51980900 JMP client.0049A159 * 00400908 C3 RETN */ cave = new byte[] { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x66, 0xA1, 0xFF, 0xFF, 0xFF, 0xFF, 0x66, 0x83, 0xF8, 0x00, 0x75, 0x06, 0x90, 0x90, 0x90, 0x90, 0x90, 0xC3, 0x66, 0x33, 0xC0, 0x66, 0xA3, 0xFF, 0xFF, 0xFF, 0xFF, 0x6A, 0x00, 0x6A, 0x00, 0x68, 0xFF, 0xFF, 0xFF, 0xFF, 0x51, 0xB8, 0xFF, 0xFF, 0xFF, 0xFF, 0xE9, 0xFF, 0xFF, 0xFF, 0xFF, 0xC3 }; gumpFunction = ClientHook.CreateCALL(caveAddress + 20, ci.GumpFunctionCaveAddress.ToInt32() + 10, CallType.CALL); pathFindJMP = ClientHook.CreateCALL(caveAddress + 50, ci.PathFindFunction, CallType.JMP); RETNDword = BitConverter.GetBytes(caveAddress + cave.Length - 1); Buffer.BlockCopy(startWord, 0, cave, 10, 4); Buffer.BlockCopy(startWord, 0, cave, 31, 4); Buffer.BlockCopy(RETNDword, 0, cave, 40, 4); Buffer.BlockCopy(EAXDword, 0, cave, 46, 4); Buffer.BlockCopy(pathFindJMP, 0, cave, 50, 5); Buffer.BlockCopy(gumpFunction, 0, cave, 20, 5); Memory.Write(ci.Handle, ci.PathFindCaveAddress, cave, true); break; } }
public static bool SetAddresses(ClientInfo clientInfo, string fileName) { try { byte[] fileBytes = File.ReadAllBytes(fileName); int baseAddress = clientInfo.BaseAddress.ToInt32(); clientInfo.Version = ExeInfo.GetFileVersion(fileName); clientInfo.DateStamp = ExeInfo.GetStamp(fileBytes); if (!GetHookAddress(baseAddress, fileBytes, clientInfo)) { return(false); } if (!GetRecvAddress(baseAddress, fileBytes, clientInfo)) { return(false); } if (!GetSendAddress(baseAddress, fileBytes, clientInfo)) { return(false); } if (!GetReturnAddress1(baseAddress, fileBytes, clientInfo)) { return(false); } if (!GetCaveAddress(baseAddress, fileBytes, clientInfo)) { return(false); } if (!GetPlayerInfoPointer(baseAddress, fileBytes, clientInfo)) { return(false); } if (!GetClientPacketData(baseAddress, fileBytes, clientInfo)) { return(false); } if (!GetCursorAddress(baseAddress, fileBytes, clientInfo)) { return(false); } if (!GetServerSendAddress(baseAddress, fileBytes, clientInfo)) { return(false); } if (!GetPathFindAddress(baseAddress, fileBytes, clientInfo)) { return(false); } if (!GetGumpPointer(baseAddress, fileBytes, clientInfo)) { return(false); } if (!GetLoginServerAddress(baseAddress, fileBytes, clientInfo)) { return(false); } clientInfo.IsValid = true; return(true); } catch (Exception) { } return(false); }
public static void PreparePrimaryCave( ClientInfo ci ) { ci.PrimaryCave = new byte[] { 0x00, 0x00, 0xE8, 0xFF, 0xFF, 0xFF, 0xFF, 0x68, 0xFF, 0xFF, 0xFF, 0xFF, 0x66, 0xA1, 0xFF, 0xFF, 0xFF, 0xFF, 0x66, 0x83, 0xF8, 0x00, 0x75, 0x01, 0xC3, 0x66, 0x31, 0xC0, 0x66, 0xA3, 0xFF, 0xFF, 0xFF, 0xFF, 0x68, 0x00, 0x00, 0x00, 0x00, 0x68, 0xFF, 0xFF, 0xFF, 0xFF, 0x68, 0xFF, 0xFF, 0xFF, 0xFF, 0x68, 0xFF, 0xFF, 0xFF, 0xFF, 0xC3, 0x83, 0xC4, 0x08, 0xC3, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x19, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; ci.PrimaryCave[0] = 0; int startWordAddress = ci.CaveAddress.ToInt32(); byte[] hookBytes = ClientHook.CreateCALL( ci.HookAddress, (IntPtr)(startWordAddress + func1offset), CallType.CALL ); byte[] origDest = BitConverter.GetBytes( ci.OriginalDest ); byte[] serverSendCaveCall = ClientHook.CreateCALL( startWordAddress + func1offset, ci.ServerSendCaveAddress.ToInt32() + 6, CallType.CALL ); byte[] startAddress = BitConverter.GetBytes( startWordAddress ); byte[] data1Address = BitConverter.GetBytes( startWordAddress + data1offset ); byte[] returnAddress = BitConverter.GetBytes( ci.ReturnAddress ); byte[] addressForFunc2 = BitConverter.GetBytes( startWordAddress + func2offset + 21 ); Buffer.BlockCopy( serverSendCaveCall, 0, ci.PrimaryCave, 2, 5 ); Buffer.BlockCopy( origDest, 0, ci.PrimaryCave, 8, 4 ); Buffer.BlockCopy( startAddress, 0, ci.PrimaryCave, 14, 4 ); Buffer.BlockCopy( startAddress, 0, ci.PrimaryCave, 30, 4 ); Buffer.BlockCopy( data1Address, 0, ci.PrimaryCave, 40, 4 ); Buffer.BlockCopy( addressForFunc2, 0, ci.PrimaryCave, 45, 4 ); Buffer.BlockCopy( returnAddress, 0, ci.PrimaryCave, 50, 4 ); Memory.Write( ci.Handle, ci.CaveAddress, ci.PrimaryCave, true ); Memory.Write( ci.Handle, ci.HookAddress, hookBytes, true ); ci.PrimaryCave[0] = 1; }
public static void PrepareGumpFunctionCave( ClientInfo ci ) { /* 00400911 FFFF ??? ; \ * 00400913 FFFF ??? ; / parent gump address * 00400915 FFFF ??? ; \ * 00400917 FFFF ??? ; / function index to call * 00400919 0000 ADD BYTE PTR DS:[EAX],AL ; nonzero = execute * 0040091B 66:A1 19094000 MOV AX,WORD PTR DS:[400919] * 00400921 66:83F8 00 CMP AX,0 * 00400925 75 06 JNZ SHORT uoml_win.0040092D * 00400927 90 NOP ; reserved for future * 00400928 90 NOP ; reserved for future * 00400929 90 NOP ; reserved for future * 0040092A 90 NOP ; reserved for future * 0040092B 90 NOP ; reserved for future * 0040092C C3 RETN * 0040092D 66:33C0 XOR AX,AX * 00400930 66:A3 19094000 MOV WORD PTR DS:[400919],AX * 00400936 8B0D 11094000 MOV ECX,DWORD PTR DS:[400911] * 0040093C A1 15094000 MOV EAX,DWORD PTR DS:[400915] * 00400941 BA 04000000 MOV EDX,4 * 00400946 F7E2 MUL EDX * 00400948 8B11 MOV EDX,DWORD PTR DS:[ECX] * 0040094A 03C2 ADD EAX,EDX * 0040094C 8B10 MOV EDX,DWORD PTR DS:[EAX] * 0040094E FFD2 CALL EDX * 00400950 C3 RETN */ byte[] cave = new byte[] { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x66, 0xA1, 0xFF, 0xFF, 0xFF, 0xFF, 0x66, 0x83, 0xF8, 0x00, 0x75, 0x06, 0x90, 0x90, 0x90, 0x90, 0x90, 0xC3, 0x66, 0x33, 0xC0, 0x66, 0xA3, 0xFF, 0xFF, 0xFF, 0xFF, 0x8B, 0x0D, 0xFF, 0xFF, 0xFF, 0xFF, 0xA1, 0xFF, 0xFF, 0xFF, 0xFF, 0xBA, 0x04, 0x00, 0x00, 0x00, 0xF7, 0xE2, 0x8B, 0x11, 0x03, 0xC2, 0x8B, 0x10, 0xFF, 0xD2, 0xC3}; int caveAddress = ci.GumpFunctionCaveAddress.ToInt32(); byte[] startWord = BitConverter.GetBytes( caveAddress + 8 ); byte[] gumpOffset = BitConverter.GetBytes( caveAddress ); byte[] functionOffset = BitConverter.GetBytes( caveAddress + 4 ); Buffer.BlockCopy( startWord, 0, cave, 12, 4 ); Buffer.BlockCopy( startWord, 0, cave, 33, 4 ); Buffer.BlockCopy( gumpOffset, 0, cave, 39, 4 ); Buffer.BlockCopy( functionOffset, 0, cave, 44, 4 ); Memory.Write( ci.Handle, ci.GumpFunctionCaveAddress, cave, true ); }
public static bool SetAddresses( ClientInfo clientInfo, string fileName ) { try { byte[] fileBytes = File.ReadAllBytes( fileName ); int baseAddress = clientInfo.BaseAddress.ToInt32(); clientInfo.Version = ExeInfo.GetFileVersion( fileName ); clientInfo.DateStamp = ExeInfo.GetStamp( fileBytes ); if (!GetHookAddress( baseAddress, fileBytes, clientInfo )) return false; if (!GetRecvAddress( baseAddress, fileBytes, clientInfo )) return false; if (!GetSendAddress( baseAddress, fileBytes, clientInfo )) return false; if (!GetReturnAddress1( baseAddress, fileBytes, clientInfo )) return false; if (!GetCaveAddress( baseAddress, fileBytes, clientInfo )) return false; if (!GetPlayerInfoPointer( baseAddress, fileBytes, clientInfo )) return false; if (!GetClientPacketData( baseAddress, fileBytes, clientInfo )) return false; if (!GetCursorAddress( baseAddress, fileBytes, clientInfo )) return false; if (!GetServerSendAddress( baseAddress, fileBytes, clientInfo )) return false; if (!GetPathFindAddress( baseAddress, fileBytes, clientInfo )) return false; if (!GetGumpPointer( baseAddress, fileBytes, clientInfo )) return false; if (!GetLoginServerAddress( baseAddress, fileBytes, clientInfo )) return false; clientInfo.IsValid = true; return true; } catch (Exception) { } return false; }
private static bool GetCursorAddress( int baseAddress, byte[] buffer, ClientInfo clientInfo ) { byte[] sig1 = new byte[] { 0xD0, 0x00, 0x00, 0x00, 0x3B, 0xC7, 0x74, 0x38 }; byte[] sig2 = new byte[] { 0x8B, 0xF1, 0x83, 0xBE, 0xFC, 0x00, 0x00, 0x00, 0x00 }; int offset; if (FindSignatureOffset( sig1, buffer, out offset )) { clientInfo.CursorAddress = (IntPtr) BitConverter.ToInt32( buffer, offset + 9 ); return true; } if (FindSignatureOffset( sig2, buffer, out offset )) { offset += 9; for (int i = 0; i < 10; i++) { if (buffer[offset + i] == 0xA1) { clientInfo.CursorAddress = (IntPtr) BitConverter.ToInt32( buffer, ( offset + i ) + 1 ); return true; } } } return false; }
private static bool GetClientPacketData( int baseAddress, byte[] buffer, ClientInfo clientInfo ) { byte[] sig1 = new byte[] { 0xA1, 0xCC, 0xCC, 0xCC, 0xCC, 0x8B, 0x0D, 0xCC, 0xCC, 0xCC, 0xCC, 0x8B, 0x16 }; byte[] sig2 = new byte[] { 0xC7, 0x06, 0xCC, 0xCC, 0xCC, 0xCC, 0x89, 0x35, 0xCC, 0xCC, 0xCC, 0xCC, 0x8B, 0x4C, 0x24, 0x0C }; int offset; if (FindSignatureOffset( sig1, buffer, out offset )) { clientInfo.ClientPacketData = BitConverter.ToInt32( buffer, offset + 7 ); return true; } if (FindSignatureOffset( sig2, buffer, out offset )) { clientInfo.ClientPacketData = BitConverter.ToInt32( buffer, offset + 8 ); return true; } return false; }
private static bool GetCaveAddress( int baseAddress, byte[] buffer, ClientInfo clientInfo ) { byte[] sig1 = new byte[3192]; //was 1024 (Reximus 02/2010) int offset; /* * In the past, client crashes I had were due to EasyUO overwriting parts of the code cave with data (I verified). * I'm still getting occasional client crashes when using big EasyUO scripts, and although I haven't checked for sure, * I will assume it's the same problem, so let's VirtualAllocEx our own memory space and use that, I don't know yet if this * will cause any problems (far jmps?) so this is purely a test. */ if (clientInfo.AllocCodeAddress != null) { uint caveAddress = (uint) clientInfo.AllocCodeAddress; uint recvCaveAddress = caveAddress + 526; uint clientSendCaveAddress = recvCaveAddress + 50; uint sendCaveAddress = clientSendCaveAddress + 180; uint serverSendCaveAddress = sendCaveAddress + 100;//26; uint pathFindCaveAddress = serverSendCaveAddress + 100; uint gumpFunctionCaveAddress = pathFindCaveAddress + 100; clientInfo.CaveAddress = (IntPtr) caveAddress; clientInfo.RecvCaveAddress = (IntPtr) recvCaveAddress; clientInfo.SendCaveAddress = (IntPtr) sendCaveAddress; clientInfo.ClientSendCaveAddress = (IntPtr) clientSendCaveAddress; clientInfo.ServerSendCaveAddress = (IntPtr) serverSendCaveAddress; clientInfo.PathFindCaveAddress = (IntPtr) pathFindCaveAddress; clientInfo.GumpFunctionCaveAddress = (IntPtr) gumpFunctionCaveAddress; #if DEBUG Log.LogMessage( clientInfo.Instance, "Cave address = 0x" + clientInfo.RecvHookAddress.ToString( "X" ) + "\r\n" + "Recv cave address = 0x" + clientInfo.RecvCaveAddress.ToString( "X" ) + "\r\n" + "Send cave address = 0x" + clientInfo.SendCaveAddress.ToString( "X" ) + "\r\n" + "Client send cave address = 0x" + clientInfo.ClientSendCaveAddress.ToString( "X" ) + "\r\n" + "Server send cave address = 0x" + clientInfo.ServerSendCaveAddress.ToString( "X" ) + "\r\n" + "Pathfind cave address = 0x" + clientInfo.PathFindCaveAddress.ToString( "X" ) + "\r\n" + "Gump function cave address = 0x" + clientInfo.GumpFunctionCaveAddress.ToString( "X" ) + "\r\n" ); #endif return true; } if (FindSignatureOffset( sig1, buffer, out offset )) { uint caveAddress = (uint) baseAddress + (uint) offset + 1750; //was 750 (Reximus 02/2010) uint recvCaveAddress = caveAddress + 526; uint clientSendCaveAddress = recvCaveAddress + 28; uint sendCaveAddress = clientSendCaveAddress + 80; uint serverSendCaveAddress = sendCaveAddress + 26; uint pathFindCaveAddress = serverSendCaveAddress + 74; uint gumpFunctionCaveAddress = pathFindCaveAddress + 64; clientInfo.CaveAddress = (IntPtr) caveAddress; clientInfo.RecvCaveAddress = (IntPtr) recvCaveAddress; clientInfo.SendCaveAddress = (IntPtr) sendCaveAddress; clientInfo.ClientSendCaveAddress = (IntPtr) clientSendCaveAddress; clientInfo.ServerSendCaveAddress = (IntPtr) serverSendCaveAddress; clientInfo.PathFindCaveAddress = (IntPtr) pathFindCaveAddress; clientInfo.GumpFunctionCaveAddress = (IntPtr) gumpFunctionCaveAddress; return true; } return false; }
private static bool GetLoginServerAddress(int baseAddress, byte[] buffer, ClientInfo clientInfo) { /* Here we're getting address for server IP as well as preventing client from overwriting our IP * we're also getting port address and protecting it as well */ byte[] sig1 = new byte[] { 0x8B, 0x44, 0x24, 0x0C, 0xC1, 0xE1, 0x08, 0x0B, 0xC8, 0x66, 0x89, 0x15 }; byte[] sig2 = new byte[] { 0xC1, 0xE1, 0x08, 0x0B, 0x4C, 0x24, 0x0C, 0x89, 0x0D }; byte[] sig3 = new byte[] { 0x56, 0x57, 0x6A, 0x1C, 0xC7 }; byte[] sig4 = new byte[] { 0x83, 0XC4, 0X04, 0X50, 0X51, 0X8B, 0XCF, 0XE8 }; int offset; if (FindSignatureOffset(sig1, buffer, out offset)) { byte[] patch = { 0x90, 0x90, 0x90, 0x90, 0x90, 0x90 }; byte[] portPatch = { 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90 }; IntPtr portPatchAddress = (IntPtr)(baseAddress + offset + 0x09); IntPtr patchAddress = (IntPtr)(baseAddress + offset + 0x10); clientInfo.LoginServerAddress = (IntPtr)(BitConverter.ToInt32(buffer, offset + 0x12)); clientInfo.LoginPortAddress = (IntPtr)(BitConverter.ToInt32(buffer, offset + 0x0C)); if (Memory.Write(clientInfo.Handle, patchAddress, patch, true)) return Memory.Write(clientInfo.Handle, portPatchAddress, portPatch, true); } if (FindSignatureOffset(sig2, buffer, out offset)) { byte[] patch = { 0x90, 0x90, 0x90, 0x90, 0x90, 0x90 }; byte[] portPatch = { 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90 }; IntPtr portPatchAddress = (IntPtr)(baseAddress + offset - 0x07); IntPtr patchAddress = (IntPtr)(baseAddress + offset + 0x07); clientInfo.LoginServerAddress = (IntPtr)(BitConverter.ToInt32(buffer, offset + 0x09)); clientInfo.LoginPortAddress = (IntPtr)(BitConverter.ToInt32(buffer, offset - 0x04)); if (Memory.Write(clientInfo.Handle, patchAddress, patch, true)) return Memory.Write(clientInfo.Handle, portPatchAddress, portPatch, true); } //if (FindSignatureOffset(sig3, buffer, out offset)) //{ // byte[] patch = { 0x90, 0x90, 0x90, 0x90, 0x90 }; // IntPtr loginPointer = (IntPtr)(BitConverter.ToInt32(buffer, offset + 0x20)); // clientInfo.LoginServerAddress = loginPointer; // clientInfo.NewStyleLoginPatch = true; // IntPtr patchAddress = (IntPtr)(baseAddress + offset + 0x1f); // Memory.Write(clientInfo.Handle, patchAddress, patch, true); // patchAddress = (IntPtr)(baseAddress + offset + 0x46); // Memory.Write(clientInfo.Handle, patchAddress, patch, true); // return true; //} if (FindSignatureOffset(sig4, buffer, out offset)) { //byte[] patch = { 0x90, 0x90, 0x90, 0x90, 0x90, 0x90 }; //IntPtr patchAddress = (IntPtr)(baseAddress + offset - 0x13); byte[] patch = { 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90 }; IntPtr patchAddress = (IntPtr)(baseAddress + offset - 0x476B); Memory.Write(clientInfo.Handle, patchAddress, patch, true); clientInfo.LoginServerAddress = (IntPtr)(BitConverter.ToInt32(buffer, offset - 0x04)); clientInfo.LoginPortAddress = (IntPtr)(BitConverter.ToInt32(buffer, offset - 0x0A)); return true; } return false; }
public static bool Attach( uint pid, OptionsData options, bool isRazor, out int index ) { lock (myLock) { Process p = null; index = -1; try { Thread.Sleep( 2000 ); p = Process.GetProcessById( (int)pid ); p.EnableRaisingEvents = true; p.Exited += new EventHandler( UOM.OnClientExit ); ClientInfo ci = new ClientInfo( p ); Memory.MemoryInit( ci ); if (ci.IsValid) ci.InstallMacroHook(); else return false; if (!isRazor && options.PatchClientEncryptionUOM) { if (!ClientPatcher.PatchEncryption( p.Handle )) { MessageBox.Show( Strings.Errorpatchingclientencryption, Strings.Error ); } } if (ci.DateStamp < 0x4AA52CC4 && options.PatchStaminaCheck) { if (!ClientPatcher.PatchStaminaCheck( p.Handle )) { MessageBox.Show( Strings.Errorpatchingstaminacheck, Strings.Error ); } } if (options.PatchAlwaysLight) { if (!ClientPatcher.PatchLight( p.Handle )) { MessageBox.Show( Strings.Errorwithalwayslightpatch, Strings.Error ); } } if (options.PatchGameSize) { if (!ClientPatcher.SetGameSize( p.Handle, options.PatchGameSizeWidth, options.PatchGameSizeHeight )) { //Silently fail for now as this will fail on UOSteam. //MessageBox.Show(Strings.Errorsettinggamewindowsize); } } int instance; if (!ClientInfoCollection.AddClient( ci, out instance )) throw new ApplicationException( String.Concat( Strings.Unknownerror, ": ClientInfoCollection.Add." ) ); ci.Instance = instance; index = instance; Macros.Macro.ChangeServer( instance, options.Server, options.Port ); Thread.Sleep( 500 ); RemoteHooking.Inject( p.Id, Path.Combine( UOM.StartupPath, "clienthook.dll" ), Path.Combine( UOM.StartupPath, "clienthook.dll" ), UOM.ServerName ); } catch (Exception e) { Utility.Log.LogMessage( e ); MessageBox.Show( Strings.Errorinjectingdll, Strings.Error ); try { if (p != null) p.Kill(); } catch (Win32Exception) { } catch (InvalidOperationException) { } return false; } UOM.SetStatusLabel( Strings.Attachedtoclient ); return true; } }
public static void PreparePrimaryCave(ClientInfo ci) { ci.PrimaryCave = new byte[] { 0x00, 0x00, 0xE8, 0xFF, 0xFF, 0xFF, 0xFF, 0x68, 0xFF, 0xFF, 0xFF, 0xFF, 0x66, 0xA1, 0xFF, 0xFF, 0xFF, 0xFF, 0x66, 0x83, 0xF8, 0x00, 0x75, 0x01, 0xC3, 0x66, 0x31, 0xC0, 0x66, 0xA3, 0xFF, 0xFF, 0xFF, 0xFF, 0x68, 0x00, 0x00, 0x00, 0x00, 0x68, 0xFF, 0xFF, 0xFF, 0xFF, 0x68, 0xFF, 0xFF, 0xFF, 0xFF, 0x68, 0xFF, 0xFF, 0xFF, 0xFF, 0xC3, 0x83, 0xC4, 0x08, 0xC3, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x19, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; ci.PrimaryCave[0] = 0; int startWordAddress = ci.CaveAddress.ToInt32(); byte[] hookBytes = ClientHook.CreateCALL(ci.HookAddress, (IntPtr)(startWordAddress + func1offset), CallType.CALL); byte[] origDest = BitConverter.GetBytes(ci.OriginalDest); byte[] serverSendCaveCall = ClientHook.CreateCALL(startWordAddress + func1offset, ci.ServerSendCaveAddress.ToInt32() + 6, CallType.CALL); byte[] startAddress = BitConverter.GetBytes(startWordAddress); byte[] data1Address = BitConverter.GetBytes(startWordAddress + data1offset); byte[] returnAddress = BitConverter.GetBytes(ci.ReturnAddress); byte[] addressForFunc2 = BitConverter.GetBytes(startWordAddress + func2offset + 21); Buffer.BlockCopy(serverSendCaveCall, 0, ci.PrimaryCave, 2, 5); Buffer.BlockCopy(origDest, 0, ci.PrimaryCave, 8, 4); Buffer.BlockCopy(startAddress, 0, ci.PrimaryCave, 14, 4); Buffer.BlockCopy(startAddress, 0, ci.PrimaryCave, 30, 4); Buffer.BlockCopy(data1Address, 0, ci.PrimaryCave, 40, 4); Buffer.BlockCopy(addressForFunc2, 0, ci.PrimaryCave, 45, 4); Buffer.BlockCopy(returnAddress, 0, ci.PrimaryCave, 50, 4); Memory.Write(ci.Handle, ci.CaveAddress, ci.PrimaryCave, true); Memory.Write(ci.Handle, ci.HookAddress, hookBytes, true); ci.PrimaryCave[0] = 1; }
public static void PrepareClientSendCave(ClientInfo ci) { byte[] cave = new byte[] { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x66, 0xA1, 0xFF, 0xFF, 0xFF, 0xFF, 0x66, 0x83, 0xF8, 0x00, 0x75, 0x06, 0x90, 0x90, 0x90, 0x90, 0x90, 0xC3, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x8B, 0x2D, 0xFF, 0xFF, 0xFF, 0xFF, 0x8B, 0x3D, 0xFF, 0xFF, 0xFF, 0xFF, 0x55, 0x8B, 0x0D, 0xFF, 0xFF, 0xFF, 0xFF, 0x8B, 0xF1, 0xE8, 0xFF, 0xFF, 0xFF, 0xFF, 0x66, 0x33, 0xC0, 0x66, 0xA3, 0xFF, 0xFF, 0xFF, 0xFF, 0x5F, 0x5E, 0x5D, 0x5C, 0x5B, 0x5A, 0x59, 0x90, 0x90, 0x90, 0x90, 0x90, 0xC3 }; /* * 0000000000000000 ffff invalid * 0000000000000002 ffff invalid * 0000000000000004 ffff invalid * 0000000000000006 ffff invalid * 0000000000000008 0000 add [eax], al * 000000000000000a 66a1ffffffff mov ax, [0xffffffff] * 0000000000000010 6683f800 cmp ax, 0x0 * 0000000000000014 7506 jnz 0x1c * 0000000000000016 90 nop * 0000000000000017 90 nop * 0000000000000018 90 nop * 0000000000000019 90 nop * 000000000000001a 90 nop * 000000000000001b c3 ret * 000000000000001c 90 nop * 000000000000001d 90 nop * 000000000000001e 90 nop * 000000000000001f 90 nop * 0000000000000020 90 nop * 0000000000000021 90 nop * 0000000000000022 90 nop * 0000000000000023 90 nop * 0000000000000024 90 nop * 0000000000000025 51 push ecx * 0000000000000026 52 push edx * 0000000000000027 53 push ebx * 0000000000000028 54 push esp * 0000000000000029 55 push ebp * 000000000000002a 56 push esi * 000000000000002b 57 push edi * 000000000000002c 8b2dffffffff mov ebp, [0xffffffff] * 0000000000000032 8b3dffffffff mov edi, [0xffffffff] * 0000000000000038 55 push ebp * 0000000000000039 8b0dffffffff mov ecx, [0xffffffff] * 000000000000003f 8bf1 mov esi, ecx * 0000000000000041 e8ffffffff call 0x45 * 0000000000000046 6633c0 xor ax, ax * 0000000000000049 66a3ffffffff mov [0xffffffff], ax * 000000000000004f 5f pop edi * 0000000000000050 5e pop esi * 0000000000000051 5d pop ebp * 0000000000000052 5c pop esp * 0000000000000053 5b pop ebx * 0000000000000054 5a pop edx * 0000000000000055 59 pop ecx * 0000000000000056 90 nop * 0000000000000057 90 nop * 0000000000000058 90 nop * 0000000000000059 90 nop * 000000000000005a 90 nop * 000000000000005b c3 ret */ int caveAddress = ci.ClientSendCaveAddress.ToInt32(); byte[] bufferDword = BitConverter.GetBytes(caveAddress); byte[] lenDword = BitConverter.GetBytes(caveAddress + 4); byte[] startWord = BitConverter.GetBytes(caveAddress + 8); byte[] packetRecvCALL = ClientHook.CreateCALL((IntPtr)(caveAddress + 65), ci.RecvHookAddress, CallType.CALL); byte[] pathFindCaveCALL = ClientHook.CreateCALL(caveAddress + 22, ci.PathFindCaveAddress.ToInt32() + 8, CallType.CALL); byte[] recheckCALL = ClientHook.CreateCALL(caveAddress + /*77*/ 86, caveAddress + 10, CallType.JMP); byte[] data = BitConverter.GetBytes(ci.ClientPacketData); Buffer.BlockCopy(startWord, 0, cave, 12, 4); Buffer.BlockCopy(pathFindCaveCALL, 0, cave, 22, 5); Buffer.BlockCopy(startWord, 0, cave, /*33*/ 75, 4); Buffer.BlockCopy(bufferDword, 0, cave, 46, 4); Buffer.BlockCopy(lenDword, 0, cave, 52, 4); Buffer.BlockCopy(data, 0, cave, 59, 4); Buffer.BlockCopy(packetRecvCALL, 0, cave, 65, 5); Buffer.BlockCopy(recheckCALL, 0, cave, /*77*/ 86, 5); Memory.Write(ci.Handle, ci.ClientSendCaveAddress, cave, true); }
private static bool GetSendAddress( int baseAddress, byte[] buffer, ClientInfo clientInfo ) { byte[] sig1 = new byte[] { 0x8D, 0x8B, 0x94, 0x00, 0x00, 0x00 }; // 8d8b94000000 lea ecx, [ebx+0x94] byte[] sig2 = new byte[] { 0x0F, 0xB7, 0xD8, 0x0F, 0xB6, 0x06, 0x83, 0xC4, 0x04 }; /* 0000000000000000 0fb7d8 movzx ebx, ax 0000000000000003 0fb606 movzx eax, byte [esi] 0000000000000006 83c404 add esp, 0x4 */ int offset; if (FindSignatureOffset( sig1, buffer, out offset )) { clientInfo.SendHookAddress = (IntPtr) ( baseAddress + offset + 11 ); clientInfo.SendHookType = 0; return true; } if (FindSignatureOffset( sig2, buffer, out offset )) { clientInfo.SendHookAddress = (IntPtr) ( baseAddress + offset + 9 ); clientInfo.SendHookType = 1; return true; } return false; }
private static bool GetServerSendAddress( int baseAddress, byte[] buffer, ClientInfo clientInfo ) { byte[] sig1 = new byte[] { 0x85, 0xC9, 0x74, 0x0A, 0x8B, 0x44, 0x24, 0x04, 0x50, 0xE8 }; int offset; if (FindSignatureOffset( sig1, buffer, out offset )) { int address = BitConverter.ToInt32( buffer, offset + 10 ); clientInfo.ServerPacketSendFunction = baseAddress + offset + 14 + address; return true; } return false; }
private static bool GetGumpPointer( int baseAddress, byte[] buffer, ClientInfo clientInfo ) { byte[] sig1 = new byte[] { 0x8B, 0x44, 0x24, 0x04, 0xC7, 0x41, 0x5C, 0x00, 0x00, 0x00, 0x00 }; byte[] sig2 = new byte[] { 0x8B, 0x44, 0x24, 0x04, 0x85, 0xC0, 0x89, 0x41, 0x64 }; int offset; if (FindSignatureOffset( sig1, buffer, out offset )) { clientInfo.TopGumpPointer = (IntPtr) BitConverter.ToUInt32( buffer, offset + 0x14 ); return true; } if (FindSignatureOffset( sig2, buffer, out offset )) { clientInfo.TopGumpPointer = (IntPtr) BitConverter.ToUInt32( buffer, offset + 0x14 ); return true; } return false; }
public static bool Attach(uint pid, OptionsData options, bool isRazor, out int index) { lock (myLock) { Process p = null; index = -1; try { Thread.Sleep(2000); p = Process.GetProcessById((int)pid); p.EnableRaisingEvents = true; p.Exited += new EventHandler(UOM.OnClientExit); ClientInfo ci = new ClientInfo(p); Memory.MemoryInit(ci); if (ci.IsValid) { ci.InstallMacroHook(); } else { return(false); } if (!isRazor && options.PatchClientEncryptionUOM) { if (!ClientPatcher.PatchEncryption(p.Handle)) { MessageBox.Show("Error patching client encryption!", "Error"); } } if (ci.DateStamp < 0x4AA52CC4 && options.PatchStaminaCheck) { if (!ClientPatcher.PatchStaminaCheck(p.Handle)) { MessageBox.Show("Error patching stamina check!", "Error"); } } if (options.PatchAlwaysLight) { if (!ClientPatcher.PatchLight(p.Handle)) { MessageBox.Show("Error with always light patch!", "Error"); } } int instance; if (!ClientInfoCollection.AddClient(ci, out instance)) { throw new ApplicationException("Unknown error at ClientInfoCollection.Add."); } ci.Instance = instance; index = instance; Macros.Macro.ChangeServer(instance, options.Server, options.Port); Thread.Sleep(500); RemoteHooking.Inject(p.Id, Path.Combine(UOM.StartupPath, "clienthook.dll"), Path.Combine(UOM.StartupPath, "clienthook.dll"), UOM.ServerName); } catch (Exception e) { Utility.Log.LogMessage(e); MessageBox.Show("Error injecting ClientHook.dll into target process. Please try again.", "Error"); try { if (p != null) { p.Kill(); } } catch (Win32Exception) { } catch (InvalidOperationException) { } return(false); } UOM.SetStatusLabel("Status: Attached to client"); return(true); } }
private static bool GetHookAddress( int baseAddress, byte[] buffer, ClientInfo clientInfo ) { byte[] sig1 = new byte[] { 0x53, 0x68, 0xE8, 0x03, 0x00, 0x00, 0x52 }; int offset; if (FindSignatureOffset( sig1, buffer, out offset )) { clientInfo.HookAddress = (IntPtr) ( baseAddress + offset + 8 ); clientInfo.OriginalDest = baseAddress + ( offset + 9 ) + 4 + BitConverter.ToInt32( buffer, offset + 9 ); return true; } return false; }
public static void PreparePathfindCave( ClientInfo ci ) { byte[] cave; int caveAddress = ci.PathFindCaveAddress.ToInt32(); byte[] startWord = BitConverter.GetBytes( caveAddress + 6 ); byte[] EAXDword = BitConverter.GetBytes( caveAddress - 0x24 ); byte[] gumpFunction; byte[] RETNDword; byte[] pathFindJMP; switch (ci.PathFindType) { case 0: cave = new byte[] { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x66, 0xA1, 0xFF, 0xFF, 0xFF, 0xFF, 0x66, 0x83, 0xF8, 0x00, 0x75, 0x06, 0x90, 0x90, 0x90, 0x90, 0x90, 0xC3, 0x66, 0x33, 0xC0, 0x66, 0xA3, 0xFF, 0xFF, 0xFF, 0xFF, 0x6A, 0x00, 0x6A, 0x00, 0x68, 0xFF, 0xFF, 0xFF, 0xFF, 0x51, 0x53, 0x55, 0x56, 0x57, 0xB8, 0xFF, 0xFF, 0xFF, 0xFF, 0xE9, 0xFF, 0xFF, 0xFF, 0xFF, 0xC3 }; gumpFunction = ClientHook.CreateCALL( caveAddress + 20, ci.GumpFunctionCaveAddress.ToInt32() + 10, CallType.CALL ); pathFindJMP = ClientHook.CreateCALL( caveAddress + 54, ci.PathFindFunction, CallType.JMP ); RETNDword = BitConverter.GetBytes( caveAddress + cave.Length - 1 ); Buffer.BlockCopy( startWord, 0, cave, 10, 4 ); Buffer.BlockCopy( startWord, 0, cave, 31, 4 ); Buffer.BlockCopy( gumpFunction, 0, cave, 20, 5 ); Buffer.BlockCopy( RETNDword, 0, cave, 40, 4 ); Buffer.BlockCopy( EAXDword, 0, cave, 50, 4 ); Buffer.BlockCopy( pathFindJMP, 0, cave, 54, 5 ); Memory.Write( ci.Handle, ci.PathFindCaveAddress, cave, true ); break; case 1: /* 004008D1 FFFF ??? ; X * 004008D3 FFFF ??? ; Y * 004008D5 FFFF ??? ; Z * 004008D7 0000 ADD BYTE PTR DS:[EAX],AL ; nonzero = execute * 004008D9 66:A1 D7084000 MOV AX,WORD PTR DS:[4008D7] * 004008DF 66:83F8 00 CMP AX,0 * 004008E3 75 06 JNZ SHORT client.004008EB * 004008E5 90 NOP ; reserved for future * 004008E6 90 NOP ; reserved for future * 004008E7 90 NOP ; reserved for future * 004008E8 90 NOP ; reserved for future * 004008E9 90 NOP ; reserved for future * 004008EA C3 RETN * 004008EB 66:33C0 XOR AX,AX * 004008EE 66:A3 D7084000 MOV WORD PTR DS:[4008D7],AX * 004008F4 6A 00 PUSH 0 * 004008F6 6A 00 PUSH 0 * 004008F8 68 08094000 PUSH client.00400908 ; RETN from pathfind * 004008FD 51 PUSH ECX * 004008FE B8 AD084000 MOV EAX,client.004008AD ; EAX + 0x24 = X word * 00400903 -E9 51980900 JMP client.0049A159 * 00400908 C3 RETN */ cave = new byte[] { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x66, 0xA1, 0xFF, 0xFF, 0xFF, 0xFF, 0x66, 0x83, 0xF8, 0x00, 0x75, 0x06, 0x90, 0x90, 0x90, 0x90, 0x90, 0xC3, 0x66, 0x33, 0xC0, 0x66, 0xA3, 0xFF, 0xFF, 0xFF, 0xFF, 0x6A, 0x00, 0x6A, 0x00, 0x68, 0xFF, 0xFF, 0xFF, 0xFF, 0x51, 0xB8, 0xFF, 0xFF, 0xFF, 0xFF, 0xE9, 0xFF, 0xFF, 0xFF, 0xFF, 0xC3 }; gumpFunction = ClientHook.CreateCALL( caveAddress + 20, ci.GumpFunctionCaveAddress.ToInt32() + 10, CallType.CALL ); pathFindJMP = ClientHook.CreateCALL( caveAddress + 50, ci.PathFindFunction, CallType.JMP ); RETNDword = BitConverter.GetBytes( caveAddress + cave.Length - 1 ); Buffer.BlockCopy( startWord, 0, cave, 10, 4 ); Buffer.BlockCopy( startWord, 0, cave, 31, 4 ); Buffer.BlockCopy( RETNDword, 0, cave, 40, 4 ); Buffer.BlockCopy( EAXDword, 0, cave, 46, 4 ); Buffer.BlockCopy( pathFindJMP, 0, cave, 50, 5 ); Buffer.BlockCopy( gumpFunction, 0, cave, 20, 5 ); Memory.Write( ci.Handle, ci.PathFindCaveAddress, cave, true ); break; } }
public static void PrepareClientSendCave( ClientInfo ci ) { byte[] cave = new byte[] { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x66, 0xA1, 0xFF, 0xFF, 0xFF, 0xFF, 0x66, 0x83, 0xF8, 0x00, 0x75, 0x06, 0x90, 0x90, 0x90, 0x90, 0x90, 0xC3, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x8B, 0x2D, 0xFF, 0xFF, 0xFF, 0xFF, 0x8B, 0x3D, 0xFF, 0xFF, 0xFF, 0xFF, 0x55, 0x8B, 0x0D, 0xFF, 0xFF, 0xFF, 0xFF, 0x8B, 0xF1, 0xE8, 0xFF, 0xFF, 0xFF, 0xFF, 0x66, 0x33, 0xC0, 0x66, 0xA3, 0xFF, 0xFF, 0xFF, 0xFF, 0x5F, 0x5E, 0x5D, 0x5C, 0x5B, 0x5A, 0x59, 0x90, 0x90, 0x90, 0x90, 0x90, 0xC3 }; /* 0000000000000000 ffff invalid 0000000000000002 ffff invalid 0000000000000004 ffff invalid 0000000000000006 ffff invalid 0000000000000008 0000 add [eax], al 000000000000000a 66a1ffffffff mov ax, [0xffffffff] 0000000000000010 6683f800 cmp ax, 0x0 0000000000000014 7506 jnz 0x1c 0000000000000016 90 nop 0000000000000017 90 nop 0000000000000018 90 nop 0000000000000019 90 nop 000000000000001a 90 nop 000000000000001b c3 ret 000000000000001c 90 nop 000000000000001d 90 nop 000000000000001e 90 nop 000000000000001f 90 nop 0000000000000020 90 nop 0000000000000021 90 nop 0000000000000022 90 nop 0000000000000023 90 nop 0000000000000024 90 nop 0000000000000025 51 push ecx 0000000000000026 52 push edx 0000000000000027 53 push ebx 0000000000000028 54 push esp 0000000000000029 55 push ebp 000000000000002a 56 push esi 000000000000002b 57 push edi 000000000000002c 8b2dffffffff mov ebp, [0xffffffff] 0000000000000032 8b3dffffffff mov edi, [0xffffffff] 0000000000000038 55 push ebp 0000000000000039 8b0dffffffff mov ecx, [0xffffffff] 000000000000003f 8bf1 mov esi, ecx 0000000000000041 e8ffffffff call 0x45 0000000000000046 6633c0 xor ax, ax 0000000000000049 66a3ffffffff mov [0xffffffff], ax 000000000000004f 5f pop edi 0000000000000050 5e pop esi 0000000000000051 5d pop ebp 0000000000000052 5c pop esp 0000000000000053 5b pop ebx 0000000000000054 5a pop edx 0000000000000055 59 pop ecx 0000000000000056 90 nop 0000000000000057 90 nop 0000000000000058 90 nop 0000000000000059 90 nop 000000000000005a 90 nop 000000000000005b c3 ret */ int caveAddress = ci.ClientSendCaveAddress.ToInt32(); byte[] bufferDword = BitConverter.GetBytes( caveAddress ); byte[] lenDword = BitConverter.GetBytes( caveAddress + 4 ); byte[] startWord = BitConverter.GetBytes( caveAddress + 8 ); byte[] packetRecvCALL = ClientHook.CreateCALL( (IntPtr)(caveAddress + 65), ci.RecvHookAddress, CallType.CALL ); byte[] pathFindCaveCALL = ClientHook.CreateCALL( caveAddress + 22, ci.PathFindCaveAddress.ToInt32() + 8, CallType.CALL ); byte[] recheckCALL = ClientHook.CreateCALL( caveAddress + /*77*/86, caveAddress + 10, CallType.JMP ); byte[] data = BitConverter.GetBytes( ci.ClientPacketData ); Buffer.BlockCopy( startWord, 0, cave, 12, 4 ); Buffer.BlockCopy( pathFindCaveCALL, 0, cave, 22, 5 ); Buffer.BlockCopy( startWord, 0, cave, /*33*/75, 4 ); Buffer.BlockCopy( bufferDword, 0, cave, 46, 4 ); Buffer.BlockCopy( lenDword, 0, cave, 52, 4 ); Buffer.BlockCopy( data, 0, cave, 59, 4 ); Buffer.BlockCopy( packetRecvCALL, 0, cave, 65, 5 ); Buffer.BlockCopy( recheckCALL, 0, cave, /*77*/86, 5 ); Memory.Write( ci.Handle, ci.ClientSendCaveAddress, cave, true ); }
public static void PrepareServerSendCave( ClientInfo ci ) { byte[] cave = new byte[] { 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x66, 0xA1, 0xFF, 0xFF, 0xFF, 0xFF, 0x66, 0x83, 0xF8, 0x00, 0x75, 0x06, 0xE8, 0xFF, 0xFF, 0xFF, 0xFF, 0xC3, 0x66, 0x33, 0xC0, 0x66, 0xA3, 0xFF, 0xFF, 0xFF, 0xFF, 0x53, 0x54, 0x55, 0x56, 0x57, 0xA1, 0xFF, 0xFF, 0xFF, 0xFF, 0x50, 0x8B, 0x0D, 0xFF, 0xFF, 0xFF, 0xFF, 0x8B, 0xD9, 0xE8, 0xFF, 0xFF, 0xFF, 0xFF, 0x5F, 0x5E, 0x5D, 0x5C, 0x5B, 0xC3 }; int caveAddress = ci.ServerSendCaveAddress.ToInt32(); byte[] bufferDword = BitConverter.GetBytes( caveAddress ); byte[] startWord = BitConverter.GetBytes( caveAddress + 4 ); byte[] packetSendCALL = ClientHook.CreateCALL( (IntPtr)(caveAddress + 52), (IntPtr)ci.ServerPacketSendFunction, CallType.CALL ); byte[] clientSendCaveCall = ClientHook.CreateCALL( (IntPtr)(caveAddress + 18), (IntPtr)(ci.ClientSendCaveAddress.ToInt32() + 10), CallType.CALL ); byte[] data = BitConverter.GetBytes( ci.ClientPacketData ); Buffer.BlockCopy( startWord, 0, cave, 8, 4 ); Buffer.BlockCopy( startWord, 0, cave, 29, 4 ); Buffer.BlockCopy( bufferDword, 0, cave, 39, 4 ); Buffer.BlockCopy( data, 0, cave, 46, 4 ); Buffer.BlockCopy( packetSendCALL, 0, cave, 52, 5 ); Buffer.BlockCopy( clientSendCaveCall, 0, cave, 18, 5 ); Memory.Write( ci.Handle, ci.ServerSendCaveAddress, cave, true ); }
public string Start(string path) { Process clientProcess = null; try { ProcessStartInfo startInfo = new ProcessStartInfo(); startInfo.WorkingDirectory = path; startInfo.FileName = Path.Combine(path, "client.exe"); UOMachine.NativeMethods.SafeProcessHandle hProcess; UOMachine.NativeMethods.SafeThreadHandle hThread; uint pid, tid; if (UOMachine.NativeMethods.CreateProcess(startInfo, true, out hProcess, out hThread, out pid, out tid)) { ClientPatcher.MultiPatch(hProcess.DangerousGetHandle()); bool result = false; m_AddressLock = new object(); clientProcess = Process.GetProcessById((int)pid); UOMachine.IPC.Network.Initialize(); UOMachine.Utility.Log.Initialize("UnitTests" + DateTime.Now.ToString("[MM - dd - yyyy HH.mm.ss] ") + ".txt"); InternalEventHandler.IPCHandler.Initialize(); UOMachine.NativeMethods.ResumeThread(hThread.DangerousGetHandle()); ClientInfo ci = new ClientInfo(clientProcess); int instance = 0; ClientInfoCollection.ClientList[instance] = ci; ClientInfoCollection.Count = 1; ulong len = (ulong)ci.EntryPoint - (ulong)ci.BaseAddress; UOMachine.NativeMethods.GainMemoryAccessEx(ci.Handle, ci.BaseAddress, len); string channelName = null; RemoteHooking.IpcCreateServer<LoginServerTest>(ref channelName, System.Runtime.Remoting.WellKnownObjectMode.SingleCall); RemoteHooking.Inject(clientProcess.Id, Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "UnitTests.dll"), null, channelName); ci.InstallMacroHook(); Macro.ChangeServer(instance, "127.0.0.1", 2593); Thread.Sleep(10000); lock (m_AddressLock) { GumpInfo[] gi = Macro.GetGumpList(instance); foreach (GumpInfo g in gi) { if (g.Type == "MainMenu gump") { foreach (GumpInfo g2 in g.SubGumps) { if (g2.Type == "AcctLogin gump") { if (ci.DateStamp > 0x43A06A35) g2.CallFunction(26); else g2.CallFunction(23); } } } } result = Monitor.Wait(m_AddressLock, 60000); } UOMachine.IPC.Network.Dispose(); Log.Dispose(); UOMachine.NativeMethods.TerminateProcess(Process.GetProcessById(clientProcess.Id).Handle, 0); return m_Address; } } catch (Exception) { UOMachine.IPC.Network.Dispose(); Log.Dispose(); UOMachine.NativeMethods.TerminateProcess(Process.GetProcessById(clientProcess.Id).Handle, 0); throw; } return null; }
private static bool GetLoginServerAddress( int baseAddress, byte[] buffer, ClientInfo clientInfo ) { /* Here we're getting address for server IP as well as preventing client from overwriting our IP * we're also getting port address and protecting it as well */ byte[] sig1 = new byte[] { 0x8B, 0x44, 0x24, 0x0C, 0xC1, 0xE1, 0x08, 0x0B, 0xC8, 0x66, 0x89, 0x15 }; byte[] sig2 = new byte[] { 0xC1, 0xE1, 0x08, 0x0B, 0x4C, 0x24, 0x0C, 0x89, 0x0D }; byte[] sig3 = new byte[] { 0x83, 0XC4, 0X04, 0X50, 0X51, 0X8B, 0XCF, 0XE8 }; int offset; if (FindSignatureOffset( sig1, buffer, out offset )) { byte[] patch = { 0x90, 0x90, 0x90, 0x90, 0x90, 0x90 }; byte[] portPatch = { 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90 }; IntPtr portPatchAddress = (IntPtr) ( baseAddress + offset + 0x09 ); IntPtr patchAddress = (IntPtr) ( baseAddress + offset + 0x10 ); clientInfo.LoginServerAddress = (IntPtr) ( BitConverter.ToInt32( buffer, offset + 0x12 ) ); clientInfo.LoginPortAddress = (IntPtr) ( BitConverter.ToInt32( buffer, offset + 0x0C ) ); if (Memory.Write( clientInfo.Handle, patchAddress, patch, true )) return Memory.Write( clientInfo.Handle, portPatchAddress, portPatch, true ); } if (FindSignatureOffset( sig2, buffer, out offset )) { byte[] patch = { 0x90, 0x90, 0x90, 0x90, 0x90, 0x90 }; byte[] portPatch = { 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90 }; IntPtr portPatchAddress = (IntPtr) ( baseAddress + offset - 0x07 ); IntPtr patchAddress = (IntPtr) ( baseAddress + offset + 0x07 ); clientInfo.LoginServerAddress = (IntPtr) ( BitConverter.ToInt32( buffer, offset + 0x09 ) ); clientInfo.LoginPortAddress = (IntPtr) ( BitConverter.ToInt32( buffer, offset - 0x04 ) ); if (Memory.Write( clientInfo.Handle, patchAddress, patch, true )) return Memory.Write( clientInfo.Handle, portPatchAddress, portPatch, true ); } if (FindSignatureOffset( sig3, buffer, out offset )) { // Tested up to 7.0.46.2 2015-10-22 //.text: 00599FB0 loc_599FB0: ; CODE XREF: sub_599F10 + E5j //.text:00599FB0 push ebx //.text:00599FB1 call sub_595C10 // NOP's here //.text:00599FB6 movzx eax, word_A9A634 // port //.text:00599FBD mov ecx, dword_A9A630 // address //.text:00599FC3 add esp, 4 //.text:00599FC6 push eax; hostshort //.text:00599FC7 push ecx; hostlong //.text:00599FC8 mov ecx, edi byte[] patch = { 0x90, 0x90, 0x90, 0x90, 0x90 }; IntPtr patchAddress = (IntPtr) ( baseAddress + offset - 0x12 ); Memory.Write( clientInfo.Handle, patchAddress, patch, true ); clientInfo.LoginServerAddress = (IntPtr) ( BitConverter.ToInt32( buffer, offset - 0x04 ) ); clientInfo.LoginPortAddress = (IntPtr) ( BitConverter.ToInt32( buffer, offset - 0x0A ) ); return true; } return false; }
public static void Execute(ClientInfo ci, byte param1, byte param2) { ci.PrimaryCave[data1offset + 24] = param1; ci.PrimaryCave[data1offset + 28] = param2; Memory.Write(ci.Handle, ci.CaveAddress, ci.PrimaryCave, true); }
public static void InstallRecvHook( ClientInfo ci ) { switch (ci.RecvHookType) { case 0: /* 00400801 50 PUSH EAX * 00400802 51 PUSH ECX * 00400803 52 PUSH EDX * 00400804 57 PUSH EDI * 00400805 55 PUSH EBP * 00400806 E8 4708B845 CALL 45F81052 * 0040080B 5A POP EDX * 0040080C 59 POP ECX * 0040080D 58 POP EAX * 0040080E 53 PUSH EBX * 0040080F 56 PUSH ESI * 00400810 57 PUSH EDI * 00400811 89CF MOV EDI,ECX * 00400813 -E9 6D420300 JMP client.00434A85 */ int caveAddress0 = ci.RecvCaveAddress.ToInt32(); IntPtr callStart0 = (IntPtr)(caveAddress0 + 5); int jmpStart0 = caveAddress0 + 18; int jmpEnd0 = ci.RecvHookAddress.ToInt32() + 5; byte[] call0 = CreateCALL( callStart0, ci.RecvFunctionPointer, CallType.CALL ); byte[] jump0 = CreateCALL( jmpStart0, jmpEnd0, CallType.JMP ); byte[] newCode0 = new byte[] { 0x50, 0x51, 0x52, 0x57, 0x55, 0xE8, 0x00, 0x00, 0x00, 0x00, 0x5A, 0x59, 0x58, 0x53, 0x56, 0x57, 0x89, 0xCF, 0xE9, 0x00, 0x00, 0x00, 0x00 }; Buffer.BlockCopy( call0, 0, newCode0, 5, 5 ); Buffer.BlockCopy( jump0, 0, newCode0, 18, 5 ); byte[] hook0 = CreateCALL( ci.RecvHookAddress, ci.RecvCaveAddress, CallType.JMP ); Memory.Write( ci.Handle, ci.RecvCaveAddress, newCode0, true ); Memory.Write( ci.Handle, ci.RecvHookAddress, hook0, true ); return; case 1: /* 004007F9 50 PUSH EAX * 004007FA 51 PUSH ECX * 004007FB 52 PUSH EDX * 004007FC 57 PUSH EDI * 004007FD 55 PUSH EBP * 004007FE E8 4F08AD45 CALL 45ED1052 * 00400803 5A POP EDX * 00400804 59 POP ECX * 00400805 58 POP EAX * 00400806 A1 D4797F00 MOV EAX,DWORD PTR DS:[7F79D4] * 0040080B -E9 45890300 JMP client.00439155 */ int caveAddress1 = ci.RecvCaveAddress.ToInt32(); byte[] firstInstruction = new byte[5]; Memory.Read( ci.Handle, ci.RecvHookAddress, firstInstruction, true ); IntPtr callStart1 = (IntPtr)(caveAddress1 + 5); int jmpStart1 = caveAddress1 + (18 + 5); int jmpEnd1 = ci.RecvHookAddress.ToInt32() + 5; byte[] call1 = CreateCALL( callStart1, ci.RecvFunctionPointer, CallType.CALL ); byte[] jump1 = CreateCALL( jmpStart1, jmpEnd1, CallType.JMP ); byte[] newCode1 = new byte[] { 0x50, 0x51, 0x52, 0x57, 0x55, 0xE8, 0x00, 0x00, 0x00, 0x00, 0x83, 0xF8, 0x01, // CMP EAX, 1 0x74, 0x0D, // JE +D 0x5A, 0x59, 0x58, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xE9, 0x00, 0x00, 0x00, 0x00, 0x5A, 0x59, 0x58, 0x90, 0x90, 0x90, 0x90, 0x90, 0xC2, 0x04, 0x00 }; Buffer.BlockCopy( firstInstruction, 0, newCode1, (13 + 5), 5 ); Buffer.BlockCopy( firstInstruction, 0, newCode1, (31), 5 ); Buffer.BlockCopy( call1, 0, newCode1, 5, 5 ); Buffer.BlockCopy( jump1, 0, newCode1, (18 + 5), 5 ); byte[] hook1 = CreateCALL( ci.RecvHookAddress, ci.RecvCaveAddress, CallType.JMP ); Memory.Write( ci.Handle, ci.RecvCaveAddress, newCode1, true ); Memory.Write( ci.Handle, ci.RecvHookAddress, hook1, true ); return; } }
private static bool GetPathFindAddress( int baseAddress, byte[] buffer, ClientInfo clientInfo ) { byte[] sig1 = new byte[] { 0x0F, 0xBF, 0x68, 0x24, 0x0F, 0xBF, 0x50, 0x26 }; byte[] sig2 = new byte[] { 0x0F, 0xBF, 0x50, 0x26, 0x53, 0x8B, 0x1D }; int offset; if (FindSignatureOffset( sig1, buffer, out offset )) { clientInfo.PathFindFunction = baseAddress + offset; clientInfo.PathFindType = 0; return true; } if (FindSignatureOffset( sig2, buffer, out offset )) { clientInfo.PathFindFunction = baseAddress + offset; clientInfo.PathFindType = 1; return true; } return false; }
private static bool GetPlayerInfoPointer( int baseAddress, byte[] buffer, ClientInfo clientInfo ) { int offset; byte[] sig1 = new byte[] { 0x0F, 0xBF, 0x4A, 0x28, 0x83, 0xC1, 0x05 }; if (FindSignatureOffset( sig1, buffer, out offset )) { clientInfo.PlayerInfoPointer = (IntPtr) BitConverter.ToUInt32( buffer, offset - 6 ); #if DEBUG Log.LogMessage( clientInfo.Instance, "Player info pointer = 0x" + clientInfo.PlayerInfoPointer.ToString( "X" ) ); #endif return true; } return false; }
private static bool GetRecvAddress( int baseAddress, byte[] buffer, ClientInfo clientInfo ) { byte[] sig1 = new byte[] { 0x53, 0x56, 0x57, 0x8B, 0xF9, 0x8B, 0x0D }; byte[] sig2 = new byte[] { 0x8B, 0x38, 0x8B, 0xE9, 0xBE }; byte[] sig3 = new byte[] { 0x8B, 0x38, 0x8B, 0xD9, 0xBE }; int offset; if (FindSignatureOffset( sig1, buffer, out offset )) { clientInfo.RecvHookAddress = (IntPtr) ( baseAddress + offset ); clientInfo.RecvHookType = 0; #if DEBUG Log.LogMessage( clientInfo.Instance, "Recv hook address = 0x" + clientInfo.RecvHookAddress.ToString( "X" ) ); #endif return true; } if (FindSignatureOffset( sig2, buffer, out offset )) { clientInfo.RecvHookAddress = (IntPtr) ( baseAddress + offset - 18 ); clientInfo.RecvHookType = 1; #if DEBUG Log.LogMessage( clientInfo.Instance, "Recv hook address = 0x" + clientInfo.RecvHookAddress.ToString( "X" ) ); #endif return true; } if (FindSignatureOffset( sig3, buffer, out offset )) { clientInfo.RecvHookAddress = (IntPtr) ( baseAddress + offset - 18 ); clientInfo.RecvHookType = 1; #if DEBUG Log.LogMessage( clientInfo.Instance, "Recv hook address = 0x" + clientInfo.RecvHookAddress.ToString( "X" ) ); #endif return true; } return false; }
public static bool GetClient(int index, out ClientInfo clientInfo) { if (index < 0 || index > 31) { clientInfo = null; return false; } clientInfo = ThreadHelper.VolatileRead<ClientInfo>(ref ClientList[index]); return clientInfo == null ? false : true; }
private static bool GetReturnAddress1( int baseAddress, byte[] buffer, ClientInfo clientInfo ) { byte[] sig1 = new byte[] { 0x6A, 0xFF, 0x68, 0xCC, 0xCC, 0xCC, 0xCC, 0x64, 0xA1, 0x00, 0x00, 0x00, 0x00, 0x50, 0xB8, 0x78, 0x30, 0x00, 0x00 }; byte[] sig2 = new byte[] { 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0x68, 0xCC, 0xCC, 0xCC, 0xCC, 0x50, 0xB8, 0xCC, 0xCC, 0xCC, 0xCC, 0x64, 0x89, 0x25, 0x00, 0x00, 0x00, 0x00, 0xE8, 0xCC, 0xCC, 0xCC, 0xCC, 0x8B, 0x84, 0x24 }; int offset; if (FindSignatureOffset( sig1, buffer, out offset )) { clientInfo.ReturnAddress = baseAddress + offset; return true; } if (FindSignatureOffset( sig2, buffer, out offset )) { clientInfo.ReturnAddress = baseAddress + offset + 6; return true; } return false; }
public static void InstallSendHook(ClientInfo ci) { switch (ci.SendHookType) { case 0: byte[] newCode0 = new byte[] { 0x50, 0x51, 0x52, 0x55, 0x56, 0xE8, 0xFF, 0xFF, 0xFF, 0xFF, 0x5A, 0x59, 0x58, 0x55, 0x8D, 0x8B, 0xBC, 0x00, 0x00, 0x00, 0xE9, 0xFF, 0xFF, 0xFF, 0xFF }; /* 0000000000000000 50 push eax 0000000000000001 51 push ecx 0000000000000002 52 push edx 0000000000000003 55 push ebp 0000000000000004 56 push esi 0000000000000005 e8ffffffff call 0xffffffff 000000000000000a 5a pop edx 000000000000000b 59 pop ecx 000000000000000c 58 pop eax 000000000000000d 55 push ebp 000000000000000e 8d8bbc000000 lea ecx, [ebx+0xbc] 0000000000000014 e9ffffffff jmp 0xffffffff */ byte[] hook0 = new byte[] { 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90 }; byte[] hookTemp0 = CreateCALL(ci.SendHookAddress, ci.SendCaveAddress, CallType.JMP); byte[] functionCall0 = CreateCALL(ci.SendCaveAddress.ToInt32() + 5, ci.SendFunctionPointer.ToInt32(), CallType.CALL); byte[] jmpBack0 = CreateCALL(ci.SendCaveAddress.ToInt32() + 20, ci.SendHookAddress.ToInt32() + 7, CallType.JMP); Buffer.BlockCopy(hookTemp0, 0, hook0, 0, 5); Buffer.BlockCopy(functionCall0, 0, newCode0, 5, 5); Buffer.BlockCopy(jmpBack0, 0, newCode0, 20, 5); Memory.Write(ci.Handle, ci.SendCaveAddress, newCode0, true); Memory.Write(ci.Handle, ci.SendHookAddress, hook0, true); break; case 1: byte[] newCode1 = new byte[] { 0x50, 0x51, 0x52, 0x53, 0x56, 0xE8, 0xFF, 0xFF, 0xFF, 0xFF, 0x83, 0xF8, 01, // CMP EAX, 1 0x74, 0x0D, // JZ +D 0x5A, 0x59, 0x58, 0x53, 0x50, 0x8D, 0x4F, 0x6C, 0xE9, 0xFF, 0xFF, 0xFF, 0xFF, 0x58, 0x59, 0x5A, 0x5E, 0x5E, 0x5E, 0xC2, 04, 00 // RETN 4 }; /* 0000000000000000 50 push eax 0000000000000001 51 push ecx 0000000000000002 52 push edx 0000000000000003 53 push ebx 0000000000000004 56 push esi 0000000000000005 e8ffffffff call 0xffffffff 000000000000000a 5a pop edx 000000000000000b 59 pop ecx 000000000000000c 58 pop eax 000000000000000d 53 push ebx 000000000000000e 50 push eax 000000000000000f 8d4f6c lea ecx, [edi+0x6c] 0000000000000012 e9ffffffff jmp 0xffffffff */ byte[] hook1 = CreateCALL(ci.SendHookAddress, ci.SendCaveAddress, CallType.JMP); byte[] functionCall1 = CreateCALL(ci.SendCaveAddress.ToInt32() + 5, ci.SendFunctionPointer.ToInt32(), CallType.CALL); byte[] jmpBack1 = CreateCALL(ci.SendCaveAddress.ToInt32() + (18+5), ci.SendHookAddress.ToInt32() + 5, CallType.JMP); Buffer.BlockCopy(functionCall1, 0, newCode1, 5, 5); Buffer.BlockCopy(jmpBack1, 0, newCode1, (18 + 5), 5); Memory.Write(ci.Handle, ci.SendCaveAddress, newCode1, true); Memory.Write(ci.Handle, ci.SendHookAddress, hook1, true); break; } }
private static bool GetCaveAddress(int baseAddress, byte[] buffer, ClientInfo clientInfo) { byte[] sig1 = new byte[3192]; //was 1024 (Reximus 02/2010) int offset; /* * In the past, client crashes I had were due to EasyUO overwriting parts of the code cave with data (I verified). * I'm still getting occasional client crashes when using big EasyUO scripts, and although I haven't checked for sure, * I will assume it's the same problem, so let's VirtualAllocEx our own memory space and use that, I don't know yet if this * will cause any problems (far jmps?) so this is purely a test. */ if (clientInfo.AllocCodeAddress != null) { uint caveAddress = (uint)clientInfo.AllocCodeAddress; uint recvCaveAddress = caveAddress + 526; uint clientSendCaveAddress = recvCaveAddress + 50; uint sendCaveAddress = clientSendCaveAddress + 180; uint serverSendCaveAddress = sendCaveAddress + 100;//26; uint pathFindCaveAddress = serverSendCaveAddress + 100; uint gumpFunctionCaveAddress = pathFindCaveAddress + 100; clientInfo.CaveAddress = (IntPtr)caveAddress; clientInfo.RecvCaveAddress = (IntPtr)recvCaveAddress; clientInfo.SendCaveAddress = (IntPtr)sendCaveAddress; clientInfo.ClientSendCaveAddress = (IntPtr)clientSendCaveAddress; clientInfo.ServerSendCaveAddress = (IntPtr)serverSendCaveAddress; clientInfo.PathFindCaveAddress = (IntPtr)pathFindCaveAddress; clientInfo.GumpFunctionCaveAddress = (IntPtr)gumpFunctionCaveAddress; #if DEBUG Log.LogMessage(clientInfo.Instance, "Cave address = 0x" + clientInfo.RecvHookAddress.ToString("X") + "\r\n" + "Recv cave address = 0x" + clientInfo.RecvCaveAddress.ToString("X") + "\r\n" + "Send cave address = 0x" + clientInfo.SendCaveAddress.ToString("X") + "\r\n" + "Client send cave address = 0x" + clientInfo.ClientSendCaveAddress.ToString("X") + "\r\n" + "Server send cave address = 0x" + clientInfo.ServerSendCaveAddress.ToString("X") + "\r\n" + "Pathfind cave address = 0x" + clientInfo.PathFindCaveAddress.ToString("X") + "\r\n" + "Gump function cave address = 0x" + clientInfo.GumpFunctionCaveAddress.ToString("X") + "\r\n"); #endif return(true); } if (FindSignatureOffset(sig1, buffer, out offset)) { uint caveAddress = (uint)baseAddress + (uint)offset + 1750; //was 750 (Reximus 02/2010) uint recvCaveAddress = caveAddress + 526; uint clientSendCaveAddress = recvCaveAddress + 28; uint sendCaveAddress = clientSendCaveAddress + 80; uint serverSendCaveAddress = sendCaveAddress + 26; uint pathFindCaveAddress = serverSendCaveAddress + 74; uint gumpFunctionCaveAddress = pathFindCaveAddress + 64; clientInfo.CaveAddress = (IntPtr)caveAddress; clientInfo.RecvCaveAddress = (IntPtr)recvCaveAddress; clientInfo.SendCaveAddress = (IntPtr)sendCaveAddress; clientInfo.ClientSendCaveAddress = (IntPtr)clientSendCaveAddress; clientInfo.ServerSendCaveAddress = (IntPtr)serverSendCaveAddress; clientInfo.PathFindCaveAddress = (IntPtr)pathFindCaveAddress; clientInfo.GumpFunctionCaveAddress = (IntPtr)gumpFunctionCaveAddress; return(true); } return(false); }