Skocz do zawartości
  • 👋 Witaj na MPCForum!

    Przeglądasz forum jako gość, co oznacza, że wiele świetnych funkcji jest jeszcze przed Tobą! 😎

    • Pełny dostęp do działów i ukrytych treści
    • Możliwość pisania i odpowiadania w tematach
    • System prywatnych wiadomości
    • Zbieranie reputacji i rozwijanie swojego profilu
    • Członkostwo w jednej z największych społeczności graczy

    👉 Dołączenie zajmie Ci mniej niż minutę – a zyskasz znacznie więcej!

    Zarejestruj się teraz

Implementacja DllCall z AutoIT.


Vesim

Rekomendowane odpowiedzi

Opublikowano

Prosta implementacja DllCall z AutoIT. Jako parametr do funkcji można przekazać wszystko co ma 4bajti.

Działa tylko w Visualu i win32.

Kod:

enum DllCall_Result
{
	error = 0,
	success
};

enum DllCall_Conv
{
	conv_cdecl = 0,
	conv_stdcall = 1,
	conv_thiscall = 2,
	conv_fastcall = 3
};

template<class T>
DllCall_Result DllCall(void* func, DllCall_Conv conv, int argc, int *argv, T *result)
{
	switch(conv)
	{
	case conv_cdecl:
	case conv_stdcall:
	case conv_thiscall:
	case conv_fastcall:
	__asm
		{
			mov eax, [argv]
			mov ecx, argc
				
			cmp conv, 2//thiscall
			jne jthis
			dec argc
	jthis:			   //thiscall

			cmp conv, 3//fastcall
			jne jfast
			sub argc, 2
	jfast:				//fastcall

			imul ecx, 4  //right to left
			add eax, ecx // ^

			cmp argc, 1
			jl noargs
			mov ecx, argc
	aloop:
			sub eax, 4
			push [eax]
			dec ecx
			cmp ecx, 0
			jg aloop
	noargs:

			cmp conv, 2 //thiscall
			jne cthis
			sub eax, 4
			mov ecx, [eax]
	cthis:			   //thiscall

			cmp conv, 3 //fastcall
			jne cfast
			push ebp
			mov ebp, eax
			sub ebp, 4
			mov edx, [ebp]
			sub ebp, 4
			mov ecx, [ebp]
			mov eax, ebp
			pop ebp
	cfast:				//fastcall

			call func

			mov ecx, argc
			imul ecx, 4

			cmp conv, 0 //stdcall/thiscall/fastcall
			jne noclean
			add esp, ecx
	noclean:			//stdcall/thiscall/fastcall
			mov ecx, result
			mov [ecx], eax
		}
	break;
	default:
		puts("Unknown call convention");
		return error;
		break;
	}
	return error;
} 
Przykład:

int Test(int a, int b, int c, int d)
{
	printf("%d %d %d %d ", a, b, c, d);
	return a + b + c;
}

class Klasa
{
public: 
	int a;
	virtual int Test2(int a, int b, int c, int d)
	{
		printf("%d %d %d %d ", a, b, c, d);
		return a + b + c;
	}
};

int __stdcall Test3(int a, int b, int c, int d)
{
	printf("%d %d %d %d ", a, b, c, d);
	return a + b + c;
}

int __fastcall Test4(int a, int b, int c, int d)
{
	printf("%d %d %d %d ", a, b, c, d);
	return a + b + c;
}

int main(int argc, char* argv[])
{
	int args[4] = {1, 10, 20, 30};
	int result;

	DllCall_Result ret = DllCall<int>((void*)Test, conv_cdecl, 4, args, &result);
	printf("cdecl %d %d\n", ret, result);

	Klasa c;
	c.a = 1;
	int args2[5] = {(int)&c, 1, 10, 20, 30};

	DWORD adr;
	__asm mov eax, Klasa::Test2
	__asm mov adr, eax

	ret = DllCall<int>((void*)adr, conv_thiscall, 5, args2, &result);
	printf("thiscall %d %d\n", ret, result);

	ret = DllCall<int>((void*)Test3, conv_stdcall, 4, args, &result);
	printf("stdcall %d %d\n", ret, result);

	ret = DllCall<int>((void*)Test4, conv_fastcall, 4, args, &result);
	printf("fastcall %d %d\n", ret, result);

	getchar();
	return 0;
}
Zwróci:

