Всем здрасте! Помогите кто может перевести сей код с синтаксиса FASM на MASM Код (Text): FORMAT PE GUI 4.0 on 'null' entry start FILE_NAME equ 'file.exe' include 'c:\fasmw\include\win32a.inc' section '.main' code readable writable executable data import library kernel32,'KERNEL32.DLL',\ user32,'USER32.DLL' include 'c:\fasmw\include\api\user32.inc' include 'c:\fasmw\include\api\kernel32.inc' end data macro xinvoke proc,[arg] { common if ~ arg eq reverse pushd arg common end if call [ebx+_#proc-_delta] } proc start locals pVA dd ? shit dd ? endl call some_file mov esi, fflile add esi,[esi+3ch] ;peheader mov ecx,[esi+34h] ;image base mov edx,[esi+50h] ;image size lea edi,[edx+ecx] ;imagebase+imagesize mov esi,alloced_size add esi,10000h and esi,0ffff0000h ;округлить значения. @@: add edi,10000h invoke VirtualAlloc,edi,esi,MEM_RESERVE+MEM_COMMIT,PAGE_EXECUTE_READWRITE ;ищем новое место где-нибудь за imagebase+imagesize, чтоб разместить там загрузчик test eax,eax jz @b mov [pVA],eax ;сохранить mov esi,api_table mov edi,esi @@: lodsd test eax,eax jz @f mov eax,[eax] stosd jmp @b ;так как таблицу импорта мы не переносим, адреса необходимых апи занесем в таблицу. @@: mov esi,alloced_area_start mov edi,[pVA] mov ecx,alloced_size rep movsb ;копирование на новое место загрузчика с образом файла jmp [pVA] ;прыжок на начало кода загрузчика endp ;дальше только базонезависимый код proc alloced_area_start locals pVA dd ? endl call _delta _delta: pop ebx ;ebx=delta lea esi,[ebx+some_file-_delta] push esi add esi,dword[esi+3ch] mov ecx,[esi+34h] ;image base mov edx,[esi+50h] ;image size mov edi,ecx stdcall Allock_Region,ecx,edx ;получим памяти под загрузку файла mov [pVA],ecx ;запомним это значение mov edx,esi ;edx=pointer to PE header pop esi push esi ;последний параметр в process_sections mov ecx,[edx+54h] add ecx,18h ;размер заголовков и таблицы секций rep movsb ;перемещаем их lea eax,[edx+78h+16*8] ;указатель на первый IMAGE_SECTION_HEADER movzx ecx,word[edx+6] ;IMAGE_NT_HEADER.FileHeader.NumberOfSections stdcall process_sections,ecx,eax,[pVA] ;расставляем секции по местам stdcall process_imports,dword[edx+78h+8],[pVA] ;заполняем импорты push MEM_RELEASE ;теперь надо освободить память, занятую загрузчиком push 0 mov eax,ebx and eax,0fffff000h push eax ;адрес mov ecx,dword[edx+28h] ;RVA точки входа add ecx,[pVA] ;VA push ecx ;адрес возврата из VirtualFree jmp [_VirtualFree+ebx-_delta] ;освобождаем память endp proc process_imports pTab,pImageBase ;pTab - RVA таблицы импортов (берем из массива DataDirectory) ;pImageBase - указатель на "память" pusha mov edx,[pTab] add edx,[pImageBase] ;VA таблицы импортов .loop: push edx mov edi,[edx+4*4] ;import address table (её и будем заполнять) mov esi,[edx] ;lookup table (можно сделать просто = import address table, они идентичны) test edi,edi jz .ends ;последний IMAGE_IMPORT_DESCRIPTOR нулевой test esi,esi jnz .ok mov esi,edi .ok: mov ecx,[pImageBase] add esi,ecx add edi,ecx ;VA соответствующих таблиц mov eax,[edx+4*3] add eax,ecx ;VA имени DLL @@: cmp byte[eax],0 jnz @f inc eax jmp @b ;могут быть нули для выравнивания @@: xinvoke LoadLibrary,eax mov edx,eax ;загрузить DLL .po_1_dll: lodsd ;RVA IMAGE_IMPORT_BY_NAME test eax,eax jz .exit_it ;таблица заканчивается нулевым элементом bt eax,31 ;если установлен 31 бит, то импорт по ординалу. jnc .no_ord and eax,0ffffh jmp .getproc .no_ord: add eax,[pImageBase] ;VA IMAGE_IMPORT_BY_NAME add eax,2 ;VA IMAGE_IMPORT_BY_NAME.Name .getproc: push edx xinvoke GetProcAddress,edx,eax ;получить адрес АПИ pop edx stosd ;поместить его на свое место jmp .po_1_dll .exit_it: pop edx add edx,5*4 ;перейти к следующему IMAGE_IMPORT_DESCRIPTOR jmp .loop .ends: pop edx popa ret endp proc process_sections num, pStable,pImageBase,pImage ;num - кол-во секций, берем Number Of Sections из IMAGE_FILE_HEADER ;pStable - указатель на таблицу секций (сразу за массивом DataDirectory) ;pImageBase - указатель на выделенную "память" ;pImage - указатель на образ Б pusha mov ecx,[num] mov edx,[pStable] @@: push ecx mov edi,[edx+0ch] ;Section RVA add edi,[pImageBase] ;Section VA mov ecx,[edx+10h] ;Physical Size mov esi,[pImage] add esi,[edx+14h] ;Physical Offset rep movsb ;копируем секцию на её законное место pop ecx add edx,28h ;следующая dec ecx jnz @b popa ret endp proc Allock_Region pRegion,Size pusha mov edi,[pRegion] mov esi,[Size] add esi,edi ;esi - указатель на конец выделяемой области ;edi - указатель на начало @@: xinvoke UnmapViewOfFile,edi xinvoke VirtualFree,edi,0,MEM_RELEASE ;освободить память xinvoke VirtualAlloc,edi,10000h,MEM_RESERVE+MEM_COMMIT,PAGE_EXECUTE_READWRITE ;зарезервировать test eax,eax jz @f ;без этой проверки функция работает, если параметры в "разумных" пределах add edi,10000h ;память резервируется по 10000h за шаг cmp edi,esi jl @b @@: popa ret endp proc some_file ;_bin file FILE_NAME ;файлик, который будем загружать ; _bin_size = $ - _bin ;alloced_size=$-alloced_area_start locals hndl dd ? size dd ? dwr dd ? pVA dd ? endl pusha invoke CreateFile, offset FILE_NAME, GENERIC_READ, NULL, NULL, OPEN_EXISTING, NULL, NULL ;mov esi, var mov dword ptr hndl, eax lea eax, dword ptr dwr invoke GetFileSize, dword ptr hndl, eax mov dword ptr size, eax lea eax, dword ptr dwr lea esi, dword ptr fflile invoke ReadFile, dword ptr hndl, esi, dword ptr size, eax, NULL invoke CloseHandle, dword ptr hndl popa ret endp api_table: _UnmapViewOfFile dd UnmapViewOfFile _VirtualAlloc dd VirtualAlloc _LoadLibrary dd LoadLibrary _GetProcAddress dd GetProcAddress _VirtualFree dd VirtualFree dd 0 ;таблица АПИ, необходимых для работы загрузчика fflile: _bin file FILE_NAME ;файлик, который будем загружать _bin_size = $ - _bin alloced_size=$-alloced_area_start Заранее огромное спасибо!
хорошо, попробую конкретней наибольшую проблему вызывает макрос Код (Text): macro xinvoke proc,[arg] { common if ~ arg eq reverse pushd arg common end if call [ebx+_#proc-_delta] } и точки в метках! Код (Text): .po_1_dll: как мне корректно заменить эти моменты?
Точки в метках роли никакой не играют. Макрос примерно так Код (Text): xinvoke macro p1 call dword ptr[ebx+p1-_delta] endm но заменить в коде, например, xinvoke VirtualFree,edi,0,MEM_RELEASE на Код (Text): push MEM_RELEASE push 0 push edi xinvoke _VirtualFree по идее, так
>>twgt Спасибо! Замучался я его переделывать, все равно не чего не получается! //******************************************************* Может кто подскажет как сделать так чтобы имя запускаемого из памяти файла FILE_NAME equ 'file.exe' принамалось из командной строки?
>>censored Да! Если можно! Буду очень благодарен! Только было бы еще круче если сделать так, что б с этого кода компилилась .lib, или .dll и в экспортируемую ею ф-ю можео было бы передать 'file.exe' Заранее спасибо!