Версия для печати
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум на Исходниках.RU > Assembler FAQ > Поиск адресов API функций


Автор: ProgramMan 23.06.06, 09:31
 
Поиск адресов API функций

Поиск адресов API функций.
При создании защиты программных продуктов, бывает необходимо ограничить взломщику возможность анализа кода, в том числе, не показывая функции в таблице импорта. Нам нужно будет программно найти адреса хотя бы некоторых необходимых нам функций, например LoadLibrary и GetProcAddress .

Нужно будет выполнить следующие шаги:
0 прочитать документацию на ФОРМАТ ИСПОЛНЯЕМЫХ ФАЙЛОВ PortableExecutables (PE)
1 получить адрес внутри библиотеки, в нашем случае возьмём адрес возврата в kernel32.dll
2 выровнять адрес на 10000h
3 искать начало библиотеки, поднимаясь вверх, с шагом в 10000h
4 проанализировать PE заголовок, найти начало и размер таблицы экспорта
5 найти в таблице экспорта нужные на адреса

Компилятор FASM
Код APISearch.inc
<{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}>
    ; TProcName - макрос который поможет сформировать таблицу из названий фунций и адресов функций
    ;
    macro TProcName [LabelName, ProcName]
    {
    local .L1,.L2
    db .L2-.L1
    .L1=$
    db ProcName
    .L2=$
    LabelName dd 0
    }  
    ; сама процедура поиска, на входе
    ; adr - адрес внутри библиотеки, в нашем случее это будет адрес возврата в kernel32.dll
    ; tabl - адрес начала таблици
    ; tablln - размер таблици в байтах
    ;***************************************************************************
    proc GetApiAdr,adr,tabl,tablln
    ;***
    ; локальные переменные, для работы с таблицой функций
    locals
    Lim             dd    ?
    Base            dd    ?
    ExpCount        dd    ?
    ExpTName        dd    ?
    ExpTAdr         dd    ?
    endl
    ;***
     
    mov [Lim],5 ; кол-во попыток поика заголовка PE образа
    mov esi,[adr]
    and     esi,0FFFF0000h
    ;вырявниваем адрес на 0FFFF0000h исходя т.к. заголовок образа PE файла может находится по адресу, кратному
    ;10000h
    ;*********
    .F1:
    cmp [Lim],0
    je _NoF
    ; если мы нашли  MZ, значит это начало образа PE файла
    cmp word[esi],"MZ"
    jz  .CheckPE
    .F2:
    sub esi,10000h
    ; уменьшаем адрес на 10000h
    dec [Lim]
    jmp     .F1
     
    ; Если мы нашли начало библиотеки
    .CheckPE:
    mov edi,[esi+3Ch]
    add edi,esi
    ; проверим действительно ли это PE файл
    cmp dword[edi],"PE"
    jz  WeGotK32
    jmp     .F2
     
    ;это то, что нам нужно
    ; далее анализируем заголовок и таблицу экспорта
    WeGotK32:
    ;*********
    mov eax,esi
    mov [Base],eax
    mov esi,[eax+3ch]
    add esi,eax ; esi - pe Signature adres
    ;esi + 78h DWord  Export Table RVA      RVA адрес таблицы экспорта
    ;esi + 7Ch DWord  Export Data Size      размер таблицы экспорта
     
    mov esi,[esi+78h]
    add esi,[Base]
    ; кол-во записей в таблице экспорта
    mov eax,[esi+18h]
    mov [ExpCount],eax
    ;таблица имён фунций
    mov eax,[esi+20h]
    add eax,[Base]
    mov [ExpTName],eax
    ;
    mov eax,[esi+1ch]
    add eax,[Base]
    mov [ExpTAdr],eax
    xor edx,edx
    xor ebx,ebx
    xor ecx,ecx
    ;далее ищем нужные нам функции в таблице экспорта
    жнайденные адреса, записываем в нашу таблицу
    ;**********************************
    .NXT1:  ; внешний цикл по таблице экспорта
    mov edi,[ExpTName]
    lea edi,[edi+edx*4]
    mov edi,[edi]
    add edi,[Base]
     
    jmp .NXT2
    ;********
    .NXT2:  ; внутренний цикл по таблице искомых функций
    mov esi,[tabl]
    inc esi
    add esi,ebx
    mov cl,byte[esi-1]         ; длина строки
    lea ebx,[ebx+ecx+5]
    push edi
    repe cmpsb
    jnz .NXT3
    ;******
    pop edi
     
    mov eax,[ExpTAdr]
    lea eax,[eax+edx*4]
    mov eax,[eax]
    add eax,[Base]
    mov [esi],eax
     
    jmp .NXT1
    ;******
    .NXT3:
    pop edi
    cmp ebx,[tablln]
    jl .NXT2
    ;********
    xor ebx,ebx
    inc edx
     
    cmp edx,[ExpCount]
    jl .NXT1
     
    ;**********************************
    mov eax,[Base]
    ret
    ;*********
    _NoF:
    mov eax,0
    ret
    endp
    ;***************************************************************************

Пример использования:
<{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}>
    include 'win32ax.inc'
    .code
     start:
    ;******************************
    mov     esi,[esp]  ; в esi адрес внутри kernel
    stdcall GetApiAdr,esi,table,tableLn   ; вызов функции поиска Api
    test eax,eax
    jz ERR ; если возвращает нуль, то ошибка
    ;******************************
    cinvoke wsprintf,StrTemp,StrMsgBoxText,eax,[LoadLibraryN],[GetProcAddressN],[LoadLibrary],[GetProcAddress]
    invoke  MessageBox,0,StrTemp,StrMsgCaption,MB_ICONINFORMATION
    jmp OK
    ERR:
    invoke  MessageBox,0,'Ошибка','Не возможно найти указанные функции',MB_ICONINFORMATION
    OK:
    invoke  ExitProcess,0
    ;**********************
    include 'APISearch.inc'
    ;**********************
    ;Данные
    .data
    StrMsgCaption  db      'Bla Bla Bla',0
    StrMsgBoxText  db      'KernelBase =%08XH',0DH,0AH
                   db      '****************************',0DH,0AH
                   db      'Search LoadLibraryA     =%08XH',0DH,0AH
                   db      'Search GetProcAddress =%08XH',0DH,0AH
                   db      '****************************',0DH,0AH
                   db      'Import LoadLibrary       =%08XH',0DH,0AH
                   db      'Import GetProcAddress =%08XH',0DH,0AH
                   db      '****************************',0DH,0AH,0
    StrTemp        rb 100h
    ;Таблица с именами искомых функций, и метками на найденный адреса формируется макросом  TProcName
    table:
    TProcName GetProcAddressN, 'GetProcAddress',LoadLibraryN , 'LoadLibraryA'
    tableLn = $-table
    .end start

Powered by Invision Power Board (https://www.invisionboard.com)
© Invision Power Services (https://www.invisionpower.com)