Показать сообщение отдельно

  #9  
Старый 14.01.2021, 04:39
memir
Постоянный
Регистрация: 21.08.2015
Сообщений: 343
С нами: 5646349

Репутация: 163
По умолчанию

Цитата:
Сообщение от ishi  

Пытаюсь реализовать класс с функцией, способной вызывать другие функции по адресам, но компилятор ругается:

Код:





Код:
результатом вычисления фрагмента не является функция, принимающая 4 аргументов


Вот, что я пытался ему впарить:

C++:





Код:
class
user32
{
char
*
base_address
;
template

void
call
(
function func
,
int
a
,
const
char
*
b
,
const
char
*
c
,
long
d
)
{
func
(
a
,
b
,
c
,
d
)
(
)
;
}
public
:
user32
(
)
{
base_address
=
(
char
*
)
GetModuleHandleA
(
"user32.dll"
)
;
}
void
MessageBoxA
(
int
a
,
const
char
*
b
,
const
char
*
c
,
long
d
)
{
call
(
(
base_address
+
0x77B30
)
,
a
,
b
,
c
,
d
)
;
}
}
;


Копаясь в интернете, я понял, что можно как-то сделать, чтобы функция объявлялась как обычная статическая и перекидывала аргументы через fastcall, stdcall и т.д., типа ты её объявил в переменной, но аргументы перекинул как в статическую и всё на ок сработало, но в тех громоздких конструкциях я так и не нашёл минималистичного примера, который смог бы понять. Всё как-то слишком уж перегружено
Отчаянно нуждаюсь в помощи в понимании этого механизма

то, что я уже написал, это попытка сделать прямой вызов MessageBoxA, не используя исходники, но зная оффсет в библиотеке (для чего и нужна эта функция в принципе)
Цитата:
Сообщение от Спойлер  


C++:





Код:
#include 
class
user32
{
using
TypeMessageBoxA
=
int
(
__stdcall
*
)
(
HWND
,
LPCSTR
,
LPCSTR
,
UINT
)
;
TypeMessageBoxA messageBoxA
;
template

void
call
(
F f
,
Args
.
.
.
args
)
{
f
(
args
.
.
.
)
;
}
public
:
user32
(
)
{
auto
user32Module
=
LoadLibraryA
(
"user32.dll"
)
;
messageBoxA
=
reinterpret_cast

(
GetProcAddress
(
user32Module
,
"MessageBoxA"
)
)
;
}
void
MessageBoxA
(
HWND a
,
LPCSTR b
,
LPCSTR c
,
UINT d
)
{
call
(
messageBoxA
,
a
,
b
,
c
,
d
)
;
}
}
;
int
main
(
)
{
user32 obj
;
obj
.
MessageBoxA
(
NULL
,
"Resource not available\nDo you want to try again?"
,
"Account details"
,
MB_ICONWARNING
|
MB_CANCELTRYCONTINUE
|
MB_DEFBUTTON2
)
;
return
0
;
}


Компилятор вычисляет тип (base_address + 0x77B30) и получает char *, а затем пытается вызвать его с четырьмя аргументами. Это приводит к ошибке.

Ты должен кастить base_address + 0x77B30, в void(__stdcall *)(int a, const char* b, const char* c, long d) чтобы всё заработало.

А ещё я бы посоветовал заменить a b c d в user32::call на вариативный шаблон с аргументами.

И у тебя скобочки в вызове лишние...
 
Ответить с цитированием