Lazy Importer Save

library for importing functions from dlls in a hidden, reverse engineer unfriendly way

Project README

lazy importer

A simple and easy to use header only library to make the life of a reverse engineer much harder.

small example

LI_FN(OutputDebugStringA)("hello world");
LI_FN(VirtualProtect).in(LI_MODULE("kernel32.dll").cached());

IDA output when compiling first line

features

  • Does not leave any strings in memory.
  • Does not allocate any memory.
  • Can be easily inlined.
  • Does not leave any imports in the executable.
  • Produces extremely small assembly.
  • Non caching functions do not leave anything in data sections.
  • Hashes are randomized for each compilation to defeat basic hash database attacks.

documentation

  • LI_FN(function_pointer) -> lazy_function
  • LI_FN_DEF(function_type) -> lazy_function
  • LI_MODULE(module_name) -> lazy_module

  • safe indicates that when function cannot complete its task successfully 0 is returned instead of undefined behaviour manifesting.
  • cached indicates that the result is only computed during the first call and later reused.
  • forwarded indicates that export forwarding will be correctly resolved.

lazy_module

function safe cached
Attempts to find the given module and returns its address
get() -> T :x: :x:
safe() -> T :white_check_mark: :x:
cached() -> T :x: :white_check_mark:
safe_cached() -> T :white_check_mark: :white_check_mark:
Attemps to find the given module using the given LDR_DATA_TABLE_ENTRY pointer
in(Ldr ldr_entry) -> T :white_check_mark: :x:
in_cached(Ldr ldr_entry) -> T :white_check_mark: :white_check_mark:

lazy_function<F>

function safe cached forwarded
calls resolved export using given arguments
operator()(...) -> result_of :x: :x: :x:
attempts to resolve an export in all loaded modules and returns the function address
get() -> T :x: :x: :x:
safe() -> T :white_check_mark: :x: :x:
cached() -> T :x: :white_check_mark: :x:
safe_cached() -> T :white_check_mark: :white_check_mark: :x:
forwarded() -> T :x: :x: :white_check_mark:
forwarded_safe() -> T :white_check_mark: :x: :white_check_mark:
forwarded_cached() -> T :x: :white_check_mark: :white_check_mark:
forwarded_safe_cached() -> T :white_check_mark: :white_check_mark: :white_check_mark:
attempts to resolve an export in the given module and returns the function address
in(A module_address) -> T :x: :x: :x:
in_safe(A module_address) -> T :white_check_mark: :x: :x:
in_cached(A module_address) -> T :x: :white_check_mark: :x:
in_safe_cached(A module_address) -> T :white_check_mark: :white_check_mark: :x:
attempts to resolve an export in ntdll and returns the function address
nt() -> T :x: :x: :x:
nt_safe() -> T :white_check_mark: :x: :x:
nt_cached() -> T :x: :white_check_mark: :x:
nt_safe_cached() -> T :white_check_mark: :white_check_mark: :x:

extra configuration

#define effects
LAZY_IMPORTER_NO_FORCEINLINE disables force inlining
LAZY_IMPORTER_CASE_INSENSITIVE enables case insensitive comparison. Might be required for forwarded export resolution.
LAZY_IMPORTER_CACHE_OPERATOR_PARENS uses cached() instead of get() in operator() of lazy_function
LAZY_IMPORTER_RESOLVE_FORWARDED_EXPORTS uses forwarded() in get(). WARNING does not apply to nt() and in().
LAZY_IMPORTER_HARDENED_MODULE_CHECKS adds extra sanity checks to module enumeration.
LAZY_IMPORTER_NO_CPP_FORWARD Removes dependence on <utility> c++ header.

example output

for ( i = *(_QWORD **)(*(_QWORD *)(__readgsqword(0x60u) + 24) + 16i64); ; i = (_QWORD *)*i )
  {
    v1 = i[6];
    v2 = *(unsigned int *)(*(signed int *)(v1 + 60) + v1 + 136);
    v3 = (_DWORD *)(v2 + v1);
    if ( v2 + v1 != v1 )
    {
      LODWORD(v4) = v3[6];
      if ( (_DWORD)v4 )
        break;
    }
LABEL_8:
    ;
  }
  while ( 1 )
  {
    v4 = (unsigned int)(v4 - 1);
    v5 = -2128831035;
    v6 = (char *)(v1 + *(unsigned int *)((unsigned int)v3[8] + 4 * v4 + v1));
    v7 = *v6;
    v8 = (signed __int64)(v6 + 1);
    if ( v7 )
    {
      do
      {
        ++v8;
        v5 = 16777619 * (v5 ^ v7);
        v7 = *(_BYTE *)(v8 - 1);
      }
      while ( v7 );
      if ( v5 == -973690651 )
        break;
    }
    if ( !(_DWORD)v4 )
      goto LABEL_8;
  }
  ((void (__fastcall *)(const char *))(v1
                                     + *(unsigned int *)(v1
                                                       + (unsigned int)v3[7]
                                                       + 4i64 * *(unsigned __int16 *)(v1 + (unsigned int)v3[9] + 2 * v4))))("hello world");

People that have supported this project

I would like to thank people that have reached out to me and donated some money to support me and my projects

Open Source Agenda is not affiliated with "Lazy Importer" Project. README Source: JustasMasiulis/lazy_importer

Open Source Agenda Badge

Open Source Agenda Rating