K čemu je to dobré? PE šifréry Vám pomohou zašifrovat obsah exe souboru, ale v paměti je exe soubor dešifrovaný. Proto je vhodné jako ochranu proti crackerům šifrovat některé funkce i za běhu a dešifrovat je jen při jejich volání.

Celá funkce funguje velice jednoduše. Nejprve načteme počáteční adresu procedury nebo funkce, kterou chceme zašifrovat. Paměť ve které je funkce, kterou chceme zašifrovat je chráněna proti zápisu – musíme tedy nejprve ochranu paměti odstranit pomocí funkce VirtualProtect(Počáteční adresa, délka, nová ochrana, stará ochrana). Abychom získali délku funkce, musíme její konec nějakým způsobem označit. V uvedeném kódu jsem použil jako označení konce funkce textový řetězec „end.“ vložený přímo do kódu aplikace. Tento řetězec stačí jen najít a tam kde začíná je konec kódu funkce. Po odečtení adresy konce a začátku dostáváme délku kódu funkce. Můžeme tedy zavolat API VirtualProtect. Pokud funkce proběhne v pořádku vrátí 1, jinak 0. Nyní můžeme paměť funkce upravovat jak chceme. Každý byte funkce je xorován s konstantou 10. Dešifrovací rutina bude vypadat totožně díky šifrování za pomocí operátoru XOR.

procedure UlozObrazek();
begin

    // zde je libovolný kód funkce, který
    // má být zašifrován

    Exit; // pokud z funkce nevyskočíme, procesor zpracuje string "end."
    asm
        db 'end.' // označení konce funkce
    end;
end;


procedure ZasifrujKod ();
label
    Nalezen_Konec, Najit_Konec_Smycka, Zasifrovano_Konec,
    Zasifruj_Smycka;
var
    dwOldProtect: DWORD;
begin

    asm
        lea eax, UlozObrazek // do eax načteme adresu začátku funkce UlozObrazek

        mov ebx, eax // do ebx uložíme začátek funkce UlozObrazek
Najit_Konec_Smycka:
        mov ecx, dword ptr[ebx] // do ecx vložíme dword na adrese ebx
        cmp ecx, 778333797 // ecx porovnáme s 778333797 = pozpátku v ASCII "end."
        je Nalezen_Konec // pokud byl nalezen řetězec "end." ukončíme jeho hledání
        inc ebx // pokud ne, zvětšíme hodnotu ebx o 1
        jmp Najit_Konec_Smycka // a pokračujeme ve smyčce
Nalezen_Konec:

        Pushad // uděláme zálohu všech registrů
push [dwOldProtect] // ukazatel na proměnnou dwOldProtect
        push PAGE_EXECUTE_READWRITE // konstanta pro nastavení práva zápisu paměti
        sub ebx, eax // vypočítáme délku kódu
        push ebx // délka kódu funkce UlozObrazek
        push eax // adresa začátku funkce UlozObrazek
        call VirtualProtect // voláme API VirtualProtect
        test eax, eax // je výsledek funkce 0?
        je Zasifrovano_Konec // pokud ano, došlo k chybě a šifrování provádět nebudeme

        popad // vyvoláme zpět zálohované registry

Zasifruj_Smycka:
        cmp ebx, eax // porovnáme adresu právě šifrovaného bytu s adresou konce
        je Zasifrovano_Konec // pokud se shodují, tak jsme na konci a šifrování ukončíme
        xor byte ptr[eax], 10 // xorujeme byte na adrese eax
        inc eax // přičteme k eax 1
        jmp Zasifruj_Smycka // skočíme zpět

Zasifrovano_Konec:
    end;
end;