<?xml version='1.0' encoding="utf-8"?>
      <rss version='2.0'>
      <channel>
      <title>Форум на Исходниках.RU</title>
      <link>https://forum.sources.ru</link>
      <description>Форум на Исходниках.RU</description>
      <generator>Форум на Исходниках.RU</generator>
  	
      <item>
        <guid isPermaLink='true'>https://forum.sources.ru/index.php?showtopic=146463&amp;view=findpost&amp;p=1150587</guid>
        <pubDate>Fri, 23 Jun 2006 09:31:35 +0000</pubDate>
        <title>Поиск адресов API функций</title>
        <link>https://forum.sources.ru/index.php?showtopic=146463&amp;view=findpost&amp;p=1150587</link>
        <description><![CDATA[ProgramMan:  <br>
<div class='tag-align-center'><span class='tag-size' data-value='13' style='font-size:13pt;'><span class="tag-color tag-color-named" data-value="blue" style="color: blue"><strong class='tag-b'>Поиск адресов API функций</strong></span></span></div> <br>
Поиск адресов API функций.<br>
При создании защиты программных продуктов, бывает необходимо ограничить взломщику возможность анализа кода, в том числе, не показывая функции в таблице импорта. Нам  нужно будет программно найти адреса хотя бы некоторых необходимых нам функций, например LoadLibrary и GetProcAddress .<br>
<br>
Нужно будет выполнить следующие шаги:<br>
0 прочитать документацию на ФОРМАТ ИСПОЛНЯЕМЫХ ФАЙЛОВ PortableExecutables (PE)<br>
1 получить адрес внутри библиотеки, в нашем случае возьмём адрес возврата в kernel32.dll<br>
2 выровнять адрес на 10000h<br>
3 искать начало библиотеки, поднимаясь вверх, с шагом в 10000h<br>
4 проанализировать PE заголовок, найти начало и размер таблицы экспорта<br>
5 найти в таблице экспорта нужные на адреса<br>
<br>
Компилятор FASM<br>
<em class='tag-i'>Код APISearch.inc</em><br>
<div class='tag-code'><span class='pre_code'></span><div class='code  code_collapsed ' title='Подсветка синтаксиса доступна зарегистрированным участникам Форума.' style=''><div><div><ol type="1"><div class="code_line">; TProcName - макрос который поможет сформировать таблицу из названий фунций и адресов функций</div><div class="code_line">; </div><div class="code_line">macro TProcName [LabelName, ProcName]</div><div class="code_line">{</div><div class="code_line">local .L1,.L2</div><div class="code_line">db .L2-.L1</div><div class="code_line">.L1=$</div><div class="code_line">db ProcName</div><div class="code_line">.L2=$</div><div class="code_line">LabelName dd 0</div><div class="code_line">} &nbsp; </div><div class="code_line">; сама процедура поиска, на входе</div><div class="code_line">; adr - адрес внутри библиотеки, в нашем случее это будет адрес возврата в kernel32.dll</div><div class="code_line">; tabl - адрес начала таблици</div><div class="code_line">; tablln - размер таблици в байтах</div><div class="code_line">;***************************************************************************</div><div class="code_line">proc GetApiAdr,adr,tabl,tablln</div><div class="code_line">;***</div><div class="code_line">; локальные переменные, для работы с таблицой функций</div><div class="code_line">locals</div><div class="code_line">Lim &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; dd &nbsp; &nbsp;?</div><div class="code_line">Base &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;dd &nbsp; &nbsp;?</div><div class="code_line">ExpCount &nbsp; &nbsp; &nbsp; &nbsp;dd &nbsp; &nbsp;?</div><div class="code_line">ExpTName &nbsp; &nbsp; &nbsp; &nbsp;dd &nbsp; &nbsp;?</div><div class="code_line">ExpTAdr &nbsp; &nbsp; &nbsp; &nbsp; dd &nbsp; &nbsp;?</div><div class="code_line">endl</div><div class="code_line">;***</div><div class="code_line">&nbsp;</div><div class="code_line">mov [Lim],5 ; кол-во попыток поика заголовка PE образа</div><div class="code_line">mov esi,[adr]</div><div class="code_line">and &nbsp; &nbsp; esi,0FFFF0000h</div><div class="code_line">;вырявниваем адрес на 0FFFF0000h исходя т.к. заголовок образа PE файла может находится по адресу, кратному</div><div class="code_line">;10000h</div><div class="code_line">;*********</div><div class="code_line">.F1:</div><div class="code_line">cmp [Lim],0</div><div class="code_line">je _NoF</div><div class="code_line">; если мы нашли &nbsp;MZ, значит это начало образа PE файла</div><div class="code_line">cmp word[esi],&quot;MZ&quot;</div><div class="code_line">jz &nbsp;.CheckPE</div><div class="code_line">.F2:</div><div class="code_line">sub esi,10000h</div><div class="code_line">; уменьшаем адрес на 10000h</div><div class="code_line">dec [Lim]</div><div class="code_line">jmp &nbsp; &nbsp; .F1</div><div class="code_line">&nbsp;</div><div class="code_line">; Если мы нашли начало библиотеки</div><div class="code_line">.CheckPE:</div><div class="code_line">mov edi,[esi+3Ch]</div><div class="code_line">add edi,esi</div><div class="code_line">; проверим действительно ли это PE файл</div><div class="code_line">cmp dword[edi],&quot;PE&quot;</div><div class="code_line">jz &nbsp;WeGotK32</div><div class="code_line">jmp &nbsp; &nbsp; .F2</div><div class="code_line">&nbsp;</div><div class="code_line">;это то, что нам нужно</div><div class="code_line">; далее анализируем заголовок и таблицу экспорта</div><div class="code_line">WeGotK32:</div><div class="code_line">;*********</div><div class="code_line">mov eax,esi</div><div class="code_line">mov [Base],eax</div><div class="code_line">mov esi,[eax+3ch]</div><div class="code_line">add esi,eax ; esi - pe Signature adres</div><div class="code_line">;esi + 78h DWord &nbsp;Export Table RVA &nbsp; &nbsp; &nbsp;RVA адрес таблицы экспорта</div><div class="code_line">;esi + 7Ch DWord &nbsp;Export Data Size &nbsp; &nbsp; &nbsp;размер таблицы экспорта</div><div class="code_line">&nbsp;</div><div class="code_line">mov esi,[esi+78h]</div><div class="code_line">add esi,[Base]</div><div class="code_line">; кол-во записей в таблице экспорта</div><div class="code_line">mov eax,[esi+18h]</div><div class="code_line">mov [ExpCount],eax</div><div class="code_line">;таблица имён фунций</div><div class="code_line">mov eax,[esi+20h]</div><div class="code_line">add eax,[Base]</div><div class="code_line">mov [ExpTName],eax</div><div class="code_line">;</div><div class="code_line">mov eax,[esi+1ch]</div><div class="code_line">add eax,[Base]</div><div class="code_line">mov [ExpTAdr],eax</div><div class="code_line">xor edx,edx</div><div class="code_line">xor ebx,ebx</div><div class="code_line">xor ecx,ecx</div><div class="code_line">;далее ищем нужные нам функции в таблице экспорта</div><div class="code_line">жнайденные адреса, записываем в нашу таблицу</div><div class="code_line">;**********************************</div><div class="code_line">.NXT1: &nbsp;; внешний цикл по таблице экспорта</div><div class="code_line">mov edi,[ExpTName]</div><div class="code_line">lea edi,[edi+edx*4]</div><div class="code_line">mov edi,[edi]</div><div class="code_line">add edi,[Base]</div><div class="code_line">&nbsp;</div><div class="code_line">jmp .NXT2</div><div class="code_line">;********</div><div class="code_line">.NXT2: &nbsp;; внутренний цикл по таблице искомых функций</div><div class="code_line">mov esi,[tabl]</div><div class="code_line">inc esi</div><div class="code_line">add esi,ebx</div><div class="code_line">mov cl,byte[esi-1] &nbsp; &nbsp; &nbsp; &nbsp; ; длина строки</div><div class="code_line">lea ebx,[ebx+ecx+5]</div><div class="code_line">push edi</div><div class="code_line">repe cmpsb</div><div class="code_line">jnz .NXT3</div><div class="code_line">;******</div><div class="code_line">pop edi</div><div class="code_line">&nbsp;</div><div class="code_line">mov eax,[ExpTAdr]</div><div class="code_line">lea eax,[eax+edx*4]</div><div class="code_line">mov eax,[eax]</div><div class="code_line">add eax,[Base]</div><div class="code_line">mov [esi],eax</div><div class="code_line">&nbsp;</div><div class="code_line">jmp .NXT1</div><div class="code_line">;******</div><div class="code_line">.NXT3:</div><div class="code_line">pop edi</div><div class="code_line">cmp ebx,[tablln]</div><div class="code_line">jl .NXT2</div><div class="code_line">;********</div><div class="code_line">xor ebx,ebx</div><div class="code_line">inc edx</div><div class="code_line">&nbsp;</div><div class="code_line">cmp edx,[ExpCount]</div><div class="code_line">jl .NXT1</div><div class="code_line">&nbsp;</div><div class="code_line">;**********************************</div><div class="code_line">mov eax,[Base]</div><div class="code_line">ret</div><div class="code_line">;*********</div><div class="code_line">_NoF:</div><div class="code_line">mov eax,0</div><div class="code_line">ret</div><div class="code_line">endp</div><div class="code_line">;***************************************************************************</div></ol></div></div></div></div><script>preloadCodeButtons('1');</script><br>
Пример использования:<br>
<div class='tag-code'><span class='pre_code'></span><div class='code  code_collapsed ' title='Подсветка синтаксиса доступна зарегистрированным участникам Форума.' style=''><div><div><ol type="1"><div class="code_line">include &#39;win32ax.inc&#39;</div><div class="code_line">.code</div><div class="code_line">&nbsp;start:</div><div class="code_line">;******************************</div><div class="code_line">mov &nbsp; &nbsp; esi,[esp] &nbsp;; в esi адрес внутри kernel</div><div class="code_line">stdcall GetApiAdr,esi,table,tableLn &nbsp; ; вызов функции поиска Api</div><div class="code_line">test eax,eax</div><div class="code_line">jz ERR ; если возвращает нуль, то ошибка</div><div class="code_line">;******************************</div><div class="code_line">cinvoke wsprintf,StrTemp,StrMsgBoxText,eax,[LoadLibraryN],[GetProcAddressN],[LoadLibrary],[GetProcAddress]</div><div class="code_line">invoke &nbsp;MessageBox,0,StrTemp,StrMsgCaption,MB_ICONINFORMATION</div><div class="code_line">jmp OK</div><div class="code_line">ERR:</div><div class="code_line">invoke &nbsp;MessageBox,0,&#39;Ошибка&#39;,&#39;Не возможно найти указанные функции&#39;,MB_ICONINFORMATION</div><div class="code_line">OK:</div><div class="code_line">invoke &nbsp;ExitProcess,0</div><div class="code_line">;**********************</div><div class="code_line">include &#39;APISearch.inc&#39;</div><div class="code_line">;**********************</div><div class="code_line">;Данные</div><div class="code_line">.data</div><div class="code_line">StrMsgCaption &nbsp;db &nbsp; &nbsp; &nbsp;&#39;Bla Bla Bla&#39;,0</div><div class="code_line">StrMsgBoxText &nbsp;db &nbsp; &nbsp; &nbsp;&#39;KernelBase =%08XH&#39;,0DH,0AH</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; db &nbsp; &nbsp; &nbsp;&#39;****************************&#39;,0DH,0AH</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; db &nbsp; &nbsp; &nbsp;&#39;Search LoadLibraryA &nbsp; &nbsp; =%08XH&#39;,0DH,0AH</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; db &nbsp; &nbsp; &nbsp;&#39;Search GetProcAddress =%08XH&#39;,0DH,0AH</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; db &nbsp; &nbsp; &nbsp;&#39;****************************&#39;,0DH,0AH</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; db &nbsp; &nbsp; &nbsp;&#39;Import LoadLibrary &nbsp; &nbsp; &nbsp; =%08XH&#39;,0DH,0AH</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; db &nbsp; &nbsp; &nbsp;&#39;Import GetProcAddress =%08XH&#39;,0DH,0AH</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; db &nbsp; &nbsp; &nbsp;&#39;****************************&#39;,0DH,0AH,0</div><div class="code_line">StrTemp &nbsp; &nbsp; &nbsp; &nbsp;rb 100h</div><div class="code_line">;Таблица с именами искомых функций, и метками на найденный адреса формируется макросом &nbsp;TProcName</div><div class="code_line">table:</div><div class="code_line">TProcName GetProcAddressN, &#39;GetProcAddress&#39;,LoadLibraryN , &#39;LoadLibraryA&#39;</div><div class="code_line">tableLn = $-table</div><div class="code_line">.end start</div></ol></div></div></div></div>]]></description>
        <author>ProgramMan</author>
        <category>Assembler FAQ</category>
      </item>
	
      </channel>
      </rss>
	