'How to call a function inside a C++ DLL injected into another process by my C# executable

I have a DLL written in C++, inside it contains a function where it makes a call inside the memory of the injected process and I have my C# executable which should call the function inside the C++ DLL after injecting into the process.

I did a test and executed the "CallFunction" function directly from within the DLL and it worked normally, however when I try to call "CallFunction" by the C# executable it generates the following error 'Attempt to read or write in protected memory. This is usually an indication that other memory is corrupted.'

Maybe it's because it's inside the process memory so I should call it another way?

I've been searching the internet and other topics on StackOverflow for more than 5 days but I haven't found any solution to my problem, I'm newbie working with communication between C++ and C# and I don't understand much about DLL injections and calls so I'm sorry if I forgot to do something obvious or if my code is totally incorrect, any example of how to do what I intend correctly is welcome.

C++ DLL

// dllmain.cpp : Defines the entry point for the DLL application.
#include "pch.h"
#include <windows.h>

#define oIssueFunc 0x5E6890
#define baseAddress (DWORD)GetModuleHandleA(NULL)
#define DEFINE_RVA(address) (baseAddress + (DWORD)address)

typedef int(__thiscall* fnIssueFunc)(int thisptr, int State, int IsList, int isListCommand, int Parameter1, int Parameter2, char unknown3);
fnIssueFunc IssueFunc = (fnIssueFunc)DEFINE_RVA(oIssueFunc);

enum class EType {
    DownList,
    UpList
};

extern "C"
{
    __declspec(dllexport) void CallFunction(int Parameter1, int Parameter2)
    {
        IssueFunc(0x12, 0, 0, true, Parameter1, Parameter2, static_cast<int>(EType::DownList));
        IssueFunc(0x12, 1, 0, true, Parameter1, Parameter2, static_cast<int>(EType::UpList));
    }
}

BOOL APIENTRY DllMain( HMODULE hModule, DWORD ul_reason_for_call,LPVOID lpReserved)
{
    switch (ul_reason_for_call)
    {
    case DLL_PROCESS_ATTACH:
    case DLL_THREAD_ATTACH:
    case DLL_THREAD_DETACH:
    case DLL_PROCESS_DETACH:
        break;
    }
    return TRUE;
}

C# Code

using System.Runtime.InteropServices;

namespace TestCall
{
    public class Test
    {
         [DllImport("Bootstrap.dll", CallingConvention = CallingConvention.Cdecl)]
         public static extern void CallFunction(int Parameter1, int Parameter2);

         public static void CallFunc()
         {
              CallFunction(1, 0);
         }
    }
}


Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source