вызов API-функции по хэш-именам
Команда POP ESI выталкивает в регистр ESI двойное слово, лежащее на вершине стека. А что у нас там? Помните команду CALL, передающую управление хитрой инструкции JMP? Она положила на стек адрес возврата, то есть адрес следующей за ней команды, равный в данном случае 021h, который тут же и вызывается инструкцией CALL ESI, принимающий два аргумента — базовый адрес KERNEL32.DLL, передаваемый в регистре EAX и непонятную константу 0EC0E4E8Eh.
seg000:00000021 60 pusha ; сохраняем все регистры
seg000:00000022 8B 6C 24 24 mov ebp, [esp+24h] ; base of KERNEL32.DLL
seg000:00000026 8B 45 3C mov eax, [ebp+3Ch] ; PE header
seg000:00000029 8B 7C 05 78 mov edi, [ebp+eax+78h] ; export table RVA
seg000:0000002D 01 EF add edi, ebp ; адрес
таблицы экспорта
seg000:0000002F 8B 4F 18 mov ecx, [edi+18h] ; numberOfNamePointers
seg000:00000032 8B 5F 20 mov ebx, [edi+20h] ; namePointerRVA
seg000:00000035 01 EB add ebx, ebp ; namePointer VA
seg000:00000037
seg000:00000037 loc_37: ; CODE XREF: seg000:00000050vj
seg000:00000037 49 dec ecx ; обрабатываем след. имя
seg000:00000038 8B 34 8B mov esi, [ebx+ecx*4]; RVA-адрес функции
seg000:0000003B 01 EE add esi, ebp ; вирт. адрес функции
seg000:0000003D 31 C0 xor eax, eax ; EAX := 0
seg000:0000003F 99 cdq ; EDX := 0
seg000:00000040
seg000:00000040 loc_40: ; CODE XREF: seg000:0000004Avj
seg000:00000040 AC lodsb ; читаем очередной байт имени
seg000:00000041 84 C0 test al, al ; это конец имени?
seg000:00000043 74 07 jz short loc_4C ; если конец, выходим из цикла
seg000:00000045 C1 CA 0D ror edx, 0Dh ; \_ хэшируем
seg000:00000048 01 C2 add edx, eax ; / имя