Есть ли у кого пример (Дельфи) для бинарного поиска в файле, требуется найти в екзешнике (желательно в памяти -mappedfile) например ($55,$75,$19,$FF,$90) и получить поинтер на это место в файле.
пример поиска, надеюсь файл сам промаппить сможешь, пример есть у Ицзелиона только не пинайте, давно писалось ) Код (Text): program Loader; uses Windows; const BaseOfImage = $000400000; SizeOfImage = $0001F2000; szFileName : PChar = 'prog.exe' + #0; BytesToWrite : array [1..2] of byte = ($EB, $FE); BytesToUnpatch : array [1..2] of byte = ($6A, $00); Signature : array [1..50] of byte = ($C1, $F9, $02, $F3, $A5, $8B, $C8, $83, $E1, $03, $F3, $A4, $5E, $68, $00, $80, $00, $00, $6A, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $83, $C6, $08, $83, $3E, $00, $0F, $85, $00, $00, $00, $00, $68, $00, $80, $00, $00, $6A); var Buff : array [1..2] of byte; hMemory, AddressToWrite : Integer; StartupInfo : tStartupInfo; ProcessInfo : tProcessInformation; pMemory : Pointer; lpNumberOfBytesRead : Cardinal; label _unlock, _free, _error, _close; function WriteWord(hProcess: Integer; AddressToWrite: Pointer; lpByteToWrite: Pointer): Boolean; stdcall; var OldProtect : Integer; lpNumberOfBytesWritten : Cardinal; begin Result := FALSE; if VirtualProtectEx(hProcess, AddressToWrite, SizeOf(WORD), PAGE_EXECUTE_READWRITE, ADDR(OldProtect)) then begin Result := WriteProcessMemory(hProcess, AddressToWrite, lpByteToWrite, SizeOf(WORD), lpNumberOfBytesWritten); VirtualProtectEx(hProcess, AddressToWrite, SizeOf(WORD), OldProtect, ADDR(OldProtect)); end; end; // Функция ищет нужное место в файле по сигнатуре и возвращает смещение от начала буфера // первого найденного байта сигнатуры. При задании сигнатуры, байты, которые необходимо пропустить, // должны быть заменены нулевыми байтами. function ParseBuffer(lpScanString: Pointer; ScanStringLength: Integer; lpBuffer: Pointer; BufferLength: Integer): Pointer; stdcall; asm push ebx push edi push esi mov edi, lpScanString mov esi, lpBuffer mov ecx, ScanStringLength mov ebx, ecx mov edx, esi add edx, BufferLength sub edx, ScanStringLength inc edx @loop: cmp esi, edx je @not_found test ecx, ecx jz @found mov al, BYTE PTR [edi] test al, al jz @00h_found cmp BYTE PTR [esi], al je @parse sub edi, ebx add edi, ecx sub esi, ebx add esi, ecx inc esi mov ecx, ebx jmp @loop @parse: inc edi inc esi dec ecx jmp @loop @00h_found: inc edi inc esi dec ecx jmp @loop @not_found: xor eax, eax jmp @return @found: mov eax, esi sub eax, ebx sub eax, lpBuffer @return: pop esi pop edi pop ebx end; begin StartupInfo.cb := SizeOf(tStartupInfo); if CreateProcess(szFileName, nil, nil, nil, FALSE, CREATE_SUSPENDED, nil, nil, StartupInfo, ProcessInfo) then begin //-------------------------------- parse image -------------------------------- hMemory := GlobalAlloc(GMEM_MOVEABLE or GMEM_ZEROINIT, SizeOfImage); if hMemory = 0 then goto _error; pMemory := GlobalLock(hMemory); if pMemory = nil then goto _free; if ReadProcessMemory(ProcessInfo.hProcess, Pointer(BaseOfImage), pMemory, SizeOfImage, lpNumberOfBytesRead) = FALSE then goto _unlock; if ParseBuffer(ADDR(Signature), 50, pMemory, SizeOfImage) = nil then goto _unlock; asm add eax, (BaseOfImage+031h) mov AddressToWrite, eax end; GlobalUnlock(DWORD(pMemory)); GlobalFree(hMemory); //------------------------------ parse image end ------------------------------ if ReadProcessMemory(ProcessInfo.hProcess, Pointer(AddressToWrite), ADDR(Buff), SizeOf(WORD), lpNumberOfBytesRead) = FALSE then goto _error; if WORD(Buff) <> $006A then goto _error; if WriteWord(ProcessInfo.hProcess, Pointer(AddressToWrite), ADDR(BytesToWrite)) = FALSE then goto _error; ResumeThread(ProcessInfo.hThread); // Здесь WaitForInputIdle можно заменить на циклический опрос нужного места в файле // на предмет его распакованности - файл будет запускаться быстрее. // В данном случае использован вариант с WaitForInputIdle лишь для упрощения примера. WaitForInputIdle(ProcessInfo.hProcess, $0100); SuspendThread(ProcessInfo.hThread); if WriteWord(ProcessInfo.hProcess, Pointer(AddressToWrite), ADDR(BytesToUnpatch)) = FALSE then goto _error; //-------------------------------- patch here --------------------------------- // Здесь, если необходимо, можно поместить код патча, в этом месте файл // уже распаковался в памяти и его можно беспрепятственно пропатчить... //--------------------------------- patch end --------------------------------- ResumeThread(ProcessInfo.hThread); goto _close; _unlock: GlobalUnlock(DWORD(pMemory)); _free: GlobalFree(hMemory); _error: TerminateProcess(ProcessInfo.hProcess, 0); _close: CloseHandle(ProcessInfo.hThread); CloseHandle(ProcessInfo.hProcess); end; end.