Таблица экспорта функций
Таблица экспорта функций позволяет неуправляемому приложению использовать определенные методы .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;
}