1 10 20 30 cdecl 0 31
1 10 20 30 thiscall 0 31
1 10 20 30 stdcall 0 31
1 10 20 30 fastcall 0 31

Nie pomagam na PW, od tego macie forum!!!

 

#PHP-things

 

 

08FMpDu.png

 

Opublikowano

To nie jest dobry sposób. Chociażby z tego powodu, że argumenty niekoniecznie muszą być przekazane w tej kolejności.

Dodatkowo bezużyteczne jeśli można tylko inty przekazywać.

 

Nie wiem czy da się to porządnie zrobić bez robienia wrappera na każdą funkcję, którą chce się udostępnić w taki sposób (wrapper przyjmuje np tuple parametrów i wywołuje z tego funckję, można wtedy dynamicznie te wrappery wywoływać np z mapy). Zabija to niestety możliwość dodania funkcji podczas runtime

 

Może ktoś ma jakiś pomysł.

Opublikowano

@Sopelek997 robiłem to według MSDN, więc jak coś nie działa to... nie mój problem, że microsoft się nie trzyma własnych standardów.

 

@edit, no i nie chodziło mi o zawsze działający kod, tylko o pokazanie jak to można zrobić.

Nie pomagam na PW, od tego macie forum!!!

 

#PHP-things

 

 

08FMpDu.png

 

Opublikowano

To trzymaj się standardu C++, a nie tego co na MSDN.

Czy mógłbyś przytoczyć treść standardu C++, która dotyczy konwencji wywołań funkcji? Ja takowej nie widziałem a jedynie opisy pod dane architektury procesorów. Jak wiadomo C++ ma kompilatory na różne architektury i nie zawsze można wykorzystać na nich konkretnych konwencji, dlatego standard C++ nie może takowych uwzględniać.

YOU MUST DIE

- Ganon, Koridai

Opublikowano
The order of evaluation of arguments is unspecified.

 

Dobra, poprawka.

http://en.wikipedia.org/wiki/X86_calling_conventions

Tabelka na samym dole, ostatnie dwa wiersze na przykład.

+ pierwszy przypis

 

Już nie mówię o tym, że pod G++ to się nawet nie skompiluje, bo wstawki asm są inaczej pisane.

 

edit

Myślałem nad rozwiązaniem w takim stylu

http://stackoverflow.com/a/6454211/3763139

Tylko ono też ma ograniczenia.

 

Nie mam kompletnie pomysłu jak to rozwiązać tak, żeby to działało tak jak ten autoitowy

 

btw.

na tym forum?

Czepiasz się... Google dość dobrze indeksuje :)

 

 

https://www.google.pl/search?q=dynamically+calling+functions+from+dl&ie=utf-8&oe=utf-8&aq=t&rls=org.mozilla:pl:official&client=firefox-a&channel=fflb&gfe_rd=cr&ei=xsDxU8SaPIaH8QfI4YGAAg#channel=fflb&q=autoit+dllcall+in+c%2B%2B&rls=org.mozilla:pl:official

 

 

Nie miałby ktoś może tej funkcji z source autoit?

Opublikowano

A czy ten DllCall z AutoIt ma rozwiązanie dla wszystkich kompilatorów czy też tylko wybranych?

Zamiast wstawek asm można zrobić shellcode + ewentualne wersje dobierane poprzez dyrektywy.

YOU MUST DIE

- Ganon, Koridai

Opublikowano

@Sopelek997

Musisz grzebać w ich source: xxx zły link

 

 

@Edit

Okazuje się, że usunęli  source starych wersji ze swojej strony, a wszystkie inne strony linkują do nich, bo było na GPL. 

 

Pozostaje tylko przyjrzenie się Auto HotKeyowi ( to jest ten sam silnik, co w AutoIcie 3.1 - od tamtego czasu AUtoIt się zamknął, a AutoHotkey ujebał sobie składnię i pozostał GPL ). 

 

https://github.com/AutoHotkey/AutoHotkey

Ta sygnatura jest pusta.

Zarchiwizowany

Ten temat przebywa obecnie w archiwum. Dodawanie nowych odpowiedzi zostało zablokowane.

×
×
  • Dodaj nową pozycję...