Exetools  

Go Back   Exetools > General > Source Code

Notices

Reply
 
Thread Tools Display Modes
  #1  
Old 03-19-2018, 17:30
0xall0c 0xall0c is offline
Friend
 
Join Date: Mar 2018
Posts: 67
Rept. Given: 0
Rept. Rcvd 4 Times in 3 Posts
Thanks Given: 25
Thanks Rcvd at 65 Times in 35 Posts
0xall0c Reputation: 4
[C] Winapi Call Dynamically and easily

This Small Function Let You call winapi dynamically, without having to define function definition, or writing nonsense wrappers.

Code:
void* DynCall(void *ptr, ...)
{
	char* function;
	char* library;
	va_list va;
	void *p;
	int i = 0;
	DWORD argBuf[32];
	DWORD ret;
	HANDLE lib;

	va_start(va, ptr);
	library = ptr;
	function = va_arg(va, void*);
	p = va_arg(va, void *);
	if(!(lib = GetModuleHandleA(library)))
		lib = _LoadLibraryA(library);
	if (!lib)
		error("Cant load libarary %s", library);
	void *funcAddress = _GetProcAddress(lib, function);
	if (!funcAddress)
		error("Cant Find Dynamic Address %s", function);
	for (; p != 0xb33f; p = va_arg(va, void *)) {
		argBuf[i++] = p;
	}
	
	for (i--; i >= 0; i--)
	{
		p = argBuf[i];
		_asm {
			push p
		}
	}
	va_end(va);
	_asm {
		push lb
		jmp funcAddress
	lb:
		mov ret, eax
	}
	return ret;
}
Example :

Code:
DWORD dwResult = DynCall("ntdll.dll","NtUnmapViewOfSection",
					PI.hProcess,
					(LPVOID)(NtHeader->OptionalHeader.ImageBase),0xb33f
				);
Dont forget to add one extra paramater at end i.e 0xb33f

I think it will be useful to someone.
Reply With Quote
The Following User Gave Reputation+1 to 0xall0c For This Useful Post:
mr.exodia (03-20-2018)
The Following 8 Users Say Thank You to 0xall0c For This Useful Post:
dosprog (04-04-2018), Indigo (07-19-2019), niculaita (03-20-2018), nimaarek (10-18-2018), ontryit (04-03-2018), schrodyn (03-11-2019), tonyweb (03-21-2018), yoza (07-28-2019)
  #2  
Old 03-19-2018, 18:25
Pansemuckl Pansemuckl is offline
Friend
 
Join Date: Nov 2005
Posts: 39
Rept. Given: 6
Rept. Rcvd 4 Times in 2 Posts
Thanks Given: 17
Thanks Rcvd at 44 Times in 15 Posts
Pansemuckl Reputation: 4
Using this with a wrong number of arguments OR screwing up stack (e.g. using wrong calling convention) ... good luck debugging this!
Reply With Quote
The Following User Says Thank You to Pansemuckl For This Useful Post:
Indigo (07-19-2019)
  #3  
Old 03-19-2018, 20:12
0xall0c 0xall0c is offline
Friend
 
Join Date: Mar 2018
Posts: 67
Rept. Given: 0
Rept. Rcvd 4 Times in 3 Posts
Thanks Given: 25
Thanks Rcvd at 65 Times in 35 Posts
0xall0c Reputation: 4
when you dont know, number of arguments or calling convention of the function, you should not call that function,

its not for a commercial application (approx no maintainance), its for different scenarios.
Reply With Quote
The Following 2 Users Say Thank You to 0xall0c For This Useful Post:
Indigo (07-19-2019), niculaita (03-20-2018)
  #4  
Old 04-03-2018, 19:18
vic4key vic4key is offline
Family
 
Join Date: Apr 2010
Posts: 57
Rept. Given: 5
Rept. Rcvd 24 Times in 10 Posts
Thanks Given: 60
Thanks Rcvd at 94 Times in 21 Posts
vic4key Reputation: 24
I think the parameter number of arguments is better than 0xb33f. Ex. void* DynCall(void *ptr, int nargs, ...).
More, need checking for 32/64-bit and calling convention (32-bit can be __stdcall, __cdecl, ... 64-bit can be C-D-8-9 ordered registers, ...).
Reply With Quote
The Following 3 Users Say Thank You to vic4key For This Useful Post:
0xall0c (04-04-2018), Indigo (07-19-2019), niculaita (04-04-2018)
  #5  
Old 04-04-2018, 17:34
0xall0c 0xall0c is offline
Friend
 
Join Date: Mar 2018
Posts: 67
Rept. Given: 0
Rept. Rcvd 4 Times in 3 Posts
Thanks Given: 25
Thanks Rcvd at 65 Times in 35 Posts
0xall0c Reputation: 4
yes number of arguments would be better, it will help in debugging,
(you can modify the function, i have just given a way to call winapi pure dynamically, which i wa not able to find anywhere)

