1

I'm trying to inject my executable payload into remote process. I allocated memory in remote process, I converted raw payload using RVA addressing. I applied relocations and imports table.

When I'm testing my solution in Windows 10 environment it works fine. Exe is injected and it runs properly, and shows me message box.

But when I'm trying to do the same on Windows 7 64bit (loader, payload and target are compiled as x86 code), I have an error:

Access violation executing location 0x7698FD1E

I checked, and this address is an MessageBoxA function's address from user32.dll library

Here is my main code to inject pe to remote process:

char* target_n = "InjectTarget.exe";
    char* payload_path  = "C:\\Users\\pb\\source\\repos\\pe-dumper\\Debug\\DummyApp.exe";

    FILE* raw_payload = get_file_buffer(payload_path);
    PIMAGE_NT_HEADERS inth = get_nt_headers(raw_payload);

    DWORD kImageSize = inth->OptionalHeader.SizeOfImage;
    DWORD kTargetProcId = get_process_id(target_n);

    HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS, NULL, kTargetProcId);
    if (hProcess == NULL) {
        printf("Error: Process handle is NULL\n");
    }

    LPVOID imageBaseRemote = VirtualAllocEx(hProcess, NULL, kImageSize, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE);
    if (imageBaseRemote == NULL) {
        printf("Error: Image base remote is NULL\n");
    }

    LPVOID imageBaseLocal = VirtualAlloc(NULL, kImageSize, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE);
    copy_raw_to_image_local(imageBaseLocal, raw_payload);
    adjust_relocations(imageBaseRemote, imageBaseLocal);
    adjust_imports(imageBaseLocal);

    DWORD bytesWritten;
    if (!WriteProcessMemory(hProcess, imageBaseRemote, imageBaseLocal, kImageSize, &bytesWritten)) {
        printf("Cannot write to remote process!\n");
    }

    LPTHREAD_START_ROUTINE routine = ((ULONG_PTR)imageBaseRemote + inth->OptionalHeader.AddressOfEntryPoint);

    DWORD threadId;
    HANDLE hThread = CreateRemoteThread(hProcess, NULL, NULL, routine, NULL, NULL, &threadId);

    if (hThread == NULL) {
        printf("%d", GetLastError());
    }

    VirtualFree(imageBaseLocal, kImageSize, MEM_RELEASE);
    fclose(raw_payload);

Why these differences between windows 10 and windows 7 appears?

  • 1
    Are you doing something special in order to get MessageBoxAs address? I would assume since you're not loading your image, that it won't be resolved for you. If you do anything to resolve it yourself, I assume the problem is there. Additionally, how did you check 0x7698FD1E is the address of MessageBoxA? Did you check the target process when it failed? – NirIzr Oct 21 '18 at 6:40
  • @bielu000 You need to show more code or give details like NirIzr pointed out. The problem is we have no idea what copy_raw_to_image_local, adjust_relocations and adjust_imports do even though the their names suggest particular functionality. But given that any of us would probably come up with a slightly different variation on the theme when tasked to implement said functions, it would make sense if you gave the details NirIzr was inquiring about. – 0xC0000022L Nov 20 '18 at 8:39
-1

This is a very interesting try.

  1. Are you sure that DummyApp and InjectTarget are both 32 bit exe?

  2. I saw you launched a thread from entrypoint of DummyApp, but you should know entry point is not a real starting point while launching exe.

Before go to entry point, automatically dlls in import table will be loaded. Furthermore, not only dlls in import table, but another dlls are loaded while exe is executing.

So I think that the list of loading dlls might NOT be same in between win7 and win10.

I hope my opinion is helpful to you.

  • Yes I'm sure that both aps are 32 bit exe. My DummyApp has only one imported dll which is user32.dll and it can be resolved by my loader, because kernel32.dll and user32.dll have the same address for all running process. I have no idea why this problem occurs. It perfectly works on Windows10 (no mater if DummyApp or InjectTarget are 32 or 64, still works). I tried to run InjectTarget under the debugger, and when the error occures I'm getting the error code which is 0x05 which means Access Denied. But why? Why I'm getting access denied? – bielu000 Aug 23 '18 at 8:56
  • The memory I'm allocating has Execute rights. When I'm looking into assembly code, before calling "MessageBoxA" function, there are some other instructions like push (pushing on the stack captions which will be show in the message box), and these instructions does not cause any errors. Ony calling MessageBoxA from user32.dll – bielu000 Aug 23 '18 at 8:59
  • Maybe it doesn't matter, but why the same application compiled in 86 bit mode has relocation table but in 64 bit mode it doesn't? – bielu000 Aug 23 '18 at 18:50
  • The x86_64 instruction set allows IP-relative addressing, so the code might contain a reference to "the string 1234 bytes after the current instruction". Compilers use this feature to produce position-independent code which does nit need to be relocated. On x86, emulating this kind if addressing is expensive, so your compiler instead emits "use the string constant at 1001230 (to be relocated)". – Michael Karcher Aug 24 '18 at 9:38
  • @bielu000 I hope your assumption is not that just because there's a 32 in user32.dll and kernel32.dll, that these DLLs (and consequently your target application) must be 32-bit. Sounds a bit like that from your comment. But that'd be a fallacy. – 0xC0000022L Nov 20 '18 at 8:35

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.