Здравствуйте. Пытаюсь написать полиморфный движок для криптора. Код декриптора пишется прямо в исходник криптора и выделяется двумя макросами (move_begin и move_end). Перед этим инициализируются некоторые массивы, которые определяют какие инструкции требуется изменить. a_modi определяет какие регистры в инструкциях надо изменить (Dst,src,index или base). Накодил уже много, но чувствую, что чтото делаю не так. =( Мой алгоритм следующий: - В программе зашита таблица с оптимизированными опкодами, префиксами, опкодами где нужно изменить первый байт и где второй. Сравниваюсь с таблицей и выполняю определенное действие. - Перед таблицей добавляю код который изменят логику программы например при встрече опкода который оптимизируется (eax,ax,al). И опкодов которые (как мне кажется) обрабатываются не по правилам. - Функция modi_st изменяет первый байт инструкции если esi==0, если esi==1, то второй и т.д. Вопросы: 1. Мне кажется, я явно чтото делаю не так, подскажите пожалуйста как реализовать это более компактно и правильно. Этих постоянных сравнений все больше и больше. Думаю мне надо переписать все нафиг. Или так и надо? =( 2. Какие еще существуют оптимизированные опкоды для eax,ax,al помимо: add/or/adc/sbb/and/sub/xor/cmp/test eax/ax/al,const xchg eax,reg Код (Text): t_opop: db 005h,004h,00Dh,00Ch,015h,014h,01Dh,01Ch,025h,024h,02Dh,02Ch,035h,034h,03Dh,03Ch db 0A9h,0A8h ; -------------------------------------------------------------------------------- ;add/or/adc/sbb/and/sub/xor/cmp/test eax/ax/al,const t_pref: db 064h,065h,066h,067h,0F0h,0F2h,0F3h,02Eh,036h,03Eh,026h t_op_1: db 040h,041h,042h,043h,044h,045h,046h,047h,048h,049h,04Ah,04Bh,04Ch,04Dh,04Eh,04Fh db 050h,051h,052h,053h,054h,055h,056h,057h,058h,059h,05Ah,05Bh,05Ch,05Dh,05Eh,05Fh db 090h,091h,092h,093h,094h,095h,096h,097h,0B0h,0B1h,0B2h,0B3h,0B4h,0B5h,0B6h,0B7h db 0B8h,0B9h,0BAh,0BBh,0BCh,0BDh,0BEh,0BFh ; -------------------------------------------------------------------------------- ; inc,dec r32/r16 || push,pop r32/r16/r8 ; xchg eax/ax/al,r32/r16/r8 || mov r32/r16/r8,const t_op_2: db 013h,012h,011h,010h,003h,002h,001h,000h,023h,022h,021h,020h,03Bh,03Ah,039h,038h db 08Bh,08Ah,089h,088h,00Bh,00Ah,009h,008h,01Bh,01Ah,019h,018h,02Bh,02Ah,029h,028h db 033h,032h,031h,030h,087h,086h,085h,084h,0F7h,0F6h,0F5h,0F4h,0FEh,00Fh,0D3h,0FFh db 080h,081h,083h ; -------------------------------------------------------------------------------- ; adc/add/and/cmp/mov/or/sbb/sub/xor/xchg/test r32/r16/r8,r32/r16/r8/modrm\sib ; not/neg/mul/imul/div/idiv r32/r16/r8 || inc/dec r8 || bswap r32 ; ror/rol/rcl/rcr/sar/sal/shr/shl r32/r16,cl || jmp r32/r16 || call r32/r16 t_end: ; /////////////////////////////////////////////////////////////////////////////////////////////////////////////// modi_st proc test ah,ah je @F and byte ptr [buff_for_op+esi],11000111b .if ah == 0FFh not ah .endif shl ah,3 or byte ptr [buff_for_op+esi],ah @@: test al,al je @F and byte ptr [buff_for_op+esi],11111000b .if al == 0FFh not al .endif or byte ptr [buff_for_op+esi],al @@: movzx eax,byte ptr [buff_for_op+esi] mov edi,eax and edi,11000000b shr edi,6 ; mode and eax,00000111b ; mem/reg .if edi<3 && eax==100b ; swapping SIB structure: inc esi test ch,ch je @F and byte ptr [buff_for_op+esi],11000111b .if ch == 0FFh not ch .endif shl ch,3 or byte ptr [buff_for_op+esi],ch @@: test cl,cl je @F and byte ptr [buff_for_op+esi],11111000b .if cl == 0FFh not cl .endif or byte ptr [buff_for_op+esi],cl @@: .endif ret modi_st endp modif proc LOCAL pr:BYTE push eax mov pr,bl ; DELETE PREFIXES: mov eax,offset t_pref .while eax != offset t_op_1 mov cl,byte ptr [eax] .if cl == byte ptr [buff_for_op] mov byte ptr [a_pref+ebx],cl mov edi,offset buff_for_op ; dst mov esi,offset buff_for_op ; src inc esi dec byte ptr [a_leng+edx] movzx ecx,byte ptr [a_leng+edx] rep movsb mov eax,offset t_pref inc ebx dec eax inc pr .endif inc eax .endw ; INITIALIZATION: xor esi,esi mov ah,byte ptr [a_modi+edx*4] ;- mov al,byte ptr [a_modi+edx*4+1] ; |> |ah|al|ch|cl|--|bl| mov ch,byte ptr [a_modi+edx*4+2] ; | |ds|sr|in|ba|--|le| mov cl,byte ptr [a_modi+edx*4+3] ; | mov bl,byte ptr [a_leng+edx] ;- ; MODIFICATION FOR OPTIMIZATION OPCODE: mov edi,offset t_opop mov bh,byte ptr [buff_for_op] .while bh != byte ptr [edi] inc edi .if edi == offset t_pref jmp next .endif .endw .if al!=0FFh mov bh,byte ptr [buff_for_op+4] ; shift right mov byte ptr [buff_for_op+5],bh mov esi,dword ptr [buff_for_op] mov dword ptr [buff_for_op+1],esi .if byte ptr [buff_for_op]==0A9h || byte ptr [buff_for_op]==0A8h mov byte ptr [buff_for_op],0F7h mov byte ptr [buff_for_op+1],0C0h jmp LB .endif mov byte ptr [buff_for_op],080h mov bh,byte ptr [buff_for_op+1] bt ebx,9 jae @F @@: inc byte ptr [buff_for_op] ; first byte 080h, maybe 081h or 0F7h (test) add byte ptr [buff_for_op+1],0BBh ; second byte LB: or byte ptr [buff_for_op+1],al inc byte ptr [a_leng+edx] ; add length inc bl .endif jmp skip next: .if byte ptr [buff_for_op]==87h && ah==0FFh && bl==2 && al!=ah || byte ptr [buff_for_op]==87h && al==0FFh && bl==2 && al!=ah ; xchg eax/ax,r32/r16 -> 9?h dec byte ptr [a_leng+edx] dec bl mov byte ptr [buff_for_op],90h mov ch,byte ptr [buff_for_op+1] and ch,00111111b mov cl,ch shr ch,3 ; dst from opcode and cl,00000111b ; src from opcode .if ah==0FFh .if cl!=0 && al==0 or byte ptr [buff_for_op],cl .else or byte ptr [buff_for_op],al .endif .elseif al==0FFh .if ch!=0 && ah==0 or byte ptr [buff_for_op],ch .else or byte ptr [buff_for_op],ah .endif .endif jmp skip .elseif byte ptr [buff_for_op]==87h && al==ah ; xchg x,x -> nop dec byte ptr [a_leng+edx] dec bl mov byte ptr [buff_for_op],90h jmp skip .elseif byte ptr [buff_for_op]>8Fh && byte ptr [buff_for_op]<98h && bl==1 && ah!=0 ; 9?h -> xchg eax/ax,r32/r16 inc byte ptr [a_leng+edx] inc bl mov cl,byte ptr [buff_for_op] and cl,00000111b ; src from opcode mov word ptr [buff_for_op],0C087h .if ah!=0FFh && al!=0FFh && ah!=0 && al!=0 and byte ptr [buff_for_op+1],11111000b shl ah,3 or byte ptr [buff_for_op+1],ah or byte ptr [buff_for_op+1],al .elseif ah!=0FFh && cl!=0 && al==0 shl ah,3 or byte ptr [buff_for_op+1],ah or byte ptr [buff_for_op+1],cl .else dec byte ptr [a_leng+edx] dec bl mov byte ptr [buff_for_op],90h .if al==0FFh not al .endif .if ah==0FFh not ah .endif .if cl==0 or byte ptr [buff_for_op],al .else or byte ptr [buff_for_op],cl .endif or byte ptr [buff_for_op],ah .endif jmp skip .elseif byte ptr [buff_for_op]==0F7h && byte ptr [buff_for_op+1]>0C0h && byte ptr [buff_for_op+1]<0C8h && bl==6 ; test r32/r16,const or byte ptr [buff_for_op+1],al .endif SR: ; SWAPPING REGISTERS: mov edi,offset t_op_1 mov bh,byte ptr [buff_for_op] .while bh != byte ptr [edi] inc edi .if edi == offset t_end ER: add esp,28 jmp _error_2 ; error (unknown opcode for modification) .endif .endw .if word ptr [buff_for_op]>3F0Fh && word ptr [buff_for_op]<500Fh || word ptr [buff_for_op]>08F0Fh && word ptr [buff_for_op]<0A00Fh || word ptr [buff_for_op]==0A30Fh || word ptr [buff_for_op]==0AB0Fh || word ptr [buff_for_op]>0AF0Fh && word ptr [buff_for_op]<0C20Fh ; stub for expanded opcodes: ; movsx r32,r16/r8 || movsx r16,r8 || movzx r32,r16/r8 || movzx r16,r8 || cmovcc r32/r16,r32/r16 ; xadd r32/r16/r8,r32/r16/r8 || cmpxchg r32/r16/r8,r32/r16/r8 || bt r32/r16,r32/r16 || bts r32/r16,r32/r16 ; btr r32/r16,r32/r16 || btc r32/r16,r32/r16 || bsf r32/r16,r32/r16 || bsr r32/r16,r32/r16 || setcc r8 inc esi inc esi .if word ptr [buff_for_op]==0C10Fh || word ptr [buff_for_op]==0C00Fh || word ptr [buff_for_op]==0B10Fh || word ptr [buff_for_op]==0B00Fh || word ptr [buff_for_op]==0A30Fh || word ptr [buff_for_op]==0AB0Fh || word ptr [buff_for_op]==0B30Fh || word ptr [buff_for_op]==0BB0Fh ; reverse order operands for next opcodes: ; xadd r32/r16/r8,r32/r16/r8 || cmpxchg r32/r16/r8,r32/r16/r8 || bt r32/r16,r32/r16 ; bts r32/r16,r32/r16 || bts r32/r16,r32/r16 || btr r32/r16,r32/r16 || btc r32/r16,r32/r16 ; btr r32/r16,r32/r16 || btc r32/r16,r32/r16 xchg ah,al .endif .elseif edi>=t_op_2 inc esi .endif call modi_st ; PAST PREFIXES: skip: xor eax,eax .while pr != NULL movzx ecx,byte ptr [a_leng+edx] .while (ecx!=-1) mov bl,byte ptr [buff_for_op+ecx] mov byte ptr [buff_for_op+ecx+1],bl dec ecx .endw movzx eax,pr mov bl,byte ptr [a_pref+eax-1] mov byte ptr [buff_for_op],bl inc byte ptr [a_leng+edx] dec pr .endw mov esi,offset buff_for_op ; src movzx ecx,byte ptr [a_leng+edx] ; length pop eax xor ebx,ebx ret modif endp move_code proc push esi push edi xor eax,eax .while (dword ptr [a_offs+eax*4]!=ebx) ; this loop set order .if byte ptr [a_repl+eax] == bl mov byte ptr [a_repl+eax],al .elseif byte ptr [a_repl+eax] == 0FFh mov byte ptr [a_repl+eax],bl .endif inc eax .endw xor eax,eax ; main counter xor edx,edx ; pointer on current opcode .while (dword ptr [a_offs+eax*4]!=ebx) movzx edx,byte ptr [a_repl+eax] ; get pointer on current opcode mov esi,dword ptr [a_offs+edx*4] ; src movzx ecx,byte ptr [a_leng+edx] ; length .if dword ptr [a_modi+edx*4] != ebx ; // modification \\ ;.if byte ptr [a_modi+edx*2] == 0FFh ; mov byte ptr [a_modi+edx*2],bl ;.endif mov edi,offset buff_for_op ; dst rep movsb call modif .endif mov edi,Delta ; dst add Delta,ecx rep movsb ; move code inc eax .endw pop edi pop esi ret move_code endp