Давеча наелся всяких плацебо"витаминчиков" и захотелось странного, а именно - выучить C++ за неделю. Начинание примечательно тем, что это первый раз, когда я изучаю что-то, связанное с программированием, по книге (обычно руководствовался примерами из гугла). Да и подобные языки мне до этого не приходилось изучать, в общем-то. Книжку выбрал первую попавшуюся на Amazon - Herbert Schildt "C++: The Complete Reference".
Результат своего непродолжительного изучения оформил в следующий класс, который позволяет грузить DLL или произвольный код в 32- и 64- разрядные процессы. Код, правда, написан не в соответствии с модным стандартом C++0x, и в нем не используется такая мощная вещь как шаблоны (хотя сомневаюсь, что они тут серьезно пригодились бы), но, тем не менее, базовые возможности языка я постарался задействовать.
Использовать класс довольно просто, например:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
#include "injector.hpp" int main() { injector a; a.set_blocking(false); try { a.inject(L"CFF Explorer.exe", L"x64.dll"); } catch(const injector_exception& e) { e.show_error(); } return 0; } |
Доступные методы:
1 2 3 4 5 6 7 8 9 10 |
//Инжект DLL в процесс с указанным именем void inject(const std::wstring& proc_name, const std::wstring& dll_name); //Инжект кода в процесс с указанным именем void inject(const std::wstring& proc_name, const BYTE * code, unsigned long int code_size); //Инжект DLL в процесс с указанным PID void inject(unsigned int pid, const std::wstring& dll_name); //Инжект кода в процесс с указанным PID void inject(unsigned int pid, const BYTE * code, unsigned long int code_size); //Снятие/Установка блокирующего режима (вызывать ли WaitForSingleObject и VirtualFreeEx после создания удаленного потока или нет) void set_blocking(bool active); |
Для работы с 64-разрядными процессами достаточно просто скомпилировать класс под соответствующую архитектуру.
Скачать: cpp-injector-class
GitHub: cpp-injector-class
Что, даже нормально работает со всякими необычными случаями, типа наличия релоков в .exe файлов, нестандартными выравниваниями и секциям нулевого размера? :) Вообще-то в данном случае вам даже класс не нужен - достаточно описать эксцепшен и объявить нужные функции в своем неймспейсе.
А какая разница если целью является инжект в запущенный процесс?
Секций нулевого размера не бывает. Если у секции нулевой виртуальный и физический размер указан в заголовке PE, то он не загрузится. Нестандартных выравниваний тоже не существует. Невыровненный exe сделать очень муторно и я сомневаюсь, что он загрузится в новых системах. Но это да, это все неважно при инжекте.
Kaimi, dx привет!
http://pikucha.ru/i5F1O
как пофиксить не подскажете?) vs2008.
или приложите пожалуйста проект, буду благодарен.
Попробуй написать типа file.open(file_name.c_str(), ....
Все в 2010 студии делалось, в ней такой проблемы нет
Угу, метод с первым параметром std::wstring/std::string в новой stl только появился. Так что .c_str().
а какие западные ресурсы по с++ посоветуешь?
http://www.cplusplus.com/
"выучить C++ за неделю" да еще и писать на таком уровне.
мммм....
если это правда, то респект тебе за это.
я думал, что синтаксис, указатели на функцию, ПРАВИЛЬНОЕ УПРАВЛЕНИЯ ПАМЯТЬЮ, указателями и ссылками, библиотеку std:: , директивы условной компиляции, особенности реализации win32 от win64, объекты ядра и куча всего, что я даже не понимаю невозможно выучить за неделю.
правда, респект тебе.
видимо, тут суть в том, что у kaimi есть огромный опыт в других языках, и посему С++ пошел за неделю.
Это как человеку, который 5 лет кодил на си, учить пхп. Ес-но что он его с лету выучит, в отличии от новичка.
А можно код DLL-ок ?
Зачем? В них просто вызов MessageBox и всё.
хочется на код взглянуть, так как никогда не писал dll и не понимаю где нужно вставить этот вызов
Ошибка 1 error LNK2019: ссылка на неразрешенный внешний символ "public: __thiscall injector::~injector(void)" (??1injector@@QAE@XZ) в функции __catch$_main$0
1>InitializeBuildStatus:
1> Creating "Debug\1234567890.unsuccessfulbuild" because "AlwaysCreate" was specified.
1>ClCompile:
1> main.cpp
1> injector.cpp
1> Generating Code...
1>Manifest:
1> Deleting file "Debug\1234567890.exe.embed.manifest".
1>LinkEmbedManifest:
1> 1234567890.vcxproj -> D:\1234567890\Debug\1234567890.exe
1>FinalizeBuildStatus:
1> Deleting file "Debug\1234567890.unsuccessfulbuild".
1> Touching "Debug\1234567890.lastbuildstate".
1>
1>Build succeeded.
1>
1>Time Elapsed 00:00:12.43
========== Rebuild All: 1 succeeded, 0 failed, 0 skipped ==========
А можна пример на внидрение кода ?)))
Пример чего? Там есть метод, которому передается в качестве аргумента в том числе указатель на массив байт, который будет исполнен.
@Kaimi, ну пожалуйста, я просто незнаю как) Как можна внедрить код например, ну там запись строки про автора)
Все зависит от языка, от ОС, от того, что представляет из себя GUI программы и от прочих вещей...
И это мало связано с внедрением кода.
@Kaimi, а как тогда можна внедрить код с строкой об авторе? Припустим что у меня есть приложение, и я хочу записать в него строку, что нет универсального метода для всех приложений?
Нет универсального метода.
@Kaimi, а если внедрить еще одну секцию?
Это ничего не меняет
injector& injector::operator=(const injector& inj); эта строчка вызывает ошибку не допустимое определения, я понял мне её разбить на атребуты?
не подскажешь как могу разбить? ибо я пару дней сижу только за с++ до этого qt немного сидел .
Думаю, что надо удалить фрагмент "injector::". Заменить "injector& injector::operator=(const injector& inj);" на "injector& operator=(const injector& inj);".