Cheat Engine Forum Index Cheat Engine
The Official Site of Cheat Engine
 
 FAQFAQ   SearchSearch   MemberlistMemberlist   UsergroupsUsergroups   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 


trouble with CreateRemoteThreadEx function

 
Post new topic   Reply to topic    Cheat Engine Forum Index -> General programming
View previous topic :: View next topic  
Author Message
flashcoder
Newbie cheater
Reputation: 0

Joined: 29 Jan 2017
Posts: 14

PostPosted: Tue May 16, 2017 11:48 am    Post subject: trouble with CreateRemoteThreadEx function Reply with quote

i found a source code of a program that have several methods to dll injection ( including Manual Map to x64 processes and modules! ).

Then, i removed all that no is Manual Map dll Injection and now have the code following, but crashes target process when CreateRemoteThreadEx is called.

I already had debugged this code and all before the StartRoutine function seems work fine.

Someone have a idea why CreateRemoteThreadEx is failing here?

Thank you by any suggestion.

Code:
 
// InjectMap.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"
#include <Windows.h>
#include <fstream>

#define INJ_ERASE_HEADER 1
#define INJ_FAKE_HEADER 2
#define INJ_UNLINK_FROM_PEB 4
#define INJ_FLAGS_ALL (INJ_ERASE_HEADER | INJ_FAKE_HEADER | INJ_UNLINK_FROM_PEB)

#define INJ_ERR_SUCCESS                 0x00000000
#define INJ_ERR_INVALID_PROC_HANDLE     0x00000001
#define INJ_ERR_FILE_DOESNT_EXIST       0x00000002
#define INJ_ERR_OUT_OF_MEMORY           0x00000003
#define INJ_ERR_INVALID_FILE            0x00000004
#define INJ_ERR_NO_X64FILE              0x00000005
#define INJ_ERR_NO_X86FILE              0x00000006
#define INJ_ERR_IMAGE_CANT_RELOC        0x00000007
#define INJ_ERR_NTDLL_MISSING           0x00000008
#define INJ_ERR_LDRLOADDLL_MISSING      0x00000009
#define INJ_ERR_LDRPLOADDLL_MISSING     0x0000000A
#define INJ_ERR_INVALID_FLAGS           0x0000000B
#define INJ_ERR_CANT_FIND_MOD           0x0000000C
#define INJ_ERR_CANT_FIND_MOD_PEB       0x0000000D

#define INJ_ERR_UNKNOWN                 0x80000000
#define INJ_ERR_CANT_CREATE_THREAD      0x80000001
#define INJ_ERR_CANT_ALLOC_MEM          0x80000002
#define INJ_ERR_WPM_FAIL                0x80000003
#define INJ_ERR_TH32_FAIL               0x80000004
#define INJ_ERR_CANT_GET_PEB            0x80000005
#define INJ_ERR_CANT_ACCESS_PEB         0x80000006
#define INJ_ERR_CANT_ACCESS_PEB_LDR     0x80000007
#define INJ_ERR_CHECK_WIN32_ERROR       0x80000008
#define INJ_ERR_VPE_FAIL                0x80000009
#define INJ_ERR_INVALID_ARGC            0x8000000A
#define INJ_ERR_SET_PRIV_FAIL           0x8000000B
#define INJ_ERR_CANT_OPEN_PROCESS       0x8000000C
#define INJ_ERR_CANT_START_X64_INJ      0x8000000D
#define INJ_ERR_INVALID_PID             0x8000000E

#define INJ_ERR_ADV_UNKNOWN             0x00000000
#define INJ_ERR_ADV_INV_PROC            0x00000001
#define INJ_ERR_ADV_TH32_FAIL           0x00000002
#define INJ_ERR_ADV_NO_THREADS          0x00000003
#define INJ_ERR_ADV_CANT_OPEN_THREAD    0x00000004
#define INJ_ERR_ADV_SUSPEND_FAIL        0x00000005
#define INJ_ERR_ADV_GET_CONTEXT_FAIL    0x00000006
#define INJ_ERR_ADV_OUT_OF_MEMORY       0x00000007
#define INJ_ERR_ADV_WPM_FAIL            0x00000008
#define INJ_ERR_ADV_SET_CONTEXT_FAIL    0x00000009
#define INJ_ERR_ADV_RESUME_FAIL         0x0000000A
#define INJ_ERR_ADV_QIP_MISSING         0x0000000B
#define INJ_ERR_ADV_QIP_FAIL            0x0000000C
#define INJ_ERR_ADV_CANT_FIND_MODULE    0x0000000D

