Долой импорт! Николай «GorluM» Андреев Хакер, номер #080, стр. 080-116-2 [всем известный поиск ядра] HMODULE GetKernel() { __asm { mov eax, dword ptr fs:[30h] mov eax, dword ptr [eax+0ch] mov esi, dword ptr [eax+1ch] lodsd mov eax, dword ptr [eax+08h] } } Имея ядро, можно найти в нем с помощью собственной функции GetProcAddress адрес LoadLibrary, подгрузить с ее помощью любую нужную библиотеку и искать уже в ней адрес необходимой для работы программы функции (как вариант, можно найти адрес GetModuleHandle). Геморрой, конечно, но он просто автоматизируется, а исследователю жизнь все-таки усложняет. В итоге, со всеми извращениями запуск API-функции, к примеру, MessageBox'а на Си выглядит следующим образом: [я не такой уж и извращенец, честное слово!] typedef int (WINAPI * tMessageBoxA) (HWND, LPCSTR, LPCSTR, UINT); typedef HMODULE (WINAPI * tLoadLibraryA) (LPCSTR); HMODULE hKernel32 = GetKernel(); tLoadLibraryA pLoadLibraryA = GetProcAddressEx (hKernel32, "LoadLibraryA"); // 0xC8AC8026 HMODULE hUser32 = pLoadLibraryA ("user32.dll"); tMessageBox pMessageBox = GetProcAddressEx (hUser32, "MessageBoxA" ); // 0xABBC680D pMessageBox(0, "Hello world", "", 0); Упс, наврал... Не со всеми извращениями. Ведь тут поиск осуществляется по имени, а нас это, как я уже говорил, не устраивает. Будем переделывать поиск, чтобы искал по хэшу. [ищем функции по хэшу] Хэш - это некоторое число, которое считается от строки. Хэш-функция, соответственно, функция, которая будет это число считать. Его ведь можно кучей разных способов получать. Она у нас будет очень простенькая, я ее выдрал из замечательных программ z0mbie и переписал на Си. [хэш-функция] DWORD CalcHash(char *str) { DWORD hash = 0; char* copystr = str; while(*copystr) { hash = ((hash << 7) & (DWORD)(-1))|(hash >> (32-7)); hash = hash^(*copystr); copystr++; } return hash; } Число, полученное в результате подсчета, почти уникально. Конечно, это я очень хреново выразился. Я хотел сказать, что вероятность того, что от двух разных строк ты получишь одно число - очень мала. А на пространстве имен функций какой-нибудь одной библиотеки вообще равна нулю. Потому-то и можно искать функцию в таблице экспорта, сравнивая не имена, а числа. Это позволяет хранить не палевное название API в программе, а всего лишь 4 байта хэша, которые влезают в любой регистр и могут просто жить в какой-нибудь инструкции, прямо в коде, а не в данных. Меня это обстоятельство радует безумно. Я вообще данные в программе не люблю. Чтобы иметь возможность искать имя по хэшу, достаточно немного модифицировать функцию GetProcAddressEx. Второй параметр ее станет DWORD'ом вместо указателя на строку, а внутри вместо сравнения имен: if (lstrcmp((char*)RVATOVA(hModule, *pdwNamePtr), lpProcName) == 0) Будет сравнение второго параметра (hash) и подсчитанного хэша от рассматриваемого в конкретный момент имени функции: if (CalcHash((char*)RVATOVA(hModule, *pdwNamePtr)) == hash) |