Здравствуйте, Stanky, Вы писали:
>> А не подскажешь как можно ее приобрести через инет, но токо чтоб >> надежный источник был. >> S>Здесь!!!
>> Может кто уже покупал ? >> S>Я у них уже достоточное количество книг купил — оплачиваю наложным платежом!!!
да наложным платежом конечно хорошо но дороговато, попробую сначала в магазине посмотреть если не будет то буду наложным покупать
_BOBAH_, ICQ# 306404574, Status:
Posted by RSDN@Home v1.1.3; Winamp:Metallica — Orion (Instrumental)
Здравствуйте, _BOBAH_, Вы писали:
_BO>да наложным платежом конечно хорошо но дороговато, попробую сначала в магазине посмотреть если не будет то буду наложным покупать
А чем тебя ebook(chm) на английском не устраивает?
Затраты между замыслом и реализацией — мерило таланта.
Здравствуйте, retn, Вы писали:
R>Здравствуйте, _BOBAH_, Вы писали:
_BO>>да наложным платежом конечно хорошо но дороговато, попробую сначала в магазине посмотреть если не будет то буду наложным покупать
R>А чем тебя ebook(chm) на английском не устраивает?
да я в принципе и не знал о существовании этой книги вообще, ну а если подскажешь где нарыть chm буду благодарен
_BOBAH_, ICQ# 306404574, Status:
Posted by RSDN@Home v1.1.3; Winamp:молчит как рыба об лед
Здравствуйте, Saintdmitry, Вы писали:
СХ>>В статье описывается один из методов внедрения DLL. Разбираются способы взаимодействия с внедренной библиотекой.
S>Меня интересует такой вопрос — а как некоторые программы(outpost firewall) узнают, что была произведенеа запись в адресное пространство другого процесса?
Читал параллельную ветвь.
Перехватывать именно WriteProcessMemory смылса великого нет, можно ведь и по другому влезть в чужое адресное пространство. Думается мне, подобные программы просто в бекграунде сканируют паямть защищаемых процессов и подсчитывают контрольные суммы. Естественно, сканировать имеет смысл только секции кода. Лучше конечно, делать это из ядра — меньше вероятность быть обманутым.
Ну а перехват "опасных" функций ( типа WriteProcessMemory) тоже конечно никто не отменял. Безопасность обеспечивается всегда комплесными мерами.
Здравствуйте, Сергей Холодилов...
Ваш способ запуска функции из собственной DLL в другом процессе оригинален, но можно предложить и другой, который, возможно, покажется проще...
Основной смысл заключается в изменении порядка действий на следующий:
1. Получаем дескриптор процесса-жертвы.
2. Получаем при помощи EnumProcessModules дескрипторы всех загруденных в нём DLL.
3. При помощи GetModuleBaseName перебираем все эти дескрипторы и находим принадлежащий модулю с именем "Kernel32.dll"
Теперь мы имеем HMODULE Kernel32.dll в другом! процессе.
4. Это единственная сомнительная операция во всей идее, но на проверку она работает... возможно потому что далее указанные функции не могут линковаться динамически...
При помощи GetProcAddress и известного HMODULE получаем адрес функций LoadLibraryA и GetProcAddress в целевом процессе процессе.
5. Теперь дело за малым... Выделить в целевом процессе память, записать в неё код, который вызовет сначала LoadLibraryA для внедряемой DLL затем GetProcAddress для нужной функции из этой DLL и передаст на неё управление.
6. Запустить этот код при помощи CreateRemoteThread
7. Для особой красоты можно передать в качестве параметра целевой функции из нашей ДЛЛ адрес и размер участка памяти, который был выделен другим процессом для её запуска, чтобы она освободила эту память.
В этом случае функция, завершив своё выполнение не имеет права исполнить команду ret так так адрес возврата указывает на освобождённую память, поэтому для выхода из этой функции надо использовать прямой вызов ExitThread, если мы хотим после завершения оставить загруженной нашу ДЛЛ или FreeLibraryAndExitThread если не хотим.
Во втором случае, наш код, отработав в другом процессе не оставляет никаких следов...
Итог... несмотря на кажущуюся сложность шага номер 5 реализация всего кода занимает 200 строчек. Из которых на пятый шаг приходится порядка сорока строк ассемблерного кода, который просто копирует нужную часть самого себя в указанное место памяти...
Способ гарантированно работает, имеется его реализация, проверена и работает на 2000 XP... Получается его использовать на всех процессах, для которых достаточно прав...
Что вы думаете по поводу такой идеи?
С уважением,
Андрей, студент программист.
Здравствуйте, Andrew.Kroupa, Вы писали:
AK>Здравствуйте, Сергей Холодилов... AK>Ваш способ запуска функции из собственной DLL в другом процессе оригинален, но можно предложить и другой, который, возможно, покажется проще...
Мне не показался
AK>Основной смысл заключается в изменении порядка действий на следующий: AK>1. Получаем дескриптор процесса-жертвы.
AK>2. Получаем при помощи EnumProcessModules дескрипторы всех загруденных в нём DLL. AK>3. При помощи GetModuleBaseName перебираем все эти дескрипторы и находим принадлежащий модулю с именем "Kernel32.dll" AK> Теперь мы имеем HMODULE Kernel32.dll в другом! процессе.
HMODULE это же просто адрес загрузки, для kernel32.dll он точно такоей же, как в своём процессе, поэтому эти пункты не нужны.
AK>4. Это единственная сомнительная операция во всей идее, но на проверку она работает... возможно потому что далее указанные функции не могут линковаться динамически... AK> При помощи GetProcAddress и известного HMODULE получаем адрес функций LoadLibraryA и GetProcAddress в целевом процессе процессе.
А зачем так сложно? Можно просто взять адреса и своего процесса, они будут такие же.
AK>5. Теперь дело за малым... Выделить в целевом процессе память, записать в неё код, который вызовет сначала LoadLibraryA для внедряемой DLL затем GetProcAddress для нужной функции из этой DLL и передаст на неё управление.
Ну, это ни чуть не проще. Кроме того, я правильно понимаю, что такой код надо писать для каждой новой функции заново? Это довольно печально..
AK>6. Запустить этот код при помощи CreateRemoteThread AK>7. Для особой красоты можно передать в качестве параметра целевой функции из нашей ДЛЛ адрес и размер участка памяти, который был выделен другим процессом для её запуска, чтобы она освободила эту память. AK> В этом случае функция, завершив своё выполнение не имеет права исполнить команду ret так так адрес возврата указывает на освобождённую память, поэтому для выхода из этой функции надо использовать прямой вызов ExitThread, если мы хотим после завершения оставить загруженной нашу ДЛЛ или FreeLibraryAndExitThread если не хотим. AK>Во втором случае, наш код, отработав в другом процессе не оставляет никаких следов...
Это значит, что функция должна быть необычная, её надо писать специально для задачи.
AK>Итог... несмотря на кажущуюся сложность шага номер 5 реализация всего кода занимает 200 строчек. Из которых на пятый шаг приходится порядка сорока строк ассемблерного кода, который просто копирует нужную часть самого себя в указанное место памяти... AK>Способ гарантированно работает, имеется его реализация, проверена и работает на 2000 XP... Получается его использовать на всех процессах, для которых достаточно прав... AK>Что вы думаете по поводу такой идеи?
Ну конечно она работает, но сказать, что она проще, у меня язык не повернётся Я вообще достаточно осторожно отношусь к автогенерации ассемблерного кода, хотя и использовал её в другой статье (http://www.rsdn.ru/Forum/Message.aspx?mid=875887#875887
). Из недостатков — ну, например, исполнение кода в памяти может быть блокировано антивирусом, как очень подозрительное действие. И на других процессорах не будет работать, хотя, конечно, другие уже почти не используются в Windows.
AK>>Ваш способ запуска функции из собственной DLL в другом процессе оригинален, но можно предложить и другой, который, возможно, покажется проще...
SH>Мне не показался
Наверное вы правы...
SH>HMODULE это же просто адрес загрузки, для kernel32.dll он точно такоей же, как в своём процессе, поэтому эти пункты не нужны.
Вот этого до прочтения вашей статьи я не знал...
SH>А зачем так сложно? Можно просто взять адреса и своего процесса, они будут такие же.
И следовательно этого тоже не знал...
И в этом собственно и заключался основной вопрос
Спасибо...
Теперь код можно сократить...
AK>>5. Теперь дело за малым... Выделить в целевом процессе память, записать в неё код, который вызовет сначала LoadLibraryA для внедряемой DLL затем GetProcAddress для нужной функции из этой DLL и передаст на неё управление.
SH>Ну, это ни чуть не проще. Кроме того, я правильно понимаю, что такой код надо писать для каждой новой функции заново? Это довольно печально..
Нет... Не надо... код можно не менять... Если поместить в процесс вместе с фиксированным кодом набор параметров (раз уж мы итак пишем в память процесса) и при создании потока передать указатель на них в качестве параметра CreateRemoteThread. Избавиться от создания фунуций в специальном виде тоже можно... AK>>6. Запустить этот код при помощи CreateRemoteThread AK>>7. Для особой красоты можно передать в качестве параметра целевой функции из нашей ДЛЛ адрес и размер участка памяти, который был выделен другим процессом для её запуска, чтобы она освободила эту память. AK>> В этом случае функция, завершив своё выполнение не имеет права исполнить команду ret так так адрес возврата указывает на освобождённую память, поэтому для выхода из этой функции надо использовать прямой вызов ExitThread, если мы хотим после завершения оставить загруженной нашу ДЛЛ или FreeLibraryAndExitThread если не хотим. AK>>Во втором случае, наш код, отработав в другом процессе не оставляет никаких следов...
SH>Это значит, что функция должна быть необычная, её надо писать специально для задачи.
Нет... это тоже обходится передачей параметров в другой процесс.
Просто эта функция вызывает третью, имя которой тоже передаётся... из той-же или из другой! ДЛЛ... и сама по себе вообще не меняется...
SH>Ну конечно она работает, но сказать, что она проще, у меня язык не повернётся Я вообще достаточно осторожно отношусь к автогенерации ассемблерного кода, хотя и использовал её в другой статье (http://www.rsdn.ru/Forum/Message.aspx?mid=875887#875887
).
Я не использовал автогенерацию ассемблерного кода... так как он не меняется вообще в этом нет необходимости. Просто ассемблерная вставка, первые несколько команд которой копируют все последующие (зная их адрес на момент исполнения) в указанную память, длина определяется как разница смещений.
SH>Из недостатков — ну, например, исполнение кода в памяти может быть блокировано антивирусом, как очень подозрительное действие.
С этим не поспоришь, но при использовании следующего...
Перед исполнением у страницы, в которую мы только что записали код надо изменить разрешение на только Чтение и Исполнение... А также можно закрыть текущий и открыть новый хэндл процесса непосредственно между изменением аттрибутов страницы и запуском удалнного трэда...
(хотя может эти операции и ничего не дают) работает... при включённых Касперском двух версий, ДрВебе, Нортоне... но нет гарантии что будет работать с другими версиями\антивирусами\системами.... это да... SH>И на других процессорах не будет работать, хотя, конечно, другие уже почти не используются в Windows.
Не будет... это правда... ассемблерная вставка написана на асме X86...
Но есть плюс... возможность передать в новосозданный трэд не только 4 байта, но и (опционально) в случае если эти 4 байта есть указатель, кусок памяти определённой длины на которые он указывает (естественно изменив значение для копии этого участка в другом пройессе)...
Здравствуйте, Andrew.Kroupa, Вы писали:
AK>Но есть плюс... возможность передать в новосозданный трэд не только 4 байта, но и (опционально) в случае если эти 4 байта есть указатель, кусок памяти определённой длины на которые он указывает (естественно изменив значение для копии этого участка в другом пройессе)...
Это и так можно, для этого не обязательно копировать в другой процесс код и запускать его. Достаточно выделить память, скопировать данные и передать указатель.
Делай что должно, и будь что будет
Re: Ошибка в коде примера
От:
Аноним
Дата:
12.11.05 19:45
Оценка:
Доброго времени суток.
Спасибо за интересную статью.
Однако Ваш пример не работает. Опечатка: other_process.cpp:396.
Вместо
BOOL VirtualFreeEx(
HANDLE hProcess,
LPVOID lpAddress,
SIZE_T dwSize,
DWORD dwFreeType
);
...
dwFreeType
...
MEM_RELEASE
0x8000 Releases the specified region of pages. After the operation, the pages are in the free state.
If you specify this value, dwSize must be 0 (zero), and lpAddress must point to the base address returned by the VirtualAllocEx function when the region is reserved. The function fails if either of these conditions is not met.
При передаче m_size, VirtualFreeEx (WinXP SP2) возвращает содержательную ошибку
87 The parameter is incorrect. ERROR_INVALID_PARAMETER
VirtualFreeEx(m_hProcess, m_buffer, 0, MEM_RELEASE); работает нормально.