#define ReCa reinterpret_cast

using namespace std;

//=================================================================================================================================================

typedef HINSTANCE(__stdcall * f_LoadLibrary)(const char*);
typedef uintptr_t(__stdcall * f_GetProcAddress)(HINSTANCE, const char*);
typedef BOOL(WINAPI * f_DLL_ENTRY_POINT)(void*, DWORD, void*);

//=================================================================================================================================================

struct MANUAL_MAPPING_DATA
{
    f_LoadLibrary       pLoadLibrary;
    f_GetProcAddress    pGetProcAddress;
};

//==========================================================================================

UINT __forceinline _strlenA(const char * szString);
void __forceinline _ZeroMemory(BYTE * pMem, UINT Size);
void __stdcall ImportTlsExecute(MANUAL_MAPPING_DATA * pData);

bool FileExistsA(const char * szFile);
HANDLE StartRoutine(HANDLE hTargetProc, void * pRoutine, void * pArg);

DWORD LastError = INJ_ERR_SUCCESS;

//==========================================================================================

DWORD ManualMap(const char * szDllFile, HANDLE hProc)
{
    if (!hProc)
        return INJ_ERR_INVALID_PROC_HANDLE;
    if (!szDllFile || !FileExistsA(szDllFile))
        return INJ_ERR_FILE_DOESNT_EXIST;

    BYTE *                  pSrcData;
    IMAGE_NT_HEADERS *      pOldNtHeader;
    IMAGE_OPTIONAL_HEADER * pOldOptHeader;
    IMAGE_FILE_HEADER *     pOldFileHeader;
    BYTE *                  pLocalBase;
    BYTE *                  pTargetBase;

    ifstream File(szDllFile, ios::binary | ios::ate);

    auto FileSize = File.tellg();
    if (FileSize <= 0x1000)
    {
        File.close();
        return INJ_ERR_INVALID_FILE;
    }

    pSrcData = new BYTE[static_cast<UINT_PTR>(FileSize)];

    if (!pSrcData)
    {
        File.close();
        return INJ_ERR_OUT_OF_MEMORY;
    }

    File.seekg(0, ios::beg);
    File.read(ReCa<char*>(pSrcData), FileSize);
    File.close();

    if (ReCa<IMAGE_DOS_HEADER*>(pSrcData)->e_magic != 0x5A4D)
    {
        delete[] pSrcData;
        return INJ_ERR_INVALID_FILE;
    }

    pOldNtHeader    = ReCa<IMAGE_NT_HEADERS*>(pSrcData + ReCa<IMAGE_DOS_HEADER*>(pSrcData)->e_lfanew);
    pOldOptHeader   = &pOldNtHeader->OptionalHeader;
    pOldFileHeader  = &pOldNtHeader->FileHeader;

    if (pOldFileHeader->Machine != IMAGE_FILE_MACHINE_AMD64)
    {
        delete[] pSrcData;
        return INJ_ERR_NO_X64FILE;
    }

    pTargetBase = ReCa<BYTE*>(VirtualAllocEx(hProc, ReCa<void*>(pOldOptHeader->ImageBase), pOldOptHeader->SizeOfImage, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE));
    if (!pTargetBase)
        pTargetBase = ReCa<BYTE*>(VirtualAllocEx(hProc, nullptr, pOldOptHeader->SizeOfImage, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE));

    if (!pTargetBase)
    {
        delete[] pSrcData;
        LastError = GetLastError();
        return INJ_ERR_CANT_ALLOC_MEM;
    }

    pLocalBase = ReCa<BYTE*>(VirtualAlloc(nullptr, pOldOptHeader->SizeOfImage, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE));

    if (!pLocalBase)
    {
        delete[] pSrcData;
        LastError = GetLastError();
        VirtualFreeEx(hProc, pTargetBase, 0, MEM_RELEASE);
        return INJ_ERR_OUT_OF_MEMORY;
    }

    memset(pLocalBase, 0, pOldOptHeader->SizeOfImage);
    memcpy(pLocalBase, pSrcData, 0x1000);

    auto * pSectionHeader = IMAGE_FIRST_SECTION(pOldNtHeader);
    for (UINT i = 0; i < pOldFileHeader->NumberOfSections; ++i, ++pSectionHeader)
        if (pSectionHeader->SizeOfRawData)
            memcpy(pLocalBase + pSectionHeader->VirtualAddress, pSrcData + pSectionHeader->PointerToRawData, pSectionHeader->SizeOfRawData);

    BYTE * LocationDelta = pTargetBase - pOldOptHeader->ImageBase;
    if (LocationDelta)
    {
        if (!pOldOptHeader->DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].Size)
        {
            VirtualFreeEx(hProc, pTargetBase, 0, MEM_RELEASE);
            VirtualFree(pLocalBase, 0, MEM_RELEASE);
            delete[] pSrcData;
            return INJ_ERR_IMAGE_CANT_RELOC;
        }

        auto * pRelocData = ReCa<IMAGE_BASE_RELOCATION*>(pLocalBase + pOldOptHeader->DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress);
        while (pRelocData->VirtualAddress)
        {
            WORD * pRelativeInfo = ReCa<WORD*>(pRelocData + 1);
            for (UINT i = 0; i < ((pRelocData->SizeOfBlock - sizeof(IMAGE_BASE_RELOCATION)) / 2); ++i, ++pRelativeInfo)
            {
                if ((*pRelativeInfo >> 0x0C) == IMAGE_REL_BASED_DIR64)
                {
                    UINT_PTR * pPatch = ReCa<UINT_PTR*>(pLocalBase + pRelocData->VirtualAddress + ((*pRelativeInfo) & 0xFFF));
                    *pPatch += ReCa<UINT_PTR>(LocationDelta);
                }
            }
            pRelocData = ReCa<IMAGE_BASE_RELOCATION*>(ReCa<BYTE*>(pRelocData) + pRelocData->SizeOfBlock);
        }
    }

    ReCa<MANUAL_MAPPING_DATA*>(pLocalBase)->pLoadLibrary    = LoadLibraryA;
    ReCa<MANUAL_MAPPING_DATA*>(pLocalBase)->pGetProcAddress = ReCa<f_GetProcAddress>(GetProcAddress);

    BOOL Ret = WriteProcessMemory(hProc, pTargetBase, pLocalBase, pOldOptHeader->SizeOfImage, nullptr);
    if (!Ret)
    {
        LastError = GetLastError();
        VirtualFree(pLocalBase, 0, MEM_RELEASE);
        delete[] pSrcData;
        return INJ_ERR_WPM_FAIL;
    }

    VirtualFree(pLocalBase, 0, MEM_RELEASE);
    delete[] pSrcData;

    ULONG_PTR FuncSize = 0x600;
    void * pFunc = VirtualAllocEx(hProc, nullptr, FuncSize, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE);
    if (!pFunc)
    {
        LastError = GetLastError();
        return INJ_ERR_CANT_ALLOC_MEM;
    }

    if (!WriteProcessMemory(hProc, pFunc, ImportTlsExecute, FuncSize, nullptr))
    {
        LastError = GetLastError();
        VirtualFreeEx(hProc, pFunc, 0, MEM_RELEASE);
        return INJ_ERR_WPM_FAIL;
    }

    HANDLE hThread = StartRoutine(hProc, pFunc, pTargetBase);

    if (!hThread)
    {
        VirtualFreeEx(hProc, pFunc, 0, MEM_RELEASE);
        VirtualFreeEx(hProc, pTargetBase, 0, MEM_RELEASE);
        return INJ_ERR_CANT_CREATE_THREAD;
    }

        WaitForSingleObject(hThread, INFINITE);
        CloseHandle(hThread);

    VirtualFreeEx(hProc, pFunc, 0, MEM_RELEASE);

    return INJ_ERR_SUCCESS;
}

