Illusion Dolphin, как обстоят дела с x64?
Цитата(Illusion Dolphin @ 25.12.2012, 10:48 ) | и убрать ассемблемные вставки |
Это не совсем вставка, это внедряемый загрузчик. Его можно заменить массивом-константой, но тогда нельзя будет его редактировать.
32for32
Код | const LoaderSize=82; //размер загрузчика Loader определяется через вызов Loader+останов -> Ctrl+Alt+C ->F7 ->LoaderSize=[end]-[begin]
//{ procedure Loader; //Внедряемый загрузчик,для удобства, выполнен в виде ассемблерной процедуры. asm mov ebp,esp push $11111110 // virtualprotect ebp-4 push $11111111 // loadlibrary ebp-8 push $11111112 // dll name ebp-12 push $11111113 // old cod ebp-16 push $11111114 // start adr ebp-20 sub esp,4 // место под memflag lea eax,[ebp-24] push eax //oldflag push $40 //PAGE_READWRITE push 5 //size push [ebp-20] //adr call [ebp-4] //virtualprotect xor ecx,ecx mov cl,5 //5 байт копировать mov esi,[ebp-16] //сохраненный код mov edi,[ebp-20] //точка входа cld rep movsb lea eax,[ebp-24] push eax //oldflag //адрес для сохранения флага push [eax] //oldflag push 5 //size push [ebp-20]//adr call [ebp-4] //virtualprotect push [ebp-12] //dll name call [ebp-8]//loadlibrary mov esp,ebp jmp [ebp-20]//goto start @b// end; //}
// кому не нравится ассемблер - может принять на веру и взять загрузчик в виде массива-константы //закомментировав Loader и раскомментировав последующие строки {// type PLoadData=^TLoadData; TLoadData=array[0..LoaderSize-1]of byte;
const cLoader:TLoadData = ( $89,$E5,$68,$10,$11,$11,$11,$68, $11,$11,$11,$11,$68,$12,$11,$11, $11,$68,$13,$11,$11,$11,$68,$14, $11,$11,$11,$83,$EC,$04,$8D,$45, $E8,$50,$6A,$40,$6A,$05,$FF,$75, $EC,$FF,$55,$FC,$31,$C9,$B1,$05, $8B,$75,$F0,$8B,$7D,$EC,$FC,$F3, $A4,$8D,$45,$E8,$50,$FF,$30,$6A, $05,$FF,$75,$EC,$FF,$55,$FC,$FF, $75,$F4,$FF,$55,$F8,$89,$EC,$FF, $65,$EC); //}
type PAdrRec=^TAdrRec; TAdrRec=packed record rb1:array [0..2]of byte; VirtualProtectAdr:pointer; rb2:byte; LoadLibraryAdr:pointer; rb3:byte; DllNameAdr:cardinal; rb4:byte; EPCodeAdr:cardinal; rb5:byte; EPAdr:cardinal; end;
TJmp=packed record jb:byte; //$E9 jsize:cardinal; end;
function inject32(exe_name,dll_name:string):bool; var h:cardinal; fm:cardinal; p,p1:pointer; entpoint:cardinal; si:TStartupInfo; pi:TProcessInformation; ob:TOFStruct; mem:pointer; memsize:cardinal; procmem:pointer; {// // раскомментировать если используем cLoader PLoad:PLoadData; //} PAdr:PAdrRec; hdll:cardinal; bc:NativeUInt; //cardinal jmp:TJmp; //e:cardinal; //buff:array[0..255]of char; const LoadLibraryName:array[1..2]of pchar =('LoadLibraryA','LoadLibraryW'); begin result:=false; fillchar(si,sizeof(si),0); fillchar(pi,sizeof(pi),0); h:=0; fm:=0; p:=nil; mem:=nil; try h:=CreateFile(pchar(exe_name),GENERIC_READ,FILE_SHARE_READ or FILE_SHARE_WRITE,nil,OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL,0); fm:=CreateFileMapping(h,nil,PAGE_READONLY ,0,getfilesize(h,nil),nil); p:=MapViewOfFile(fm,FILE_MAP_READ,0,0,0); if p=nil then exit; if PImageDosHeader(p)^.e_magic<>IMAGE_DOS_SIGNATURE then exit; p1:=pointer(cardinal(p)+PImageDosHeader(p)^._lfanew); if (PIMAGENTHEADERS(p1)^.Signature<>IMAGE_NT_SIGNATURE)or //если файл не PE (PIMAGENTHEADERS(p1)^.FileHeader.Machine<>IMAGE_FILE_MACHINE_I386)or //или если файл не Win32 (PIMAGENTHEADERS(p1)^.OptionalHeader.Magic<>IMAGE_NT_OPTIONAL_HDR32_MAGIC)//или если заголовок OptionalHeader не PE32 then exit; entpoint:=PIMAGENTHEADERS(p1).OptionalHeader.ImageBase+PIMAGENTHEADERS(p1).OptionalHeader.AddressOfEntryPoint; if (entpoint=0) or //если адрес точки входа нулевой (IMAGE_FILE_EXECUTABLE_IMAGE<>(IMAGE_FILE_EXECUTABLE_IMAGE and PIMAGENTHEADERS(p1).FileHeader.Characteristics))or //или если файл не исполняемый (IMAGE_FILE_DLL=(IMAGE_FILE_DLL and PIMAGENTHEADERS(p1).FileHeader.Characteristics))//или если файл dll then exit; si.cb:=sizeof(si); if not createprocess(nil,pchar(exe_name),nil,nil,true,CREATE_SUSPENDED,nil,nil,si,pi)then exit; memsize:=LoaderSize+sizeof(tjmp)+(length(dll_name)+1)*sizeof(dll_name[1]); getmem(mem,memsize); procmem:=VirtualAllocEx(pi.hProcess,nil,memsize,MEM_COMMIT, PAGE_EXECUTE_READWRITE); if procmem=nil then exit; PAdr:=mem; //{ move((@loader)^,mem^,LoaderSize); //закомментировать если используем сLoader //} {// PLoad:=mem; // раскомментировать если используем cLoader PLoad^:=cLoader; //} hdll:=GetModuleHandle('kernel32.dll'); PAdr^.VirtualProtectAdr:=GetProcAddress(hdll,'VirtualProtect'); PAdr^.LoadLibraryAdr:=GetProcAddress(hdll,LoadLibraryName[sizeof(dll_name[1])]); PAdr^.DllNameAdr:=cardinal(procmem)+LoaderSize+sizeof(tjmp); PAdr^.EPCodeAdr:=cardinal(procmem)+LoaderSize; PAdr^.EPAdr:=entpoint; StrCopy(PChar(cardinal(mem)+LoaderSize+sizeof(tjmp)),PChar(dll_name)); jmp.jb:=$E9; jmp.jsize:=cardinal(procmem)-entpoint-sizeof(tjmp); if not ReadProcessMemory(pi.hProcess,pointer(entpoint),pointer(cardinal(mem)+LoaderSize),sizeof(tjmp),bc) or not WriteProcessMemory(pi.hProcess,pointer(entpoint),@jmp,sizeof(TJmp),bc) or not WriteProcessMemory(pi.hProcess,procmem,mem,memsize,bc) then begin //e:=GetLastError; //FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM,nil,e,0,@buff,sizeof(buff),0); //MessageBox(0,@buff,pchar('Error:'+inttostr(e)),0); TerminateProcess(pi.hProcess,0); exit; end; ResumeThread(pi.hThread); finally FreeMem(mem); CloseHandle(pi.hProcess); CloseHandle(pi.hThread); UnMapViewOfFile(p); CloseHandle(fm); CloseHandle(h) end;
result:=true; end;
|
64for64
Код | const LoaderSize=152; //размер загрузчика Loader определяется через вызов Loader+останов -> Ctrl+Alt+C ->F7 ->LoaderSize=[end]-[begin] //{ procedure Loader; //Внедряемый загрузчик,для удобства, выполнен в виде ассемблерной процедуры. asm push rbp mov rax, $0000000000000001 // virtualprotect rbp+$48 push rax mov rax, $0000000000000002 // loadlibrary rbp+$40 push rax mov rax, $0000000000000003 // dll name rbp+$38 push rax mov rax, $0000000000000004 // EP data rbp+$30 push rax mov rax, $0000000000000005 // EP adr rbp+$28 push rax sub rsp,$28 // переменная сохранения флага памяти rbp+$20 +32байта резерв mov rbp,rsp
mov rcx,[rbp+$28] //Адрес точки входа mov rdx,12 //12 байт mov r8,PAGE_READWRITE //новый флаг памяти lea r9,[rbp+$20] //куда сохранять старый флаг call [rbp+$48] //virtualprotect
xor rcx,rcx mov cl,12 //копировать 12 байт mov rsi,[rbp+$30] //источник - оригинальные данные mov rdi,[rbp+$28] //приемник - точка входа cld //направление ВПЕРЕД rep movsb //копировать
mov rcx,[rbp+$38] //адрес с именем dll call [rbp+$40] //loadlibrary
mov rcx,[rbp+$28] //Адрес точки входа mov rdx,12 //12 байт lea r9,[rbp+$20] //куда сохранять флаг памяти mov r8,[r9] //востанавливаем старый флаг call [rbp+$48] //virtualprotect
mov rax,[rbp+$28] //адреc точки входа lea rsp,[rbp+$50] //востанавливаем стек pop rbp //востаавливаем rbp push rax //в стек адрес точки входа ret //возвращаемся на точку входа end; //}
// кому не нравится ассемблер - может принять на веру и взять загрузчик в виде массива-константы //закоментировав Loader и раскоментировав последующие строки {// type PLoadData=^TLoadData; TLoadData=array[0..LoaderSize-1]of byte;
const cLoader:TLoadData=( $55,$48,$B8,$01,$00,$00,$00,$00, $00,$00,$00,$50,$48,$B8,$02,$00, $00,$00,$00,$00,$00,$00,$50,$48, $B8,$03,$00,$00,$00,$00,$00,$00, $00,$50,$48,$B8,$04,$00,$00,$00, $00,$00,$00,$00,$50,$48,$B8,$05, $00,$00,$00,$00,$00,$00,$00,$50, $48,$83,$EC,$28,$48,$89,$E5,$48, $8B,$4D,$28,$48,$BA,$0C,$00,$00, $00,$00,$00,$00,$00,$49,$B8,$04, $00,$00,$00,$00,$00,$00,$00,$4C, $8D,$4D,$20,$FF,$55,$48,$48,$31, $C9,$B1,$0C,$48,$8B,$75,$30,$48, $8B,$7D,$28,$FC,$F3,$A4,$48,$8B, $4D,$38,$FF,$55,$40,$48,$8B,$4D, $28,$48,$BA,$0C,$00,$00,$00,$00, $00,$00,$00,$4C,$8D,$4D,$20,$4D, $8B,$01,$FF,$55,$48,$48,$8B,$45, $28,$48,$8D,$65,$50,$5D,$50,$C3); //}
type PAdrRec=^TAdrRec; TAdrRec=packed record rb1:array[0..2]of byte; VirtualProtectAdr:pointer; rb2:array[0..2]of byte; LoadLibraryAdr:pointer; rb3:array[0..2]of byte; DllNameAdr:NativeUInt; rb4:array[0..2]of byte; EPCodeAdr:NativeUInt; rb5:array[0..2]of byte; EPAdr:NativeUInt; end;
TJmp=packed record movrax:word; //$B848 adr:pointer; pushrax:byte; //$50 ret:byte; //$c3 end;
function inject64(exe_name,dll_name:string):bool; var h:THandle; fm:THandle; p,p1:pointer; entpoint:NativeUInt; si:TStartupInfo; pi:TProcessInformation; ob:TOFStruct; mem:pointer; memsize:NativeUInt; procmem:pointer; {// // раскоментировать если используем cLoader PLoad:PLoadData; //} PAdr:PAdrRec; hdll:THandle; bc:NativeUInt; jmp:TJmp; //e:cardinal; //buff:array[0..255]of char; begin result:=false; fillchar(si,sizeof(si),0); fillchar(pi,sizeof(pi),0); h:=0; fm:=0; p:=nil; mem:=nil; try h:=CreateFile(pchar(exe_name),GENERIC_READ,FILE_SHARE_READ or FILE_SHARE_WRITE,nil,OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL,0); fm:=CreateFileMapping(h,nil,PAGE_READONLY ,0,getfilesize(h,nil),nil); p:=MapViewOfFile(fm,FILE_MAP_READ,0,0,0); if p=nil then exit; if PImageDosHeader(p)^.e_magic<>IMAGE_DOS_SIGNATURE then exit; p1:=pointer(NativeUInt(p)+PImageDosHeader(p)^._lfanew); if (PIMAGENTHEADERS(p1)^.Signature<>IMAGE_NT_SIGNATURE)or //если файл не PE (// (PIMAGENTHEADERS(p1)^.FileHeader.Machine<>IMAGE_FILE_MACHINE_IA64) and // ??? на IA64 файлах не проверял (PIMAGENTHEADERS(p1)^.FileHeader.Machine<>IMAGE_FILE_MACHINE_AMD64) )or //или если файл не Win64 (PIMAGENTHEADERS(p1)^.OptionalHeader.Magic<>IMAGE_NT_OPTIONAL_HDR64_MAGIC)//или если заголовок OptionalHeader не PE64 then exit; entpoint:=PIMAGENTHEADERS(p1).OptionalHeader.ImageBase+PIMAGENTHEADERS(p1).OptionalHeader.AddressOfEntryPoint; if (entpoint=0) or //если адрес точки входа нулевой (IMAGE_FILE_EXECUTABLE_IMAGE<>(IMAGE_FILE_EXECUTABLE_IMAGE and PIMAGENTHEADERS(p1).FileHeader.Characteristics))or //или если файл не исполняемый (IMAGE_FILE_DLL=(IMAGE_FILE_DLL and PIMAGENTHEADERS(p1).FileHeader.Characteristics))//или если файл dll then exit; si.cb:=sizeof(si); if not createprocess(nil,pchar(exe_name),nil,nil,true,CREATE_SUSPENDED,nil,nil,si,pi)then exit; memsize:=LoaderSize+sizeof(tjmp)+(length(dll_name)+1)*2; getmem(mem,memsize); procmem:=VirtualAllocEx(pi.hProcess,nil,memsize,MEM_COMMIT, PAGE_EXECUTE_READWRITE); if procmem=nil then exit; PAdr:=mem; //{ move((@loader)^,mem^,LoaderSize); //закоментировать если используем сLoader //} {// PLoad:=mem; // раскоментировать если используем cLoader PLoad^:=cLoader; //} hdll:=GetModuleHandle('kernel32.dll'); PAdr^.VirtualProtectAdr:=GetProcAddress(hdll,'VirtualProtect'); PAdr^.LoadLibraryAdr:=GetProcAddress(hdll,'LoadLibraryW'); PAdr^.DllNameAdr:=NativeUInt(procmem)+LoaderSize+sizeof(tjmp); PAdr^.EPCodeAdr:=NativeUInt(procmem)+LoaderSize; PAdr^.EPAdr:=entpoint; StrCopy(PChar(NativeUInt(mem)+LoaderSize+sizeof(tjmp)),PChar(dll_name)); jmp.movrax:=$B848; jmp.adr:=procmem; jmp.pushrax:=$50; jmp.ret:=$C3; if not ReadProcessMemory(pi.hProcess,pointer(entpoint),pointer(NativeUInt(mem)+LoaderSize),sizeof(tjmp),bc) or not WriteProcessMemory(pi.hProcess,pointer(entpoint),@jmp,sizeof(TJmp),bc) or not WriteProcessMemory(pi.hProcess,procmem,mem,memsize,bc) then begin //e:=GetLastError; //FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM,nil,e,0,@buff,sizeof(buff),0); //MessageBox(0,@buff,pchar('Error:'+inttostr(e)),0); TerminateProcess(pi.hProcess,0); exit; end; ResumeThread(pi.hThread); finally FreeMem(mem); CloseHandle(pi.hProcess); CloseHandle(pi.hThread); UnMapViewOfFile(p); CloseHandle(fm); CloseHandle(h) end;
result:=true; end;
|
|