public bool SendPacketToClientByMemory(Objects.Client client, byte[] packet) { bool ret = false; if (client.LoggedIn()) { if (!client.IO.IsSendToClientCodeWritten) if (!client.IO.WriteOnGetNextPacketCode()) return false; byte[] originalStream = client.Memory.ReadBytes(Pokemon.Addresses.Client.RecvStream, 12); IntPtr myStreamAddress = WinAPI.VirtualAllocEx( client.Handle, IntPtr.Zero, (uint)packet.Length, WinAPI.AllocationType.Commit | WinAPI.AllocationType.Reserve, WinAPI.MemoryProtection.ExecuteReadWrite); if (myStreamAddress != IntPtr.Zero) { if (client.Memory.WriteBytes( myStreamAddress.ToInt64(), packet, (uint)packet.Length)) { byte[] myStream = new byte[12]; Array.Copy(BitConverter.GetBytes(myStreamAddress.ToInt32()), myStream, 4); Array.Copy(BitConverter.GetBytes(packet.Length), 0, myStream, 4, 4); if (client.Memory.WriteBytes(Pokemon.Addresses.Client.RecvStream, myStream, 12)) { if (client.Memory.WriteByte(client.IO.SendToClientAddress.ToInt64(), 0x1)) { IntPtr threadHandle = WinAPI.CreateRemoteThread( client.Handle, IntPtr.Zero, 0, new IntPtr(Pokemon.Addresses.Client.ParserFunc), IntPtr.Zero, 0, IntPtr.Zero); WinAPI.WaitForSingleObject(threadHandle, 0xFFFFFFFF);//INFINITE=0xFFFFFFFF WinAPI.CloseHandle(threadHandle); ret = true; client.Memory.WriteByte(client.IO.SendToClientAddress.ToInt64(), 0x0); } client.Memory.WriteBytes(Pokemon.Addresses.Client.RecvStream, originalStream, 12); } } } if (myStreamAddress != IntPtr.Zero) { WinAPI.VirtualFreeEx( client.Handle, myStreamAddress, 12, WinAPI.AllocationType.Release); } } return ret; }
// (http://www.tpforums.org/forum/showthread.php?t=2832) /// <summary> /// Send a packet through the client by writing some code in memory and running it. /// The packet must not contain any header(no length nor Adler checksum) and be unencrypted /// </summary> /// <param name="client"></param> /// <param name="packet"></param> /// <returns></returns> public static bool SendPacketToServerByMemory(Objects.Client client, byte[] packet) { if (client.LoggedIn()) { if (!client.IO.IsSendToServerCodeWritten) if (!client.IO.WriteSocketSendCode()) return false; uint bufferSize = (uint)(4 + msg.Length); byte[] readyPacket = new byte[bufferSize]; Array.Copy(BitConverter.GetBytes(msg.Length), readyPacket, 4); Array.Copy(packet, 0, readyPacket, 4, packet.Length); IntPtr pRemote = WinAPI.VirtualAllocEx(client.Handle, IntPtr.Zero, /*bufferSize*/ bufferSize, WinAPI.AllocationType.Commit | WinAPI.AllocationType.Reserve, WinAPI.MemoryProtection.ExecuteReadWrite); if (pRemote != IntPtr.Zero) { if (client.Memory.WriteBytes(pRemote.ToInt64(), readyPacket, bufferSize)) { IntPtr threadHandle = Pokemon.Util.WinAPI.CreateRemoteThread(client.Handle, IntPtr.Zero, 0, client.IO.SendToServerAddress, pRemote, 0, IntPtr.Zero); Pokemon.Util.WinAPI.WaitForSingleObject(threadHandle, 0xFFFFFFFF);//INFINITE=0xFFFFFFFF Pokemon.Util.WinAPI.CloseHandle(threadHandle); return true; } } return false; } else return false; }