![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
CreateRemoteThread [D6, WinXP]
Тимохов © (2004-06-18 11:08:00)Когда читал Рихтера пропустил эту функцию. Но тут любопытство заело - не ужто можно в любом процессе создать поток. Во-первых, я понял, что не в любом - есть ограничения (правда не совсем понял какие). Во-вторых, почитав того же Рихтера понял, что в качестве потоковой функции он передает LoadLibrary, в функции инициализации которой он и делает нужные действия в другом процессе.
Насколько я понимаю точка входа в LoadLabriary определается в исходном процессе. Считается, что точка входа LoadLabriary в remote процессе будет таже, т.к. Kernel32.dll будет якобы загружена по тому же базовому адресу. Но как я понимаю никаких гарантий этого нет (Рихтер и сам говорит, что по опытуэто так и не более).
Поэтому возникло желание внедрить не LoadLibrary, а свою функцию в качестве потоковой.
Ясно, что она должна быть в адресном пространстве другого процесса. Т.е. нужно:
1. Зарезервировать и выделить памятиь в помощью VirtualAllocEx в remote процессе.
2. С помощью WriteProcessMemory в выделенной памяти сохранить функцию.
3. Вызвать CreateRemoteThread.
В связи в пунктом 2 и вопрос: как переписать функцию?Допустим, можно в текущем процессе описать функцию и затем ее скопировать в remote процесс. Но тогда поползут все адреса. К тому же непонятно как определять конец функции, т.е. сколько копировать.
:))Все, что после жирного - мои домыслы, предназначенные показать, что я сам над этим тоже думал :)) Скорее всего они абсолютно лажовые.
Тимохов (2004-06-18 16:13:00) [21]
> Игорь Шевченко © (18.06.04 16:09) [18]
Я тоже так думал, но вот Panov мне сказал, что не всегда это хорошо.
Да и интересно же. Вы же в [6] сказали что делали без LoadLibrary. Вот и мне интересно как это.
Игорь Шевченко (2004-06-18 16:09:00) [22]
> в данном коде @LStrLAsg является абсолютной ссылкой?
А какая разница ? В целевом процессе функции @LStrLAsg нет и быть не может (тем более, по нужному адресу).
Используй LoadLibrary, как советует Рихтер, и не мучайся
Тимохов (2004-06-18 15:45:00) [23]
> Вот для этого и можно бы вручную записать код для выполнения.
предасталяю какие это муки сделать на дельфи - вдруг случайно используешь функцию, которой нет в remote процессе.
Думаю, что реально сделать только знатокам асма :)
Вопрос знатокам delphi+asm
в данном коде @LStrLAsg является абсолютной ссылкой?
0045283B E88C1AFBFF call @LStrLAsg
Мне как бы нужно понять можно ли в экспортируемой функции потока допускать наличие таких конструкций или нет.
panov (2004-06-18 15:37:00) [24]>Тимохов © (18.06.04 14:45) [15]
А раз так, то зачем вообще нужно делать это (т.е. свою потоковую функцию)
Представь, что тебе надо создать отдельный поток в некотороом процессе.
Функция отока у тебя также импортируется из библиотеки.
И тут возникает проблема.
Если ты хочешь, чтобы поток продолжал работать, но DLL-ку ты хочешь выгрузить, то при попытке это сделать процесс-жертва успешно молча исчезнет(терминируется).
Вот для этого и можно бы вручную записать код для выполнения.
Тимохов (2004-06-18 14:45:00) [25]
> VMcL © (18.06.04 14:42) [14]
Функции oadLibrary() & GetProcAddress() она вроде должна (вернее вероятно) ипмортирует.
Понятно, что можно подргузить dll.
А раз так, то зачем вообще нужно делать это (т.е. свою потоковую функцию) - можно воспользоваться методом Рихтера из 22 главы 4-го издания - т.е. к качестве потоковой функции использовать LoadLibrary
VMcL (2004-06-18 14:42:00) [26]>>Тимохов © (18.06.04 14:34) [13]
А вот так и быть. Или руцями писать. Или вызывать только те функции, которые импортируются программой-жертвой из DLL. Если она импортирует LoadLibrary() & GetProcAddress(), то уже немного легче.
Тимохов (2004-06-18 14:34:00) [27]
> Игорь Шевченко © (18.06.04 13:35) [12]
Я вот, что подумал - в remote процессе не будет же никакого дельфового манагера памяти! Т.е. там не будет никаких длинный строк!
И еще в коде
0045283B E88C1AFBFF call @LStrLAsg
@LStrLAsg является абсолютной ссылкой (или нет?). Т.е. я вообще в другом процессе не смогу вызывать никакие знакомые мне функции.
А как же быть то ? :)))
Игорь Шевченко (2004-06-18 13:35:00) [28]
> Так?
Так, вроде.
> Как кстати в данном примере можно заполнить s строкой 'dima'?
Например, объявить переменную из 5-и символов и каждый символ заполнить вручную, последний - нулем.
Тимохов (2004-06-18 13:07:00) [29]
> Игорь Шевченко © (18.06.04 12:58) [10]
> Не писать такого кода, например. Тщательно изучать сгенерированный
> компилятором код.
Я так понимаю, что вы имеете в виду следующий цикл операций для получения позиционно независимого кода в дельфи:
1. Написать код в дельфи.
2. Посмотреть асм.
3. Если есть абсолютные ссылки, переписать.
4. Повторить шаг 1.
Так?
Как кстати в данном примере можно заполнить s строкой 'dima'?
Cуммирую полученные сведения:
1. Нужно написать функцию, которая будет позиционна НЕзависима (пока не понял, как это делать на дельфи, а не на asm).
2. Далее посползоваться VirtualAllocEx, WriteProcessMemorty, CreateRemoteThread.
И результат готов.
Игорь Шевченко (2004-06-18 12:58:00) [30]
> Т.е. это позиционно зависимый код. И как быть.
Не писать такого кода, например. Тщательно изучать сгенерированный компилятором код.
Тимохов (2004-06-18 12:56:00) [31]И как же надо писать, чтобы был позиционно независим?
Вот например такой код
procedure TForm1.Button6Click(Sender: TObject);
var
s: string;
begin
s := 'Dima';
end;
имеет в себе такой асм фрагмент на строке s := 'Dima'
00452833 8D45FC lea eax,[ebp-$04]
00452836 BA68284500 mov edx,$00452868
0045283B E88C1AFBFF call @LStrLAsg
Т.е. это позиционно зависимый код. И как быть.
Игорь Шевченко (2004-06-18 12:49:00) [32]Тимохов © (18.06.04 12:39)
> В дельфи разве позиционно независимый код?
Как написать
Тимохов (2004-06-18 12:39:00) [33]
> Игорь Шевченко © (18.06.04 12:36) [6]
В дельфи разве позиционно независимый код?
Игорь Шевченко (2004-06-18 12:36:00) [34]Тимохов © (18.06.04 12:18)
Для обоснования могу предложить попробовать провести следующий эксперимент: напиши программу на Delphi, укажи у нее базовый адрес в опциях линкера чуть меньше базового адреса kernel32.dll, запусти и посмотри, что тебе скажет система.
> Т.е. на дельфи не выйдет?
>
> Вы делали такое сами?
Выйдет. Делал.
Тимохов (2004-06-18 12:18:00) [35]
> Игорь Шевченко © (18.06.04 12:06) [3]
Рихтер, 4изд, 22 глава, если не ошибаюсь 549-551 стр. Вот Жефри такого не утверждает однозначно - он говорит по опыту. Вы думаете он не прав? Почему не может быть по другому адресу? Есть документальное подтверждение?
Теперь вопрос по поводу:
> А почему они (адреса) поползут, если писать функцию в позиционно-независимом
> коде (обычно на языке ассемблера) ? "Конец функции", точнее,
> ее размер, определяется одним из доступных способов, например,
> по MAP-файлу или по разнице адресов между нужной фукнцией
> и следующей за ней.
Т.е. на дельфи не выйдет?
Вы делали такое сами?
Игорь Шевченко (2004-06-18 12:09:00) [36]
> В связи в пунктом 2 и вопрос: как переписать функцию? Допустим,
> можно в текущем процессе описать функцию и затем ее скопировать
> в remote процесс. Но тогда поползут все адреса. К тому же
> непонятно как определять конец функции, т.е. сколько копировать
А почему они (адреса) поползут, если писать функцию в позиционно-независимом коде (обычно на языке ассемблера) ? "Конец функции", точнее, ее размер, определяется одним из доступных способов, например, по MAP-файлу или по разнице адресов между нужной фукнцией и следующей за ней.
Игорь Шевченко (2004-06-18 12:06:00) [37]
> Считается, что точка входа LoadLabriary в remote процессе
> будет таже, т.к. Kernel32.dll будет якобы загружена по тому
> же базовому адресу.
kernel32.dll НЕ МОЖЕТ БЫТЬ ЗАГРУЖЕН ПО ДРУГОМУ БАЗОВУМУ АДРЕСУ!!!
Тимохов (2004-06-18 12:02:00) [38]
> panov © (18.06.04 11:43) [1]
спасибо за ссылку - почитаю.
Но, как я сказал выше, мы предполагаем, что loadlibrary загружен по тому же адресу. Но это же не гарантировано...
panov (2004-06-18 11:43:00) [39]Так LoadLibrary для того и используется, чтобы в другом процессе загрузить функцию из библиотеки во внедренном в процесс потоке.
http://bugtraq.ru/library/programming/invisible.html