Experimental memory reading
This commit is contained in:
parent
8a8d2e3ba6
commit
5a5dd1ab88
@ -43,6 +43,7 @@
|
|||||||
<DefineConstants>DEBUG;TRACE</DefineConstants>
|
<DefineConstants>DEBUG;TRACE</DefineConstants>
|
||||||
<ErrorReport>prompt</ErrorReport>
|
<ErrorReport>prompt</ErrorReport>
|
||||||
<WarningLevel>4</WarningLevel>
|
<WarningLevel>4</WarningLevel>
|
||||||
|
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
|
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
|
||||||
<PlatformTarget>x86</PlatformTarget>
|
<PlatformTarget>x86</PlatformTarget>
|
||||||
@ -52,6 +53,7 @@
|
|||||||
<DefineConstants>TRACE</DefineConstants>
|
<DefineConstants>TRACE</DefineConstants>
|
||||||
<ErrorReport>prompt</ErrorReport>
|
<ErrorReport>prompt</ErrorReport>
|
||||||
<WarningLevel>0</WarningLevel>
|
<WarningLevel>0</WarningLevel>
|
||||||
|
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<TargetZone>LocalIntranet</TargetZone>
|
<TargetZone>LocalIntranet</TargetZone>
|
||||||
@ -108,6 +110,7 @@
|
|||||||
<Compile Include="TrueSkill.cs" />
|
<Compile Include="TrueSkill.cs" />
|
||||||
<Compile Include="Utilities.cs" />
|
<Compile Include="Utilities.cs" />
|
||||||
<Compile Include="WebFront.cs" />
|
<Compile Include="WebFront.cs" />
|
||||||
|
<Compile Include="IW4_GameStructs.cs" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<Content Include="lib\Kayak.dll">
|
<Content Include="lib\Kayak.dll">
|
||||||
|
134
Admin/IW4_GameStructs.cs
Normal file
134
Admin/IW4_GameStructs.cs
Normal file
@ -0,0 +1,134 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Runtime.InteropServices;
|
||||||
|
|
||||||
|
|
||||||
|
namespace IW4MAdmin
|
||||||
|
{
|
||||||
|
[StructLayout(LayoutKind.Explicit)]
|
||||||
|
public struct netadr_t
|
||||||
|
{
|
||||||
|
[FieldOffset(0x0)]
|
||||||
|
Int32 type;
|
||||||
|
|
||||||
|
[FieldOffset(0x4)]
|
||||||
|
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 4)]
|
||||||
|
public Byte[] ip;
|
||||||
|
|
||||||
|
[FieldOffset(0x8)]
|
||||||
|
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 10)]
|
||||||
|
public Byte[] ipx;
|
||||||
|
|
||||||
|
[FieldOffset(0x12)]
|
||||||
|
public short port;
|
||||||
|
}
|
||||||
|
|
||||||
|
[StructLayout(LayoutKind.Explicit)]
|
||||||
|
public struct client_s
|
||||||
|
{
|
||||||
|
[FieldOffset(0x0)]
|
||||||
|
public Int32 state;
|
||||||
|
|
||||||
|
[FieldOffset(0x28)]
|
||||||
|
public netadr_t adr;
|
||||||
|
|
||||||
|
[FieldOffset(0x65C)]
|
||||||
|
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 1024)]
|
||||||
|
public String connectInfoString;
|
||||||
|
|
||||||
|
[FieldOffset(0x20EA4)]
|
||||||
|
[MarshalAs(UnmanagedType.ByValTStr, SizeConst=400)] // doubt this is the correct size
|
||||||
|
public String lastUserCmd;
|
||||||
|
|
||||||
|
[FieldOffset(0x212A4)]
|
||||||
|
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 16)]
|
||||||
|
public String name;
|
||||||
|
|
||||||
|
[FieldOffset(0x212C0)]
|
||||||
|
public int snapNum;
|
||||||
|
|
||||||
|
[FieldOffset(0x212C8)]
|
||||||
|
public short ping;
|
||||||
|
|
||||||
|
[FieldOffset(0x41AF0)]
|
||||||
|
public int isBot;
|
||||||
|
|
||||||
|
[FieldOffset(0x43F00)]
|
||||||
|
public UInt64 steamid;
|
||||||
|
};
|
||||||
|
|
||||||
|
[StructLayout(LayoutKind.Explicit)]
|
||||||
|
public struct dvar_t
|
||||||
|
{
|
||||||
|
[FieldOffset(0)]
|
||||||
|
public IntPtr name;
|
||||||
|
|
||||||
|
[FieldOffset(4)]
|
||||||
|
public IntPtr description;
|
||||||
|
|
||||||
|
[FieldOffset(8)]
|
||||||
|
public uint flags;
|
||||||
|
|
||||||
|
[FieldOffset(12)]
|
||||||
|
short type;
|
||||||
|
|
||||||
|
[FieldOffset(16)]
|
||||||
|
public IntPtr current;
|
||||||
|
|
||||||
|
[FieldOffset(32)]
|
||||||
|
public IntPtr latched;
|
||||||
|
|
||||||
|
[FieldOffset(48)]
|
||||||
|
public IntPtr _default;
|
||||||
|
|
||||||
|
[FieldOffset(65)]
|
||||||
|
public IntPtr min;
|
||||||
|
|
||||||
|
[FieldOffset(68)]
|
||||||
|
public IntPtr max;
|
||||||
|
}
|
||||||
|
|
||||||
|
// not iw4
|
||||||
|
public struct dvar
|
||||||
|
{
|
||||||
|
public String name;
|
||||||
|
|
||||||
|
public String description;
|
||||||
|
|
||||||
|
public int flags;
|
||||||
|
|
||||||
|
short type;
|
||||||
|
|
||||||
|
public String current;
|
||||||
|
|
||||||
|
public String latched;
|
||||||
|
|
||||||
|
public String _default;
|
||||||
|
|
||||||
|
public int min;
|
||||||
|
|
||||||
|
public int max;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
class Helpers
|
||||||
|
{
|
||||||
|
public static String NET_AdrToString(netadr_t a)
|
||||||
|
{
|
||||||
|
// not worrying about NA_TYPE
|
||||||
|
StringBuilder s = new StringBuilder(64);
|
||||||
|
s.AppendFormat("{0}.{1}.{2}.{3}:{4}", a.ip[0], a.ip[1], a.ip[2], a.ip[3], a.port);
|
||||||
|
return s.ToString();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static unsafe T ReadStruct<T>(byte[] buffer) where T : struct
|
||||||
|
{
|
||||||
|
fixed (byte* b = buffer)
|
||||||
|
return (T)Marshal.PtrToStructure(new IntPtr(b), typeof(T));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -1,7 +1,11 @@
|
|||||||
using System;
|
#define USINGMEMORY
|
||||||
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
|
using System.Diagnostics;
|
||||||
|
using System.Runtime.InteropServices;
|
||||||
|
using System.Net;
|
||||||
|
|
||||||
namespace IW4MAdmin
|
namespace IW4MAdmin
|
||||||
{
|
{
|
||||||
@ -12,7 +16,8 @@ namespace IW4MAdmin
|
|||||||
static String RCON;
|
static String RCON;
|
||||||
static public double Version = 0.9;
|
static public double Version = 0.9;
|
||||||
static public double latestVersion;
|
static public double latestVersion;
|
||||||
static public List<Server> Servers;//
|
static public List<Server> Servers;
|
||||||
|
static public bool usingMemory = true;
|
||||||
|
|
||||||
static void Main(string[] args)
|
static void Main(string[] args)
|
||||||
{
|
{
|
||||||
@ -26,8 +31,14 @@ namespace IW4MAdmin
|
|||||||
Console.WriteLine(" Version " + Version + " (unable to retrieve latest)");
|
Console.WriteLine(" Version " + Version + " (unable to retrieve latest)");
|
||||||
Console.WriteLine("=====================================================");
|
Console.WriteLine("=====================================================");
|
||||||
|
|
||||||
Servers = checkConfig();
|
List<Server> viableServers = getServers();
|
||||||
foreach (Server IW4M in Servers)
|
|
||||||
|
if (viableServers.Count < 1)
|
||||||
|
viableServers = checkConfig(); // fall back to config
|
||||||
|
|
||||||
|
Servers = viableServers;
|
||||||
|
|
||||||
|
foreach (Server IW4M in viableServers)
|
||||||
{
|
{
|
||||||
//Threading seems best here
|
//Threading seems best here
|
||||||
Server SV = IW4M;
|
Server SV = IW4M;
|
||||||
@ -88,7 +99,7 @@ namespace IW4MAdmin
|
|||||||
Config = new file("config\\servers.cfg", true);
|
Config = new file("config\\servers.cfg", true);
|
||||||
Config.Write(IP + ':' + Port + ':' + RCON);
|
Config.Write(IP + ':' + Port + ':' + RCON);
|
||||||
Config.Close();
|
Config.Close();
|
||||||
Servers.Add(new Server(IP, Port, RCON));
|
Servers.Add(new Server(IP, Port, RCON, 0));
|
||||||
}
|
}
|
||||||
|
|
||||||
else
|
else
|
||||||
@ -102,11 +113,43 @@ namespace IW4MAdmin
|
|||||||
Console.WriteLine("You have an error in your server.cfg");
|
Console.WriteLine("You have an error in your server.cfg");
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
Servers.Add(new Server(server_line[0], newPort, server_line[2]));
|
Servers.Add(new Server(server_line[0], newPort, server_line[2],0));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return Servers;
|
return Servers;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[DllImport("kernel32.dll")]
|
||||||
|
public static extern IntPtr OpenProcess(int dwDesiredAccess, bool bInheritHandle, int dwProcessId);
|
||||||
|
|
||||||
|
[DllImport("kernel32.dll")]
|
||||||
|
public static extern bool ReadProcessMemory(int hProcess,
|
||||||
|
int lpBaseAddress, byte[] lpBuffer, int dwSize, ref int lpNumberOfBytesRead);
|
||||||
|
|
||||||
|
static List<Server> getServers()
|
||||||
|
{
|
||||||
|
List<Server> Servers = new List<Server>();
|
||||||
|
foreach ( Process P in Process.GetProcessesByName("iw4m"))
|
||||||
|
{
|
||||||
|
IntPtr Handle = OpenProcess(0x0010, false, P.Id);
|
||||||
|
int numberRead = 0;
|
||||||
|
Byte[] dediStuff = new Byte[1];
|
||||||
|
ReadProcessMemory((int)Handle, 0x5DEC04, dediStuff, 1, ref numberRead);
|
||||||
|
|
||||||
|
if (dediStuff[0] == 0)
|
||||||
|
{
|
||||||
|
Console.WriteLine("Viable IW4M Instance found with PID #" + P.Id);
|
||||||
|
|
||||||
|
dvar net_ip = Utilities.getDvar(0x64A1DF8, (int)Handle);
|
||||||
|
dvar net_port = Utilities.getDvar(0x64A3004, (int)Handle);
|
||||||
|
dvar rcon_password = Utilities.getDvar(0x111FF634, (int)Handle);
|
||||||
|
|
||||||
|
Servers.Add(new Server(Dns.GetHostAddresses(net_ip.current)[1].ToString(), Convert.ToInt32(net_port.current), rcon_password.current, (int)Handle));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return Servers;
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,10 +1,12 @@
|
|||||||
|
//#define USINGMEMORY
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Collections;
|
using System.Collections;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using System.Threading; //SLEEP
|
using System.Threading; //SLEEP
|
||||||
using System.IO;
|
using System.IO;
|
||||||
|
using System.Diagnostics;
|
||||||
|
using System.Runtime.InteropServices;
|
||||||
|
|
||||||
|
|
||||||
namespace IW4MAdmin
|
namespace IW4MAdmin
|
||||||
@ -13,8 +15,9 @@ namespace IW4MAdmin
|
|||||||
{
|
{
|
||||||
const int FLOOD_TIMEOUT = 300;
|
const int FLOOD_TIMEOUT = 300;
|
||||||
|
|
||||||
public Server(string address, int port, string password)
|
public Server(string address, int port, string password, int H)
|
||||||
{
|
{
|
||||||
|
Handle = H;
|
||||||
IP = address;
|
IP = address;
|
||||||
Port = port;
|
Port = port;
|
||||||
rcon_pass = password;
|
rcon_pass = password;
|
||||||
@ -334,7 +337,7 @@ namespace IW4MAdmin
|
|||||||
{
|
{
|
||||||
if (players[cNum] == null)
|
if (players[cNum] == null)
|
||||||
{
|
{
|
||||||
Log.Write("Error - Disconnecting client slot is already empty!", Log.Level.Debug);
|
//Log.Write("Error - Disconnecting client slot is already empty!", Log.Level.Debug);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -509,7 +512,7 @@ namespace IW4MAdmin
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
//process new event every 100 milliseconds
|
//process new event every 50 milliseconds
|
||||||
private void manageEventQueue()
|
private void manageEventQueue()
|
||||||
{
|
{
|
||||||
while (isRunning)
|
while (isRunning)
|
||||||
@ -519,10 +522,16 @@ namespace IW4MAdmin
|
|||||||
processEvent(events.Peek());
|
processEvent(events.Peek());
|
||||||
events.Dequeue();
|
events.Dequeue();
|
||||||
}
|
}
|
||||||
Utilities.Wait(0.1);
|
Utilities.Wait(0.05);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[DllImport("kernel32.dll")]
|
||||||
|
public static extern IntPtr OpenProcess(int dwDesiredAccess, bool bInheritHandle, int dwProcessId);
|
||||||
|
|
||||||
|
[DllImport("kernel32.dll")]
|
||||||
|
public static extern bool ReadProcessMemory(int hProcess, int lpBaseAddress, byte[] lpBuffer, int dwSize, ref int lpNumberOfBytesRead);
|
||||||
|
|
||||||
//Starts the monitoring process
|
//Starts the monitoring process
|
||||||
public void Monitor()
|
public void Monitor()
|
||||||
{
|
{
|
||||||
@ -551,11 +560,11 @@ namespace IW4MAdmin
|
|||||||
Utilities.Wait(10);
|
Utilities.Wait(10);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
#if DEBUG == false
|
||||||
//Thread to handle polling server for IP's
|
//Thread to handle polling server for IP's
|
||||||
Thread statusUpdate = new Thread(new ThreadStart(pollServer));
|
Thread statusUpdate = new Thread(new ThreadStart(pollServer));
|
||||||
statusUpdate.Start();
|
statusUpdate.Start();
|
||||||
|
#endif
|
||||||
//Handles new events in a fashionable manner
|
//Handles new events in a fashionable manner
|
||||||
Thread eventQueue = new Thread(new ThreadStart(manageEventQueue));
|
Thread eventQueue = new Thread(new ThreadStart(manageEventQueue));
|
||||||
eventQueue.Start();
|
eventQueue.Start();
|
||||||
@ -576,6 +585,8 @@ namespace IW4MAdmin
|
|||||||
|
|
||||||
while (isRunning)
|
while (isRunning)
|
||||||
{
|
{
|
||||||
|
|
||||||
|
|
||||||
#if DEBUG == false
|
#if DEBUG == false
|
||||||
try
|
try
|
||||||
#endif
|
#endif
|
||||||
@ -613,6 +624,27 @@ namespace IW4MAdmin
|
|||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
#if DEBUG
|
||||||
|
if ((DateTime.Now - lastPoll).Milliseconds > 750)
|
||||||
|
{
|
||||||
|
int numberRead = 0;
|
||||||
|
|
||||||
|
for (int i = 0; i < players.Count; i++)
|
||||||
|
{
|
||||||
|
Byte[] buff = new Byte[681872]; // struct size ( 0.68MB :( )
|
||||||
|
ReadProcessMemory((int)Handle, 0x31D9390 + (buff.Length)*(i), buff, buff.Length, ref numberRead); // svs_clients start + current client
|
||||||
|
|
||||||
|
client_s eachClient = (client_s)Helpers.ReadStruct<client_s>(buff);
|
||||||
|
|
||||||
|
if (eachClient.state == 0)
|
||||||
|
removePlayer(i);
|
||||||
|
else if (eachClient.state > 1)
|
||||||
|
addPlayer(new Player(eachClient.name, eachClient.steamid.ToString("x16"), i, 0, i, null, 0, Helpers.NET_AdrToString(eachClient.adr).Split(':')[0]));
|
||||||
|
}
|
||||||
|
|
||||||
|
lastPoll = DateTime.Now;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
if (l_size != logFile.getSize())
|
if (l_size != logFile.getSize())
|
||||||
{
|
{
|
||||||
@ -658,7 +690,7 @@ namespace IW4MAdmin
|
|||||||
}
|
}
|
||||||
oldLines = lines;
|
oldLines = lines;
|
||||||
l_size = logFile.getSize();
|
l_size = logFile.getSize();
|
||||||
Thread.Sleep(1);
|
Thread.Sleep(250);
|
||||||
}
|
}
|
||||||
#if DEBUG == false
|
#if DEBUG == false
|
||||||
catch (Exception E)
|
catch (Exception E)
|
||||||
@ -672,7 +704,6 @@ namespace IW4MAdmin
|
|||||||
isRunning = false;
|
isRunning = false;
|
||||||
RCONQueue.Abort();
|
RCONQueue.Abort();
|
||||||
eventQueue.Abort();
|
eventQueue.Abort();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void pollServer()
|
private void pollServer()
|
||||||
@ -748,6 +779,30 @@ namespace IW4MAdmin
|
|||||||
}
|
}
|
||||||
|
|
||||||
//Vital RCON commands to establish log file and server name. May need to cleanup in the future
|
//Vital RCON commands to establish log file and server name. May need to cleanup in the future
|
||||||
|
#if USINGMEMORY
|
||||||
|
private bool initializeBasics()
|
||||||
|
{
|
||||||
|
dvar map = Utilities.getDvar(0x2098DDC, Handle);
|
||||||
|
|
||||||
|
String mapOut;
|
||||||
|
|
||||||
|
mapname = map.current;
|
||||||
|
|
||||||
|
dvar sv_hostname = Utilities.getDvar(0x2098D98, Handle);
|
||||||
|
hostname = sv_hostname.current;
|
||||||
|
|
||||||
|
dvar shortversion = Utilities.getDvar(0x1AD79D0, Handle);
|
||||||
|
IW_Ver = shortversion.current;
|
||||||
|
|
||||||
|
dvar party_maxplayers = Utilities.getDvar(0x1080998, Handle);
|
||||||
|
maxClients = Convert.ToInt32(party_maxplayers.current);
|
||||||
|
|
||||||
|
dvar g_gametype = Utilities.getDvar(0x1AD7934, Handle);
|
||||||
|
Gametype = g_gametype.current;
|
||||||
|
|
||||||
|
// skipping website b/c dynamically allocated ( we will pick it up on maprotate )
|
||||||
|
}
|
||||||
|
#else
|
||||||
private bool intializeBasics()
|
private bool intializeBasics()
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
@ -922,11 +977,11 @@ namespace IW4MAdmin
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
//Process any server event
|
//Process any server event
|
||||||
public bool processEvent(Event E)
|
public bool processEvent(Event E)
|
||||||
{
|
{
|
||||||
/*if (E.Type == Event.GType.Connect) // this is anow handled by rcon status :(
|
/*if (E.Type == Event.GType.Connect) // this is anow handled by memory :)
|
||||||
{
|
{
|
||||||
if (E.Origin == null)
|
if (E.Origin == null)
|
||||||
Log.Write("Connect event triggered, but no client is detected!", Log.Level.Debug);
|
Log.Write("Connect event triggered, but no client is detected!", Log.Level.Debug);
|
||||||
@ -1089,7 +1144,8 @@ namespace IW4MAdmin
|
|||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
mapname = maps.Find(m => m.Name.Equals(mapname)).Alias;
|
Map newMap = maps.Find(m => m.Name.Equals(newMapName));
|
||||||
|
mapname = newMap.Alias;
|
||||||
}
|
}
|
||||||
|
|
||||||
catch (Exception)
|
catch (Exception)
|
||||||
@ -1151,7 +1207,14 @@ namespace IW4MAdmin
|
|||||||
public void Tell(String Message, Player Target)
|
public void Tell(String Message, Player Target)
|
||||||
{
|
{
|
||||||
if (Target.getClientNum() > -1)
|
if (Target.getClientNum() > -1)
|
||||||
|
{
|
||||||
|
#if DEBUG
|
||||||
|
RCON.addRCON("tell " + Target.getClientNum() + " " + Message + "^7");
|
||||||
|
|
||||||
|
#else
|
||||||
RCON.addRCON("tellraw " + Target.getClientNum() + " " + Message + "^7"); // I fixed tellraw :>
|
RCON.addRCON("tellraw " + Target.getClientNum() + " " + Message + "^7"); // I fixed tellraw :>
|
||||||
|
#endif
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Kick(String Message, Player Target)
|
public void Kick(String Message, Player Target)
|
||||||
@ -1460,6 +1523,7 @@ namespace IW4MAdmin
|
|||||||
private Dictionary<String, Object> Macros;
|
private Dictionary<String, Object> Macros;
|
||||||
private Moserware.TrueSkill Skills;
|
private Moserware.TrueSkill Skills;
|
||||||
private DateTime lastWebChat;
|
private DateTime lastWebChat;
|
||||||
|
private int Handle;
|
||||||
|
|
||||||
|
|
||||||
//Will probably move this later
|
//Will probably move this later
|
||||||
|
@ -3,6 +3,7 @@ using System.Collections.Generic;
|
|||||||
using System.Text;
|
using System.Text;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
using System.Text.RegularExpressions;
|
using System.Text.RegularExpressions;
|
||||||
|
using System.Runtime.InteropServices;
|
||||||
|
|
||||||
namespace IW4MAdmin
|
namespace IW4MAdmin
|
||||||
{
|
{
|
||||||
@ -314,6 +315,81 @@ namespace IW4MAdmin
|
|||||||
return "a very long time";
|
return "a very long time";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[DllImport("kernel32.dll")]
|
||||||
|
public static extern IntPtr OpenProcess(int dwDesiredAccess, bool bInheritHandle, int dwProcessId);
|
||||||
|
|
||||||
|
[DllImport("kernel32.dll")]
|
||||||
|
public static extern bool ReadProcessMemory(int hProcess, int lpBaseAddress, byte[] lpBuffer, int dwSize, ref int lpNumberOfBytesRead);
|
||||||
|
|
||||||
|
public static dvar getDvar(int Location, int Handle)
|
||||||
|
{
|
||||||
|
int numberRead = 0;
|
||||||
|
Byte[] Buff = new Byte[72];
|
||||||
|
Byte[] Ptr = new Byte[4];
|
||||||
|
|
||||||
|
ReadProcessMemory(Handle, Location, Ptr, Ptr.Length, ref numberRead); // get location of dvar
|
||||||
|
|
||||||
|
ReadProcessMemory(Handle, (int)BitConverter.ToUInt32(Ptr, 0), Buff, Buff.Length, ref numberRead); // read dvar memory
|
||||||
|
|
||||||
|
dvar_t dvar_raw = Helpers.ReadStruct<dvar_t>(Buff); // get the dvar struct
|
||||||
|
|
||||||
|
dvar dvar_actual = new dvar(); // gotta convert to something readable
|
||||||
|
|
||||||
|
dvar_actual.name = getStringFromPointer((int)dvar_raw.name, Handle);
|
||||||
|
dvar_actual.description = getStringFromPointer((int)dvar_raw.description, Handle);
|
||||||
|
|
||||||
|
if ((int)dvar_raw._default > short.MaxValue)
|
||||||
|
dvar_actual._default = getStringFromPointer((int)dvar_raw._default, Handle);
|
||||||
|
else
|
||||||
|
dvar_actual._default = dvar_raw._default.ToString();
|
||||||
|
|
||||||
|
if ((int)dvar_raw.current > short.MaxValue)
|
||||||
|
dvar_actual.current = getStringFromPointer((int)dvar_raw.current, Handle);
|
||||||
|
else
|
||||||
|
dvar_actual.current = dvar_raw.current.ToString();
|
||||||
|
|
||||||
|
if ((int)dvar_raw.latched > short.MaxValue)
|
||||||
|
dvar_actual.latched = getStringFromPointer((int)dvar_raw.latched, Handle);
|
||||||
|
else
|
||||||
|
dvar_actual.latched = dvar_raw.latched.ToString();
|
||||||
|
|
||||||
|
dvar_actual.flags = getIntFromPointer((int)dvar_raw.flags, Handle);
|
||||||
|
dvar_actual.max = getIntFromPointer((int)dvar_raw.max, Handle);
|
||||||
|
dvar_actual.min = getIntFromPointer((int)dvar_raw.min, Handle);
|
||||||
|
|
||||||
|
// done!
|
||||||
|
|
||||||
|
return dvar_actual;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String getStringFromPointer(int Location, int Handle)
|
||||||
|
{
|
||||||
|
int numberRead = 0;
|
||||||
|
Byte[] Buff = new Byte[256];
|
||||||
|
|
||||||
|
ReadProcessMemory(Handle, Location, Buff, Buff.Length, ref numberRead);
|
||||||
|
|
||||||
|
StringBuilder str = new StringBuilder();
|
||||||
|
for ( int i = 0; i < Buff.Length; i++)
|
||||||
|
{
|
||||||
|
if (Buff[i] == 0)
|
||||||
|
break;
|
||||||
|
|
||||||
|
str.Append((char)Buff[i]);
|
||||||
|
}
|
||||||
|
return str.ToString();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static int getIntFromPointer(int Location, int Handle)
|
||||||
|
{
|
||||||
|
int numberRead = 0;
|
||||||
|
Byte[] Buff = new Byte[4];
|
||||||
|
|
||||||
|
ReadProcessMemory(Handle, Location, Buff, Buff.Length, ref numberRead);
|
||||||
|
|
||||||
|
return BitConverter.ToInt32(Buff, 0);
|
||||||
|
}
|
||||||
|
|
||||||
public static String timesConnected(int connection)
|
public static String timesConnected(int connection)
|
||||||
{
|
{
|
||||||
String Prefix = String.Empty;
|
String Prefix = String.Empty;
|
||||||
|
@ -2,6 +2,7 @@
|
|||||||
CHANGELOG:
|
CHANGELOG:
|
||||||
-fixed issue with `history` timelime
|
-fixed issue with `history` timelime
|
||||||
-fixed issue with mapname not being updated
|
-fixed issue with mapname not being updated
|
||||||
|
-now reads memory for player info! ( experimental debug only )
|
||||||
|
|
||||||
VERSION: 0.9
|
VERSION: 0.9
|
||||||
CHANGELOG:
|
CHANGELOG:
|
||||||
|
Loading…
Reference in New Issue
Block a user