Через WriteProcessMemory туда запихнуть тело. Правда, я очень смутно представляю, что при этом случится с переменными, но что-нибудь простое сделать, наверное, будет можно.
> 1.Есть HANDLE процесса > 2.Есть указатель void * на данные в этом процессе, > полученный из VirtualAllocEx, в эти данные записана своя > функция > > Как получить FARPROC дальний указатель на эти данные(на мою > функцию) , такой же какой возвращает GetProcAddress для > экспортируемых функций??? > > ???
а вобщё в windows.h
есть такая строчька
#define HANDLE void*
и ещё такие
#define FARPROC __stdcall
просто привести к нему void*: (farproc)pdata07.03.06 20:05 Автор: dl <Dmitry Leonov>
как так привести?
VirtualAllocEx возвращает указатель на выделенную память в контексте указанного процесса(в его адресном пространстве), т.е. он виртуальный. Если просто привести его к FARPROC, он будет указывать хрен знает куда...
Или я что-то не понимаю?
это уже другой вопрос :)07.03.06 22:15 Автор: dl <Dmitry Leonov> Отредактировано 07.03.06 22:18 Количество правок: 1
Смысла в таком приведении вообще нет, если оно нужно для последующего вызова функции, то даже если каким-то чудом удастся получить эти данные, функция все равно будет выполняться в контексте текущего процесса.
как ты сам сказал..07.03.06 21:03 Автор: Killer{R} <Dmitry> Статус: Elderman
Он будет указывать на выделенную память в контексте того процесса. В контексте ТВОЕГО процесса этой памяти не будет. Вообще. Ни по какому адресу. Потому напрямую ты ту функцию никак не вызовешь. Проще всего - CreateRemoteThread. Но я очень сильно подозреваю что она все равно там работать не будет.
почему бы и нет07.03.06 22:13 Автор: dl <Dmitry Leonov> Отредактировано 07.03.06 22:16 Количество правок: 1
Через WriteProcessMemory туда запихнуть тело. Правда, я очень смутно представляю, что при этом случится с переменными, но что-нибудь простое сделать, наверное, будет можно.
почему бы и да07.03.06 22:34 Автор: Kirka Статус: Незарегистрированный пользователь
Мне собсно нужно вычислить указатель, который записывать в таблицу импорта(я делаю перехват winapi)
Функция-заменитель внедрена в перехватываемый процесс при помощи VirtualAllocEx, WriteProcessMemory(кстати CreateRemoteThread с ней прекрасно работает)
Так вот какой адрес мне записать в таблицу импорта этого перехватываемого процесса вместо оригинального?
Я так понимаю там делается прыжок на ФИЗИЧЕСКИЙ адрес памяти?
Или обычный прыжок на указатель в адресном пространстве данного процесса? Если так, то просто записать в таблицу импорта адрес возвращенный из VirtualAllocEx (с кастом (FARPROC)?
Валидный в адресном пространстве того процесса. Собсно это и есть нужный тебе указатель. По поводу "прыжков на физический адрес" рекомендую почитать доки по защищенному режиму i386 и архитектуре современных ОС. Хотя бы в гугле поискать это. Кратко - никаких физических адресов. Все совсем по другому.
всё, я уже разобрался :)07.03.06 22:43 Автор: Kirka Статус: Незарегистрированный пользователь
> Валидный в адресном пространстве того процесса. Собсно это > и есть нужный тебе указатель. По поводу "прыжков на > физический адрес" рекомендую почитать доки по защищенному > режиму i386 и архитектуре современных ОС. Хотя бы в гугле > поискать это. Кратко - никаких физических адресов. Все > совсем по другому.
всё, я уже разобрался :)
спасибо за помощь, просто я внедрял и запускал поток в другом процесее, передавая ему адреса функций из библиотек kernel32 и user32, вычисляя их при помощи GetProcAddress(вычисление происходило в своём процессе!). Поток их без проблем вызывал.
Умные люди мне объяснили что это происходило изза того, что в виндосе одна и та же библиотека редко загружается повторно, и поток смог их вызывать только потому, что бибилиотеки для обоих процессов какбы оказались "в одном и том же месте"
Либо умные люди тебе неправильно объяснили либо ты...07.03.06 22:47 Автор: Killer{R} <Dmitry> Статус: Elderman Отредактировано 07.03.06 22:48 Количество правок: 1
> всё, я уже разобрался :) > спасибо за помощь, просто я внедрял и запускал поток в > другом процесее, передавая ему адреса функций из библиотек > kernel32 и user32, вычисляя их при помощи > GetProcAddress(вычисление происходило в своём процессе!). > Поток их без проблем вызывал. > Умные люди мне объяснили что это происходило изза того, что > в виндосе одна и та же библиотека редко загружается > повторно, и поток смог их вызывать только потому, что > бибилиотеки для обоих процессов какбы оказались "в одном и > том же месте" Либо умные люди тебе неправильно объяснили либо ты неправильно понял. То что "длл не загружается повторно" - в смысле то что промапленная в разные процессы copy-on-write секция не занимает в свопе/физической памяти отдельные страницы до модификации вовсе не означает то что эта секция (образ длл) промапится по одним и тем же адресам в разных процессах.
Но так уж устроена винда что основные длл всегда оказываются на одних и тех же адресах. Просто они обычно первыми грузятся и адреса эти свободны на тот момент. А они там указаны в РЕ заголовках длл как preferred,
извиняюсь за оффтоп, еще один вопрос мучает :)07.03.06 22:56 Автор: Kirka Статус: Незарегистрированный пользователь
извиняюсь за оффтоп, еще один вопрос мучает :)
функции WriteProcessMemory и ReadProcessMemory используют проецируемые файлы для копирования данных из памяти одного процесса в другой, или прямо так из "физической памяти" и читают без посредников?
Я где-то у Рихетра читал вроде бы все функции обмена данными между процессами работают через mapped files, то есть без них никак не получится?
А что значит напрямую?07.03.06 23:05 Автор: Killer{R} <Dmitry> Статус: Elderman Отредактировано 07.03.06 23:06 Количество правок: 1
В общем случае адреса одного процесса не видны другому никакими разрешенными командами процессора. Я очень не уверен насчет создания секции для чтения памяти процесса через ReadProcessMemory. Слишком это расточительно имхо былобы. Ядро может доступится к памяти любых процессов. Но естественно некий общий функционал они юзают. Имя ему- memory manager :)
напрямую - значит без посредников
тоесть ReadProcessMemory(proc, procaddr, buff, size)
работает так: [память процесса proc] -> [buff в вызывающем процессе]
или так: [память процесса proc] -> [буфер-посредник(напр. map-file)] -> [buff в вызывающем процессе]
> напрямую - значит без посредников > тоесть ReadProcessMemory(proc, procaddr, buff, size) > работает так: [память процесса proc] -> [buff в > вызывающем процессе] > или так: [память процесса proc] -> > [буфер-посредник(напр. map-file)] -> [buff в вызывающем > процессе] > > ???
Специально пошел глянул сперты сырцы винды. ReadProcessMemory вызывает ядро. Передает ему хэндлы на 2 процесса, 2 адреса и 2 размера. Итого - 6 32хбитных (на x86) переменных. Ядро делает валидацию хэндлов, адресов и далее исходя из размера буфера:
Если буфер небольшой аттачится к одному процессу, копирует в nonpaged буфер из его адресного пространства кусок в себя, затем аттачится к другому и пишет в него это дело.
Если буфер больше определенного значения ядро аттачится к одному из процессов процессу лочит виртуальные адреса в физические (кстати если физ. памяти мало а хочется скопировать много то по идее это дело обломается), мапит нужные физически адреса себе в виртуальные адреса в пространстве ядра, затем аттачится назад и делает банальный memcpy на эти адреса.
хм.. у меня буфер не большой, значит большой разницы по...07.03.06 23:49 Автор: Kirka Статус: Незарегистрированный пользователь
> это у тебя исходники kernel32 ? > круто, а не скажешь где эти сорсы скачать мона? kernel32 - это не ядро.
А скачал в свое время в сети едонки. Но тебе нужно читать доки.
Что касается скорости - обмен через секцию будет самым быстрым. Медленным он был бы если бы при каждом вызове обмена пересоздавалась секция. Но если ты создашь секцию нужного размера и будешь через нее потом гонять толпу данных - быстрее ничего не придумаешь. Read/Write ProcessMemory будут медленнее тк они дергают ядро.
ты имеешь в виду секции - маппед файлы?08.03.06 00:00 Автор: Kirka Статус: Незарегистрированный пользователь
> > это у тебя исходники kernel32 ? > > круто, а не скажешь где эти сорсы скачать мона? > kernel32 - это не ядро. > А скачал в свое время в сети едонки. Но тебе нужно читать > доки. > Что касается скорости - обмен через секцию будет самым > быстрым. Медленным он был бы если бы при каждом вызове > обмена пересоздавалась секция. Но если ты создашь секцию > нужного размера и будешь через нее потом гонять толпу > данных - быстрее ничего не придумаешь. Read/Write > ProcessMemory будут медленнее тк они дергают ядро.
ты имеешь в виду секции - маппед файлы?
или что за секции?