{"id":15025810,"url":"https://github.com/justasmasiulis/lazy_importer","last_synced_at":"2025-04-08T00:36:27.148Z","repository":{"id":39179936,"uuid":"118803332","full_name":"JustasMasiulis/lazy_importer","owner":"JustasMasiulis","description":"library for importing functions from dlls in a hidden, reverse engineer unfriendly way","archived":false,"fork":false,"pushed_at":"2023-08-03T01:51:27.000Z","size":96,"stargazers_count":1735,"open_issues_count":5,"forks_count":228,"subscribers_count":40,"default_branch":"master","last_synced_at":"2025-04-08T00:36:21.635Z","etag":null,"topics":["anti-reversing","compile-time","cpp","export","game-hacking","getmodulehandle","getprocaddress","hashing","header-only","import","malware","obfuscation","reverse-engineering","small","static-analysis","windows"],"latest_commit_sha":null,"homepage":"","language":"C++","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/JustasMasiulis.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null}},"created_at":"2018-01-24T18:13:42.000Z","updated_at":"2025-04-07T15:05:44.000Z","dependencies_parsed_at":"2024-01-14T06:56:04.016Z","dependency_job_id":null,"html_url":"https://github.com/JustasMasiulis/lazy_importer","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/JustasMasiulis%2Flazy_importer","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/JustasMasiulis%2Flazy_importer/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/JustasMasiulis%2Flazy_importer/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/JustasMasiulis%2Flazy_importer/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/JustasMasiulis","download_url":"https://codeload.github.com/JustasMasiulis/lazy_importer/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247755560,"owners_count":20990620,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["anti-reversing","compile-time","cpp","export","game-hacking","getmodulehandle","getprocaddress","hashing","header-only","import","malware","obfuscation","reverse-engineering","small","static-analysis","windows"],"created_at":"2024-09-24T20:03:04.145Z","updated_at":"2025-04-08T00:36:27.123Z","avatar_url":"https://github.com/JustasMasiulis.png","language":"C++","funding_links":[],"categories":[],"sub_categories":[],"readme":"# lazy importer [![](https://img.shields.io/badge/version-2.1.0-green.svg)]()\n\nA simple and easy to use header only library to make the life of a reverse engineer much harder.\n\n## small example\n\n```cpp\nLI_FN(OutputDebugStringA)(\"hello world\");\nLI_FN(VirtualProtect).in(LI_MODULE(\"kernel32.dll\").cached());\n```\n\n[IDA output when compiling first line](#example-output)\n\n## features\n\n- Does not leave any strings in memory.\n- Does not allocate any memory.\n- Can be easily inlined.\n- Does not leave any imports in the executable.\n- Produces extremely small assembly.\n- Non caching functions do not leave anything in data sections.\n- Hashes are randomized for each compilation to defeat basic hash database attacks.\n\n## documentation\n\n- `LI_FN(function_pointer)  -\u003e lazy_function`\n- `LI_FN_DEF(function_type) -\u003e lazy_function`\n- `LI_MODULE(module_name)  -\u003e lazy_module`\n\n---\n\n- `safe` indicates that when function cannot complete its task successfully 0 is returned instead of undefined behaviour manifesting.\n- `cached` indicates that the result is only computed during the first call and later reused.\n- `forwarded` indicates that export forwarding will be correctly resolved.\n\n#### **`lazy_module`**\n\n\u003ctable\u003e\n  \u003ctr\u003e\n    \u003cth\u003efunction\u003c/th\u003e\n    \u003cth\u003esafe\u003c/th\u003e\n    \u003cth\u003ecached\u003c/th\u003e\n  \u003c/tr\u003e\n  \u003ctr\u003e\n    \u003ctd colspan=\"4\"\u003eAttempts to find the given module and returns its address\u003c/td\u003e\n  \u003c/tr\u003e\n  \u003ctr\u003e\n    \u003ctd\u003e\u003ccode\u003eget\u0026lt;T = void*\u0026gt;() -\u0026gt; T\u003c/code\u003e\u003c/td\u003e\n    \u003ctd align=\"center\"\u003e:x:\u003c/td\u003e\n    \u003ctd align=\"center\"\u003e:x:\u003c/td\u003e\n  \u003c/tr\u003e\n    \u003ctr\u003e\n    \u003ctd\u003e\u003ccode\u003esafe\u0026lt;T = void*\u0026gt;() -\u0026gt; T\u003c/code\u003e\u003c/td\u003e\n    \u003ctd align=\"center\"\u003e:white_check_mark:\u003c/td\u003e\n    \u003ctd align=\"center\"\u003e:x:\u003c/td\u003e\n  \u003c/tr\u003e\n  \u003ctr\u003e\n    \u003ctd\u003e\u003ccode\u003ecached\u0026lt;T = void*\u0026gt;() -\u0026gt; T\u003c/code\u003e\u003c/td\u003e\n    \u003ctd align=\"center\"\u003e:x:\u003c/td\u003e\n    \u003ctd align=\"center\"\u003e:white_check_mark:\u003c/td\u003e\n  \u003c/tr\u003e\n  \u003ctr\u003e\n    \u003ctd\u003e\u003ccode\u003esafe_cached\u0026lt;T = void*\u0026gt;() -\u0026gt; T\u003c/code\u003e\u003c/td\u003e\n    \u003ctd align=\"center\"\u003e:white_check_mark:\u003c/td\u003e\n    \u003ctd align=\"center\"\u003e:white_check_mark:\u003c/td\u003e\n  \u003c/tr\u003e\n  \u003ctr\u003e\n    \u003ctd colspan=\"4\"\u003eAttemps to find the given module using the given LDR_DATA_TABLE_ENTRY pointer\u003c/td\u003e\n  \u003c/tr\u003e\n  \u003ctr\u003e\n    \u003ctd\u003e\u003ccode\u003ein\u0026lt;T = void*, Ldr\u0026gt;(Ldr ldr_entry) -\u0026gt; T\u003c/code\u003e\u003c/td\u003e\n    \u003ctd align=\"center\"\u003e:white_check_mark:\u003c/td\u003e\n    \u003ctd align=\"center\"\u003e:x:\u003c/td\u003e\n  \u003c/tr\u003e\n  \u003ctr\u003e\n    \u003ctd\u003e\u003ccode\u003ein_cached\u0026lt;T = void*, Ldr\u0026gt;(Ldr ldr_entry) -\u0026gt; T\u003c/code\u003e\u003c/td\u003e\n    \u003ctd align=\"center\"\u003e:white_check_mark:\u003c/td\u003e\n    \u003ctd align=\"center\"\u003e:white_check_mark:\u003c/td\u003e\n  \u003c/tr\u003e\n\u003c/table\u003e\n\n#### **`lazy_function\u003cF\u003e`**\n\n\u003ctable\u003e\n  \u003ctr\u003e\n    \u003cth\u003efunction\u003c/th\u003e\n    \u003cth\u003esafe\u003c/th\u003e\n    \u003cth\u003ecached\u003c/th\u003e\n    \u003cth\u003eforwarded\u003c/th\u003e\n  \u003c/tr\u003e\n  \u003ctr\u003e\n    \u003ctd colspan=\"4\"\u003ecalls resolved export using given arguments\u003c/td\u003e\n  \u003c/tr\u003e\n  \u003ctr\u003e\n    \u003ctd\u003e\u003ccode\u003eoperator()(...) -\u0026gt; result_of\u0026lt;F, ...\u0026gt;\u003c/code\u003e\u003c/td\u003e\n    \u003ctd align=\"center\"\u003e:x:\u003c/td\u003e\n    \u003ctd align=\"center\"\u003e:x:\u003c/td\u003e\n    \u003ctd align=\"center\"\u003e:x:\u003c/td\u003e\n  \u003c/tr\u003e\n  \u003ctr\u003e\n    \u003ctd colspan=\"4\"\u003eattempts to resolve an export in all loaded modules and returns the function address\u003c/td\u003e\n  \u003c/tr\u003e\n  \u003ctr\u003e\n    \u003ctd\u003e\u003ccode\u003eget\u0026lt;T = F\u0026gt;() -\u0026gt; T\u003c/code\u003e\u003c/td\u003e\n    \u003ctd align=\"center\"\u003e:x:\u003c/td\u003e\n    \u003ctd align=\"center\"\u003e:x:\u003c/td\u003e\n    \u003ctd align=\"center\"\u003e:x:\u003c/td\u003e\n  \u003c/tr\u003e\n  \u003ctr\u003e\n    \u003ctd\u003e\u003ccode\u003esafe\u0026lt;T = F\u0026gt;() -\u0026gt; T\u003c/code\u003e\u003c/td\u003e\n    \u003ctd align=\"center\"\u003e:white_check_mark:\u003c/td\u003e\n    \u003ctd align=\"center\"\u003e:x:\u003c/td\u003e\n    \u003ctd align=\"center\"\u003e:x:\u003c/td\u003e\n  \u003c/tr\u003e\n  \u003ctr\u003e\n    \u003ctd\u003e\u003ccode\u003ecached\u0026lt;T = F\u0026gt;() -\u0026gt; T\u003c/code\u003e\u003c/td\u003e\n    \u003ctd align=\"center\"\u003e:x:\u003c/td\u003e\n    \u003ctd align=\"center\"\u003e:white_check_mark:\u003c/td\u003e\n    \u003ctd align=\"center\"\u003e:x:\u003c/td\u003e\n  \u003c/tr\u003e\n  \u003ctr\u003e\n    \u003ctd\u003e\u003ccode\u003esafe_cached\u0026lt;T = F\u0026gt;() -\u0026gt; T\u003c/code\u003e\u003c/td\u003e\n    \u003ctd align=\"center\"\u003e:white_check_mark:\u003c/td\u003e\n    \u003ctd align=\"center\"\u003e:white_check_mark:\u003c/td\u003e\n    \u003ctd align=\"center\"\u003e:x:\u003c/td\u003e\n  \u003c/tr\u003e\n  \u003ctr\u003e\n    \u003ctd\u003e\u003ccode\u003eforwarded\u0026lt;T = F\u0026gt;() -\u0026gt; T\u003c/code\u003e\u003c/td\u003e\n    \u003ctd align=\"center\"\u003e:x:\u003c/td\u003e\n    \u003ctd align=\"center\"\u003e:x:\u003c/td\u003e\n    \u003ctd align=\"center\"\u003e:white_check_mark:\u003c/td\u003e\n  \u003c/tr\u003e\n  \u003ctr\u003e\n    \u003ctd\u003e\u003ccode\u003eforwarded_safe\u0026lt;T = F\u0026gt;() -\u0026gt; T\u003c/code\u003e\u003c/td\u003e\n    \u003ctd align=\"center\"\u003e:white_check_mark:\u003c/td\u003e\n    \u003ctd align=\"center\"\u003e:x:\u003c/td\u003e\n    \u003ctd align=\"center\"\u003e:white_check_mark:\u003c/td\u003e\n  \u003c/tr\u003e\n  \u003ctr\u003e\n    \u003ctd\u003e\u003ccode\u003eforwarded_cached\u0026lt;T = F\u0026gt;() -\u0026gt; T\u003c/code\u003e\u003c/td\u003e\n    \u003ctd align=\"center\"\u003e:x:\u003c/td\u003e\n    \u003ctd align=\"center\"\u003e:white_check_mark:\u003c/td\u003e\n    \u003ctd align=\"center\"\u003e:white_check_mark:\u003c/td\u003e\n  \u003c/tr\u003e\n  \u003ctr\u003e\n    \u003ctd\u003e\u003ccode\u003eforwarded_safe_cached\u0026lt;T = F\u0026gt;() -\u0026gt; T\u003c/code\u003e\u003c/td\u003e\n    \u003ctd align=\"center\"\u003e:white_check_mark:\u003c/td\u003e\n    \u003ctd align=\"center\"\u003e:white_check_mark:\u003c/td\u003e\n    \u003ctd align=\"center\"\u003e:white_check_mark:\u003c/td\u003e\n  \u003c/tr\u003e\n  \u003ctr\u003e\n    \u003ctd colspan=\"4\"\u003eattempts to resolve an export in the given module and returns the function address\u003c/td\u003e\n  \u003c/tr\u003e\n  \u003ctr\u003e\n    \u003ctd\u003e\u003ccode\u003ein\u0026lt;T = F, A\u0026gt;(A module_address) -\u0026gt; T\u003c/code\u003e\u003c/td\u003e\n    \u003ctd align=\"center\"\u003e:x:\u003c/td\u003e\n    \u003ctd align=\"center\"\u003e:x:\u003c/td\u003e\n    \u003ctd align=\"center\"\u003e:x:\u003c/td\u003e\n  \u003c/tr\u003e\n  \u003ctr\u003e\n    \u003ctd\u003e\u003ccode\u003ein_safe\u0026lt;T = F, A\u0026gt;(A module_address) -\u0026gt; T\u003c/code\u003e\u003c/td\u003e\n    \u003ctd align=\"center\"\u003e:white_check_mark:\u003c/td\u003e\n    \u003ctd align=\"center\"\u003e:x:\u003c/td\u003e\n    \u003ctd align=\"center\"\u003e:x:\u003c/td\u003e\n  \u003c/tr\u003e\n  \u003ctr\u003e\n    \u003ctd\u003e\u003ccode\u003ein_cached\u0026lt;T = F, A\u0026gt;(A module_address) -\u0026gt; T\u003c/code\u003e\u003c/td\u003e\n    \u003ctd align=\"center\"\u003e:x:\u003c/td\u003e\n    \u003ctd align=\"center\"\u003e:white_check_mark:\u003c/td\u003e\n    \u003ctd align=\"center\"\u003e:x:\u003c/td\u003e\n  \u003c/tr\u003e\n  \u003ctr\u003e\n    \u003ctd\u003e\u003ccode\u003ein_safe_cached\u0026lt;T = F, A\u0026gt;(A module_address) -\u0026gt; T\u003c/code\u003e\u003c/td\u003e\n    \u003ctd align=\"center\"\u003e:white_check_mark:\u003c/td\u003e\n    \u003ctd align=\"center\"\u003e:white_check_mark:\u003c/td\u003e\n    \u003ctd align=\"center\"\u003e:x:\u003c/td\u003e\n  \u003c/tr\u003e\n  \u003ctr\u003e\n    \u003ctd colspan=\"4\"\u003eattempts to resolve an export in \u003ccode\u003entdll\u003c/code\u003e and returns the function address\u003c/td\u003e\n  \u003c/tr\u003e\n  \u003ctr\u003e\n    \u003ctd\u003e\u003ccode\u003ent\u0026lt;T = F\u0026gt;() -\u0026gt; T\u003c/code\u003e\u003c/td\u003e\n    \u003ctd align=\"center\"\u003e:x:\u003c/td\u003e\n    \u003ctd align=\"center\"\u003e:x:\u003c/td\u003e\n    \u003ctd align=\"center\"\u003e:x:\u003c/td\u003e\n  \u003c/tr\u003e\n  \u003ctr\u003e\n    \u003ctd\u003e\u003ccode\u003ent_safe\u0026lt;T = F\u0026gt;() -\u0026gt; T\u003c/code\u003e\u003c/td\u003e\n    \u003ctd align=\"center\"\u003e:white_check_mark:\u003c/td\u003e\n    \u003ctd align=\"center\"\u003e:x:\u003c/td\u003e\n    \u003ctd align=\"center\"\u003e:x:\u003c/td\u003e\n  \u003c/tr\u003e\n  \u003ctr\u003e\n    \u003ctd\u003e\u003ccode\u003ent_cached\u0026lt;T = F\u0026gt;() -\u0026gt; T\u003c/code\u003e\u003c/td\u003e\n    \u003ctd align=\"center\"\u003e:x:\u003c/td\u003e\n    \u003ctd align=\"center\"\u003e:white_check_mark:\u003c/td\u003e\n    \u003ctd align=\"center\"\u003e:x:\u003c/td\u003e\n  \u003c/tr\u003e\n  \u003ctr\u003e\n    \u003ctd\u003e\u003ccode\u003ent_safe_cached\u0026lt;T = F\u0026gt;() -\u0026gt; T\u003c/code\u003e\u003c/td\u003e\n    \u003ctd align=\"center\"\u003e:white_check_mark:\u003c/td\u003e\n    \u003ctd align=\"center\"\u003e:white_check_mark:\u003c/td\u003e\n    \u003ctd align=\"center\"\u003e:x:\u003c/td\u003e\n  \u003c/tr\u003e\n\u003c/table\u003e\n\n#### extra configuration\n\n| `#define`                                 | effects                                                                                 |\n| ----------------------------------------- | --------------------------------------------------------------------------------------- |\n| `LAZY_IMPORTER_NO_FORCEINLINE`            | disables force inlining                                                                 |\n| `LAZY_IMPORTER_CASE_INSENSITIVE`          | enables case insensitive comparison. Might be required for forwarded export resolution. |\n| `LAZY_IMPORTER_CACHE_OPERATOR_PARENS`     | uses `cached()` instead of `get()` in `operator()` of lazy_function                     |\n| `LAZY_IMPORTER_RESOLVE_FORWARDED_EXPORTS` | uses `forwarded()` in `get()`. WARNING does not apply to `nt()` and `in()`.             |\n| `LAZY_IMPORTER_HARDENED_MODULE_CHECKS`    | adds extra sanity checks to module enumeration.                                         |\n| `LAZY_IMPORTER_NO_CPP_FORWARD`            | Removes dependence on `\u003cutility\u003e` c++ header.                                           | \n\n## example output\n\n```c\nfor ( i = *(_QWORD **)(*(_QWORD *)(__readgsqword(0x60u) + 24) + 16i64); ; i = (_QWORD *)*i )\n  {\n    v1 = i[6];\n    v2 = *(unsigned int *)(*(signed int *)(v1 + 60) + v1 + 136);\n    v3 = (_DWORD *)(v2 + v1);\n    if ( v2 + v1 != v1 )\n    {\n      LODWORD(v4) = v3[6];\n      if ( (_DWORD)v4 )\n        break;\n    }\nLABEL_8:\n    ;\n  }\n  while ( 1 )\n  {\n    v4 = (unsigned int)(v4 - 1);\n    v5 = -2128831035;\n    v6 = (char *)(v1 + *(unsigned int *)((unsigned int)v3[8] + 4 * v4 + v1));\n    v7 = *v6;\n    v8 = (signed __int64)(v6 + 1);\n    if ( v7 )\n    {\n      do\n      {\n        ++v8;\n        v5 = 16777619 * (v5 ^ v7);\n        v7 = *(_BYTE *)(v8 - 1);\n      }\n      while ( v7 );\n      if ( v5 == -973690651 )\n        break;\n    }\n    if ( !(_DWORD)v4 )\n      goto LABEL_8;\n  }\n  ((void (__fastcall *)(const char *))(v1\n                                     + *(unsigned int *)(v1\n                                                       + (unsigned int)v3[7]\n                                                       + 4i64 * *(unsigned __int16 *)(v1 + (unsigned int)v3[9] + 2 * v4))))(\"hello world\");\n```\n\n## People that have supported this project\nI would like to thank people that have reached out to me and donated some money to support me and my projects\n\n* [@DefCon42](https://github.com/DefCon42)\n* [@Mecanik](https://github.com/Mecanik)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjustasmasiulis%2Flazy_importer","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fjustasmasiulis%2Flazy_importer","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjustasmasiulis%2Flazy_importer/lists"}