![]() |
![]() |
Крокодил Гена 21.07.2004 - 02:16 |
Нужно написать маленькую прогу на дельфи. Задача такая: чтоб при нажатии на кнопку прога меняла значение по адресу в памяти по адресу 004С3160. Надо поменять значение которое храниться по этому адресу с 250 на 120. Однако этот адрес памяти используется другим приложением. Подскажите что надо вставить в это место: procedure TForm1.Button1Click(Sender: TObject); begin end; Я в программировании разбираюсь плохо, но надо очень 8( Огромная просьба помочь. Писал даже на www.delphikingdom.ru. Никто не помог, все молчат. Прога должна работать по принципу O'Matic(а), но адрес известен и при каждом новом запуске он одинаковый. |
Delphist 1 - 21.07.2004 - 10:45 |
Уважаемый Крокодил! Я сильно Вас разочарую, но! Дело в том, что КАЖДАЯ запущенная программа работает в СВОЕМ адресном пространстве, и соответственно имеет свой собственный адрес 004С3160. Это как в комедии "С легким паром" - улица Строителей есть в каждом городе, но живут на ней разные люди. Поэтому написав procedure TForm1.Button1Click(Sender: TObject); var p: PBYTE; begin p = Ptr($004C3160); p^ = 120; end; Вы ничего не добьетесь - это изменит память ЭТОЙ программы, а не другой. Тут нужно применять cross-process subclassing с внедрением DLL, но эта тема - не для начинающего. |
archimag 2 - 21.07.2004 - 11:03 |
Адрес то физический или виртуальный? Какая операционная система? Если это адресс из чужого виртуального адресого пространства, то делаем следущее: загружаем в адресное пространство чужого процесса свой dll-моудуль и создаём там свой поток, который сразу переводим в режим ожидания с помощью какого-нибудь объекта синхронизации (например, мьютекса). В обработчике Button1Click переводим, используемый объект синхронизации в незатяное состояние, наш поток просыпается, изменяет 250 на 120 и, если необходимо, снова ждёт. Алгоритм примерно такой. Более подробную информацию смотри у Рихтера ("Windows для профессионалов") или ищи в нете инфу о внедрении dll. В принципе, есть ещё вариант работы в режиме ядра с обращением к диспетчеру страниц - но это значительно сложнее. Обрати внимание, что Windwos (особенно семейство NT)- специально разработано так, чтобы исключить ситуацию, когда один процесс пишет по адресам другого :-) |
tvv 3 - 21.07.2004 - 11:55 |
Есть такой утиль ArtMoney это типа для взлома игрушек, так он так и работает: выбираешь процесс, находишь в нем нужные адреса (для этого там много способов), и меняешь значения по ним. Так вот для твоей цели сгодится. Смотри здесь http://www.artmoney.ru/rus.htm тебе подойдет и бесплатная версия. Хотя решение не сосвсем стандартное. |
Delphist 4 - 21.07.2004 - 18:27 | Вспомнил, на Королевстве Дельфи пример есть - Memory Inspector |
Старый Добрый UE 5 - 22.07.2004 - 14:57 | WriteProcessMemory() ? |
Sabrian 6 - 23.07.2004 - 14:56 |
var hproc:hhandle; buffer,writen:integer; begin //получить handle нужного процесса hproc:=OpenProcess(PROCESS_ALL_ACCESS,True,handle); buffer:=120; WriteProcessMemory(hproc,$004С3160,buffer,4,writen); end; |
Sabrian 7 - 23.07.2004 - 15:07 |
Верхний код не совсем верен (он по MSDN писан). Прототип Windows.WriteMemory отличается от того каким я его полагал. Верно будет вот-так: var process,hproc:cardinal; buffer,writen:cardinal; begin hproc:=OpenProcess(PROCESS_ALL_ACCESS,true,process); buffer:=120; WriteProcessMemory(hproc,ptr($004C3160),@buffer,4,writen); end; Я не знаю будет ли это работать в NT семействе. |
archimag 8 - 23.07.2004 - 15:29 | 7: не будет :-) |
archimag 9 - 23.07.2004 - 16:26 | Беру свои слова обратно. WriteProcessMemory можно писать что угодно и куда угодно, за исключением закрытого 64КБ раздела в 2000(и страше) - который начинается с 0х7FFF000. Техника с внедрением dll обычно нужна для определения куда писать, ну а если уже узвестно куда писать - без проблем... |
Sabrian 10 - 26.07.2004 - 11:24 |
Вообще говоря, применяя dll можно читать и писать пямать на порядок быстрее (не нужны вызовы, копирование памяти и.т.д) |
Крокодил Гена 11 - 01.08.2004 - 15:32 |
Всем спасибо, особенно Sabrianu. Менять значение по определенному адресу получается, но возникла другая проблемма: чтоб его менять необходимо указывать ид процесса, я его выуживаю с помощью армини там есть "информация о процессе", где отражается его ид, но он при каждом новом запуске другой. Подскажите как с этим бороться. Вот используемый мною листинг: var hproc:cardinal; buffer,writen:cardinal; const PatchAddr: pointer = Pointer($004С3160); process: cardinal; = cardinal($FFF98467); //ид процесса begin hproc:=OpenProcess(PROCESS_VM_WRITE,false,process); buffer:=120; WriteProcessMemory(hproc,PatchAddr,@buffer,4,writen); end |
Крокодил Гена 12 - 01.08.2004 - 15:37 | Имя другого приложения в памяти которого необходимо менять значение - известно. |
Крокодил Гена 13 - 01.08.2004 - 15:39 | Как задать ид используя имя файла? |
Старый Добрый UE 14 - 02.08.2004 - 00:43 |
Посмотри в сторону ToolHelp Api: CreateToolhelp32Snapshot и т.д. Ты получаешь список процессов, и находишь нужный, сравнивая имя модуля каждого процесса с нужным тебе. |
Sabrian 15 - 03.08.2004 - 18:45 |
var h:integer; p:tagProcessEntry32; b:boolean; begin h:=CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS,0); b:=process32First(h,p); while b do begin //сдесь смотри p b:=Process32Next(h,p); end; end; Не забудь добавить в Uses модуль tlhelp32 У структуры tagProcessEntry32 есть поля szExeName и th32ProcessID. И скажи спасибо UE, иначе я бы не знал бы где мне искать информацию, и наверное тогда я и не стал бы. |