Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/justasmasiulis/lazy_importer
library for importing functions from dlls in a hidden, reverse engineer unfriendly way
https://github.com/justasmasiulis/lazy_importer
anti-reversing compile-time cpp export game-hacking getmodulehandle getprocaddress hashing header-only import malware obfuscation reverse-engineering small static-analysis windows
Last synced: 23 days ago
JSON representation
library for importing functions from dlls in a hidden, reverse engineer unfriendly way
- Host: GitHub
- URL: https://github.com/justasmasiulis/lazy_importer
- Owner: JustasMasiulis
- License: apache-2.0
- Created: 2018-01-24T18:13:42.000Z (almost 7 years ago)
- Default Branch: master
- Last Pushed: 2023-08-03T01:51:27.000Z (over 1 year ago)
- Last Synced: 2024-10-14T09:23:30.314Z (23 days ago)
- Topics: anti-reversing, compile-time, cpp, export, game-hacking, getmodulehandle, getprocaddress, hashing, header-only, import, malware, obfuscation, reverse-engineering, small, static-analysis, windows
- Language: C++
- Homepage:
- Size: 93.8 KB
- Stars: 1,639
- Watchers: 41
- Forks: 220
- Open Issues: 4
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README
# lazy importer [![](https://img.shields.io/badge/version-2.1.0-green.svg)]()
A simple and easy to use header only library to make the life of a reverse engineer much harder.
## small example
```cpp
LI_FN(OutputDebugStringA)("hello world");
LI_FN(VirtualProtect).in(LI_MODULE("kernel32.dll").cached());
```[IDA output when compiling first line](#example-output)
## 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 = void*>() -> T
:x:
:x:
safe<T = void*>() -> T
:white_check_mark:
:x:
cached<T = void*>() -> T
:x:
:white_check_mark:
safe_cached<T = void*>() -> T
:white_check_mark:
:white_check_mark:
Attemps to find the given module using the given LDR_DATA_TABLE_ENTRY pointer
in<T = void*, Ldr>(Ldr ldr_entry) -> T
:white_check_mark:
:x:
in_cached<T = void*, Ldr>(Ldr ldr_entry) -> T
:white_check_mark:
:white_check_mark:
#### **`lazy_function`**
function
safe
cached
forwarded
calls resolved export using given arguments
operator()(...) -> result_of<F, ...>
:x:
:x:
:x:
attempts to resolve an export in all loaded modules and returns the function address
get<T = F>() -> T
:x:
:x:
:x:
safe<T = F>() -> T
:white_check_mark:
:x:
:x:
cached<T = F>() -> T
:x:
:white_check_mark:
:x:
safe_cached<T = F>() -> T
:white_check_mark:
:white_check_mark:
:x:
forwarded<T = F>() -> T
:x:
:x:
:white_check_mark:
forwarded_safe<T = F>() -> T
:white_check_mark:
:x:
:white_check_mark:
forwarded_cached<T = F>() -> T
:x:
:white_check_mark:
:white_check_mark:
forwarded_safe_cached<T = F>() -> 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<T = F, A>(A module_address) -> T
:x:
:x:
:x:
in_safe<T = F, A>(A module_address) -> T
:white_check_mark:
:x:
:x:
in_cached<T = F, A>(A module_address) -> T
:x:
:white_check_mark:
:x:
in_safe_cached<T = F, A>(A module_address) -> T
:white_check_mark:
:white_check_mark:
:x:
attempts to resolve an export inntdll
and returns the function address
nt<T = F>() -> T
:x:
:x:
:x:
nt_safe<T = F>() -> T
:white_check_mark:
:x:
:x:
nt_cached<T = F>() -> T
:x:
:white_check_mark:
:x:
nt_safe_cached<T = F>() -> 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 `` c++ header. |## example output
```c
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* [@DefCon42](https://github.com/DefCon42)
* [@Mecanik](https://github.com/Mecanik)