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