1
0

inject-library.c 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148
  1. #include <windows.h>
  2. #include <stdbool.h>
  3. #include "obfuscate.h"
  4. #include "inject-library.h"
  5. typedef HANDLE (WINAPI *create_remote_thread_t)(HANDLE, LPSECURITY_ATTRIBUTES,
  6. SIZE_T, LPTHREAD_START_ROUTINE, LPVOID, DWORD, LPDWORD);
  7. typedef BOOL (WINAPI *write_process_memory_t)(HANDLE, LPVOID, LPCVOID, SIZE_T,
  8. SIZE_T*);
  9. typedef LPVOID (WINAPI *virtual_alloc_ex_t)(HANDLE, LPVOID, SIZE_T, DWORD,
  10. DWORD);
  11. typedef BOOL (WINAPI *virtual_free_ex_t)(HANDLE, LPVOID, SIZE_T, DWORD);
  12. int inject_library_obf(HANDLE process, const wchar_t *dll,
  13. const char *create_remote_thread_obf, uint64_t obf1,
  14. const char *write_process_memory_obf, uint64_t obf2,
  15. const char *virtual_alloc_ex_obf, uint64_t obf3,
  16. const char *virtual_free_ex_obf, uint64_t obf4,
  17. const char *load_library_w_obf, uint64_t obf5)
  18. {
  19. int ret = INJECT_ERROR_UNLIKELY_FAIL;
  20. DWORD last_error = 0;
  21. bool success = false;
  22. size_t written_size;
  23. DWORD thread_id;
  24. HANDLE thread = NULL;
  25. size_t size;
  26. void *mem;
  27. /* -------------------------------- */
  28. HMODULE kernel32 = GetModuleHandleW(L"KERNEL32");
  29. create_remote_thread_t create_remote_thread;
  30. write_process_memory_t write_process_memory;
  31. virtual_alloc_ex_t virtual_alloc_ex;
  32. virtual_free_ex_t virtual_free_ex;
  33. FARPROC load_library_w;
  34. create_remote_thread = get_obfuscated_func(kernel32,
  35. create_remote_thread_obf, obf1);
  36. write_process_memory = get_obfuscated_func(kernel32,
  37. write_process_memory_obf, obf2);
  38. virtual_alloc_ex = get_obfuscated_func(kernel32,
  39. virtual_alloc_ex_obf, obf3);
  40. virtual_free_ex = get_obfuscated_func(kernel32,
  41. virtual_free_ex_obf, obf4);
  42. load_library_w = get_obfuscated_func(kernel32,
  43. load_library_w_obf, obf5);
  44. /* -------------------------------- */
  45. size = (wcslen(dll) + 1) * sizeof(wchar_t);
  46. mem = virtual_alloc_ex(process, NULL, size, MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE);
  47. if (!mem) {
  48. goto fail;
  49. }
  50. success = write_process_memory(process, mem, dll,
  51. size, &written_size);
  52. if (!success) {
  53. goto fail;
  54. }
  55. thread = create_remote_thread(process, NULL, 0,
  56. (LPTHREAD_START_ROUTINE)load_library_w, mem, 0,
  57. &thread_id);
  58. if (!thread) {
  59. goto fail;
  60. }
  61. if (WaitForSingleObject(thread, 4000) == WAIT_OBJECT_0) {
  62. DWORD code;
  63. GetExitCodeThread(thread, &code);
  64. ret = (code != 0) ? 0 : INJECT_ERROR_INJECT_FAILED;
  65. SetLastError(0);
  66. }
  67. fail:
  68. if (ret == INJECT_ERROR_UNLIKELY_FAIL) {
  69. last_error = GetLastError();
  70. }
  71. if (thread) {
  72. CloseHandle(thread);
  73. }
  74. if (mem) {
  75. virtual_free_ex(process, mem, 0, MEM_RELEASE);
  76. }
  77. if (last_error != 0) {
  78. SetLastError(last_error);
  79. }
  80. return ret;
  81. }
  82. /* ------------------------------------------------------------------------- */
  83. typedef HHOOK (WINAPI *set_windows_hook_ex_t)(int, HOOKPROC, HINSTANCE, DWORD);
  84. #define RETRY_INTERVAL_MS 500
  85. #define TOTAL_RETRY_TIME_MS 4000
  86. #define RETRY_COUNT (TOTAL_RETRY_TIME_MS / RETRY_INTERVAL_MS)
  87. int inject_library_safe_obf(DWORD thread_id, const wchar_t *dll,
  88. const char *set_windows_hook_ex_obf, uint64_t obf1)
  89. {
  90. HMODULE user32 = GetModuleHandleW(L"USER32");
  91. set_windows_hook_ex_t set_windows_hook_ex;
  92. HMODULE lib = LoadLibraryW(dll);
  93. LPVOID proc;
  94. HHOOK hook;
  95. size_t i;
  96. if (!lib || !user32) {
  97. return INJECT_ERROR_UNLIKELY_FAIL;
  98. }
  99. #ifdef _WIN64
  100. proc = GetProcAddress(lib, "dummy_debug_proc");
  101. #else
  102. proc = GetProcAddress(lib, "_dummy_debug_proc@12");
  103. #endif
  104. if (!proc) {
  105. return INJECT_ERROR_UNLIKELY_FAIL;
  106. }
  107. set_windows_hook_ex = get_obfuscated_func(user32,
  108. set_windows_hook_ex_obf, obf1);
  109. hook = set_windows_hook_ex(WH_GETMESSAGE, proc, lib, thread_id);
  110. if (!hook) {
  111. return GetLastError();
  112. }
  113. /* SetWindowsHookEx does not inject the library in to the target
  114. * process unless the event associated with it has occurred, so
  115. * repeatedly send the hook message to start the hook at small
  116. * intervals to signal to SetWindowsHookEx to process the message and
  117. * therefore inject the library in to the target process. Repeating
  118. * this is mostly just a precaution. */
  119. for (i = 0; i < RETRY_COUNT; i++) {
  120. Sleep(RETRY_INTERVAL_MS);
  121. PostThreadMessage(thread_id, WM_USER + 432, 0, (LPARAM)hook);
  122. }
  123. return 0;
  124. }