void __stdcall ImportTlsExecute(MANUAL_MAPPING_DATA * pData)
{
    BYTE * pBase            = reinterpret_cast<BYTE*>(pData);
    auto * pOp              = &ReCa<IMAGE_NT_HEADERS*>(pBase + ReCa<IMAGE_DOS_HEADER*>(pData)->e_lfanew)->OptionalHeader;
    auto _LoadLibraryA      = pData->pLoadLibrary;
    auto _GetProcAddress    = pData->pGetProcAddress;
    auto _DllMain           = ReCa<f_DLL_ENTRY_POINT>(pBase + pOp->AddressOfEntryPoint);

    if (pOp->DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].Size)
    {
        auto * pImportDescr = ReCa<IMAGE_IMPORT_DESCRIPTOR*>(pBase + pOp->DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress);
        while (pImportDescr->Name)
        {
            HINSTANCE hDll = _LoadLibraryA(ReCa<const char*>(pBase + pImportDescr->Name));
            ULONG_PTR * pThunkRef   = ReCa<ULONG_PTR*>(pBase + pImportDescr->OriginalFirstThunk);
            ULONG_PTR * pFuncRef    = ReCa<ULONG_PTR*>(pBase + pImportDescr->FirstThunk);

            _ZeroMemory(pBase + pImportDescr->Name, _strlenA(ReCa<char*>(pBase + pImportDescr->Name)));

            if (!pImportDescr->OriginalFirstThunk)
                pThunkRef = pFuncRef;

            for (; *pThunkRef; ++pThunkRef, ++pFuncRef)
            {
                if (IMAGE_SNAP_BY_ORDINAL(*pThunkRef))
                {
                    *pFuncRef = _GetProcAddress(hDll, ReCa<const char*>(*pThunkRef & 0xFFFF));
                    _ZeroMemory(ReCa<BYTE*>(*pThunkRef & 0xFFFF), _strlenA(ReCa<char*>(*pThunkRef & 0xFFFF)));
                }
                else
                {
                    auto * pImport = ReCa<IMAGE_IMPORT_BY_NAME*>(pBase + (*pThunkRef));
                    *pFuncRef = _GetProcAddress(hDll, (const char*)pImport->Name);
                    _ZeroMemory(ReCa<BYTE*>(pImport->Name), _strlenA((const char*)pImport->Name));
                }
            }
            ++pImportDescr;
        }
    }

    if (pOp->DataDirectory[IMAGE_DIRECTORY_ENTRY_TLS].Size)
    {
        auto * pTLS = ReCa<IMAGE_TLS_DIRECTORY*>(pBase + pOp->DataDirectory[IMAGE_DIRECTORY_ENTRY_TLS].VirtualAddress);
        auto * pCallback = ReCa<PIMAGE_TLS_CALLBACK*>(pTLS->AddressOfCallBacks);
        for (; pCallback && *pCallback; ++pCallback)
            (*pCallback)(pBase, DLL_PROCESS_ATTACH, nullptr);
    }

    _DllMain(pBase, DLL_PROCESS_ATTACH, nullptr);

    for (UINT i = 0; i <= IMAGE_DIRECTORY_ENTRY_COM_DESCRIPTOR; ++i)
    {
        if (i == IMAGE_DIRECTORY_ENTRY_IAT)
            continue;

        DWORD Size = pOp->DataDirectory[i].Size;
        if (Size)
            _ZeroMemory(pBase + pOp->DataDirectory[i].VirtualAddress, Size);
    }

    for (UINT i = 0; i != 0x1000; i += sizeof(ULONG64))
        *ReCa<ULONG64*>(pBase + i) = 0;
}

