Здравствуйте, https://2ch.hk/pr/res/849076.html я вот отсюда, описываю суть:Надо на Windows 7 x64 скрыть процесс в диспетчере задач по имени. Вводишь в программе имя процесса, она убирает его из диспетчера задач, хотя процесс по-прежнему работает.Прилагаю портянку кода: pastebin.com/CF8Kh2LGЭто работает, собирал кодблоксом 32бит, запускал на Windows 8.1 x64 и Windows 7 x64 - везде всё идет хорошо ровно до момента, пока не приходит пора получать адрес LoadLibrary, записывать её аргумент (адрес инжектируемой DLL) в виртуальное адресное пространство taskmgr.exe и вызывать её удаленным потоком, создавая последний. Там я сначала чуток запутался, а потом когда вникал в проблему, внезапно осознал, что я собираю всё под 32 бит, кодблокс в 64 бит не умеет, встроить 32бит DLL в 64бит taskmgr.exe невозможно (разве что как данные) и пора всё переписывать в Visual Studio, которая под 64бит нормально собирает.Занимаюсь этим уже неделю, реально сдуру взялся, голова трещит просто. Вопросы таковы:Как вы бы поступили, зная что LoadLibrary и прочие функции 100% будут работать с латиницей - приводили бы их аргументы к char или к wchar_t? Или как-то иначе? Какие тут подводные камни при использовании каждого из решений? И что поменялось при смене разрядности (когда я пересел с кодблокса на студию), если у меня теперь просто нихуя не работает, ссылаясь на неверные аргументы функций, работающих со строками и указателями на них (strcmp в строке 29 например)? По идее, должен был измениться sizeof(const char), и что мне теперь с ним делать, если WinAPI-функции были написаны для 32-битных систем? С каждым часом чтения манов понимаю всё меньше, прошу объяснить.Второе - правильно ли я понимаю, что в общем случае в Windows такие библиотеки как kernel32, ntdll и им подобные загружаются единожды и где-то при старте системы, а не как другие библиотеки в момент загрузки их конкретным процессом? Но предположим, что библиотека загружена условно говоря в самые первые мегабайты физической памяти (0x00000000 - 0x000000FF к примеру), может ли быть такое, что виртуальное адресное пространство процесса начинается с 0x0000FFFF и как мне тогда ссылаться на функции из той же kernel32? В общем где-то на этом моменте я окончательно запутался в миллиарде аргументов VirtualAllocEx, CreateRemoteThread и LoadLibrary.
Пытался аккуратно переписать получившееся под 64бит, получилось вот что: pastebin.com/7MqCG2Hs, так вот почему оно в упор не видит запущенного taskmgr? Не потому ли, что я первый аргумент strcmp тупо конвертирую в char*? Как это надо сделать по-человечески?
>>850865 (OP)бамп
>>850865 (OP)Вот хочешь человеку помочь. Возможно, даже знаешь, в чём проблема. А на пике какая-то хрень стоит. Ты не мог нейтральную пикчу выбрать? Мне вот теперь пролистывать её, чтобы на глаза не попадалась? Ну вот зачем ты так сделал? Мучайся сам теперь.Кстати, вместо CreateToolhelp32Snapshot можно использовать NtQuerySystemInformation.>>850866>Пытался аккуратно переписать получившееся под 64бит>почему оно в упор не видит запущенного taskmgrРазницы между 32 и 64 в данном случае не должно быть. 32 должно видеть и 32 и 64 битные приложения. Не проверял, но предполагаю.>Не потому ли, что я первый аргумент strcmp тупо конвертирую в char*? Узнай о Unicode и ANSI функциях. Конвертишь-то зачем? А вообще, это кастинг называется, его аккуратно надо использовать, зная о последствиях.
Чего-то подумал тут. А зачем инжектить dll? Всё, что тебе нужно - скрыть процесс из диспетчера задач? Обычным CreateToolhelp32Snapshot/NtQuerySystemInformation из другого процесса покажет твой скрытый процесс, правильно?
>>850960Нужно чтобы чужой запущенный диспетчер задач не показывал процесса, а для этого нужно встроить в него dll, перехватывающую NtQuerySystemInformation, вот в чем дело. Узнал про Unicode и ANSI функции, всякие LoadLibraryA/LoadLibraryW, буду пробовать.>>850950Насчет разницы между 32 и 64 - а как я 32-битный код буду инжектить в 64-битный процесс? Никак.
>>850950>вместо CreateToolHelp32Snapshot...Да можно-то можно, но в итоге всё равно придётся получать список структур (я не удивлюсь если tlhlp32 это обертка над NtQuery), проходиться по нему и сравнивать строки. Какая в общем разница.
>>850973>а как я 32-битный код буду инжектить в 64-битный процессПо твоему функции WriteProcessMemory есть дело до того, что ты через неё пишешь?>нужно встроить в него dll, перехватывающую NtQuerySystemInformation, вот в чем делоЕщё раз спрашиваю - зачем нужна dll для этого? Ты можешь выделить память, скопировать в неё данные и создать поток, исполняющий код в этой памяти. DLL нужна, если необходимо все процессы контролировать, так или нет?
>>850975>я не удивлюсь если tlhlp32 это обертка над NtQueryТак и есть.>Какая в общем разница.Это не Ъ подход. Или ты делаешь так, или про твоё существование забывают. Выбирай мудро.
>>850984Дело в том, что внутри 64-битного приложения я могу исполнять только 64-битный код, не так ли?Задача "скрыть из диспетчера задач", если есть способ сделать её иначе, чем хукать вызов диспетчером NtQuery, я бы с удовольствием им воспользовался.
>>850985Что означает "не Ъ", ты считаешь мне с WinAPI мало возни, надо ещё со всего обёртки поснимать и нативные функции использовать?
>>850991>внутри 64-битного приложения я могу исполнять только 64-битный код, не так лиДа. Но передать этот код на исполнение можно и из 32 битного приложения. И нужно предусмотреть инжект кода как в 32, так и в 64 битное приложение. Только если задача не поставлена так, что нужно только в 64 битное приложение инжектить.>если есть способ сделать её иначе, чем хукать вызов диспетчером NtQueryНа этом и будет основано. Только здесь не dll нужна, а заранее подготовленный код, который, оказавшить внутри процесса, поставит хук на нужных функциях и будет следить за исполнением. Задача на первый взгляд элементарная.
>>851003Так какая разница, будет ли это встраиваемый код (просто функция) или DLL? Или разница в том, что встраиваемый код я могу внутри основного приложения оформить как функцию и передавать в CreateRemoteThread указатель на неё, а не на IntDLL, для получения которой надо LoadLibrary дергать?И тогда основное приложение точно должно быть 64-бит?Разбираюсь пока со снапшотами, в ANSI буду делать наверное.
>>851003Программа-минимум - хук в 64-битное приложение, я планировал сделать 2 DLL с инжектируемым кодом и определив разрядность Windows обращаться в будущем к нужной, но пока задача упирается именно в 64бит.
>>851004>Так какая разница, будет ли это встраиваемый код (просто функция) или DLL?Потому что первый вариант Ъ. Или делаешь так или никак. Вопросов по этому пункту больше не задаёшь.>И тогда основное приложение точно должно быть 64-бит?Не важна разрядность.На тебе подсказку. Пишешь код так, будто бы ты уже внутри нужного приложения. Это, естественно, отдельное приложение будет. Изначально тебе ничего не известно, все необходимые функции ты ищешь вручную. Делаешь инжект из своего приложения в своё же приложение. Хукаешь, что необходимо, обрабатываешь как надо. Конпелируешь свой код. Запускаешь любой HEX-редактор. Находишь начало и конец необходимого кода (можно спецметками начало и конец пометить, например, magic number или ещё чем-то). Копируешь двоичный код, вставляешь как последовательность байт в свою прогу для инжекта. А дальше находишь нужный процесс, записываешь через WriteProcessMemory свой массив байт, создаёшь удалённый поток и запускаешь его на исполнение. Ну элементарно же, в чём трудности-то могли возникнуть?
>>851017Дай угадаю, запрос к 2ch.hk составляешь сам, включая свой пост, а потом через какой-нить telnet-клиент (по-моему в них можно было связываться по http) отправляешь сюда? Чем капчу разгадываешь?
>>851017Чтобы не морочить себе голову, я не буду считать это за толстоту, а отвечать буду как на любой другой псто - пиздец элементарно, когда я очередной раз запутаюсь в WinAPI, мне абсолютно нечем будет себя проверить.
>>851024Нет, через FF. Мой mitm-proxy сломался, даже не посмотришь теперь, что он отправляет.>>851025Может быть, мудрёно написал. Но, если разобраться, всё просто. Там ещё особенность будет - никаких абсолютных адресов, ссылок, переходов. Всё относительно твоего кода. Можно даже упростить себе задачу. Т.к. dll ты написать можешь, то готовый код у тебя как-бы есть. Просишь конпелятор генерировать не только двоичный код, но и asm файлы. Чуток поправишь абсолютные переходы на относительный, каким-нибудь masm'ом соберёшь этот файл и готово.
>>851031Мне нужно постоянно проверять, что я нагородил в коде, и вариант не для меня. Это как прыгать без парашюта с двухсотметровой высоты, надеясь попасть в бассейн метр на метр - что-нибудь да обязательно помешает.Вот только что сделал наконец нормальный поиск процесса в 64бит - выключил заигрывания Visual Studio с Юникодом, использую везде обыкновенные литералы без L и char без wchar_t. С методикой уровня "если разобраться всё просто" я бы сейчас ломал голову просто над вопросом, что конкретно у меня не работает в коде, который я только что перевёл в машинные инструкции и встроил в таскман (да вангую там сегфолты начались бы раньше чем я задумался об ошибках).
>>851034>что конкретно у меня не работает в кодеЭто тот, который pastebin.com/CF8Kh2LG ? Сейчас посмотрел более внимательно. Ты создаёшь поток в удалённом приложении, который должен начинаться с функции LoadLibraryA. И толку от этого? Тебе написал, что надо делать. В любом случае, мини-загрузчик твоей dll тебе надо записать в чужой процесс, выделив перед этим память, записав его туда и не забыть про флаги защиты памяти, и передать адрес выделенной памяти в CreateRemoteThread. Либо предлагаю тебе залить туда готовый код, чтобы лишних телодвижений с загрузкой dll не делать.
оп, ваших компетенций не достаточно для решения данной задачи
>>851045Да ладно тебе, все с чего-то начинали.
>>851047мы начинали не с того чтобы брать заказ, который заведомо будет не выполнен
>>851049Ну чего ты хочешь? Новое поколение же выросло, думать не хочет, бросается на всё, где деньги предлагают. Его проблему легко решить, грамотно погуглив. И подумать надо немного. Задача то, в принципе, элементарная. А он застрял в самом начале. Думал, что погромирование - 300 тыщь в сек и думать не надо, а оказалось не так радужно. Такие быстро отсеиваются. Или из него выйдет толк. Редкий случай, но вдруг.
>>851045Будет достаточно. Это одна из задач, которые приходится решать методом щенка, брошенного в воду, и оттого они очень развивают мозги. Ясное дело, что я сделал херню, взявшись за этот заказ, но херня уже сделана.>>851042Схема действий, если я всё-таки буду использовать DLL, такова:1. Получить адрес LoadLibraryA в пространстве taskmgr'а. Адрес своей IntDLL записать в const char[].2. Выделить в taskmgr'е память под const char[], записать туда аргумент LoadLibraryA(адрес моей DLL), запустить удаленный поток, передав в него адрес функции (LoadLibraryA) и адрес её аргумента (путь к DLL). LoadLibraryA даст мне адрес IntDLL, загруженной в taskmgr, его сохранить.3. Получить адрес моего обработчика NtQuery с помощью GetProcAddress, снять с него NX-бит VirtualProtect'ом, запустить ещё один удаленный поток, в который передать адрес обработчика.а дальше всякая дилда с поиском NtQuery в таблице импорта taskmgr'а и сплайсингомПравильно? А вот второй путь:1. Написать функцию, которая ищет в собственном процессе NtQuery-чего-то-там и сплайсит его вызов. Выделить память VirtualAlloc'ом, имея уже открытый taskmgr.exe, снять NX VirtualProtect'ом, записать функцию в выделенную память, запустить.Верно? Но где я возьму количество памяти, которое следует выделить для моей функции, если она ещё не скомпилирована? Или мне чем-нибудь собрать её в .asm, затем .asm вставить в .c, используя ключевое слово _asm, и размер функции теперь заранее известен, потому что её не надо собирать или как? Это крайний вариант, повторюсь
>>851051Задача элементарная, просто я схватился за неё, не имея опыта в WinAPI и плохо себе представляя, как это работает. Решить её "грамотно погуглив" можно, если ты до этого сколько-то дрочился с похожими темами, если набил уже руку. Я тоже пытаюсь "грамотно гуглить", но периодически застреваю, это как шашечные алгоритмы программировать - вроде бы несложно, но долго, муторно и постоянно запутываешься, а запас сил ограничен. Тем не менее, задача есть, и я надеюсь её всё-таки решить. Ах да, всё написанное под 32, под 64 наконец стало работать, это просто загоны Visual Studio были.
>>851054Сколько тебе заплатить должны в случае успеха?>1. 2. 3.Загрузчик нужен для твоей dll. В любом случае, нужен минимальный код. Можно на ассемблере его написать, там строк 100 будет, а то и меньше. Все эти LoadLibraryA, GetProcAddress надо выполнять в адресном пространстве нужного тебе процесса, а не так, как ты хочешь. Может быть, чего нибудь и получится, если создать удалённый поток с адресом LoadLibraryA. И то только из-за того, что прототипы функций совпадают. Пишу же тебе, что это элементарная задача - инжект кода в адресное пространство другого процесса. Тебе ни от антивируса, ни от пользователя скрываться не надо. Ничего сложного не вижу.>Но где я возьму количество памяти, которое следует выделить для моей функцииСделаешь sizeof(inject_x64). А inject_x64 объявишь какstatic const char inject_x64[] = {тут твой код вида 0x90, 0x90, 0x90};>Или мне чем-нибудь собрать её в .asmДа.>затем .asm вставить в .c, используя ключевое слово _asmНет. Скопируешь из готовой программы, тебе уже написал, как это сделать.Мне реверсить программу надо, а тут хернёй какой-то маюсь. Делай, задавай конкретные вопросы, получишь конкретные ответы.
>>851074Прежде всего спасибо, что уделяешь (уделяете) время. Слова людей, которые пообтесались в деле, очень заряжают моралью, а иногда и помогают по делу (иногда не от того, что они неинформативны, а от того, что их редко понимаешь как надо, ну это дело обычное).Всё-таки делаю загрузку DLL, для меня такие телодвижения проще. Я полностью понимаю, о чем ты говоришь и как это делается (в теории), но боюсь запутаться с реализацией.pastebin.com/bsPWxv7P <- вон там текущий вариант кода, всё под 64 бит, всё работает и что-то инжектирует. Библиотека весит пока что 29 Кб, так вот после того как код отработает (а он я так понимаю выделяет память ещё и под стек, который я указал в dwStackSize), выделение памяти для taskmgr.exe увеличивается на 24 Кб. Думаю, беспокоиться не о чем, и DLL просто в несколько ином виде попадает в процесс, оттого и разница в занимаемой памяти. Пока что дело идёт, сейчас начну писать код, который будет работать внутри процесса и буду задавать вопросы.
>>851085Господи, я же НЕ ЗАПИСАЛ адрес DLL в выделенную память -_\
>>851074Заплатить мне должны двадцать долларов, я бы отказался, но очень хочу вкатиться-таки на Freelancer.com, а без отзывов (или с таким, который будет у меня, принявшего заказ и проебавшегося) я думаю это бесполезно.Вопрос - после того как отрабатывает CreateRemoteThread, запуская LoadLibraryA из самого taskmgr'а, куда передаётся возвращаемый адрес библиотеки? Мне он нужен для запуска следующего удаленного потока, и я не могу его найти.
бамп
>>851085Нашёл ещё одну ошибку - я записываю указатель, а не содержимое...ох уж эти const char*, где стандартный класс строк, весь в C++ остался?И всё-таки, где мне взять адрес своей библиотеки в памяти taskmgr.exe? Без него ни один адрес функции из своей dll мне не получить.
А ещё LoadLibrary, какую бы чушь я ни написал в PathIntDLL, нулевой хендл никогда не возвращает.
А ещё LoadLibrary, какую бы чушь я ей ни передал в качестве аргумента, никогда не возвращает нулевой хендл. GetLastError молчит, выдает нуль.
>>851098>после того как отрабатывает CreateRemoteThread, запуская LoadLibraryA из самого taskmgr'а, куда передаётся возвращаемый адрес библиотекиНапиши в своей программе этот код и посмотри, что произойдёт. Вместо CreateRemoteThread используй CreateThread.В реальном коде надо было бы сделать так (не инжект, само собой):DWORD WINAPI Load_Library(voidparam){some_lib_handle = LoadLibraryA((const char)param);}Ты же передаёшь адрес LoadLibraryA напрямую, надеясь, что всё будет в порядке. Может и будет.А как возвращать результат из удалённого (remote который, а не remove) процесса - не знаю. В DWORD 64-битный адрес может не влезть, результат зависит от того, по какому адресу система загрузит dll.В твоём коде ты преждевременно открываешь процесс. Открывай его после проверки и оттуда возвращай результат. Да и вообще, неплохо бы записать что-нибудь в выделенную память.>>851098>но очень хочу вкатиться-таки на Freelancer.comС меня там какую-то абонентскую плату в размере 30$ в месяц потребовали. Или месяц бесплатно, а дальше абонентская плата. Так ведь не должно быть.
>>851181Про звёздочки и парсер их съедающий забыл. Ну ты поймёшь, где они должны были быть.
>>851181pastebin.com/9J5zeXDkДелаю так. LoadLibraryA у меня принимает const char[]. Записывает его в выделенную память, как если бы там не стояло экранирующих слэшей (если без них посчитать, выходит как раз 38 записанных однобайтных символов, а ровно столько WriteProcessMemory оставляет в NumOfWritBytes).Не вполне понял по поводу "напрямую передаешь адрес". А как надо? Попытался прочитать то, что записал в память, вот таким образом:char* PathBuff = new char[50];ReadProcessMemory(TaskmanHandle, NameDLLBuff, PathBuff, 38, &NumOfReadBytes);for...вывод PathBuff, i от 0 до 38Выводит "Юааааааааааааааааааааа", NumOfReadBytes равно 0.-Freelancer.com просто сделал платными отклики на заказы, по одному бесплатному отклику раз в пару дней тебе прибавляется просто так, месяц ты можешь попробовать триал подписки с большим количеством откликов, а сама подписка стоит 30 баксов, как-то так.
>>851185Сама суть кода до меня немного не дошла. Я "передаю адрес в LoadLibraryA напрямую", а у тебя разве не так? Не понял просто, в чем твоё замечание состояло.
>>851200>выходит как раз 38 записанных однобайтных символовТы забыл про бульон. 38 символов + 1 нулевой символ.>sizeof(PathToIntDLL)То ли ты умышленно так сделал, то ли по незнанию, но тут правильно. sizeof вернёт размер строки (в байтах) + завершающий ноль.>Попытался прочитать то, что записал в памятьУ тебя нет разрешение на чтение.> OpenProcess(PROCESS_CREATE_THREAD | PROCESS_VM_OPERATION | PROCESS_VM_WRITE,>Не вполне понял по поводу "напрямую передаешь адрес".CreateThread(0, 0, LoadLibraryA, string, 0, 0);Это у тебя так. Аналогично, в общем. На месте LoadLibraryA можно вообще любой адрес подставить, хоть 0x123456. У тебя как-раз случайный адрес. То, что там случайно оказалась LoadLibraryA, сути не меняет. Можно и ReadFile передать с таким же результатом.>а у тебя разве не такНет, у меня отдельная функция-обёртка. LoadLibraryA не предназначена как функция для отдельного потока. То, что она, может быть, сможет работать, лишь случайность, т.к. количество параметров LoadLibraryA и функции обратного вызова, принимаемого CreateRemoteThread, одинаково. Попробуй LoadLibraryEx, к примеру, программа сразу же свалится.>Не понял просто, в чем твоё замечание состояло.Нужна отдельная функция-обёртка. Хотя бы на слово поверь, потом поймёшь, почему. Коротенькая функция на асме. Твоя обёртка будет загружать dll и передавать управление на функцию внутри dll. Перед этим найдёт все необходимые для работы функции.>printf("[OK] Remote address of kernel32.dll received!\n");В том то и проблема, что не remote.Кстати, не обязательно задавать размер стека. Система его выберет по умолчанию.>месяц ты можешь попробовать триал подписки с большим количеством откликовЧего же у меня в профиле висит этот триал, если от него отказался? Этот фриланс.ком ещё более непонятен, чем апворк.
>>851206Я забыл про нулевой символ - значит, LoadLibraryA получила на вход охулиардную строку?Насчет sizeof(PathToIntDLL) - так аргумент тут статический char[], в котором лежит литерал, тут я видать случайно взял нужный размер.Вот же ж, а я ни за что бы не догадался, что PROCESS_VM_OPERATION не дает права на чтение!Мне нужно приводить аргумент LoadLibrary к const char* или что? Чего-то я всё равно не совсем понимаю.А разве...а-а-а, нужна обёртка, чтобы передать адрес этой обёртки в CreateRemoteThread, и туда же передать параметр, а потом всё это обёртка передаст в функцию? Хорошо, попробую.В смысле не remote? Я читал, что kernel32.dll не такая уж динамическая, и в современных виндах она подгружается единожды по адресу, который в пределах одной загрузки виндов является одинаковым для всех использующих её приложений. Что ты имеешь ввиду?Стек задал просто на всякий случай. Буду знать.Насчет профиля - просто ты можешь в любой момент активировать триал, насколько я знаю.
>>851208>Я забыл про нулевой символ - значит, LoadLibraryA получила на вход охулиардную строку?Нет, так случилось, что ты передал размер строки + нулевой символ.>Вот же ж, а я ни за что бы не догадался, что PROCESS_VM_OPERATION не дает права на чтение!Да, там отдельный флаг есть PROCESS_VM_READ.>нужна обёртка, чтобы передать адрес этой обёртки в CreateRemoteThread, и туда же передать параметр, а потом всё это обёртка передаст в функциюДа, именно так.>kernel32.dll не такая уж динамическаяМожет быть и так можно. Просто нельзя определять адрес функции из одного процесса, чтобы передать его в другой. Здесь частный случай. Ты вообще можешь упростить себе кодирование. Создай структуру, куда передашь строку с путём dll, необходимые адреса, чтобы не искать их. А потом эту структуру скопируешь в другой процесс и передашь адрес при создании потока. Таким образом твоя функция-обёртка ещё больше упростится. Хотя это не совсем верно, но работать должно.
>>851213Просто любопытно.В общем случае для передачи в удаленный поток в качестве аргумента передают структуру, которая содержит нужные функции, скрывающейся под обёрткой, аргументы, верно?
>>851017Интересно, а как бы я тогда передавал название скрываемого процесса, которое программа принимает на вход? Пересобирал бы её с другим массивом char среди асмового кода?
>>851213В общем решил хукать MinHook'ом. Планирую встраивать MinHook64.lib в свою dll, загружать dll, загружать имя процесса для неё и запускать поток. В связи с этим вопрос - как же всё-таки, загрузив dll в чужую память, получить оттуда нужную функцию? GetProcAddress по идее должен работать?
>>851396бамп