СветКа
Интересующийся
Offline
|
|
« : 18-04-2011 10:21 » |
|
Есть программа на FASM, в которой 2 секции кода, причём в каждой секции прописаны переменные. Как структуру такой программы можно перевести на MASM 32? В MASMе не допускается же в секции кода чередование команд и данных. При создании для MASM общей для всех переменных секции .data программа компилируется, но при запуске выскакивает окно, что обнаружена ошибка и приложение будет закрыто. Что делать, подскажите. Вот упрощённая структура программы:
format PE GUI 4.0 entry start section '.A' code executable readable writeable ; Код секции A ; Данные типа A dd 0
section '.AAA' code executable readable writeable ; Данные типа AAA dd 0 start: ; Код секции AAA invoke ExitProcess, 0
|
|
|
Записан
|
|
|
|
Dimka
Деятель
Команда клуба
Offline
Пол:
|
|
« Ответ #1 : 18-04-2011 11:50 » |
|
СветКа, если оперировать понятиями сегментов (страниц памяти), то, что ты говоришь, смысл имеет. Если речь идёт о непрерывном адресном пространстве, то данные с кодом перемешиваются несложно - достаточно сделать jmp с конца участка кода на метку в начале следующего участка кода, "перепрыгивая" данные, избегая попытки их выполнения, как кода.
Что именно ты пишешь, под какой процессор и под какой режим работы процессора?
|
|
|
Записан
|
Программировать - значит понимать (К. Нюгард) Невывернутое лучше, чем вправленное (М. Аврелий) Многие готовы скорее умереть, чем подумать (Б. Рассел)
|
|
|
СветКа
Интересующийся
Offline
|
|
« Ответ #2 : 18-04-2011 14:51 » |
|
Под .386 процессор и выше, только не пишу, а перевожу с одного компилятора на другой. В программе используются обычные функции WinAPI. Правилен ли мой перевод: с FASM: mov eax, [FindWindow] ;FindWindow - обычная функция WinAPI mov [MyVariable], eax ;где MyVariable dd 0 на MASM32: mov eax, FindWindow mov MyVariable, eax
И вот эти функции правильно ли перевела? Меня интересует правильность написания. На мой взгляд всё должно быть правильным. В них: ProcHandle dd 0 BaseAddr dd 0 ThrID dd 0 pr_en.th32ProcessID – поле структуры CodeSize equ B-A CodeStart – метка начала секции section '.A' code executable readable writeable С invoke OpenProcess, PROCESS_CREATE_THREAD or PROCESS_VM_OPERATION or PROCESS_VM_WRITE, FALSE, [pr_en.th32ProcessID] на invoke OpenProcess, PROCESS_CREATE_THREAD or PROCESS_VM_OPERATION or PROCESS_VM_WRITE, FALSE, proc_entry.th32ProcessID С invoke VirtualAllocEx, [ProcHandle], 0, CodeSize,\ MEM_COMMIT+MEM_RESERVE, PAGE_EXECUTE_READWRITE на invoke VirtualAllocEx, ProcHandle, 0, offset CodeSize,\ MEM_COMMIT+MEM_RESERVE, PAGE_EXECUTE_READWRITE
С invoke WriteProcessMemory, [ProcHandle], eax, CodeStart,\ RemoteCodeSize, Writed на invoke WriteProcessMemory, ProcHandle, eax, offset CodeStart,\ RemoteCodeSize, offset Writed С invoke CreateRemoteThread, [ProcHandle], 0, 0, [BaseAddr],\ 0, 0, ThrID на invoke CreateRemoteThread, ProcHandle, 0, 0, BaseAddr,\ 0, 0, offset ThrID
|
|
|
Записан
|
|
|
|
Dimka
Деятель
Команда клуба
Offline
Пол:
|
|
« Ответ #3 : 19-04-2011 06:17 » |
|
СветКа, если ты пишешь под x86 для Windows, то задача в Windows исполняется в непрерывном виртуальном адресном пространстве размером 2 Гб. Поэтому обход участков данных при исполнении можно делать через jmp. Что касается "правильно ли ты пишешь"? Ну дак запусти и посмотри, работает ли программа или нет Зачем об этом спрашивать тут? Тут спрашивают, если что-то не работает, и говорят, какие ошибки возникли.
|
|
|
Записан
|
Программировать - значит понимать (К. Нюгард) Невывернутое лучше, чем вправленное (М. Аврелий) Многие готовы скорее умереть, чем подумать (Б. Рассел)
|
|
|
СветКа
Интересующийся
Offline
|
|
« Ответ #4 : 19-04-2011 10:47 » |
|
Под FASM программа как часы работает, под MASM программа компилируется без ошибок, но не запускается, вылазит окно с предупреждением. Я же не знаю точно, почему оно вылазит. Думаю, что в первую очередь из-за неправильной переделанной структуры программы. Непонятно, создавать .data или мешать код с данными? Смотри, вот отрывок из FASM: section '.A' code executable readable writeable ; Код секции A call [ebp+pFindWindow] pFindWindow dd 0
section '.AAA' code executable readable writeable start: ;Код секции AAA mov eax, [FindWindow] mov [pFindWindow], eax ; следующие команды
И как прыгнуть из кода в одной секции к переменной в секции A? Если так (для МАСМ): .code A ; Код секции A mov pFindWindow, eax call [ebp+pFindWindow] pFindWindow dd 0
.code B start: ;Код секции mov eax, FindWindow jmp pFindWindow ;прыжок в секцию A ; следующие команды то команда mov pFindWindow, eax оказывается не в той секции. Это нормально? К тому же нужно сделать возврат на следующую команду второй секции кода. Таких переменных как pFindWindow несколько.
|
|
|
Записан
|
|
|
|
Dimka
Деятель
Команда клуба
Offline
Пол:
|
|
« Ответ #5 : 19-04-2011 11:59 » |
|
СветКа, я не знаю FASM и я не знаю, что у него означает множество секций кода. Программа, работающая в один поток, выполняется последовательно вне зависимости от всяких секций. Зачем тебе все эти секции? Тебе код нужен работающий. Для этого достаточно иметь одну секцию .data с данными и одну секцию .code с инструкциями.
|
|
|
Записан
|
Программировать - значит понимать (К. Нюгард) Невывернутое лучше, чем вправленное (М. Аврелий) Многие готовы скорее умереть, чем подумать (Б. Рассел)
|
|
|
СветКа
Интересующийся
Offline
|
|
« Ответ #6 : 26-04-2011 13:18 » |
|
Вот программа перезагрузки компьютера. Код и данные в одной секции. Что в ней неправильного? Если переменные перенести в .data, то программа работает. А если код и данные вместе, то компилируется, но не запускается. .386 .model flat, stdcall option casemap :none include \MASM32\INCLUDE\windows.inc include \MASM32\INCLUDE\kernel32.inc include \MASM32\INCLUDE\shell32.inc include \MASM32\INCLUDE\masm32.inc include \MASM32\include\user32.inc include \MASM32\include\advapi32.inc includelib \MASM32\LIB\kernel32.lib includelib \MASM32\LIB\shell32.lib includelib \MASM32\LIB\masm32.lib includelib \MASM32\LIB\user32.lib includelib \MASM32\LIB\advapi32.lib ; ####################### .code start: jmp x
szShut db 'SeShutdownPrivilege',0 tkp TOKEN_PRIVILEGES <> h_token dd ?
x: xor ebx,ebx xor eax,eax mov al,1 inc eax or eax,EWX_FORCE mov esi,eax invoke GetVersion test eax,80000000h jnz Win9x invoke GetCurrentProcess invoke OpenProcessToken,eax,28h,offset h_token invoke LookupPrivilegeValue,ebx,offset szShut,offset tkp.Privileges[0].Luid mov tkp.PrivilegeCount,1 mov tkp.Privileges[0].Attributes,2 invoke AdjustTokenPrivileges,h_token,ebx,offset tkp,ebx,ebx,ebx Win9x: invoke ExitWindowsEx,esi,0FFFFh invoke ExitProcess, 0 end start
|
|
« Последнее редактирование: 08-07-2011 13:57 от Джон »
|
Записан
|
|
|
|
Dimka
Деятель
Команда клуба
Offline
Пол:
|
|
« Ответ #7 : 26-04-2011 17:31 » |
|
СветКа, и должно быть в data, если ты собираешь exe-файл.
|
|
|
Записан
|
Программировать - значит понимать (К. Нюгард) Невывернутое лучше, чем вправленное (М. Аврелий) Многие готовы скорее умереть, чем подумать (Б. Рассел)
|
|
|
СветКа
Интересующийся
Offline
|
|
« Ответ #8 : 26-04-2011 21:27 » |
|
Dimka, я всё понимаю, но в моём случае, мне не нужно, чтобы данные находились в .data, а нужно, чтобы обязательно в .code. Вот работающая программа вывода обычного MessageBox’а, в которой и код и данные расположены вместе в одной секции. Вот почему эта программа работает, а предыдущая нет, хотя если в предыдущей программе перезагрузки компа, данные разместить в .data, то работает. .586 option casemap:none .model flat,stdcall include \masm32\include\windows.inc include \masm32\include\user32.inc include \masm32\include\kernel32.inc includelib \masm32\lib\user32.lib includelib \masm32\lib\kernel32.lib .code start: jmp x Title1 db "Пример",0 Text1 db "Здесь код и данные находятся в одной секции - .code",0 x: invoke MessageBox, NULL,addr Text1, addr Title1, MB_OK invoke ExitProcess,0 end start
|
|
« Последнее редактирование: 08-07-2011 13:58 от Джон »
|
Записан
|
|
|
|
darkelf
Молодой специалист
Offline
|
|
« Ответ #9 : 27-04-2011 05:17 » |
|
СветКа, последний пример вообще не пишет в сегмент кода, а читать оттуда, насколько я помню, не запрещено, так-что оно работает, а предыдущая программа - пытается писать, с соответствующими последствиями. В общем, разнесите код и данные как Вам советовали и будет Вам счастье.
|
|
« Последнее редактирование: 27-04-2011 07:18 от darkelf »
|
Записан
|
|
|
|
СветКа
Интересующийся
Offline
|
|
« Ответ #10 : 27-04-2011 16:14 » |
|
последний пример вообще не пишет в сегмент кода Точно! Спасибо за подсказку! Секция в FASM имеет атрибут writeable, т.е. туда можно записывать. Прогу нужно значит в MASM’е линковать с помощью опции /section:.text,RWE, вот таким образом: link /SUBSYSTEM:WINDOWS /LIBPATH:d:\masm32\lib /SECTION:.text,RWE MyProg.obj. Но даже и таким образом у меня компилируется, но не запускается. «В общем, разнесите код и данные как Вам советовали». Вы не поняли сути. У меня же ЕСТЬ эта же самая программа, причём работающая, с разнесёнными кодом и данными. Зачем мне дубликат? Просто я тренируюсь изменять программы с раздельным кодом и данными таким образом, чтобы данные были в коде. В FASM это получается, а вот для MASM – проблема. Добавлено через 71 день, 20 часов, 22 минуты и 39 секунд:Разобралась! Давно разобралась, но если кому интересно, напишу свои ошибки. 1. В программе перезагрузки компа, где код и данные в одной секции, нужно TokenPrivs TOKEN_PRIVILEGES <> выровнять по двойному слову, т.е. перед TokenPrivs TOKEN_PRIVILEGES <> вставить align dword. Получится вот так: .code start: jmp x szShut db 'SeShutdownPrivilege',0 align dword tkp TOKEN_PRIVILEGES <> h_token dd ? x: ... 2. В другой программе, где переменные типа Perem dd ? находятся в секции кода A, а заполняются в секции кода B командами типа mov Perem,12345678, то компилировать нужно: link /SUBSYSTEM:WINDOWS /SECTION:A,RWE /RELEASE /VERSION:4.0 Programma.obj если в обеих секциях находятся переменные, которые заполняются, то link /SUBSYSTEM:WINDOWS /LIBPATH:d:\masm32\lib /SECTION:A,RWE /SECTION:B,RWE Programma.obj Вроде просто, а когда не знаешь, мало не покажется))) 3. Ни фига адреса функций API в МАСМ не заносятся как в ФАСМ, типа: mov eax, [FindWindow] mov [pFindWindowA], eax при условии, что FindWindow dd ? в секции кода. МАСМ делает это по-другому, через jmp))) В общем тема закрыта! Добавлено через 17 часов, 43 минуты и 10 секунд:Модераторы, зачем сдваивать два разных сообщения: одно апрельское, другое июльское?!
|
|
« Последнее редактирование: 09-07-2011 06:20 от СветКа »
|
Записан
|
|
|
|
RXL
Технический
Администратор
Offline
Пол:
|
|
« Ответ #11 : 09-07-2011 08:21 » |
|
Бывает... Ничего, в общем-то, страшного, но мы над этим подумаем. Возможно стоит ограничиться склейкой постов, скажем, не старше двух недель.
|
|
« Последнее редактирование: 09-07-2011 08:29 от RXL »
|
Записан
|
... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
|
|
|
Dimka
Деятель
Команда клуба
Offline
Пол:
|
|
« Ответ #12 : 09-07-2011 11:55 » |
|
RXL, думаю, не надо. Цель склейки - минимизация количества постов. А сообщение о том, когда добавлена новая часть, присутствует. Вопрос лишь в статусе темы (значок NEW) - сохраняется ли он в случае склейки?
|
|
|
Записан
|
Программировать - значит понимать (К. Нюгард) Невывернутое лучше, чем вправленное (М. Аврелий) Многие готовы скорее умереть, чем подумать (Б. Рассел)
|
|
|
RXL
Технический
Администратор
Offline
Пол:
|
|
« Ответ #13 : 09-07-2011 13:15 » |
|
Не уверен, т.к. фактически новый пост удаляется.
|
|
|
Записан
|
... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
|
|
|
|