also the function was written for 32bit, no 64bit support
but as you posted i got a requirement to port it in 64 bit
(coincidence!!)
Reply With Quote
The Following User Says Thank You to 0xall0c For This Useful Post:
Indigo (07-19-2019)
  #6  
Old 04-04-2018, 19:01
dosprog dosprog is offline
Friend
 
Join Date: Feb 2018
Posts: 114
Rept. Given: 0
Rept. Rcvd 17 Times in 16 Posts
Thanks Given: 33
Thanks Rcvd at 146 Times in 74 Posts
dosprog Reputation: 17
It's likely not a good idea.
Any of imported functions must be correctly declared individulally,
and thus must be called normally.
In addition - without of using __asm directive.
In addition2 - repeated calls will be performed much faster.
In addition3 - [less or more] universal solution for x32/x64.

..It's likely not a good idea but it works..

--Add--

Add 1st argument of function as enum {C_CALL,STD_CALL}
and produce separate __asm code for this conventions ?



--Add2--

Quote:
Originally Posted by 0xall0c View Post
Example :

Code:
DWORD dwResult = DynCall("ntdll.dll","NtUnmapViewOfSection",
					PI.hProcess,
					(LPVOID)(NtHeader->OptionalHeader.ImageBase),0xb33f
				);
Dont forget to add one extra paramater at end i.e 0xb33f
This example rewritten without of DynCall():
Quote:
DWORD(__stdcall*_NtUnmapViewOfSection)(DWORD,DWORD);

void main(void)
{
DWORD result;

if(!(_NtUnmapViewOfSection=(DWORD(__stdcall*)(DWORD,DWORD))GetProcAddress(LoadLibrary("ntdll.dll"),"NtUnmapViewOfSection")))goto dos_exit;

result=_NtUnmapViewOfSection(0,0);

dos_exit:;
}



Last edited by dosprog; 04-05-2018 at 07:24.
Reply With Quote
The Following User Says Thank You to dosprog For This Useful Post:
Indigo (07-19-2019)
  #7  
Old 04-05-2018, 01:55
0xall0c 0xall0c is offline
Friend
 
Join Date: Mar 2018
Posts: 67
Rept. Given: 0
Rept. Rcvd 4 Times in 3 Posts
Thanks Given: 25
Thanks Rcvd at 65 Times in 35 Posts
0xall0c Reputation: 4
this code resolves problem when you don't want imports to be created in an executables, you can use getprocaddress and loadlibrary obviously, but using them and declaring each function prototype is very frustrating.
Reply With Quote
The Following User Says Thank You to 0xall0c For This Useful Post:
Indigo (07-19-2019)
  #8  
Old 04-05-2018, 03:07
mcp mcp is offline
Friend
 
Join Date: Dec 2011
Posts: 73
Rept. Given: 4
Rept. Rcvd 12 Times in 11 Posts
Thanks Given: 7
Thanks Rcvd at 47 Times in 35 Posts
mcp Reputation: 12
@0xalloc: I don't understand what problem this solves in the first place? In which cases do you call an API while at the same time not knowing its function signature? I mean, you cannot even correctly call any API without knowing its signature, i.e., how many bytes to push/pop off the stack?
Reply With Quote
The Following User Says Thank You to mcp For This Useful Post:
Indigo (07-19-2019)
  #9  
Old 04-05-2018, 16:14
0xall0c 0xall0c is offline
Friend
 
Join Date: Mar 2018
Posts: 67
Rept. Given: 0
Rept. Rcvd 4 Times in 3 Posts
Thanks Given: 25
Thanks Rcvd at 65 Times in 35 Posts
0xall0c Reputation: 4
Quote:
Originally Posted by mcp View Post
@0xalloc: I don't understand what problem this solves in the first place? In which cases do you call an API while at the same time not knowing its function signature? I mean, you cannot even correctly call any API without knowing its signature, i.e., how many bytes to push/pop off the stack?
in c/c++ you need to define function prototype first, with this no prototypes are needed.
Reply With Quote
The Following User Says Thank You to 0xall0c For This Useful Post:
Indigo (07-19-2019)
  #10  
Old 04-05-2018, 16:16
0xall0c 0xall0c is offline
Friend
 
Join Date: Mar 2018
Posts: 67
Rept. Given: 0
Rept. Rcvd 4 Times in 3 Posts
Thanks Given: 25
Thanks Rcvd at 65 Times in 35 Posts
0xall0c Reputation: 4
Quote:
Originally Posted by dosprog View Post
It's likely not a good idea.
Any of imported functions must be correctly declared individulally,
and thus must be called normally.
In addition - without of using __asm directive.
In addition2 - repeated calls will be performed much faster.
In addition3 - [less or more] universal solution for x32/x64.

..It's likely not a good idea but it works..

--Add--

