Блоґ одного кібера

Історія хвороби контуженого інформаційним вибухом

Posts Tagged ‘linux

Випадковий ідентифікатор в Python

with 4 comments

Можна отримати так:

import random
def random_id(length=6):
   return ''.join(
        random.choice(string.lowercase)
        for i in range(length)
    )

###############
>>> random_id()
'kqxmua'

Якщо треба особливо оформлений, як от IP, чи MAC-адреса, то можна зробити перетворення:

def asmac(val):
    """Convert a byte string to a MAC address string.  """
    return ':'.join('%02X' % ord(c) for c in val)

def random_mac():
    return asmac(random_id())

###################
>>> random_mac()
'78:71:6A:72:6E:63'

Але такі ідентифікатори як “kqxmua” нормальній людині важко запам’ятати, бо вони не асоціюються з жодними поняттями. Ну окрім частинки “ua”, але й то вона туди випадково потрапила. Проте, в Linux можна легко отримати випадкове слово, бо в ньому є словник:

def random_word():
    return random.choice(
        open('/usr/share/dict/words').readlines() # жертиме пам’ять! 
    ).strip()

#################
'.join(random_word() for i in range(5))
'hermitical, Canter, Paryavi, mergences, Mind'

Хоча я знайомий лише з “hermitical” та “mind”, але асоціації вже легше побудувати, правда?

Advertisements

Written by bunyk

Березень 18, 2015 at 12:34

Оприлюднено в Всяке, Кодерство

Tagged with ,

Пишемо простий keylogger для Linux

with 6 comments

Кейлоггер це така шкідлива корисна програма яка записує всі натискання клавіш користувачем в будь-яких інших програмах операційної системи. І сьогодні ми вивчатимемо як таке написати. Якщо ви навчитесь працювати з файлами в Linux – ви зможете все. Серйозно. Тому я колись планую детально вивчити і написати про файли там.

Все в лінуксі файл, і клавіатура – теж. Щоб знати який – відкриваємо /proc/bus/input/devices. Нас цікавить абзац в якому написано про клавіатуру, і він зазвичай містить рядок EV=120013, тому можете пошукати його. Коли знайшли абзац, читаємо в ньому рядок H: Handlers=sysrq kbd event3.

Можна дістати однією командою:

cat /proc/bus/input/devices | grep EV=120013 -B 2 | grep event

Слово event3 означає що нам треба читати файл пристрою /dev/input/event3.

Так як в заголовку було слово простий, ми спростимо собі життя і поставимо деяку бібліотеку:

pip-2.7 install evdev

Прочитати решту цього запису »

Written by bunyk

Березень 8, 2015 at 00:29

Оприлюднено в Кодерство

Tagged with ,

Комп’ютери дістали!

with 7 comments

В цій публікації нічого корисного, одне ниття. Треба собі нагадувати, що сидіти перед монітором це не те саме що сидіти в холодному окопі, і віддати ще трохи грошей тим хто купує всілякі там флісові футболки та інші корисні речі.
Прочитати решту цього запису »

Written by bunyk

Листопад 14, 2014 at 23:42

Оприлюднено в Нещоденник

Tagged with ,

Німецьке QWERTY

with 7 comments

Німці використовують деякі букви, яких нема в стандартній латинській розкладці: ÄÖÜẞ, тому існує окрема німецька розкладка. Але біда, біда, вона не QWERTY, а QWERTZ, і Z та Y поміняні місцями. Правильної розкладки чомусь нема, тому я вирішив зробити свою. Має працювати на всіх системах що використовують X keyboard extension з X Window System.

