Results 1 to 1 of 1
  1. #1
    Dwar
    Dwar is offline
    Veteran Dwar's Avatar
    Join Date
    2010 Mar
    Posts
    2,221
    Thanks
    211
    Thanked 2,224 Times in 289 Posts
    Rep Power
    10

    Call Exports of a Module in a Remote Process

    Here's some code you can use to call the exports of a module in a remote process. My code assumes the function prototype is:
    extern "C" void ();

    But you can easily modify it to whatever you want.

    Requires EnsureCleanup class collection posted in the utilities section. The function is a class member, but you can easily change it to a free function, it's a static member so simply removing the member qualification should do.
     // Call an exported function in a module in a remote process
    inline DWORD Injector::CallExport(DWORD ProcID, const std::string& ModuleName,
    const std::string& ExportName)
    {
    // For HCommon
    using namespace Hades;
    // For C++ Standard Library
    using namespace std;

    // Grab a new snapshot of the process
    EnsureCloseHandle Snapshot(CreateToolhelp32Snapshot(TH32CS_SNAPMODUL E,
    ProcID));
    if (Snapshot == INVALID_HANDLE_VALUE)
    {
    throw runtime_error("Injector::CallExport: Could not get module "
    "snapshot for remote process.");
    }

    // Get the HMODULE of the desired library
    MODULEENTRY32W ModEntry = { sizeof(ModEntry) };
    bool Found = false;
    BOOL bMoreMods = Module32FirstW(Snapshot, &ModEntry);
    for (; bMoreMods; bMoreMods = Module32NextW(Snapshot, &ModEntry))
    {
    wstring ExePath(ModEntry.szExePath);
    wstring ModuleTmp(ModuleName.begin(), ModuleName.end());
    Found = (ExePath == ModuleTmp);
    if (Found) break;
    }
    if (!Found)
    {
    throw runtime_error("Injector::CallExport: Could not find module in "
    "remote process.");
    }

    // Get module base address
    PBYTE ModuleBase = ModEntry.modBaseAddr;

    // Get a handle for the target process.
    EnsureCloseHandle Process(OpenProcess(
    PROCESS_QUERY_INFORMATION |
    PROCESS_CREATE_THREAD |
    PROCESS_VM_OPERATION |
    PROCESS_VM_READ,
    FALSE, ProcID));
    if (!Process)
    {
    throw runtime_error("Injector::CallExport: Could not get handle to "
    "process.");
    }

    // Load module as data so we can read the EAT locally
    EnsureFreeLibrary MyModule(LoadLibraryExA(ModuleName.c_str(), NULL,
    DONT_RESOLVE_DLL_REFERENCES));

    // Get module pointer
    PVOID Module = static_cast<PVOID>(MyModule);

    // Get pointer to DOS header
    PIMAGE_DOS_HEADER pDosHeader = reinterpret_cast<PIMAGE_DOS_HEADER>(
    static_cast<HMODULE>(Module));
    if (!pDosHeader || pDosHeader->e_magic != IMAGE_DOS_SIGNATURE)
    {
    throw runtime_error("Injector::CallExport: DOS PE header "
    "is invalid.");
    }

    // Get pointer to NT header
    PIMAGE_NT_HEADERS pNtHeader = reinterpret_cast<PIMAGE_NT_HEADERS>
    (reinterpret_cast<PCHAR>(Module) + pDosHeader->e_lfanew);
    if (pNtHeader->Signature != IMAGE_NT_SIGNATURE)
    throw runtime_error("Injector::CallExport: NT PE header "
    "is invalid.");

    // Get pointer to image export directory
    PVOID pExportDirTemp = reinterpret_cast<PBYTE>(Module) +
    pNtHeader->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].
    VirtualAddress;
    PIMAGE_EXPORT_DIRECTORY pExportDir =
    reinterpret_cast<PIMAGE_EXPORT_DIRECTORY>(pExportD irTemp);

    // Symbol names could be missing entirely
    if (pExportDir->AddressOfNames == NULL)
    {
    throw runtime_error("Injector::CallExport: Symbol names "
    "missing entirely.");
    }

    // Get pointer to export names table
    PDWORD pNamesRvas = reinterpret_cast<PDWORD>(
    reinterpret_cast<PBYTE>(Module) + pExportDir->AddressOfNames);
    // Get pointer to export ordinal table
    PWORD pNameOrdinals = reinterpret_cast<PWORD>(
    reinterpret_cast<PBYTE>(Module) + pExportDir->AddressOfNameOrdinals);
    // Get pointer to export address table
    PDWORD pFunctionAddresses = reinterpret_cast<PDWORD>(
    reinterpret_cast<PBYTE>(Module) + pExportDir->AddressOfFunctions);

    // Variable to hold the export address
    FARPROC pExportAddr = 0;

    // Walk the array of this module's function names
    for (DWORD n = 0; n < pExportDir->NumberOfNames; n++)
    {
    // Get the function name
    PSTR CurrentName = reinterpret_cast<PSTR>(
    reinterpret_cast<PBYTE>(Module) + pNamesRvas[n]);

    // If not the specified function, try the next function
    if (ExportName != CurrentName) continue;

    // We found the specified function
    // Get this function's Ordinal value
    WORD Ordinal = pNameOrdinals[n];

    // Get the address of this function's address
    pExportAddr = reinterpret_cast<FARPROC>(reinterpret_cast<PBYTE>( Module)
    + pFunctionAddresses[Ordinal]);

    // We got the func. Break out.
    break;
    }

    // Nothing found, throw exception
    if (!pExportAddr)
    {
    throw runtime_error("Injector::CallExport: Could not find "
    + ExportName + ".");
    }

    // Convert local address to remote address
    // TODO: Clean the casts. Currently working but could be simplified.
    PTHREAD_START_ROUTINE pfnThreadRtn =
    reinterpret_cast<PTHREAD_START_ROUTINE>((reinterpr et_cast<DWORD_PTR>(
    pExportAddr) - reinterpret_cast<DWORD_PTR>(Module)) +
    reinterpret_cast<DWORD_PTR>(ModuleBase));

    // Create a remote thread that calls the desired export
    EnsureCloseHandle Thread(CreateRemoteThread(Process, NULL, 0,
    pfnThreadRtn, ModEntry.modBaseAddr, 0, NULL));
    if (!Thread)
    {
    throw runtime_error("Injector::CallExport: Could not create thread in "
    "remote process.");
    }

    // Wait for the remote thread to terminate
    WaitForSingleObject(Thread, INFINITE);

    // Get thread exit code
    DWORD ExitCode = 0;
    if (!GetExitCodeThread(Thread,&ExitCode))
    {
    throw runtime_error("Injector::CallExport: Could not get thread exit "
    "code.");
    }

    // Return thread exit code
    return ExitCode;
    }

    Author: Chazwazza
    Please, post your questions on forum, not by PM or mail

    I spend my time, so please pay a little bit of your time to keep world in equilibrium

Visitors found this page by searching for:

DONT_RESOLVE_DLL_REFERENCES CreateRemoteThread

vc 如何 使用 lib#

get remote module handle

getthreadexitcode VC

get remote process module handle

get HMODULE of remote process

c# injector callexport

find address in process c#

c# list remote process modules

remote process module handle

c# process modules how to remote

c# get exports of a module

invoke remote process in c

c# remote processmodule

Export Address Table c#

modules in process c#

GetRemote ModuleHandle c#

get Module from process C#

get module handle address from process c

CreateRemoteThread DONT_RESOLVE_DLL_REFERENCES

getmoduleaddress

c# get module of thread

call remote export process

process modules c#

c get the function address reinterpret_cast

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •