Top.Mail.Ru
Мастера DELPHI, Delphi programming community Титульная страница Поиск, карта сайта Написать письмо 
| Новости | Поиск | FAQ | Статьи | Книги | Новости VCL |
| Форумы ЧАТ | Орешник | KOL и MCK |
Форумы -» Основная («Начинающим»)/ Базы / WinAPI / Компоненты / Сети / Media / Игры / Corba и COM / KOL / FreePascal / .Net / Прочее / RSDN.ORG

« предыдущая ветвь | форум | следующая ветвь »

CreateRemoteThread [D6, WinXP]


Страницы:   1 2

Тимохов ©   (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


Страницы:   1 2

Наверх

Титульная страница Поиск, карта сайта Написать письмо