Při tzv. hard-address programmingu, který je vcelku běžný například v případě shellkódu, se programátor dostane do situace, kdy potřebuje získat adresy funkcí v paměti. Výhodou tohoto stylu programování je skutečnost, že výsledný kód je mnohem menší než je tomu u dynamic-address programmingu (a to v některých případech dost podstatně menší). Tvrdou daní za takové pohodlí však platíme v podobě nepřenositelnosti takového kódu.

Důvod? DLL knihovny, ve kterých se tyto funkce nachází, jsou na konkrétním stejném typu/verzi operačního systému nahrávány do stejného paměťového prostoru (chápej: stále na stejnou adresu), což ovšem nemusí platit (a většinou neplatí) v případě jiné verze, jiné jazykové mutace systému, jiného service packu. Ve výsledku tak přistupujeme do úplně jiného adresního prostoru.

Jak se tedy dostat k adresám API funkcí při hard-address codingu? Teorie je jednoduchá. Nahrát do paměti potřebnou DLL knihovnu (například pomocí API funkce LoadLibrary), ve které se funkce nachází a následně získáme adresu požadované funkce (například pomocí API funkce GetProcAddress).

Kód takového jednoduchého programu by mohl vypadat následovně:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
#include <stdio.h>
#include <windows.h>
 
int main(int argc, char *argv[]){
    if(argc &lt; 3){
        printf("Usage: %s <NAME.DLL> <FUNCTION.NAME>\n", argv[0]);
        printf("Example: %s user32.dll MessageBoxA\n", argv[0]);
        return 0;
    }
 
    HMODULE hLib;
    PVOID lpAddress;
 
    if((hLib = LoadLibraryA(argv[1])) == NULL){
        printf("Library %s not loaded!\n", argv[1]);
        return 0;
    }
 
    if((dwAddress = (PVOID)GetProcAddress(hLib, argv[2])) == NULL){
        printf("Function %s not found!\n", argv[2]);
        return 0;
    }
 
    printf("Address of %s in %s == 0x%p\n", argv[2], argv[1], dwAddress);
 
    FreeLibrary(hLib);
 
    return 0;
}

Poznámka: V případě, že by měl někdo zájem zachytávat chybové hlášky, stačí si zeditovat návratové hodnoty. (Díky Vrtulemu za všechny připomínky a výtky 🙂