Таблица экспорта функций

Таблица экспорта функций

 

Таблица экспорта функций позволяет неуправляемому приложению использовать определенные методы .NET сборки точно так же, как при работе с обычной динамической Win32 библиотекой (DLL). Пометить как экспортируемые в сборке можно только статические методы.


 

  • Таблица экспорта содержит информацию символах, которые доступны другим модулям, через динамическое связывание.
  • Состоит из:
    • Таблицы экспортируемых адресов – это массив RVA экспортируемых символов
    • Таблица указателей на имена – массив указателей на открытые экспортируемые имена
    • Таблица ординалов – массив ординалов, идёт параллельно массиву указателей на открытые экспортируемые имена
    • Таблица экспортируемых имён – массив ASCII-строк, на них указывают элементы массива указателей на открытые экспортируемые имена


Настройка параметров создания таблицы экспорта

 

Внешний вид вкладки Таблица экспорта функций (с пометками)

 

Опции:

  • Разрешить создание таблицы экспорта - Включение режима создания таблицы экспорта кода при обфускации;
  • Дерево таблицы экспорта - В дереве можно указать методы, которые требуется добавить в таблицу экспорта. В дереве отображаются только те методы, экспортирование которых возможно;
  • Список экспортируемых функций - В этом списке те методы которые в дереве помечены как экспортируемые;
  • Добавить - Добавляет метод в список экспортируемых функций;
  • Удалить - Удаляет элемент из списка экспортируемых функций;


Добавление методов в таблицу экспорта - из исходного кода

Указать на необходимость добавления метода в таблицу экспорта так же непосредственно из кода (C#, VB и т.д.).
Для этого нужно использовать атрибут [System.Reflection.Obfuscation(Feature="DllExport")]

Например:

//
// Добавить в таблицу экспорта метод 'FunctionForExport'
//
public class Class1
{
    [System.Reflection.Obfuscation(Feature="DllExport")]
    public static void FunctionForExport(string message )
    {
        System.Windows.Forms.MessageBox.Show(message,
             "Message from Class1.FunctionForExport");
    }
        
    public void Function1(stirng message) { }

    protected void Function2(string license_key ) {}

    internal void Function3(int number) { }
}

 

Результат создания таблицы экспорта в сборке ClassLibrary1.dll:

 

 

Пример вызова функции Class1.FunctionForExport (.NET dll) из кода на с++:

 

#include "stdafx.h"
#include 


int _tmain(int argc, _TCHAR* argv[])
{
    HMODULE hDll2=LoadLibraryA(
        "D:\\_Temp\\VS2005\\TestProject\\OutputObfuscate\\ClassLibrary1.dll");
    VOID (WINAPI *FunctionForExport)(char*);
    (FARPROC &)FunctionForExport= GetProcAddress(hDll2, "FunctionForExport");
    FunctionForExport("Call from c++");

    return 0;
}


Исходный код: TestProject-dllExport.zip



При вызове из неуправляемого кода экспортируемой функции, включающей исходящие параметры (ref, out), необходимо для этих параметров передавать указатели на указатели на целевую переменную. Кроме того, в ряде случаев может потребоваться явное указание типов преобразований параметров в управляемом коде.

В примере ниже, экспортируемая функция funForOutString возвращает указатель на Unicode строку, а функция funForInt записывает значение в переменную, передаваемую по ссылке

 

using System;
using System.Runtime.InteropServices;

namespace ClassLibrary2
{
    public class Class1
    {
        // для типа int (in,out)
        [System.Reflection.Obfuscation(Feature = "DllExport")] 
        public static void  funForInt(ref int val)
        {
            val += 10;
        }

        // для типа string (out)
        [System.Reflection.Obfuscation(Feature = "DllExport")]
        public static void funForOutString([Out, 
           MarshalAs(UnmanagedType.LPWStr)] out string str)
        {
            str = "Init from funForOutString";
        }
    }
}

 

Код на языке C++, использующий данные функции

 

[code]#include "stdafx.h"
#include 

typedef void (__stdcall *funForInt)(int*);
typedef void (__stdcall *funForOutString)(WCHAR**);

int _tmain(int argc, _TCHAR* argv[])
{
	HMODULE lib2 = LoadLibraryA("ClassLibrary2.dll");
	if(!lib2) 
		return 0;
	
	funForInt FunInt = (funForInt) GetProcAddress(lib2, "funForInt");
	
	int i=5;
	printf("in: i=%d\n",i);
	FunInt(&i);
	printf("result: i=%d\n",i);

	funForOutString FunString = (funForOutString)
	    GetProcAddress(lib2, "funForOutString");

	WCHAR* lpstr=0;
	FunString(&lpstr);
	printf("result: %S\n",lpstr);
	
	getchar();
	return 0;
}

 

 

 
15.11.2008
 
 
 
 
10.12  .NET Reactor
15.11  n
15.11  C# ClickOnce
 
11.10  GAC и ngen
10.10  SqlTypes