Advertisement
Meliodas0_0

ExternalPrintSource.cpp

Feb 7th, 2020
365
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 5.49 KB | None | 0 0
  1. #include "pch.h"
  2. #include <Windows.h>
  3. #include <Psapi.h>
  4. #include <string>
  5. #include <iostream>
  6.  
  7. /**
  8. * \brief Gratis to Microsoft's documentation! Note this can be done by enumerating through the PEB of the process,
  9. * but that requires utilizing some not so well-documented functions so for simplicity I used the standard way.
  10. * If you want the specifics of how this works: https://docs.microsoft.com/en-us/windows/win32/psapi/enumerating-all-modules-for-a-process
  11. * \param hProcess Process Handle
  12. * \return ModuleHandle of the main module
  13. */
  14. MODULEINFO GetExternalModule(HANDLE hProcess, const TCHAR* mName)
  15. {
  16. HMODULE module_handles[1024];
  17. DWORD cb_needed = 0;
  18.  
  19.  
  20. if (EnumProcessModules(hProcess, module_handles, sizeof(module_handles), &cb_needed))
  21. {
  22. for (unsigned int i = 0; i < (cb_needed / sizeof(HMODULE)); i++)
  23. {
  24. TCHAR szModName[MAX_PATH];
  25. if (GetModuleBaseName(hProcess, module_handles[i], szModName,
  26. sizeof(szModName) / sizeof(TCHAR)))
  27. {
  28. if (wcscmp(szModName, mName) == 0)
  29. {
  30. MODULEINFO module_information = {};
  31. GetModuleInformation(hProcess, module_handles[i], &module_information, cb_needed);
  32. return module_information;
  33. }
  34. }
  35. }
  36. }
  37. }
  38.  
  39.  
  40. /**
  41. * \brief The shell_code buffer includes the epilogue and prologue for the function along with the mCode already implemented by the 0x0, 0x0, 0x0, 0x0 are purposely there
  42. * to be later replaced in the loops below that write in the correct address. This utilizes the correct rel32 address for the call. If you wish to learn more, just
  43. * research how calls are done in x86. Furthermore, we allocate memory in the process that will be enough for our injection code + message which is referenced in the
  44. * shell code!
  45. * \param hProcess Handle to Process
  46. * \param pAddress Rebased address
  47. * \param mCode Which print code to use (I think any value 0-2)
  48. * \param sMsg Message you have to print
  49. * \return Location of shellcode in process
  50. */
  51. void* InjectShellCode(HANDLE hProcess, const unsigned pAddress, int mCode, const char* sMsg)
  52. {
  53. unsigned char shell_code[] = {
  54. 0x55, //push ebp
  55. 0x8B, 0xEC, //mov ebp, esp
  56. 0x68, 0x0, 0x0, 0x0, 0x0, //push (address of string)
  57. 0x6A, (unsigned char)mCode, //push (value of mCode)
  58. 0xE8, 0x0, 0x0, 0x0, 0x0, //call (address of print function)
  59. 0x83, 0xC4, 0x08, //add esp, 8
  60. 0x8B, 0xE5, //mov esp, ebp
  61. 0x5D, //pop ebp
  62. 0xC3 //retn
  63. };
  64.  
  65.  
  66.  
  67. const PVOID kAllocatedMemory = VirtualAllocEx(hProcess, NULL, 51 + strlen(sMsg), MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE);
  68.  
  69. SIZE_T bytes_written = NULL;
  70.  
  71. const LPVOID kHeapHandle = HeapCreate(NULL, NULL, sizeof(shell_code));
  72. const LPVOID kHeapBytes = HeapAlloc(kHeapHandle, HEAP_ZERO_MEMORY, sizeof(shell_code));
  73. memcpy(kHeapBytes, shell_code, sizeof(shell_code));
  74.  
  75. WriteProcessMemory(hProcess, (LPVOID)((unsigned)kAllocatedMemory + 50), sMsg, strlen(sMsg) + 1, &bytes_written); //The string will be written
  76. //50 bytes into our allocated memory.
  77.  
  78.  
  79. for (unsigned i = 0, j = 0; i < sizeof(shell_code); ++i)
  80. {
  81. if (*(unsigned*)((unsigned)kHeapBytes + i) == 0) //0x0 0x0 0x0 0x0 = 0; thereby this looks for our filler-shell code that we hope to actually fill in now.
  82. {
  83. if (j == 0)
  84. {
  85. *(unsigned*)((unsigned)kHeapBytes + i) = ((unsigned)kAllocatedMemory + 50); //Write the string's address into our shell code.
  86. j++;
  87. }
  88. else if (j == 1)
  89. {
  90. *(unsigned*)((unsigned)kHeapBytes + i) = 0 - ((unsigned)kAllocatedMemory + i - pAddress) - 4; //rel32 offset for the call instruction to the print function
  91. }
  92. }
  93. }
  94.  
  95. WriteProcessMemory(hProcess, (LPVOID)kAllocatedMemory, kHeapBytes, sizeof(shell_code), &bytes_written); //write our shell code into the allocated memory
  96. HeapFree(kHeapHandle, NULL, kHeapBytes); //free the heap that I allocated so I could edit my shell code.
  97. HeapDestroy(kHeapHandle); //ditto
  98. return kAllocatedMemory; //return the address of our allocated memory that is now ready to be executed!
  99. }
  100.  
  101. /**
  102. * \brief Gets Process Handle, and then injects the shellcode and frees the allocated shellcode! This uses the API WaitForSingleObjectEx to make sure the thread concluded
  103. * before we free up the memory!
  104. * \return
  105. */
  106. int main()
  107. {
  108. const unsigned kPrintAddress = 0x5A36C0; //address of console print function
  109. unsigned rebased_print_address = NULL;
  110. MODULEINFO external_main_module = {};
  111. HWND window_handle = NULL;
  112. HANDLE process_handle = NULL;
  113. DWORD process_id = NULL;
  114.  
  115. window_handle = FindWindow(NULL, L"Roblox");
  116. if (!window_handle)
  117. return -1;
  118.  
  119. GetWindowThreadProcessId(window_handle, &process_id);
  120. if (!process_id)
  121. return -1;
  122.  
  123. process_handle = OpenProcess(PROCESS_ALL_ACCESS, FALSE, process_id);
  124. if (!process_handle)
  125. return -1;
  126.  
  127. external_main_module = GetExternalModule(process_handle, L"RobloxPlayerBeta.exe");
  128. rebased_print_address = kPrintAddress - 0x400000 + (unsigned)external_main_module.lpBaseOfDll; //rebase address
  129.  
  130. std::string input;
  131.  
  132. while (true)
  133. {
  134. std::getline(std::cin, input);
  135. void* shell_code_location = InjectShellCode(process_handle, rebased_print_address, 1, input.c_str());
  136. if (shell_code_location)
  137. {
  138. const HANDLE kThread = CreateRemoteThread(process_handle, NULL, NULL, (LPTHREAD_START_ROUTINE)shell_code_location, NULL, NULL, NULL);
  139. if (WaitForSingleObjectEx(kThread, INFINITE, FALSE) == WAIT_OBJECT_0)
  140. VirtualFreeEx(process_handle, shell_code_location, 0, MEM_RELEASE);
  141. }
  142. }
  143.  
  144. return 0;
  145. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement