Original Entry Point Finding [Исследование] Subject: Educational Purpose Target: Any Delphi programm URL:www..borland.com. Author: aSL! Before starting! Все ниже изложенное предназначено только для образовательных целей. I. Вступление Да, да про OEP. Ну ладно, давайте же займемся этим вплотную... II. Постановка задачи Необходимо найти OEP у программы, написанной на Delphi. III. Исследование Необходимые инструменты: W32Dasm 8.9x VCL Source, неважно от каких делфей.. У меня будет от 4.3. Итак, приступим... Что мы имеем? Да, вот, дамп из памяти проги, сделанной на делфях... Нам ведь не помешает узнать OEP, не роясь в отладчике, верно? Загружаем и дизассемблируем сегмент кода. Для дальнейших действий мы должны будем взять VCL Source. Как известно, в делфях system.pas прикомпиливается в любом случае, поэтому, очевидно, что код из нее будет выполнятся где-то в самом начале .exe. Далее, смотрим в нее, что-то я тут малость не втыкаю... Всего-то наворочено. Но что это? Хех: uses SysInit; Весьма и весьма интересно, скажу я вам. Смотрим sysinit.pas. А там... Меня заинтересовали следующие строки: procedure _GetTls; function _InitPkg(Hinst: Integer; Reason: Integer; Resvd: Pointer): LongBool; stdcall; procedure _InitLib; procedure _InitExe; А в особенности процедура _InitExe. Смотрим и ее: procedure _InitExe; asm { -> EAX Inittable } { MOV ModuleIsLib,0 ; zero initialized anyway } PUSH EAX PUSH 0 CALL GetModuleHandle MOV EDX,offset Module PUSH EDX MOV HInstance,EAX MOV [EDX].TLibModule.Instance,EAX MOV [EDX].TLibModule.CodeInstance,0 MOV [EDX].TLibModule.DataInstance,0 CALL InitializeModule POP EDX POP EAX CALL _StartExe end; Чуете, чем пахнет? Этот код нигде больше в .pas не вызывается. Имя этой процедуры вложено в компилятор и он ее компилирует первой!. Это можно легко проверить, вставив в нее что-нить. Пример (консольное Delphi приложение -- {$APPTYPE CONSOLE}): //******************** Program Entry Point ******** :0041A1FC 55 :0041A1FD 8BEC :0041A1FF 81C4F0FEFFFF :0041A205 53 :0041A206 56 :0041A207 57 :0041A208 33C0 :0041A20A 8945F0 :0041A20D A154B94100 :0041A212 C60001 :0041A215 B8FCA04100 :0041A21A E8A5B6FEFF push ebp mov ebp, esp add esp, FFFFFEF0 push ebx push esi push edi xor eax, eax mov dword ptr [ebp-10], eax mov eax, dword ptr [0041B954] mov byte ptr [eax], 01 mov eax, 0041A0FC call 004058C4 Залезем-ка мы в call: :004058C4 50 :004058C5 6A00 push eax push 00000000 * Reference To: kernel32.GetModuleHandleA, Ord:0000h :004058C7 E8F8FEFFFF :004058CC BA9CB04100 :004058D1 52 :004058D2 8905D4C44100 :004058D8 894204 :004058DB C7420800000000 :004058E2 C7420C00000000 :004058E9 E88AFFFFFF :004058EE 5A :004058EF 58 :004058F0 E8E3D7FFFF :004058F5 C3 Call 004057C4 mov edx, 0041B09C push edx mov dword ptr [0041C4D4], eax mov dword ptr [edx+04], eax mov [edx+08], 00000000 mov [edx+0C], 00000000 call 00405878 pop edx pop eax call 004030D8 ret Узнаете? Да, да, да это та самая _InitExe, код которой не менялся аж со вторых делфей и до пятых. Стало понятно как искать OEP? Примерно. Вот полное решение. Очевидно, что надо искать следующую последовательность байтов (для этого используйте достаточно продвинутый hex редактор с масками в поиске): 556A00E8????????BA????????5289??????????89????C7420800000000C7420C00000000E8 ????????5A58E8????????C3. Достаточно длинная последовательность, чтобы она была единственной??? :))) К сожалению, я не знаю ни одного редактора, работающего с битовыми масками, иначе строка была бы подробнее. На худой конец, эту строку можно икать в отлдачике и поставить бряк на память. (Естественно, уже после того, как распакуется код). Так, наверное, будет даже надежнее... После всего этого, грузим наш сегмент кода в W32Dasm, дизассемблируем и после этого ищем ту гадость, что вызывает _InitExe.. А там уже легко. Не секрет, что большинство (если даже не все) .exe начинаются с 558BEC (push ebp/ mov ebp,esp). Вот и все! IV. Подводим итоги: Мне действительно нечего сказать, поскольку OEP мы нашли. Единственное, что хочу отметить, что этот код не меняли НИ В ОДНОМ мне известном билде делфей. Вот собственно и все! :)