My Youth Romantic Comedy Is Wrong, As I Expected
»Фанфики(БЛ) Бесконечное лето Ru VN Семен(БЛ) Женя(БЛ) Электроник(БЛ) Ветала Визуальные новеллы фэндомы
Как Семён стал вором (часть 1)
«Похоже, наша вожатая поехала кукушкой. Это же надо было послать меня за мукой... в библиотеку! Откуда муке там взяться?!» — так думал Семён, вступая в лагерное книгохранилище.
Внутри, как всегда, прохладно и тихо.
Библиотекарша была полностью поглощена своим любимым занятием — дрыхла как суслик. Уложила голову на руки вместо подушки и сладко посапывала.
«Интересно, она вообще бывает бодрствующей на рабочем месте?» — подумал Семён.
Ему почему-то всегда было неловко её будить. И он предпочитал дожидаться, пока она проснётся сама, или вовсе уходил. Но в этот раз его отправили сюда с ответственным поручением, не терпящим отлагательств.
Семён подошёл поближе к Жене, чтобы аккуратно потрясти её за плечи. Глядя на эту девушку, он осознал, почему никогда не хотел прерывать её сон: такая безмятежная, лежащая с закрытыми глазами и чему-то улыбающаяся — она была невероятно хорошенькой. Совсем не похожей на ту жужелицу, которая триггерилась и орала по никому не понятным поводам.
Семён ещё раз подумал, стоит ли из-за очередного и, очевидно, бессмысленного поручения вожатой разрушать такую милоту. Возможно, мука лежит где-то в другом месте, а у Жени есть ключи. И Ольга Дмитриевна говорила, что нужно принести её побыстрей, чтобы повара успели к ужину.
Вздохнув, Семён наклонился, чтобы предельно осторожно прошептать ей на ухо: «Подъём, соня!» Его лицо оказалось на минимальном расстоянии от лица Жени. И в этот момент он уловил лёгкий аромат духов, какой-то фруктовый и очень приятный. Он услышал, как она неразборчиво шепчет во сне. Он увидел на румяной, слегка загорелой щеке девушки еле заметный бесцветный пушок, похожий на тот, что бывает на спелых персиках, словно молящих, чтобы вкусили их сочную мякоть.
Не отдавая отчёта в своих действиях, Семён коснулся губами её прелестной щеки. Он и сам не подозревал, до чего сильно ему хотелось этого! И только в момент поцелуя, испытывая небывалое наслаждение, он осознал, что наконец-то совершает то, о чём давно мечтал.
Женя довольно замычала и начала тереться щекой, подставляя всё большую поверхность для поцелуя. Ей это нравилось даже сквозь сон! Она повернулась, и её губы соприкоснулись с влажными губами Семёна, а через миг они страстно впились друг в друга.
«Так вот ты какая на самом деле!» — подумал охмелевший от удовольствия Семён.Внезапно Женя открыла глаза. Пару секунд она отходила ото сна, не понимая, что происходит, потом она узнала Семёна, почувствовала вкус поцелуя, и в её взгляде возник неподдельный ужас.
Она моментально отпрянула от него. Затем она вскочила и отбежала от библиотечного стола. Испуг сменился яростью.
— Ты совсем что ли обалдел??? — библиотека заполнилась её рёвом. — Ты что творишь, хунта проклятая?!!
Семён понял, что в этом состоянии ей бесполезно что-либо объяснять, и самым разумным решением в текущей ситуации будет ретироваться без всякого промедления.
Семён выскочил из библиотеки. Женя в бешенстве бросилась за ним, размахивая увесистым фолиантом.
— А ну стоять, контра! — заорала она вслед.
Семён не собирался выполнять её требование. Он бежал по дороге к медпункту. Видимо, сидение в библиотеке не способствовало поддержанию хорошей физической формы — Женя отставала.
— Лови его! — кричала она на бегу. — Держи вора!!!
«Какой я ей вор?» — мысленно возмутился Семён.
Он заметил, что к погоне присоединились другие пионеры. Вот уже незнакомый парень летел к нему наперерез. Семён свернул в аллею из деревьев, но и там было полно бегущих к нему ребят.
Он споткнулся то ли об корягу, то ли об чью-то подножку, и больно ударился о землю. В следующий миг его окружили, привалили к земле и скрутили руки.
— Попался, расхититель социалистической собственности! — ликовали они.
Семён был ошеломлён, его придавило навалившимся весом, руки расцарапались до крови и ссаднили. Он хотел что-то сказать в своё оправдание, но злорадно галдящие пионеры совершенно сбили его с толку, и он не мог подобрать слов.
Поняв, что беглец не собирается вырываться, с него слезли и подняли, но руки всё равно крепко держали. Все смотрели на него заинтригованно и одновременно осуждающе. Он заметил в толпе лица знакомых пионерок, которые шокированных происходящим не меньше его.
Наконец, появилась запыхавшаяся и красная от злости библиотекарша.
— Что он украл? — спросили её пионеры.
Женя гневно указала перстом на Семёна.
— Он... Он... — зашипела она и вдруг разрыдалась. — Он украл мой первый поцелуй!
Женя плакала навзрыд, по щекам катились крупные слёзы.
— Я... спала, а он взял и поцеловал!
Мику обняла её за плечи. Лена закрыла своё лицо руками. Ульянка лыбилась. Незнакомые пионеры отпустили его и стояли в нерешительности.
Из толпы выскочила разъярённая Двачевская и больно ударила Семёна в живот.
— Да как ты посмел поцеловать Женю!
Последнее слово она выкрикнула, а потом резко скрылась за деревьями. Семён так и не понял, что так взбесило Алису: то, что он поцеловал спящую девочку, или то, что он поцеловал нееё.
А вот остальные пионеры уже не были столь категорично против него настроены. Поняв, что передними никакой не злостный преступник, а незадачливый герой-любовник, они улыбались и перешёптывались между собой.
Ульянка громко захихикала:
— А Сёмка-то у нас — вор поцелуев!
Все засмеялись.
Никто не знал, что делать в такой ситуации. Все громко перешёптывались между собой, кто-то с кем-то спорил, но разобрать что-то в этот гвалте было решительно невозможно. Женя продолжала плакать, но уже беззвучно. Мику гладила её по голове, а Лена куда-то делась. Пионеры начинали потихоньку расходиться. Семён заметил, что некоторые девочки поглядывают на него смущённо-одобряюще.
В этот момент на шум прибежала Славя.
— Что тут происходит? — строго спросила она.
— Семён поцеловал Женю, пока она спала, и теперь она плачет. — ответили пионеры.
Славя посмотрела на Семёна, потом на Женю, потом снова на Семёна. И с недоумением обратилась к нему:
— Зачем ты её поцеловал?
Этот, в сущности, простой вопрос застал Семёна врасплох. Действительно, зачем? Он и сам этого не знал. Просто поддался внезапно возникшему импульсу.
— Не знаю... — неуверенно отвечал Семён. — Захотел и поцеловал...
Женя сняла залитые слезами очки и уткнулась лицом в Мику. Которая за всё время не проронила ни слова, что само по себе было весьма странным.
— Мику, отведи Женю в домик. А вы все расходитесь! — приказала Славя пионерам.
Она посмотрела на Семёна дружелюбно, но её тон оставался серьёзным:
— Семён, это, конечно, хорошо, что ты не побоялся проявить свои чувства к девочке, но нужно было убедиться, что она не против. И уж тем более не целовать, когда она спит и не может знать о твоих намерениях. В следующий раз сначала проверь, что тоже нравишься девочке, а если не знаешь как — спроси её напрямую.
— Хорошо. — пообещал Семён. Он и сам уже был не рад своему поступку.
— Жене нужно сейчас побыть одной и успокоится. — продолжала Славя уже мягче. — Тебе стоит обратиться за медицинской помощью. Потом приходи к ней извиниться. А мне пора по делам.
— Ладно, — сказал он и поплёлся в сторону медпункта.
VN Дайджест Стенгазета лагеря Вечерний костёр(БЛ) Бесконечное лето Ru VN Визуальные новеллы фэндомы
№6 - 2020
Да, я не объективен.
№6 - 2020 / №191
03-09.02.20
Началась неделя с моей одинокой мысли о том, что не плохо было бы добавить тег "Коронавирус (БЛ)" Почему? Ответ на картинке.
Неожиданно всплыл милый домашний вайфусрачик, даже потеплело на душе. (А Рэй все-таки б... Неее, не угадали. Милая барышня, вот.)
Далее, чуть-чуть новостей от разработчиков:
Little Green Girl. Возможно, вероятно, когда-нибудь. Заранее рад за внуков.
LMR, это как линия горизонта. Чем ближе к ней подходишь, тем дальше она отдаляется.
Орика наша, в отличие от СГ порадовала нас. Ну, кому-то не понравилась новелла, кто-то отмолчался. Я кстати еще не читал. Но скоро.
Но вернемся к фэндому
Сильви, это не шарики. Но тоже радуют. А вот Славяне надо что-то делать с завязавшимся жирком. Или это не Славяна? Нет, автор утверждает что она.
У кого-то в одной колоде девять тузов. И как тут не вскрываться?
По моему один из участников заслужил персонального знака отличия: "Библиограф Литературного кружка."
Чего мы ждем от Художника-куна? Что получаем, того и ждём.
Содержание Костра
ШаурМяу, просто шаурмяу.
Задание Мрачнюшке, конспектировать учебник по истории КПСС -- не взяла.
Есть художники у которых всё смешалось в кучу. Кони, люди...
Джейн, мысленно вместе с нами. Что приятно.
Интересно, может старому самураю назвать свой меч Буратинка?
И финтифлюшечки от одного из участников. Сделаем из них маленькую горку!
Именинник недели KamitsuKun
Cheat engine hook hcode Визуальные новеллы фэндомы
Делаем собственный hcode к новелле.
Собственно почему бы и нет. В русскоязычном сегменте гайдов никаких нет, в англоязычном все довольно-таки старенькие. Поэтому запилю свой гайд как делать хук код к новелле которую вы собирались почитать, а текст нихуя не вытаскивается.
Во первых нам нужен инструментарий.
1. Cheat Engine как дебагер, удобный, мало весит, имеет вполне себе юзерфрендли интерфейс. Скачать можно всегда с офф сайта https://www.cheatengine.org/
2. Textractor — собственно достойная замена ITH и ITHVNR, хотя если точнее продолжение. Скачать можно на странице релизов с гитхаба https://github.com/Artikash/Textractor/releases
3. Наша подопытная новелла. Я взял тупа первую новеллу к которой просили хук на хонге. Скачать эту новеллу можно отсюда https://sukebei.nyaa.si/view/2640189
Собственно поехали.
Я скачал данную новеллу и открыл текстрактор. Жмакаем аттач то гейм и выбираем процесс с нашей игрой. Автоматом подхватились нужные треды с обрывками текста.
В данном случае это GetGlyphOutlineA, как видно текст дают нам не полностью а только его часть. Данный косяк мы и будем исправлять.
Прежде всего следует поискать существует ли в памяти нужная строка в неизменном виде.
Жмакаем кнопку add hook и в открывшимся окне вводим S[впечатываем сюда нужную строку]
Жмем ок и чуточку ждем. В консоли должны появится записи, что добавились новые юзерхуки, проверяем их.
Жмакаем на окно нашей новеллы и прогоняем несколько строк, смотрим добавились ли они в окно с нашим юзерхуком. В данном случае вторая строка добавилась, но на третьей споткнулась, похоже, что меняется адрес куда записывается новая строка и этот вариант нам не подходит.
Переходим к самому интересному и веселому открываем cheat engine.
Подрубаемся деббагером к нашей новелле. Выбираем процесс и жмакаем Attach debugger to process.
После того как подключились к процессу необходимо перейти на нужный адресс в окне memory view.
В красной рамке собственно располагается окно с ассемблерными инструкциями. Жмем по нему правой кнопкой мышки и нажимаем Go to address.
Нужный нам адресс можно получить в окне textractora треда который не полностью захватывает текст.
Красным подчеркиванием выделил где находится данный адрес. Вводим его в окошко Goto Adress, первые две цифры не трогаем, мы должны поменять только последние 6.
Собственно в окне memory view должна выделится нужная позиция.
Конкретно здесь выделение должно быть в инструкции адрес который я подчеркнул красным. Кстати в окне memory view адрес пишется с учетом оффсета от реального адреса, а не того который выделили в памяти. Поэтому реальный адрес инструкции 6F298 относительно начала файла экзешника нашей новеллы, в то время как в памяти нашего пк адрес 0046F298. Ну это так чисто техническая инфа, я хуй знает зачем это пишу.
Далее мы должны поставить breakpoint, выделяем нужный адрес и правой кнопкой мыши установить breakpoint либо же просто жмем ф5.
Итак мы выделили нужный адрес и поставили брикпоинт, когда он ставится, до инструкция выделяется зеленым цветом.
Ткнем в диалог новеллы и она должна зависнуть, а интерфейс memory viewera слегка изменится. Давайте пройдемся по нему поподробнее.
Собственно 1 это окно просмотра адреса памяти в хекс режиме. Полезно посмотреть что скрывается в различных адресах. Нихуя не буду углубляться в что такое поинтеры и с чем их едят. Я вообще когда начинал ебашил все методом научного тыка и нихуя не знал.
2. Окно с нашим стеком, что такое стек я тоже нихуя не буду писать, во всяком случае сейчас. Окно это дюже полезное и позже объясню почему.
3. Регистры, собственно в 32битных программах есть регистры EAX, EBX, ECX, EDX, ESI, EDI, EBP и ESP подробнее про них вы можете прочитать не у меня, так-как по большему счету я тоже мало знаю об этом, короче считайте регистры что-то вроде переменных. Про флаги и сегменты регистров я тем более нихуя не знаю, так-как их не использую в принципе.
4. Окно с ассемблерными инструкциями.
Окей. С этим мы разобрались, хотя я почти на сто процентов уверен, что никто нихуя не понял. Неудивительно из меня хуевый учитель, но поехали дальше.
Собственно наше окно с регистрами горит красным и если мы пощелкаем ф9, то сможем увидеть как некоторые показатели в регистрах меняются. Мы знаем, что по адресу 6F292 вызывается инструкция GDI32.GetGlyphOutlineA собственно туда отправляются наши японские символы в количестве одной штуки. Я кстати не читал документацию но чисто на эмпирическом уровне думаю, что данное апи выводит на экран текст, хотя если бы было так, оно выводило не весь текст, хуй с ним, может люди умнее меня скажут нахуй она нужна. Опять я что-то отвлекся.
Конкретно в данном случае можно сразу запалить 2 байта
В регистре ESI 82B1 я уже столько раз делал хук коды, что точно знаю, что все японские символы в SJIS кодировке состоят из двух байтов и первый байт у них начинается с 80. Есть очень полезный сайт который позволит хекс коды перевести в читабельный текст http://freaka.freehostia.com/charset.php
Благодаря этому сайту мы понимаем, что 82В1 = こ. Да так и есть, каждый раз при вызове ф9 мы продолжаем выполнение программы и каждый раз когда срабатывает брикпойнт регистр ESI меняется показывая нам новую букву. Хорошо с этим мы разобрались. Но как же выловить весь текст полностью? Ну в данном случае придется окунуться в наш стек, что бы найти истину.
В окошке со стеком, жмем правой кнопкой мышки и выбираем Not system modules only. Теперь мы увидим в окне адреса модулей. Наша задача выйти из этой подпрограммы в которой вызывается функция GDI32. Тут наверное стоит сделать лирическое отступление. Я сам нихуя не понимаю до конца как это работает, буду говорить с той позиции какой вижу это я.
Зеленой рамочкой обведен наш брикпоинт, наша задача выйти из данной функции в место откуда её собирались вызывать жирная черная стрелочка. В начале каждой новой функции на вершину стека кладется адрес возврата выполнения программы. По мере заполнения стека он будет опускаться все дальше вниз в окне стеков. Поэтому мы ищем в окне стека именно этот адрес возврата. На рисунке выше он 00473CF0. На нашей схеме я его обвел красной рамочкой.
Итак в окне стеков первые три модуля отправляют нас в область защищенной памяти, это не ассемблерные инструкции поэтому они нам не интересны. 4 же возвращает адрес куда должно передаться управление программой после завершения этой функции то есть до оператора ret что в простонородье означает return ака возвращение.
Нам нужно поставить брикпоинт прямо перед выполнением функции в которой происходит вызов в GDI32.
В нашем случае это адрес 72CE9 чуть ниже мы можем увидеть функцию call и еще на один ниже наш адрес возврата из той функции 72CF0. Поставим брикпойнт и немного погоняем ф9, смотрим есть ли где-нибудь наш текст. Ах да, поставим full stack в окне стека. Если мы дважды щелкнем кнопкой мыши на первую позицию в стеке после того как нажмем ф9, то в окне хекс отображения сможем увидить два байта нашей буквы в sjis кодировке. Значит мы сделали все правильно и буква появляется еще выше по выполнению данной функции, если бы мы нигде не смогли отыскать нашу букву, то алгоритм работы слегка изменился и нам пришлось искать место где она появляется в функции где вызывается GDI32, но этого не произошло и продолжаем искать дальше.
В данный момент у нас должно быть активно два брикпоинта при нажатии Ctrl+b мы увидим их адреса, либо же можно нажать мышкой сверху view -> breakpointlist. Наша задача понять они выполняются каждый одинаково, то есть сначала первый потом второй и если да, то это место для хука не подходит, так-как мы знаем что у нас проебаны буквы.
Жмакаем ф9 и видим, что они выполняются последовательно, значит ищем дальше. Мне чуйка сразу подсказала, что текст формируется именно в этой функции и я решил пройтись по ней с самого начала. Брекпоинт по адресу 0046F292 можно нахрен удалять. Что бы попасть в начало функции жмакаем правой кнопкой мыши на окне с инструкциями выбираем select current function, наш отшвырнет на адрес 72A2D, поставим здесь брикпойнт и пощелкаем ф9.
Заодно не забываем проверять наш стек и регистры на наличие чего нибудь напоминающие буквы в хекс виде. Из проделанной работы мы узнаем, что начало функции вызывается куда чаще чем адрес 72CE9, а значит вот оно, больше никуда лезть не нужно, нам осталось отыскать место где появятся наши заветные два байта. Жмем ф8 и потихонечку спускаемся вниз все это время следя за регистрами и стеком.
Ага, вот тут после выполнение команды в адресе 72A88 в регистре EAX появилось кое-что интересное. А именно появляется первый байт нашей буквы, мы ведь помним, что первый байт всех японских символов начинаются с 80. Отлично идем дальше.
А вот наклюнулся и второй байт в регистре ECX, он появился после выполнения команды в адресе 72A92. За ним идут две операции and, где по сути избавляются от минуса, и мы применяем побайтовый сдвиг влево на 8 у регистра EAX. Вот оно, уже рядом.
Собственно вот и оно. После инструкции в адресе 72AA2 наши два байта объединились и стали единым целым. В адресе 72AA4 можно поставить брикпойнт и пожамкать ф9, что бы убедится, что все буквы появляются именно здесь. Как только мы в этом убедились. Жмем Ctrl+B и удаляем все брекпойнты, они нам больше не понадобятся. Самое время запилить наш хук.
Цепляться будем ка адресу 72AA4 который идет сразу после того как наши два байта объединяются.
Откроем textractor подрубимся к экзешнику с нашей игрой, если вы вдруг его закрыли, если не закрывали, то он должен быть уже заатачен к процессу игры. жмем добавить хук код add hook
Ну и собственно вбиваем наш хук. Если у вас экзешник из иероглифов, имя желательно полностью скопировать. Как составлять хуки тут есть целая памятка. /H собственно с этого начинается любой хук код. A - берет два байта в кодировке SJIS little endian, B следует использовать когда байты повернуты наоборот. То есть в данном примере у нас 8179 - это А, а если бы было 7981, то нужно было бы в писать в хук B. Префикс N, блядь, я знаю, что это значит но по умному хуй знает как описать. Короче, суть. Если не писать N, то будет дополнительно учитываться регистер ESI вроде бы, точно не помню и если он постоянный то все будет ок, но если вдруг каждый вызов он будет меняться, то вы получите кучу всяких потоков, поэтому использовать его нужно с умом. Собственно собака, потом адрес куда мы будем хукаться, напомню этот адрес идет сразу после того как мы получили наши цельные два байта. Двоеточие и имя экзешника полностью. Жмем окей и вуаля. Хук работает, а мы великолепны.