Is there any way to avoid RTL?

I played with something in Delphi where RTL is not allowed. This is a kind of dll.

After choosing the PE (Portable Executable) file format, I realized that all PE files have an “entry point”. This is the first thing Windows calls after loading a module (exe or dll).

The name of the function that is at this entry point, and the implied parameters, depends on the type of PE:

  • Dynamic Link Library (* .dll): DllMain

    function DllMain(hinstDLL: HINST; fdwReason: DWORD; 
          lpvReserved: Pointer): BOOL; stdcall;
    
  • Executable file (* .exe): WinMain

    function WinMain(hInstance: HINST; hPrevInstance: HINST; 
          lpCmdLine: LPSTR; nCmdShow: Integer): Integer; stdcall;
    
  • Device Driver (* .sys): DriverEntry

    function DriverEntry(DriverObject: PDriverObject; 
          RegistryPath: PUnicodeString): NTSTATUS; stdcall;
    

In Delphi, this entry point is the code that is in your main project file.

In the case of a DLL, you can read the parameters passed to our "DllMain" on LoadLibrary. If you set a breakpoint in EntryPointAddress:

enter image description here

you can see three parameters on the stack:

enter image description here

All you have to do is grab them:

library Project1;

function DllMain(hinstDLL: HINST; fdwReason: Cardinal; lpvReserved: Pointer): Integer; stdcall;
begin
    Result := 1; //Windows uses FALSE=0, TRUE=1. Delphi uses False=0, True=-1
end;

begin
    //Code in here is run during DllMain.
    //i.e. DllMain does not return until this code completes.
    asm
        { Get the parameters to DllMain that Windows passed to us:
                [ESP+4] hinstDLL
                [ESP+8] fdwReason
                [ESP+12] lpvReserved
        }
        MOV eax, [ESP+12];  //push lpvReserved onto the stack
        PUSH eax;
        MOV eax, [ESP+8];  //push fdwReason onto the stack
        PUSH eax
        MOV eax, [ESP+4];  //push hinstDLL onto the stack
        PUSH eax;

        CALL DllMain;       //Call our DllMain function
                            //DllMain leaves BOOL result in EAX
   end;
end.

But there is RTL

, . , :

enter image description here

, DllMain :

function DllMain(hinstDLL: HINST; fdwReason: Cardinal; lpvReserved: Pointer): LongBool; stdcall;
begin
    SysInit._InitLib(InitTable, hinstDLL, fdwReason, lpvReserved);

    asm
        MOV eax, [ESP+12];  //push lpvReserved onto the stack
        PUSH eax;
        MOV eax, [ESP+8];  //push fdwReason onto the stack
        PUSH eax
        MOV eax, [ESP+4];  //push hinstDLL onto the stack
        PUSH eax;

        CALL DllMain;       //Call our DllMain function
                            //DllMain leaves BOOL result in EAX
   end;

   System._Halt0;
end;

_InitLib , hinstDLL fdwReason; (, EBP+8, +12 +16).

, RTL , . Import Directory, , :

  • user32.dll (, MessageBoxA)
  • kernel32.dll (, VirtualAlloc, VirtualFree, CloseHandle)

RTL?

, System._InitLib System._Halt0? :

function DllMain(hinstDLL: HINST; fdwReason: Cardinal; lpvReserved: Pointer): LongBool; stdcall;
begin
   SysInit._InitLib(InitTable, hinstDLL, fdwReason, lpvReserved);

   //...
   System._Halt0;
end;

, , , , . , EntryPointProcedure, , .

: WinMain

WinMain :

function WinMain(hInstance: HINST; hPrevInstance: HINST; 
          lpCmdLine: LPSTR; nCmdShow: Integer): Integer; stdcall;
  • hInstance: HINSTANCE
  • hPrevInstance: HINSTANCE
  • lpCmdLine: LPSTR
  • nCmdShow: Integer

, EntryPointFunction:

enter image description here

. . Windows Entry Point. :

Windows .exe:

DWORD CALLBACK RawEntryPoint(void);

:

function RawEntryPoint(): DWORD; stdcall;

WinMain, ?

, :

  • GetModuleHandle(NULL)
  • GetCommandLine
  • nCmdShow GetStartupInfo
  • hPrevInstance NULL

, .

+4
3

, , /RTL. System SysInit . , , , System.

System SysInit, , . .

, , , FPC.

+4

KOL , http://kolmck.net ( ) , .

+8

DLL DPR, hinstDLL RTL SysInit.HInstance, , fdwReason DLL_PROCESS_ATTACH. , DLL_PROCESS_ATTACH, - lpvReserved, RTL , -. , , fdwReason lpvReserved , , , DllProcEx, RTL DllMain , :

library Project1;

{$R *.res}

procedure MyDllMain(Reason: Integer; Reserved: Pointer);
begin
  // use SysInit.HInstance, Reason, and Reserved as needed...
  case Reason of
    //...
  end;
end;

begin
  DllProcEx := @MyDllMain;
  // The RTL does not expose access to lpvReserved here because 
  // DllProcEx has not been assigned yet when the RTL processes
  // DLL_PROCESS_ATTACH before calling unit initializations. If
  // you need lpvReserved here, you will have to manually pull
  // it from the call stack directly...
  DllProcEx(DLL_PROCESS_ATTACH, nil);
end.
+1

All Articles