Add 1st argument of function as enum {C_CALL,STD_CALL}
and produce separate __asm code for this conventions ?



--Add2--


This example rewritten without of DynCall():



see the function prototype you defined, when there are lot functions to call, that's an extra headache.
Reply With Quote
The Following User Says Thank You to 0xall0c For This Useful Post:
Indigo (07-19-2019)
  #11  
Old 04-05-2018, 16:35
mcp mcp is offline
Friend
 
Join Date: Dec 2011
Posts: 73
Rept. Given: 4
Rept. Rcvd 12 Times in 11 Posts
Thanks Given: 7
Thanks Rcvd at 47 Times in 35 Posts
mcp Reputation: 12
Quote:
Originally Posted by 0xall0c View Post
in c/c++ you need to define function prototype first, with this no prototypes are needed.
Right, but you cannot invoke an API without knowing its prototype! So that means you know the prototype already when using the "DynCall" mechanism. So the only thing it saves you is a one-line typedef? But you loose type correctness for all API arguments...that seems like a very bad trade-off.

Last edited by mcp; 04-05-2018 at 16:40.
Reply With Quote
The Following User Says Thank You to mcp For This Useful Post:
Indigo (07-19-2019)
  #12  
Old 04-05-2018, 16:44
Pansemuckl Pansemuckl is offline
Friend
 
Join Date: Nov 2005
Posts: 39
Rept. Given: 6
Rept. Rcvd 4 Times in 2 Posts
Thanks Given: 17
Thanks Rcvd at 44 Times in 15 Posts
Pansemuckl Reputation: 4
Quote:
Originally Posted by 0xall0c View Post
see the function prototype you defined, when there are lot functions to call, that's an extra headache.
Not if you're using variadic templates (C++ 11)...
It produces even simpler, smaller and clean code.
Reply With Quote
The Following 2 Users Say Thank You to Pansemuckl For This Useful Post:
0xall0c (04-05-2018), Indigo (07-19-2019)
  #13  
Old 04-05-2018, 17:25
0xall0c 0xall0c is offline
Friend
 
Join Date: Mar 2018
Posts: 67
Rept. Given: 0
Rept. Rcvd 4 Times in 3 Posts
Thanks Given: 25
Thanks Rcvd at 65 Times in 35 Posts
0xall0c Reputation: 4
Quote:
Originally Posted by mcp View Post
Right, but you cannot invoke an API without knowing its prototype! So that means you know the prototype already when using the "DynCall" mechanism. So the only thing it saves you is a one-line typedef? But you loose type correctness for all API arguments...that seems like a very bad trade-off.
trade-off is bad or not is subjective to where it is used.
Reply With Quote
The Following User Says Thank You to 0xall0c For This Useful Post:
Indigo (07-19-2019)
  #14  
Old 04-05-2018, 17:27
0xall0c 0xall0c is offline
Friend
 
Join Date: Mar 2018
Posts: 67
Rept. Given: 0
Rept. Rcvd 4 Times in 3 Posts
Thanks Given: 25
Thanks Rcvd at 65 Times in 35 Posts
0xall0c Reputation: 4
Quote:
Originally Posted by Pansemuckl View Post
Not if you're using variadic templates (C++ 11)...
It produces even simpler, smaller and clean code.
i didn't used variadic templates before. thank you for pointing out.
Reply With Quote
The Following User Says Thank You to 0xall0c For This Useful Post:
Indigo (07-19-2019)
  #15  
Old 04-05-2018, 18:44
mcp mcp is offline
Friend
 
Join Date: Dec 2011
Posts: 73
Rept. Given: 4
Rept. Rcvd 12 Times in 11 Posts
Thanks Given: 7
Thanks Rcvd at 47 Times in 35 Posts
mcp Reputation: 12
Quote:
Originally Posted by 0xall0c View Post
trade-off is bad or not is subjective to where it is used.
Well, it's pretty uncontroversial that losing type correctness for your API calls *is* bad for overall correctness of your program. The amount of work you're saving is marginal, and at the same time you have to deal with the dangers of type system violations. How is that not a bad trade-off? And we haven't even talked about the loss of readability of DynCall vs regular API calls...
Reply With Quote
The Following User Says Thank You to mcp For This Useful Post:
Indigo (07-19-2019)
Reply

Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is On


Similar Threads
Thread Thread Starter Forum Replies Last Post
Calling any function dynamically without typedef Succubus Source Code 0 10-21-2021 16:34
[MASM Source] - ZwCreateThread example (winAPI CreateThread emulation) TomaHawk Source Code 4 09-08-2019 14:06
WinAPI: No WM_COMMAND Message? aldente General Discussion 2 07-05-2006 07:17


All times are GMT +8. The time now is 17:25.


Always Your Best Friend: Aaron, JMI, ahmadmansoor, ZeNiX, chessgod101
( 1998 - 2024 )