HANDLE StartRoutine(HANDLE hTargetProc, void * pRoutine, void * pArg)
{
            HANDLE hThread = CreateRemoteThreadEx(hTargetProc, nullptr, 0, ReCa<LPTHREAD_START_ROUTINE>(pRoutine), pArg, 0, nullptr, nullptr);
            if (!hThread)
                LastError = GetLastError();

            return hThread;
}

UINT __forceinline _strlenA(const char * szString)
{
    UINT Ret = 0;
    for (; *szString++; Ret++);
    return Ret;
}

void __forceinline _ZeroMemory(BYTE * pMem, UINT Size)
{
    for (BYTE * i = pMem; i < pMem + Size; ++i)
        *i = 0x00;
}

bool FileExistsA(const char * szFile)
{
    return (GetFileAttributesA(szFile) != INVALID_FILE_ATTRIBUTES);
}

int main()
{

    ULONG rc;

    STARTUPINFOA StartupInfo;
    PROCESS_INFORMATION ProcessInfo;

    memset(&StartupInfo, 0, sizeof(StartupInfo));
    memset(&ProcessInfo, 0, sizeof(ProcessInfo));
    StartupInfo.cb = sizeof(STARTUPINFOA);
    StartupInfo.dwFlags = STARTF_USESHOWWINDOW;
    StartupInfo.wShowWindow = SW_HIDE;

    if (!CreateProcessA( NULL, "c:\\windows\\system32\\notepad.exe", NULL, NULL, FALSE,
        CREATE_NEW_CONSOLE,
        NULL,
        NULL,
        &StartupInfo,
        &ProcessInfo))
    {
        return 0;     
    }

    WaitForSingleObject(ProcessInfo.hProcess, 5000);
    if(!GetExitCodeProcess(ProcessInfo.hProcess, &rc))
        rc = 0;

    CloseHandle(ProcessInfo.hThread);
    ManualMap("C:\\Project1.dll", ProcessInfo.hProcess);
    CloseHandle(ProcessInfo.hProcess);

    return 0;
}
[/code]


