@8iKS

Почему не удается получить адрес функции?

Я не совсем понимаю почему не удается получить адрес функции auth() пробовал разные способы, но толку ноль. Может знающие люди подскажут?

Вот код программы из которой я хочу получить адрес:
#include <iostream>
#include <string>

using namespace std;

bool auth(const string& pass)
{
	if (pass == "test123")
	{
		return true;
	}
	return false;
}

int main(void)
{
	string pas;
	cout << "INPUT PASS~# ";
	cin >> pas;

	if (auth(pas))
	{
		cout << "SUCCESSFULLY" << endl;
	}
	else
	{
		cout << "ERROR" << endl;
	}

	system("pause");

	return 0;
}


А вот код dll которая загружается в память:
// dllmain.cpp : Defines the entry point for the DLL application.
#include "pch.h"
#include <detours/detours.h>
#include <Windows.h>
#include <string>
#include <iostream>

using namespace std;

typedef bool(__stdcall* auth_type)(const string&);

auth_type original_auth = nullptr;

bool __stdcall hooked_auth(const string& password)
{
    cout << "auth() HOOKED" << endl;

    return true;
}

BOOL APIENTRY DllMain(HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved)
{
    switch (ul_reason_for_call)
    {
    case DLL_PROCESS_ATTACH:
        DetourTransactionBegin();
        DetourUpdateThread(GetCurrentThread());

        original_auth = (auth_type)GetProcAddress(NULL, "auth");

        DetourAttach((PVOID*)&original_auth, hooked_auth);

        DetourTransactionCommit();
        break;

    case DLL_PROCESS_DETACH:
        DetourTransactionBegin();
        DetourUpdateThread(GetCurrentThread());
        DetourDetach((PVOID*)&original_auth, hooked_auth);
        DetourTransactionCommit();
        break;
    }

    return TRUE;
}


original_auth равняется nullptr что бы я не делал
  • Вопрос задан
  • 163 просмотра
Решения вопроса 1
TrueBers
@TrueBers
Гуглю за еду
Если эта целевая программа не твоя и часто обновляется, то нужно найти сигнатуру функции, представляющую собой уникальный паттерн инструкций. Потом прогонять поиск по памяти образа на наличие этой сигнатуры и брать итоговое смещение относительно базового адреса. Это и будет нужный адрес.

Если программа не обновляется никогда, то возьми да захардкодь RVA этой функции.

Если программа твоя, то как у уже сказали остальные, просто сделай символ публичным плюс C abi через extern "C"
Ответ написан
Комментировать
Пригласить эксперта
Ответы на вопрос 2
@vanyamba-electronics
Файл DLL имеет макет, очень похожий на EXE-файл, с одним важным отличием — DLL-файл содержит таблицу экспорта. Таблица экспорта содержит имя каждой функции, которую библиотека DLL экспортирует в другие исполняемые файлы. Эти функции являются точками входа в библиотеку DLL; другие исполняемые файлы могут обращаться только к функциям из таблицы экспорта. Все остальные функции библиотеки DLL являются закрытыми. Таблицу экспорта библиотеки DLL можно просмотреть с помощью средства DUMPBIN с параметром /EXPORTS.

Экспортировать функции из библиотеки DLL можно двумя способами:

  • Создайте файл определения модуля (DEF) и используйте DEF-файл при сборке библиотеки DLL. Используйте этот подход, если требуется экспортировать функции из библиотеки DLL по порядковому номеру, а не по имени.

  • Используйте ключевое слово __declspec(dllexport) в определении функции.


При экспорте функций любым способом убедитесь, что используется соглашение о вызовах __stdcall.
Ответ написан
AshBlade
@AshBlade
Просто хочу быть счастливым
Уже подсказали про проблему с экспортом, но не в ту сторону.
Ты хочешь получить адрес функции из исполняемого файла с помощью дин. либы. То есть тебе надо экспортировать символ не из dll, а из исполняемого файла. Грубо говоря, из main.c. В шиндоузе, если не указывать видимость символа, то по умолчанию он не импортируется, т.е. надо добавить __declspec(dllexport) вручную.

Также, проблема может быть из-за манглинга - ты используешь c++ и функция не в extern "C". В результате, ее имя не auth, а какое-нибудь B4__authV
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы