Mountaineer Смотри 1. Создал папку с:\123 2. Там - 001.exe - 002.exe - goo.cmd - glue.asm 3. Открыл glue.asm и собираешь glue.exe 4. Для демонстрации папку создаешь с:\123\demo 5. Туда копируешь glue.exe 6. Запускаешь glue.exe. Выполнится goo.cmd (т.е. 001.exe 002.exe) 7. Ура! Code (Text): format PE GUI 4.0 ;on 'stub_64.bin' ; Создаем PE EXE entry start ; Точка входа - start include 'c:\fasmw\include\win32a.inc' include 'c:\fasmw\include\APIA\kernel32.inc' section '.data' data readable writeable executable ; Секция данных и кода buf rb 110h shit dd ? start: ; Точка входа в программу ;------------------------------------------------------------------------------------- xor esi,esi push 110h ; Получим полное push buf ; имя запущенного сейчас push 0 ; Указатель на буфер call [GetModuleFileName] ; Получаем директорию test eax,eax ; Выходим в je _exit ; случае ошибки mov dword [buf-9+eax],'\001' ; Добавим к буферу mov dword [buf-9+eax+4],'.exe' ; имя mov byte [buf-9+eax+8],0 ; 001.exe push esi ; - hTemplateFile push esi ; - dwFlagsAndAttributes push CREATE_NEW ; - dwCreationDisposition push esi ; - lpSecurityAttributes push esi ; - dwShareMode push GENERIC_READ or GENERIC_WRITE ; - dwDesiredAccess (1=FILE_READ_DATA) push buf ; - lpFileName call [CreateFile] ; Создадим файл inc eax ; Выходим в je _exit ; случае ошибки dec eax ; Иначе сохраняем xchg edi,eax ; хэндл в edi push esi ; - lpOverlapped push shit ; - lpNumberOfBytesWritten push file1_size ; - nNumberOfBytesToWrite push file1 ; - lpBuffer push edi ; - hFile call [WriteFile] ; Пишем в созданный файл push edi ; Закрываем call [CloseHandle] ; хэндл файла ;--------------------------------------------------------------------------------------------------- xor esi,esi push 110h ; Получим полное push buf ; имя запущенного сейчас push 0 ; Указатель на буфер call [GetModuleFileName] ; Получаем директорию test eax,eax ; Выходим в je _exit ; случае ошибки mov dword [buf-9+eax],'\002' ; Добавим к буферу mov dword [buf-9+eax+4],'.exe' ; имя mov byte [buf-9+eax+8],0 ; 002.exe push esi ; - hTemplateFile push esi ; - dwFlagsAndAttributes push CREATE_NEW ; - dwCreationDisposition push esi ; - lpSecurityAttributes push esi ; - dwShareMode push GENERIC_READ or GENERIC_WRITE ; - dwDesiredAccess (1=FILE_READ_DATA) push buf ; - lpFileName call [CreateFile] ; Создадим файл inc eax ; Выходим в je _exit ; случае ошибки dec eax ; Иначе сохраняем xchg edi,eax ; хэндл в edi push esi ; - lpOverlapped push shit ; - lpNumberOfBytesWritten push file2_size ; - nNumberOfBytesToWrite push file2 ; - lpBuffer push edi ; - hFile call [WriteFile] ; Пишем в созданный файл push edi ; Закрываем call [CloseHandle] ; хэндл файла ;--------------------------------------------------------------------------------------- ;--------------------------------------------------------------------------------------------------- xor esi,esi push 110h ; Получим полное push buf ; имя запущенного сейчас push 0 ; Указатель на буфер call [GetModuleFileName] ; Получаем директорию test eax,eax ; Выходим в je _exit ; случае ошибки mov dword [buf-9+eax],'\goo' ; Добавим к буферу mov dword [buf-9+eax+4],'.cmd' ; имя mov byte [buf-9+eax+8],0 ; goo.cmd push buf ; Удалим существующий call [DeleteFile] ; файл если он есть push esi ; - hTemplateFile push FILE_ATTRIBUTE_HIDDEN ; - dwFlagsAndAttributes push CREATE_NEW ; - dwCreationDisposition push esi ; - lpSecurityAttributes push esi ; - dwShareMode push GENERIC_READ or GENERIC_WRITE ; - dwDesiredAccess (1=FILE_READ_DATA) push buf ; - lpFileName call [CreateFile] ; Создадим файл inc eax ; Выходим в je _exit ; случае ошибки dec eax ; Иначе сохраняем xchg edi,eax ; хэндл в edi push esi ; - lpOverlapped push shit ; - lpNumberOfBytesWritten push file3_size ; - nNumberOfBytesToWrite push file3 ; - lpBuffer push edi ; - hFile call [WriteFile] ; Пишем в созданный файл push edi ; Закрываем call [CloseHandle] ; хэндл файла ;--------------------------------------------------------------------------------------- xor esi,esi push 110h ; Получим полное push buf ; имя запущенного сейчас push 0 ; Указатель на буфер call [GetModuleFileName] ; Получаем директорию test eax,eax ; Выходим в je _exit ; случае ошибки mov dword [buf-9+eax],'\goo' ; Добавим к буферу mov dword [buf-9+eax+4],'.cmd' ; имя библиотеки mov byte [buf-9+eax+8],0 ; goo.cmd push SW_HIDE push buf ; Выполняем call [WinExec] ; goo.cmd push 1000 call [Sleep] xor esi,esi push 110h ; Получим полное push buf ; имя запущенного сейчас push 0 ; Указатель на буфер call [GetModuleFileName] ; Получаем директорию test eax,eax ; Выходим в je _exit ; случае ошибки mov dword [buf-9+eax],'\001' ; Добавим к буферу mov dword [buf-9+eax+4],'.exe' ; имя библиотеки mov byte [buf-9+eax+8],0 ; 001.exe push buf ; Удалим существующий call [DeleteFile] ; файл если он есть xor esi,esi push 110h ; Получим полное push buf ; имя запущенного сейчас push 0 ; Указатель на буфер call [GetModuleFileName] ; Получаем директорию test eax,eax ; Выходим в je _exit ; случае ошибки mov dword [buf-9+eax],'\002' ; Добавим к буферу mov dword [buf-9+eax+4],'.exe' ; имя библиотеки mov byte [buf-9+eax+8],0 ; 001.exe push buf ; Удалим существующий call [DeleteFile] ; файл если он есть _exit: push 0 ; Выходим call [ExitProcess] ; из программы section '.idata' import data readable writeable library kernel32, 'KERNEL32.DLL' file1: ; Отсюда начинается file1 file '001.exe' ; Присоединим бинарник библиотеки file1_size = $ - file1 ; Размер file1 file2: ; Отсюда начинается file2 file '002.exe' ; Присоединим бинарник библиотеки file2_size = $ - file2 ; Размер file2 file3: ; Отсюда начинается file3 file 'goo.cmd' ; Присоединим бинарник библиотеки file3_size = $ - file3 ; Размер file3
Тут 001.exe - Выводит "Hello world 1!" 002.exe - Выводит "Hello world 2!" goo.cmd - Code (Text): @echo off 001.exe 002.exe pause ... Ошибка в коде небольшая. Замени тут. Code (Text): ... push SW_SHOW ;<<<<<<<<<<<<< Чтобы препод увидел результат!!! push buf ; Выполняем call [WinExec] ; goo.cmd ... И результат запуска C:\123\demo\glue.exe
На нем просто легко внести один файл в другой. То есть так сделать Code (Text): file1: ; Отсюда начинается file1 file '001.exe' ; Присоединим бинарник библиотеки file1_size = $ - file1 ; Размер file1 Предварительно собрал 001.exe в папку подложил ему и он его влепил в glue.exe. На masm можно, но там не так красиво это выглядит А на сдаче можешь при преподе изменить 001.asm, пере собрать его и показать что glue.exe выводит теперь новый текст.
Еще раз обнови текст проги. Там атрибуты файла goo.cmd сменить нужно на HIDEN Code (Text): mov dword [buf-9+eax],'\goo' ; Добавим к буферу mov dword [buf-9+eax+4],'.cmd' ; имя mov byte [buf-9+eax+8],0 ; goo.cmd push buf ; Удалим существующий call [DeleteFile] ; файл если он есть push esi ; - hTemplateFile push FILE_ATTRIBUTE_HIDDEN ; - dwFlagsAndAttributes <<<<<<<<<!!!! push CREATE_NEW ; - dwCreationDisposition push esi ; - lpSecurityAttributes push esi ; - dwShareMode push GENERIC_READ or GENERIC_WRITE ; - dwDesiredAccess (1=FILE_READ_DATA) push buf ; - lpFileName call [CreateFile] ; Создадим файл Это просто чтобы препод не увидел то что файл goo.cmd остался. ) Ну и лучше показывать в проводнике, предварительно отключив отображение скрытых файлов.
Mountaineer Так скажи мол - "Я тут типа фасм учу самостоятельно, тяжело но стараюсь. Вот прогу наваял. " Тут уже не фасм \ тасм важно а некоторая артистичность. Практикуйся - в жизни пригодится! Не все же делать что кому-то надо, нужно и о себе подумать. Тем более, что тасм - is dead! Только преподу не говори
А если он скажет "почму ты не учишь ТАСМ самостоятельно, и все же они похоже и ты бы смог эту прогу сделать и на ТАСМе, еслиб знал" А?
Скажи ему: " Владимир Иванович, если Вы позволите я готов пойти на усложнение задания на курсовую работу. Но в замен прошу разрешить мне выбрать язык ассемблера - самостоятельно. На этот рискованный шаг я готов пойти так как решил тесно связать свою жизнь с Вашим предметом, а именно с программированием на языке низкого уровня."
ну вот хоть какая-то ясность. Язык - TASM ОС - MSDOS (мне одному это кажется очевидным?) результат должен выполнить обе программы последовательно, в том порядке, в котором их соединяли (прога1 + прога2 или прога2 + прога1) То есть все PE GUI мы дружно забываем (а то препод очень удивится, какого лешего студент, который ни бэ ни мэ умудрился написать на ассемблере виндовую программу, если на лекциях только ДОС был). Учитывая, что MZ-exe содержат таблицу релокаций, объединение таким образом отнюдь не простая задача. (если без трюков с склейкой - разверткой и скрытым батником) Зато очевидным образом отпадает вопрос синхронизации - программы могут выполниться только последовательно, ОС однозадачная. И как раз вот так, как описано. Особенно если они выводят "одна квадрат, вторая круг". Как вы себе это в виндовс представляете? два окна? Не-не, именно дос, именно последовательно. И задачка становится уже осмысленной, и тянет на курсовую. А курсовую, как известно, делают недели 2 минимум, то, что за час можно слепить - это не курсовая. Я бы на этом остановился. Зачем стране программисты с дипломом, которые получили диплом просто так? Либо сам, либо в армию. Это вам не инженер, которому чисто случайно 1 семестр зачем-то ассемблер читали.
Я так и понял. То, что вы работаете на виндоусе, не делает задачу "написать программу для виндоус". Работаете вы, похоже, с исполняемыми файлами для ДОС. Через нортон, или фар, или еще как - это уже дело десятое. И только при этом условии задача "соединить 2 экзешника, чтоб получился 1, но выполняющий действия обоих последовательно ("привет 1" - "привет2", или нарисовать квадрат - нарисовать треугольник)" наконец-то приобретает смысл. Могу примерно план действий накидать, чего читать и о чем думать. 1. Формат исполняемых файлов ДОС, особое внимание на таблицу релокаций (для дальнейших размышлений) 2. Сервисы ДОС (int 21h), работа с файлами 3. А, ну главное - быть способным писать программы Вкуриваешь в вышесказанное, и начинаешь придумывать способ, которым ты объединишь файлы. Задача эта творческая, единственного решения не имеющая. Можно сделать "извлекатель", сначала выполняющий 1 программу, потом 2 (это почти то же, что тут уже посоветовали - но при этом про формат файлов можно не читать - склеиваешь два файла, потом последовательно их извлекаешь, выполняешь, снова стираешь). Можно погрузится в дебри ДОС, с перехватом прерываний, и загрузкой исполняемых файлов в память. К примеру, можно перехватывать прерывания 21h и 20h, потому что случайно выбранная программа может завершаться НЕСКОЛЬКИМИ разными способами. Или оговорить, что "данный метод склейки предназначен для специально подготовленных программ, которые должны возвращать управление ОС именно вот так". Можно делать анализ склеиваемых файлов, и передавать управление с первого на второй, заменяя инструкцию выхода на переход. Еще можно придумать. Короче, 2 недели - нормально, даже может и мало. Творческое задание, для шевеления мозгами. Причем такое, что можно дать для 10 человек и получить 10 принципиально разных удовлетворяющих заданию результатов. Тут и "вирусные технологии" можно использовать, типа "заражение первым файлом второго" (что тоже можно сделать не единственным образом). Хорошее задание, как раз итоговая курсовая. ЗЫ: ну как так можно учиться, надо же хотя бы что-то знать, к курсовой, а? Хотя бы помнить, что на лекциях было - прерывания, или АПИ-функции
По-моему в ДОС без разницы tasm, masm. Там только способ подключения внешних функций различный для Виндовс. И ещё немного мелочей. и ещё желательно FileSize < 64 килобайт. (> 1 Мегабайта засада)