Страница 3 из 3
Re: Доступ к неэкспортируемым функциям DLL
Добавлено: 16 апр 2009, 15:23
BBB
Я как-то кодировал звук в AAC-формат с помощью DLL, которая шла плагином для WinAmp-а (нажеюсь, ничего не перепутал

).
Так там кодировщих был в виде C++ - класса с несколькими методами (причем, помнится, один из которых виртуальный). А далее, вроде как, из DLL вызывалась предназначенная для этого функция, котораявозвращала указатель на экземпляр этого класса. И вызывающая программа делала то, что ей требуется, через методы класса.
Как это все делалось, я нашел примеры в интернете. И на основе этого "руководства к действию" сам сделал. Если кого-то заинтересовало, могу найти свой исходник.
Re: Доступ к неэкспортируемым функциям DLL
Добавлено: 17 апр 2009, 09:49
Decoder
Yes!!! У меня получилось.
Я передаю массив с адресами функций через основную кучу процесса.
Вот код DLL, в которой нет ни одной экспортируемой функции...
Код: Выделить всё
// HeapLib.cpp : Defines the entry point for the DLL application.
#include "stdafx.h"
#include <tchar.h>
BOOL PrintText(LPCTSTR szText)
{
static HANDLE hConsole = ::GetStdHandle(STD_OUTPUT_HANDLE);
//
DWORD dw(0);
return ::WriteConsole(hConsole, szText, ::lstrlen(szText), &dw, NULL);
}
BOOL SayHello()
{
return PrintText(_T("Привет всем программерам!\r\n"));
}
BOOL SayGoodBye()
{
return PrintText(_T("Всем пока! :-)\r\n"));
}
class Global
{
public:
Global()
{
HANDLE hHeap = ::GetProcessHeap();
m_lpData = (LPBYTE)::HeapAlloc(hHeap, HEAP_ZERO_MEMORY, 80);
if (m_lpData != NULL)
{
char Signature[] = "HEAP :D LL";
memcpy((LPSTR)m_lpData, Signature, sizeof(Signature));
FARPROC* lpFarProc = (FARPROC*)(m_lpData+16);
lpFarProc[0] = (FARPROC)SayHello;
lpFarProc[1] = (FARPROC)SayGoodBye;
}
}
~Global()
{
if (m_lpData != NULL)
{
HANDLE hHeap = ::GetProcessHeap();
::HeapFree(hHeap, 0, m_lpData);
}
}
private:
LPBYTE m_lpData;
} _global;
BOOL APIENTRY DllMain( HMODULE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved )
{
return TRUE;
}
А вот код, который вызывает из неё функции...
Код: Выделить всё
#include "stdafx.h"
typedef BOOL (*SAYHELLO)(void);
typedef BOOL (*SAYGOODBYE)(void);
int _tmain(int argc, _TCHAR* argv[])
{
HMODULE hModule = ::LoadLibrary(_T("HeapLib.dll"));
if (hModule != NULL)
{
FARPROC* lpFarProc(NULL);
HANDLE hHeap = ::GetProcessHeap();
PROCESS_HEAP_ENTRY phe = {NULL};
BOOL bNext = ::HeapWalk(hHeap, &phe);
while (bNext != FALSE)
{
bNext = ::HeapWalk(hHeap, &phe);
if (phe.cbOverhead > 0)
{
LPCSTR lps = (LPCSTR)phe.lpData;
if (strcmp(lps, "HEAP :D LL") != 0)
continue;
lpFarProc = (FARPROC*)((LPBYTE)phe.lpData+16);
break;
}
}
if (lpFarProc != NULL)
{
SAYHELLO fhSayHello = (SAYHELLO)lpFarProc[0];
SAYGOODBYE fhSayGoodBye = (SAYGOODBYE)lpFarProc[1];
// вызов полученных функций...
fhSayHello();
fhSayGoodBye();
}
//
::FreeLibrary(hModule);
}
getc(stdin);
return 0;
}
При выполнении программы на экране появляются строки:
Привет всем программерам!
Всем пока! :-)
WinMain, спасибо за прекрасную идею!
.
Добавлено: 17 апр 2009, 11:33
BBB
Decoder писал(а):Yes!!! У меня получилось.
Я передаю массив с адресами функций через основную кучу процесса.
...............
WinMain, спасибо за прекрасную идею!
Хм. Лихо закручено.
Т.е. получился этакий "lib-файл", расположенный в памяти (в Heap-е). Вызывающая программа находит его, "линкует" к себе - т.е. получает адреса "экспортируемых" функций и использует их.
Re: Доступ к неэкспортируемым функциям DLL
Добавлено: 30 июл 2009, 21:08
maxrfon
А вот такую задачу как решить? Нужно вызвать GeNeRator функцию, но со своими параметрами. Есть мысли (если можно практичные) как это можно сделать?
Код: Выделить всё
.text:0526CCA0 CheckMEproc near ; CODE XREF: LoadGenFiles+85p
.text:0526CCA0
.text:0526CCA0 var_20 = dword ptr -20h
.text:0526CCA0 arg_0 = dword ptr 4
.text:0526CCA0 arg_4 = dword ptr 8
.text:0526CCA0
.text:0526CCA0 mov ecx, [ecx+8]
.text:0526CCA3 sub esp, 20h
.text:0526CCA6 test ecx, ecx
.text:0526CCA8 jnz short loc_526CCCB
.text:0526CCAA lea eax, [esp+20h+var_20]
.text:0526CCAE push (offset unk_534B3FF+0AF456B1h) ; Format
.text:0526CCB3 push eax ; int
.text:0526CCB4 call sub_526C360
.text:0526CCB9 add esp, 8
.text:0526CCBC lea ecx, [esp+20h+var_20]
.text:0526CCC0 push (offset unk_5322BFF+0AF4C241h)
.text:0526CCC5 push ecx
.text:0526CCC6 call __CxxThrowException@8
.text:0526CCCB
.text:0526CCCB loc_526CCCB: ; CODE XREF: CheckME+8j
.text:0526CCCB mov eax, [esp+20h+arg_4]
.text:0526CCCF mov edx, [ecx] ; Pointer to offset of cryptoroutines
.text:0526CCD1 push eax ; EAX = 0x0F
.text:0526CCD2 mov eax, [esp+24h+arg_0]
.text:0526CCD6 push eax ; Входные данные
[b].text:0526CCD7 call dword ptr [edx+20h] ; GeNeRaTor <- Вот эту функцию мне нужно вызвать... Но как?? [/b]
.text:0526CCDA add esp, 20h
.text:0526CCDD retn 8
Головоломка
Re: Доступ к неэкспортируемым функциям DLL
Добавлено: 31 июл 2009, 00:54
WinMain
Зная текущий адрес вызываемой функции, нужно найти её RVA (Relative Virtual Address). Для этого нужно из текущего адреса функции вычесть значение HMODULE (или HINSTANCE) этой DLL.
Значение RVA является постоянным и не меняется с момента последней сборки модуля. А значение HMODULE при каждой новой загрузке DLL может каждый раз отличаться. При следующей загрузке DLL нужно значение RVA прибавить к значению HMODULE загруженной DLL. Получившееся значение и есть адрес вызываемой функции.
Если функция является экспортируемой, то её RVA можно посмотреть с помощью утилиты Dependency Walker.