123.png
 Description:
 Filesize:  73.74 KB
 Viewed:  7741 Time(s)

123.png


Back to top
View user's profile Send private message
atom0s
Moderator
Reputation: 198

Joined: 25 Jan 2006
Posts: 8516
Location: 127.0.0.1

PostPosted: Tue May 16, 2017 4:15 pm    Post subject: Reply with quote

The remote thread creation worked fine, as seen by hThread having a valid handle value returned. The issue is the dll you are injecting is causing the target to crash. Either due to being initialized incorrectly or some other issue with the dll. Use the option to debug the target and see what and where the issue is.
_________________
- Retired.
Back to top
View user's profile Send private message Visit poster's website
flashcoder
Newbie cheater
Reputation: 0

Joined: 29 Jan 2017
Posts: 14

PostPosted: Tue May 16, 2017 6:46 pm    Post subject: Reply with quote

Thank by your anwer, but i already tested with two dlls diferent and the problem still is present.
Back to top
View user's profile Send private message
atom0s
Moderator
Reputation: 198

Joined: 25 Jan 2006
Posts: 8516
Location: 127.0.0.1

PostPosted: Wed May 17, 2017 11:52 pm    Post subject: Reply with quote

flashcoder wrote:
Thank by your anwer, but i already tested with two dlls diferent and the problem still is present.


Like I said, the way you are mapping the file into memory may have problems, the issue is not with CreateRemoteThreadEx itself since that is returning a valid handle. The rest of the code has issues or the DLLs you are injecting have problems. Debug the crash and see what is having issues.

_________________
- Retired.
Back to top
View user's profile Send private message Visit poster's website
flashcoder
Newbie cheater
Reputation: 0

Joined: 29 Jan 2017
Posts: 14

PostPosted: Thu May 18, 2017 7:06 am    Post subject: Reply with quote

I discovered that problem is with my dll. Very Happy
Back to top
View user's profile Send private message
Display posts from previous:   
Post new topic   Reply to topic    Cheat Engine Forum Index -> General programming All times are GMT - 6 Hours
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum
You cannot attach files in this forum
You can download files in this forum


Powered by phpBB © 2001, 2005 phpBB Group

CE Wiki   IRC (#CEF)   Twitter
Third party websites