Как стать автором
Обновить

Пишем локер для Windows на Python 3.x

Время на прочтение5 мин
Количество просмотров7.5K

Приветствую любителей питона. Как-то раз я невзначай сунул палец в ctypes. И знаете, мне понравилось. Особенно блок ввода с клавиатуры и мыши. И первое, что мне взбрело в голову,- "А почему бы не написать локер для винды на питоне, с разблокировкой по флешке, как ключом" (Не спрашивайте почему именно это, я сам не знаю). И тут пошло поехало моё воображение. Сейчас я распишу с чем вам придётся столкнуться для его написания.

Ну что ж, приступим!

Первым делом создадим граф часть локера. Не будем же мы делать тупо белый лист :d
Назовём . . . locker.pyw

Почему pyw? Да потому что при запуске локера вылезет консоль, которую потенциальный плохой дядя может закрыть, тогда и весь локер накроется, а оно нам не надо.

import hashlib
import time
import sys
import os
from tkinter import Tk, Entry, Label
import tkinter
import pyautogui
import threading
from lofu import *

Импортируем библиотеки для locker.pyw

* hashlib нам нужен для сохранения ключа в хэш виде, так меньше шансов на лом (если вам это не нужно, можете не импортировать!)


* time просто для sleep()


* sys для красивого выхода exit()


* os для старта задачи части локера system()


* tkinter это и есть наша граф часть


* pyautogui для смещения мыши в угол (пусть подумает над свои поведением)


* threading для второго потока смещения мыши (чтобы не мешалась основному потоку)


* lofu . . . . я накинул пару функций, просто в другой файл и всё, я художник, я так вижу!

Сделаем функцию смещения мыши в сторону, чтобы пользователь не успел никуда нажать.

def mouse_trac(screen_width, screen_height):
	while True:
		pyautogui.moveTo(screen_width, screen_height)

pyautogui.moveTo(screen_width, screen_height) - сместить курсор по указанным координатам (в нашем случае в правый нижний угол, что равно размерам экрана)

screen_width, screen_height это размер вашего экрана
Теперь нужно вызвать Tk(), чтобы сделать граф начинку, а после и получить размеры этого самого экрана

root = Tk()

root.attributes('-fullscreen', True)
pyautogui.FAILSAFE = False
screen_width = root.winfo_screenwidth()
screen_height = root.winfo_screenheight()

root.attributes('-fullscreen', True) - выводит нашу граф часть в полноэкранный режим.

pyautogui.FAILSAFE = False - отключает установленную по умолчанию в библиотеке защиту, на случай прямых рук.

screen_width = root.winfo_screenwidth() screen_height = root.winfo_screenheight() - собственно, наши размеры экрана

Вот мы и получили размеры экрана, теперь можно и запускать поток

x = threading.Thread(target=mouse_trac, args=(screen_width, screen_height), daemon=True)
x.start()

target=mouse_trac - цель, а именно функция для которой необходимо выделить поток

args=(screen_width, screen_height) - какие переменки передавать функции

daemon=True - работать отдельно ото всех или поочерёдно

Подробнее читайте в документации к Threading

Теперь сделаем граф начинку

label = Label(root, text='Enter flesh drive with code!', font='Courier 15', fg='#C71585')
label.place(relx=.5, rely=.94, anchor="center")

label3 = Label(root, text='USBCODE waiting...', font='Courier 20', fg='#00BFFF')
label3.place(relx=.5, rely=.40, anchor="center")

label4 = Label(root, text='Powered by .... wait....by who?', font='Courier 15', fg='#C71585')
label4.place(relx=.1, rely=.95, anchor="center")

root.update()

label = Label(root, text='Enter flesh drive with code!', font='Courier 15', fg='#C71585') label.place(relx=.5, rely=.94, anchor="center") - это наша заставка

root - какую именно граф часть мы хотим изменить

text - ну понятное дело текст :G

font - размеры

