How to get memory address of procedure RRS feed

  • Question

  • How can I get address of any procedure in my project? SEE file gra/Biblioteki.cs or gra/bin/gebug/gra.exe -> Main window->Menu->Pomoc->Biblioteki
    I need to correct export address for each entry in export table because it gives me RVA address that i need to transform into memory address before i would be able to call it remotely from other process and from other programing language than Visual Studio.

    I used delegates, Func<> or Action<> like below but it returns address which 
    is outside of my loaded into memory program so it is also no use in fixing export tables.
    void static myProc(){}
    Delegate myDelegate = new Action(myProc);
    // GCHandle gch = GCHandle.Alloc(myDelegate);// for nonstatic procedures
    IntPtr ptr = Marshal.GetFunctionPointerForDelegate(myDelegate);

    How can I get memory address from export table which lies inside my app loaded into memory?

    AND second issue is that Visual Studio fails to set import address table and export address table for *.DLL files. SEE gra/DLL and load it into process by clicking ładuj bibliotekę button on form Biblioteki and than choose file gra/dll.dll. Then select dll.dll in upper combobox to view its details and export and import addresses. SEE that Visual Studio failed to set address tables. HOW can i make Visual Studio to fill export and import tables for DLL?

    There is code below:

            DataTable tableExports = null;
            private void bExports_Click(object sender, EventArgs e)
                tableExports = new DataTable();
                tableExports.Columns.Add("export name", typeof(string));
                tableExports.Columns.Add("address", typeof(cAddress));
                tableExports.Columns.Add("size", typeof(cSize));
                    IntPtr pHandle = OpenProcess(0x1F0FFF, true, (comboBox2.SelectedItem as cbProcess).id);
                    ulong baseOfDll;
                    bool status;
                    status = SymInitialize(pHandle, null, false);
                    baseOfDll = SymLoadModuleEx(pHandle, IntPtr.Zero, (comboBox1.SelectedItem as cbModule).file, null, 0, 0, IntPtr.Zero, 0);
                    if (baseOfDll != 0 && SymEnumerateSymbols64(pHandle, baseOfDll, EnumSyms, IntPtr.Zero) != false)
                        dataGridView1.DataSource = tableExports;
                        (dataGridView1.DataSource as DataTable).DefaultView.Sort = "export name";
            public bool EnumSyms(string name, ulong address, uint givenSize, IntPtr context)
                tableExports.Rows.Add(name,new cAddress{address = address}, new cSize { size = givenSize });
                return true;

    Above returns RVA (relative virtual address) for each entry in export table for both DLL and EXE files. But it loads module, gets RVAs and unloads module. Since I get my module base address from:

    Process[] processTable = Process.GetProcesses();

    baseAddress = processTable[myProcess].Modules[myModule].BaseAddress;

    So, since I have both RVA for each procedure for any module and base memory address for that module,

    all I need to do is to calculate VA (real memory address where the procedure is physically). I know

    that there must be some recalculation:

    some value must be subtracted from RVA and then base memory address added to it...

    HOW TO GET that value (which I must subtract) since it should lie somewhere in file header 

    of module and I can read that file contents because I know its base address?????????

    static void foo() { } static void Main(string[] args) { Delegate fooDelegate = new Action(foo); IntPtr p = Marshal.GetFunctionPointerForDelegate(fooDelegate); Console.WriteLine(p); }

    above code returns working code from outside of my program module and may not be there at some point in time

    Monday, May 20, 2019 4:12 PM

All replies

  • If there is any code to traverse manually my program Export Address table that would help as there should be all memory addresses in export table because what I do is relative address and do not know how to transform it into real memory address.

    Anyone knows how to do it without calling any external functions since I know base address of my program?????????????????


    Tuesday, May 21, 2019 2:10 AM
  • Hi zweigs,

    Thank you for posting here.

    For your question, could you describe your problem more clearly?

    Besides, you could provide the complete code with us. It will help us to solve your problem in time.

    We are waiting for your update.

    Best Regards,


    MSDN Community Support
    Please remember to click "Mark as Answer" the responses that resolved your issue, and to click "Unmark as Answer" if not. This can be beneficial to other community members reading this thread. If you have any compliments or complaints to MSDN Support, feel free to contact

    Tuesday, May 21, 2019 6:24 AM
  • That's not how managed code works. You're trying to apply native import/export logic to managed code and it isn't correct. Managed code can move around so there is no export table where you can auto-magically call managed code from another process. If you need that kind of behavior you're going to have to go back to a native DLL in C++.

    The general approach to writing managed code that can be called by a separate process is to use COM. You could technically use any IPC mechanism but "calling functions" would generally be limited to COM. If you simply want to call managed functions from within native code running in the same process then you can do that via marshalling.

    None of this has any relation to how the PE file is storing stuff or how PE base addresses work. Again, you're apply native code logic to a managed DLL and they don't work the same.

    Michael Taylor

    • Proposed as answer by Tim Roberts Thursday, May 23, 2019 5:29 PM
    Thursday, May 23, 2019 3:00 PM
  • I'd like to add just a bit to Michael's correct answer.

    A C# DLL never has exports in the PE sense.  Remember that you can't just jump in to C# code arbitrarily.  C# code compiled to an intermediate language that needs to be executed by the Common Language Runtime.  If it were being called by a C++ program, the CLR would not be running, so there's no one that knows how to run the code.

    There are third-party libraries that can provide exports.  They work by adding new unmanaged functions that load and initialize the CLR and use the CLR facilities to find individual functions within the DLL.

    Tim Roberts | Driver MVP Emeritus | Providenza &amp; Boekelheide, Inc.

    Thursday, May 23, 2019 5:48 PM
  • What third party library would make unmanaged machine code as exports

    to load and initialize CLR and call managed code then?

    Thursday, May 30, 2019 12:08 AM