Sources
Delphi Russian Knowledge Base
DRKB - это самая большая и удобная в использовании база знаний по Дельфи в рунете, составленная Виталием Невзоровым

Пример программы на Delphi, которая морфирует во время работы свой код

01.01.2007

Пример программы на DELPHI которая морфирует во время работы свой код и при этом не имеет секции импорта

пример также показывает, как сделать программу очень маленькой хоть не на максимум, но предельно! После компиляций EXE весит 800 байт.

unit Demo;
 
{
 
Автор: Нуржанов Аскар
 
Email: NikNet@yandex.ru
 
Сайт : NikNet.narod.ru
}
 
interface
 
 
Procedure EntryCode;
 
 
implementation
 
 
Procedure EntryCode;
 
 
function _DeltaOfs:cardinal;stdcall;
 
asm
        call @get_eip
     @get_eip
:
        pop  eax
       
sub  eax, offset @get_eip
 
end
 
function _Library:cardinal;stdcall;
 
asm
   
@FreeLibrary               : dd 078A25FBBh  // 00
   
@GetProcAddress            : dd 0F2509B84h  // 04
   
@LoadLibraryA              : dd 0A412FD89h  // 08
   @_ENDLIB                  
: dd 0FFFFFFFFh  // 12
 
end
 procedure _CalcHashFunction
;
 
asm
        lea     edi
, dword ptr [_Library]
        push    ebx
        push    ebp
        mov     ebp
, esp
        xchg    eax
, ebx
    mov edx
, [ebx + 3ch]                // PE
    mov esi
, [ebx + edx + 78h]              // Export Table RVA
    lea esi
, [ebx + esi + 18h]              // Export Table VA+18h
    lodsd
    xchg    eax
, ecx                    // NumberOfNames
    lodsd                          
// AddressOfFunctions
    push    eax
    lodsd                          
// AddressOfNames
    add eax
, ebx
    xchg    eax
, edx
    lodsd                                      
// AddressOfNameOrdinals
    add eax
, ebx
    push    eax
    mov esi
, edx                                // ESI - указывает на начало таблицы экспорта
     @search_api_name
:
    lodsd                                          
// Переходим на Export Name Table
        add eax
, ebx            // eax - Находится первая буква имений ф-ций
        xor edx
, edx                    // обнулим регистр EDX
     @calc_hash
:
    rol     edx
,3
    xor dl
,byte [eax]                           // xor dl with current character
    inc eax                    
// character shift
    cmp
byte [eax], 0                   // is we in the endof chain?
        jnz     @calc_hash
        mov eax
, [esp]                  // AddressOfNameOrdinals
    add dword
[esp], 2                  // Move to next ordinal word
 
     @ok_hash
:
    cmp
[edi], edx
    jnz
@SkipHash
    movzx   eax
, word [eax]                    // Name ordinal
    shl eax
, 2                         // Multiply by 4
    add eax
, [esp + 4]
    add eax
, ebx
    mov eax
, [eax]
    add eax
, ebx
    stosd
 
 
@SkipHash:
        cmp dword ptr
[edi],       0FFFFFFFFh        // Skip function hash
    jne @search_api_name
   leave
        pop     ebx
 
end
 
 
 
Function _GetKernelBase:cardinal;stdcall;
 
asm
        call  _DeltaOfs
        xchg  eax
,ebx
        mov     edx
, fs:[0]                             // SEH:0
     
@NextSEH:
        mov     eax
, [edx+4]                            // Переходим на следующий эелемент
        mov     edx
, [edx]                              // Берем первый элемент
        cmp     edx
, $FFFFFFFF                          // Сравниваем первый эелемент
        jnz    
@NextSEH                                // Если не равно $FFFFFFFF идем дальше
       
and     eax, $FFFF0000                          // тначе нормализуем ????0000
     
@Circle:                                              // Теперь будем провирять...
        cmp     word ptr
[eax],5A4Dh                    // Проверим на MZ сигнатуру
        jnz    
@NotFoundMZ                             // Если не равно то это не Kernel
        mov     edx
, eax                                // Иначе сохраняем базовый адрес в EDX
        add     edx
, [edx+3Ch]                          // И добовляем адрес начало PE заголовка
        cmp     dword ptr
[edx],00004550h               // Сверяем, является ли это PE?
        jz     @K32Found                                
// Если да, то переходим на метку K32Found
     
@NotFoundMZ:                                          // Иначе
       
sub     eax, 10000h                             // Уменьшаем базовый адрес 10000h
        cmp     eax
, 70000000h                          // и сверяем если не ниже
        jnb    
@Circle                                 // то повторяем пойск иначе
        mov     eax
, 0BFF70000h                         // присваеваем базовый адрес 0BFF70000 для Win98
     @K32Found
:
 
end
 
 
 
Procedure _ExitProc;stdcall;
 
asm
        pop     dword ptr fs
:[0]
        add     esp
,4
 
end
//****************************************************************
 
 
 
 
 
begin
   _GetKernelBase
;
   _CalcHashFunction
;
 
asm
 JMP @MSBOX
   @User32                        
: db 'User32.dll',000
   @ms                            
: db 'MessageBoxA',000
   @lpTitle                        
: db 'VIRUS',000
   @lpText                        
: db 'HULIGAN',000
 
@MSBOX
:
        lea      esi
, [ebx + @User32]
        push     esi
       
Call     dword ptr [_Library+8]
        mov      edx
, eax
        lea      esi
, [ebx + @MS]
        push     esi
        push     eax
       
Call     dword ptr [_Library+4]
        push    
0
        lea      esi
, [ebx + @lpTitle]
        push     esi
        lea      esi
, [ebx + @lpText]
        push     esi
        push    
0
        call     eax
        push edx
        call     dword ptr
[_Library+0]
end      _ExitProc;
 
end;
 
 
 
end.
 

Автор: NikNet_

Взято из https://forum.sources.ru