fg - цвет в формате HTML цветов ( https://colorscheme.ru/html-colors.html )

relx - положение чего либо относительно X

rely - положение чего либо относительно Y

anchor="center" - как будет расположен текст

root.update() - обновляет граф часть (считайте что это CTRL+S)

Подробнее читайте в документации Tkinter

Теперь нужно как сделать локер ввода с клавиатуры и мыши.
Вот тут я сделал костыль.

Проблема в том, чтобы заблокировать ввод необходимы права администратора. Так как мы собираемся сделать работу в один клик, нажимать на выскакивающее окно "повышения прав" не очень хочется, поэтому воспользуемся тем что нам даёт сама windows. В windows есть очень полезная утилита "Планировщик заданий". Мы сделаем бесконечный цикл который будет проверять в определённом месте, определённое значение и решать, блокировать ввод или нет. А запускать мы его будет как раз из Планировщика заданий с наивысшими правами (При запуске скрипта в планировщике задач, не будет запрашиваться повышение прав, что нам и нужно ).

  • Нажмите "Создать задачу"

  • В поле "Имя" введите на свой каприз любое название (желательно слитно)

  • Снизу обязательно нажмите на галочку "Выполнить с наивысшими правами"

  • Всё, больше не трогаете вкладку "Общие"

  • Откройте вкладку "Триггеры"

  • Добавьте триггеры : "При входе в систему" и "Один раз (Однократно, повторять задачу каждые 1 минуту, в течении Бесконечно)"

  • Откройте вкладку "Действия"

  • Создайте действие "Запуск программы"

  • А теперь стоп! Что мы будем запускать? . . .

Создаём файл с бесконечным циклом про который мы говорили чуть выше. Назовём его input_block.pyw

from ctypes import *
import time
import sys
from lofu import *

while True:
	statusl = status_lock()
	if str(statusl) == '0':
		windll.user32.BlockInput(False)
	elif str(statusl) == '1':
		windll.user32.BlockInput(True)

Теперь сделаем lofu

def status_lock():
	filee = open(r'Путь до файла', 'r')
	filee_out = filee.read()
	filee.close()
  return filee_out

def disable_lock():
	filee = open(r'Путь до файла', 'w')
	text = 0
	filee.write(str(text))
	filee.close()

def enable_lock():
	filee = open(r'Путь до файла', 'w')
	text = 1
	filee.write(str(text))
	filee.close()

Да, да я знаю что вы хотите сказать: "ФУУУУ ЮЗАЕШЬ ТУПА ФАЙЛ, КАК ТАК МОЖНО? ВСЕ ДАВНО ЛИБО ЛОКАЛЬНУЮ БД ЛИБО JSON ИСПОЛЬЗУЮТ! МУСОР!"

Вы конечно можете юзать json, sqlite3 и тд. Это не меняет сути. Как пример я просто использую файл. Всё!

Теперь нам нужно сделать из input_block.pyw >> input_block.exe
Для этого используем pyinstaller

pyinstall input_block.pyw --onefile

Что? Нет pyinstaller?

pip install pyinstaller

Для полученного файла делаем ярлык и ставим ему флажок "Запускать от имени Администратора".

Возвращаемся к "Планировщику заданий" и в поле "Программа или сценарий" вводим адрес до ярлыка.

Возвращаемся к нашему locker.pyw

os.system('schtasks.exe /run /tn "ИМЯ ВАШЕЙ ЗАДАЧИ В ПЛАНИРОВЩИКЕ ЗАДАНИЙ"')

Отлично, а теперь осталось лишь доделать граф часть, блокировку и разблокировку

while True:
	try:
		enable_lock()
		file = open(r'F:\key.txt','r')
		file_t = str(file.read())
		file.close()
		hash_object = hashlib.sha256(file_t.encode())
		hex_dig = hash_object.hexdigest()
		if 'ВАШ ХЕШ-КЛЮЧ' == str(hex_dig):
			label3.configure(text='USBCODE correct. Unlocking...', fg='#00FF00', font="Courier 30")
			root.update()
			time.sleep(4)
			disable_lock()
			sys.exit()
		else:
			label3.configure(text='USBCODE incorrect. Try again!', fg='#FF0000', font="Courier 30")
			enable_lock()
			root.update()
	except SystemExit:
		sys.exit()
	except:
		time.sleep(10)
		label3.configure(text='USBCODE not found! Waiting...', fg='#FF1493', font="Courier 20")
		enable_lock()
		root.update()

Тут уже на вкус, кому как нравится. Регулируйте задержки, текст

enable_lock() - функция lofu которая активирует лок ввода

disable_lock() - функция lofu которая де-активирует лок ввода

time.sleep(N) - задержка

file = open(r'F:\key.txt','r')
file_t = str(file.read())
file.close() - читаем файл на флешке с нашим ключом, если он конечно есть

hash_object = hashlib.sha256(file_t.encode())
hex_dig = hash_object.hexdigest() - а это уже сама хэш функция

if 'ВАШ ХЕШ' == str(hex_dig): - я вам что ещё как иф работает объяснять должен :d
Хэш получаете очень просто:
* Придумайте какую-нибудь комбинацию (Для восстановления, если забыли, потеряли, утопили флешку)
* Сделайте хэш этой комбинации (Это ключ вашей флешки)
* Сделайте хэш вашего хеша (Это хэш-ключ в locker.pyw)

Всё, теперь нужно подумать об автостарте locker.pyw.

Можно через реестр, shell:startup, да даже через "Планировщик заданий".

На этом всё. Я вас поздравляю! Мы только что сделали локер для Windows на Python 3.x c полной блокировкой ввода через "Планировщик заданий", с разблокировкой через флешку, с хэш ключом и граф интерфейсом!

P.S. можно ещё поставить в ярлык locker.pyw в поле "Быстрый вызов" бинд клавиш для быстрой блокировки.

Только зарегистрированные пользователи могут участвовать в опросе. Войдите, пожалуйста.
Была ли полезна вам эта статья?
25% Да2
75% Нет6
Проголосовали 8 пользователей. Воздержались 2 пользователя.
Теги:
Хабы:
-4
Комментарии9

Публикации

Истории

Работа

Python разработчик
141 вакансия
Data Scientist
63 вакансии

Ближайшие события

Weekend Offer в AliExpress
Дата20 – 21 апреля
Время10:00 – 20:00
Место
Онлайн
Конференция «Я.Железо»
Дата18 мая
Время14:00 – 23:59
Место
МоскваОнлайн