Кодеры помогите! Видел исходники программ которые не используют "Include", "Includelib" короче подключаемые при компиляции библиотеки, а скомпилированные проги (по большей части "Вири") работают с WinAPI функциями путем заражения файлов и модернизации РЕ-заголовков через Delta-смещение. Возник вопрос как можно используя Delta-смещение пользоваться WinAPI не заражая файл, просто вызывать функции из тела запущенной программы (не подключая при компиляции библиотеки). Киньте пожалуйста ссылки или сорец какой-нибудь (masm32) желательно с хорошими комментариями и хешами функций Kernel32. Инфу которую читал расчитана на вирусы и заражение файлов. Просто нужно вызвать функции kernel32 на "чистом" ассемблере (masm32).
Что-то вроде этого. Поиск Kernel и тд. .486 .model flat,stdcall .code start: VirDelta: sub dword ptr [esp], OFFSET VirDelta push dword ptr [esp] ; - ; SEH ReadSEH: xor edx, edx ; edx = 0 assume fs:flat mov eax, fs:[edx] ; SEH dec edx ; edx = 0FFFFFFFFh ; 0FFFFFFFFh SearchKernel32: cmp [eax], edx ; 0FFFFFFFFh je CheckKernel32 ; , mov eax, [eax] ; jmp SearchKernel32 ; - ; Kernel32 CheckKernel32: mov eax, [eax + 4] ; - ; kernel32.dll xor ax, ax ; ; MZ SearchKernelMZ: cmp word ptr [eax], 5A4Dh ; MZ je CheckKernelMZ ; , ; PE sub eax, 10000h ; MZ, jmp SearchKernelMZ ; PE CheckKernelMZ: mov edx, [eax + 3Ch] ; PE- cmp word ptr [eax + edx], 4550h ; jne Exit ; , ; HashTable: dd 0F867A91Eh ; CloseHandle dd 03165E506h ; FindFirstFileA dd 0CA920AD8h ; FindNextFileA dd 0860B38BCh ; CreateFileA dd 029C4EF46h ; ReadFile dd 0CC17506Ch ; GlobalAlloc dd 0AAC2523Eh ; GetFileSize dd 07F3545C6h ; SetFilePointer dd 0F67B91BAh ; WriteFile dd 03FE8FED4h ; GlobalFree dd 015F8EF80h ; VirtualProtect dd 0D66358ECh ; ExitProcess dd 05D7574B6h ; GetProcAddress dd 071E40722h ; LoadLibraryA dd 0E65B28ACh ; FindClose dd 059B44650h ; GetModuleFileNameA dd 00709DC94h ; SetCurrentDirectoryA dd 0D64B001Eh ; FreeLibrary dw 0FFFFh ; _SearchAPI: mov esi, [eax + edx + 78h] add esi, eax add esi, 18h xchg eax, ebx lodsd ; push eax ; [ebp+4*4] lodsd ; RVA push eax ; [ebp+4*3] lodsd ; RVA ; push eax ; [ebp+4*2] add eax, ebx push eax ; ; [ebp+4*1] lodsd ; RVA push eax ; [ebp] mov edi, [esp+4*5] ; edi = _ lea edi, [edi+HashTable] ; edi HashTable mov ebp, esp ; _BeginSearch: mov ecx, [ebp+4*4] ; xor edx, edx ; ; ( 0) _SearchAPIName: mov esi, [ebp+4*1] mov esi, [esi] add esi, ebx ; AS II- API- ; ; - _GetHash: xor eax, eax push eax _CalcHash: ror eax, 7 xor [esp],eax lodsb test al, al jnz _CalcHash pop eax ; OkHash: cmp eax, [edi] ; hash ; HashTable je _OkAPI ; add dword ptr [ebp+4*1], 4 ; ; inc edx loop _SearchAPIName jmp Exit ; _OkAPI: shl edx, 1 ; mov ecx, [ebp] ; add ecx, ebx add ecx, edx mov ecx, [ecx] and ecx, 0FFFFh mov edx, [ebp+4*3] ; RVA add edx, ebx shl ecx, 2 add edx, ecx mov edx, [edx] add edx, ebx push edx ; ; cmp word ptr [edi+4], 0FFFFh ; ? je _Call_API add edi, 4 ; hash- _NextName: mov ecx, [ebp+4*2] ; add ecx, ebx mov [ebp+4*1], ecx ; Index jmp short _BeginSearch _Call_API Exit: ret end start
Вот еще к теме! .486 .model flat, stdcall .code start: call $+5 pop ebx sub ebx, $-1 call GetKernel ret GetKernel proc local Result: dword pushad xor eax, eax mov Result, eax mov eax, esp sub eax, 14h push eax push ebp lea eax, dword ptr [ebx+SkipPage] push eax lea eax, dword ptr [ebx+SehHandler] push eax assume fs:nothing push fs:[0] mov fs:[0], esp mov ecx, 0FFFFh mov eax, ecx shl eax, 16 NextPage: cmp word ptr [eax], "ZM" jz CheckPE SkipPage: sub eax, 10000h loop NextPage jmp ExitGetKernel32Base CheckPE:mov edi, dword ptr [eax+3Ch] add edi, eax cmp dword ptr [edi], "EP" jnz SkipPage mov edi, dword ptr [edi+78h] add edi, eax mov edi, dword ptr [edi+0Ch] add edi, eax cmp dword ptr [edi], "NREK" jnz SkipPage cmp dword ptr [edi+4], "23LE" jnz SkipPage mov Result, eax ExitGetKernel32Base: pop fs:[0] add esp, 10h popad mov eax, Result ret GetKernel endp ;------------------------------------------------------------------------------- SehHandler proc ExceptionRecord: dword, Err: dword, Context: dword, Param: dword pushad mov eax, Err mov edi, Context push dword ptr [eax+08] pop dword ptr [edi+0B8h] push dword ptr [eax+0Ch] pop dword ptr [edi+0B4h] push dword ptr [eax+10h] pop dword ptr [edi+0C4h] popad xor eax, eax ret SehHandler endp end start ;===============================================================================
Дельта-смещение не имеет практически никакого отношения к использованию апи. Главная цель дельты - использование прямых адресов в программе (обращение к глобальным переменным). Теперь об апи: ты сам привел пример. Что ж еще тебе непонятно? В памяти ищется модуль, в котором находятся нужные тебе апи. Их адреса ищутся в этом модуле и сохраняются в переменные (дельта нужна только для обращения к этим переменным, больше ни для чего). После этого ты вызываешь апи не через свою таблицу импорта, а через эти переменные.
Брат я понял что второй пример это и есть то что надо! Я "зеленый" и меня интересует синтаксис, т.е. "Как её вызвать?" Ну например: CALL Function или INVOKE Function Ну не работал я с такой формой вызова (через переменные). Прошу не смеяться )))))
Atas Ну в последнем (#4) ты нашел адрес по которому в оперативной памяти выделенной твоему процессу подгружена библиотека kernel32.dll, так ведь? Теперь нужно искать адреса функций в этой dll - ке, которые нужны тебе для твоего виря. Например я ищу адрес функции ExitProcess: Код (Text): .data szExitProcess DB "ExitProcess",0 _ExitProcess DD 0 .code PUSH OFFSET szExitProcess PUSH EAX CALL GetProcAddr OR EAX, EAX JZ GetApiErr MOV _ExitProcess, EAX ; И сам вызов CALL _ExitProcess ;) ;------------------------------------------------------- GetProcAddr PROC USES ESI EDI ECX EBX EDX, dwDllBase : DWORD, szApi : LPSTR ; check PE Signarue MOV ESI, dwDllBase CMP WORD PTR [ESI], IMAGE_DOS_SIGNATURE JNZ @@BadExit ADD ESI, [ESI+03Ch] CMP DWORD PTR [ESI], IMAGE_NT_SIGNATURE JNZ @@BadExit ; get the string length of the target Api MOV EDI, szApi MOV ECX, MAX_API_STRING_LENGTH XOR AL, AL REPNZ SCASB MOV ECX, EDI SUB ECX, szApi ; ECX -> Api string length ; trace the export table MOV EDX, [ESI+078h] ; EDX -> Export table ADD EDX, dwDllBase ASSUME EDX : PTR IMAGE_EXPORT_DIRECTORY MOV EBX, [EDX].AddressOfNames; EBX -> AddressOfNames array pointer ADD EBX, dwDllBase XOR EAX, EAX ; EAX AddressOfNames Index .REPEAT MOV EDI, [EBX] ADD EDI, dwDllBase MOV ESI, szApi PUSH ECX ; save the api string length REPZ CMPSB .IF ZERO? .BREAK .ENDIF POP ECX ADD EBX, 4 INC EAX .UNTIL EAX == [EDX].NumberOfNames ; find the corresponding Ordinal MOV ESI, [EDX].AddressOfNameOrdinals ADD ESI, dwDllBase PUSH EDX ; save the export table pointer MOV EBX, 2 XOR EDX, EDX MUL EBX ;POP EDX ADD EAX, ESI XOR ECX, ECX MOV WORD PTR CX, [EAX] ; ECX -> Api Ordinal POP EDX ; get the address of the api MOV EDI, [EDX].AddressOfFunctions XOR EDX, EDX MOV EBX, 4 MOV EAX, ECX MUL EBX ADD EAX, dwDllBase ADD EAX, EDI MOV EAX, [EAX] ADD EAX, dwDllBase JMP @@ExitProc ASSUME EDX : NOTHING @@BadExit: XOR EAX, EAX @@ExitProc: RET GetProcAddr ENDP