Замість кнопки “-” отримуємо “ß”, замість “[” – “Ü”, “;” – “Ö” ну а замість “‘” – “Ä”. Всі інші залишаються на місці, а не перескакують чорт зна куди як в традиційній німецькій розкладці.

Відкриваємо розкладки для Німеччини:

cd /usr/share/X11/xkb/
sudo vim symbols/de

Додаємо розкладку з наступними клавішами (наслідується від базової американської):

xkb_symbols "germanqwerty" {
    include "us(basic)"
    name[Group1]="German (QWERTY)";

    key <AD11>	{ [udiaeresis, Udiaeresis, dead_diaeresis, dead_abovering ] };
    key <AC10>	{ [odiaeresis, Odiaeresis, dead_doubleacute, dead_belowdot ] };
    key <AC11>	{ [adiaeresis, Adiaeresis, dead_circumflex, dead_caron ] };
    key <AE11> {type[Group1]="FOUR_LEVEL_PLUS_LOCK",  symbols[Group1]=
                  [ssharp, question, backslash, questiondown, 0x1001E9E ]};
};

Далі додаємо нову розкладку до списку відомих:

cd /usr/share/X11/xkb/
sudo vim rules/evdev.xml

Знаходимо список розкладок для Німеччини і додаємо туди свій варіант:

        <variant>
          <configItem>
            <name>germanqwerty</name>
            <description>German (QWERTY)</description>
          </configItem>
        </variant>

Далі треба розлогінитись і залогінитись заново, і можна додавати розкладки через аплет панелі робочого стола.

Посилання

Written by bunyk

Листопад 4, 2014 at 01:10

Оприлюднено в Кодерство, Конспекти

Tagged with ,

Покращене запрошення до вводу $ ▮

with 12 comments

Кольорове запрошення до вводу дозволяє візуально виділяти місця де ви ввели команду і лог виконання команди.

Для цього, потрібно задати змінну середовища PS1 в файлі ~/.bashrc для звичайного і для суперкористувача.

Наприклад:

export PS1="\[\e[0;34m\]\u@\h : \w\[\e[m\]\n\[\e[0;32m\]\A \$> \[\e[m\]"
export PS1="\[\e[0;34m\]┌─[\u@\h : \w\n└─[\[\e[0;31m\]\A\[\e[0;34m\]]─> \$ \[\e[m\]"

\[Все що поміщається в екрановані квадратні дужки\] – не враховується при обчисленні довжини запрошення, і важливо поміщати в такі дужки невидимі символи, бо довжина запрошення впливає на те як відображатиметься команда наприклад при навігації по історії команд.

\e[0;34m – синій колір, \e[0;32m – зелений, \e[m – повернутись до звичайного кольору. Повний список кольорів наприклад тут.

\u – користувач, \h – ім’я хоста до першої крапки, \w – повний шлях до поточної директорії, \A – час в 24-годинному форматі HH:MM, \$ – #, якщо ефективний UID користувача 0, інакше – $. Більше можна через man bash, в секції PROMPTING.

Written by bunyk

Жовтень 23, 2014 at 23:05

Оприлюднено в Інструменти, Кодерство

Tagged with

Асемблер x86 на Linux

with 2 comments

Давно хотів познайомитись, але все стримувало те що в дитинстві я почав з синтаксису Intel, і хотів програмувати тут теж з синтаксисом Intel. Пройшло багато років, я забув, тому давайте вивчимо AT & T синтаксис. Потім при потребі можна перевчитись.

Ну й крім того, я знайшов книжку Programming from the Ground Up, в якій все дуже зрозуміло (як для дітей) пояснюють.

Ну дууууже коротка теорія

Перше що потрібно знати – x86 – це архітектура Фон Неймана, тобто код програми і дані зберігаються в одній і тій же пам’яті, і для комп’ютера виглядають однаково. (Щоправда операційні системи можуть обмежувати виконання лише областями з кодом, для того щоб запобігти можливим помилкам, якими можуть скористатись хитрі хакери)

Пам’ять – це довгий список байтів (можуть містити цілі числа від 0 до 255), кожен з яких має свою адресу. Адреса – це просто номер байта. Щоправда ми працюватимемо переважно не з байтами, а зі словами (в 32-х розрядній архітектурі це 4 байти, які можуть приймати значення від 0 до 4294967295). Тому що регістри процесора якраз стільки вміщають. Адреси – це теж слова (4 байти).

Найпростіша програма

Надрукуємо “Привіт, світе!”? О, ні, на ассемблері це надто складно. Давайте напишемо програму яка завершує роботу. Ага. В Unix, програма яка завершує свою роботу має повернути статус код. Статус код останньої виконаної команди можна побачити у спеціальній змінній командної оболонки: echo $?

_start – в лінкера за замовчуванням позначає точку входу в програму. Тобто адресу з якої почнеться її виконання. Можна замінити її наприклад на main, але тоді лінкер, якщо йому не вказати опцію -e main скаже:

ld: warning: cannot find entry symbol _start; defaulting to 0000000008048054

Символ відсотка позначає регістр процесора (наприклад %eax), долар позначає константу (наприклад $1, $0x80 (= 128 в шістнадцятковому записі) ).

Переривання – це місце в коді де контроль передається в якесь інше місце (в ядро). Коли ядро виконає своє переривання – воно поверне контроль нам, і програма продовжить виконання (стан регістрів може змінитись). Щоправда після системного виклику exit контроль нам ніколи не повернуть, але так й було задумано.

Щоб перевірити нашу програму, потрібно виконати команди:

as exit.s -o exit.o
ld exit.o -o exit

Перша створює об’єктний файл. Об’єктний файл – це вже код машинною мовою, але ще не до кінця зібраний. Потрібно передати його лінкеру – програмі яка вміє збирати багато об’єктних файлів в одну програму, та додавати інформацію для того щоб ядро знало як працювати з програмою.

Якщо все пройшло без помилок – можна перевірити роботу:

./exit 
echo $?

Також можна спробувати замінити код повернення в %ebx на якісь інші і подивитись результат.

Опис інструкцій

mov – це інструкція переміщення, яка має два операнди – звідки й куди.

Суфікс l означає розмір даних (long = 4 байти). Інші можливі префікси: b byte = (8 біт); s short = (2 байти (16 біт).

Багато інших інструкцій мають два операнди, як наприклад addl (додавання), subl (віднімання). Але, наприклад, інструкція div приймає єдиний аргумент, бере вміст регістрів %edx та %eax як велике 64-х розрядне число (якщо треба менше, %edx має містити нуль) ділить на переданий аргумент а тоді результат поміщує в %eax, а остачу від ділення в %ebx.

Регістри загального призначення, які можна використовувати як аргументи команд переміщення та арифметичних – це %eax, %ebx, %ecx, %edx, %edi, %esi.

Контроль ходу виконання

Давайте напишемо наступну програму, яка не просто даватиме наперед заданий статус код, а даватиме максимальне число серед заданих. Нехай ці числа зберігатимуться за адресою, яку ми позначимо data_items, і останнім числом буде нуль, щоб ми знали коли припинити пошук.

Виконання має повернути 89 (найбільше в списку). Це вже набагато цікавіша програма.

По-перше, ми маємо дані. Окрім типу .long (4 байти), ми можемо використовувати .byte, .int (2 байти), та .ascii – рядок символів, наприклад .ascii "Hello, world!\n".

По-друге, цікава інструкція movl data_items(,%edi,4), %eax. Лівий її операнд означає взяти дані з адреси data_items, але зсунутись на %edi елементів розміру 4. Тобто це як доступ до елементу масиву. Синтаксис паскудний, в Intel здається писали б data_items + %edi * 4, що виглядає зрозуміліше, але маємо що маємо.

Також, якщо ми хочемо отримати значення за адресою – теж використовуємо дужки. Наприклад – %esp – містить адресу вершини стеку. movl %esp, %eax – збереже цю адресу в %eax, а от movl (%esp), %eax – значення з вершини стеку.

Наступна незнайома інструкція – cmpl. Вона порівнює два чотирибайтові числа (суфікс бачите?), а результат порівняння записує в певні біти регістру %eflags. Про нього я дуже давно написав непогану статтю на CybWiki а потім на вікіпедії, тому в деталі не вдаватимусь.

Після порівняння зазвичай йде інструкція зробити стрибок на певну адресу, якщо виконується умова порівняння. Існують такі інструкції стрибків з умовою: je – стрибати якщо рівні, jg – якщо друге значення було більше за перше, jge – більше або рівне, jl – менше, jle – менше рівне.

incl – збільшує аргумент на одиничку. incl %edi – це те саме що й addl $1, %edi, тільки коротше й швидше працює.

Далі буде

Вже скоро ранок, а hello world ми ще так і не написали. Треба розібратись з написанням і викликом функцій, викликом функцій роботи з файлами, щоб можна було писати в STDOUT. Але це вже завтра, бо це вже й так надто червоноока публікація.

Хоча в книжці там ще йде мова про рекурсію, обробку помилок, бібліотеки функцій, та їх створення, менеджер пам’яті і інші цікаві речі.

Written by bunyk

Вересень 6, 2014 at 03:34

Оприлюднено в Кодерство

Tagged with

Timeout decorator

with 2 comments

Декоратор який використовуючи сигнал Unix SIGALRM перериває роботу функції якщо та працює довше ніж задане число секунд:

import signal

class TimeOut(Exception):
    def __init__(self, msg='Time out error'):
        super(Exception, self).__init__(msg)

def on_alarm(signum, frame): # при надходженні сигналу кидати виняток
    raise TimeOut()

def limit_time(t, default=None):
    signal.signal(signal.SIGALRM, on_alarm) # встановити обробник сигналу

    def decorator(f): 
        def decorated(*args, **kwargs):
            signal.alarm(t) # попросити ОС прислати нам сигнал через t секунд
            try:
                return f(*args, **kwargs)
            except TimeOut:
                return default
        return decorated
    return decorator

import contextlib
# Дякую Алекс!
@contextlib.contextmanager
def time_limit(t):
    signal.signal(signal.SIGALRM, on_alarm)
    signal.alarm(t)
    try:
        yield
    except TimeOut:
        pass


import time

@limit_time(5) # працювати не довше 5 секунд
def test():
    for i in range(10):
        print i
        time.sleep(1)

test()

with time_limit(5):
    for i in range(10):
        print i
        time.sleep()

Written by bunyk

Вересень 2, 2014 at 14:13

Оприлюднено в Кодерство

Tagged with ,