#1
|
|||
|
|||
[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; } Code:
DWORD dwResult = DynCall("ntdll.dll","NtUnmapViewOfSection", PI.hProcess, (LPVOID)(NtHeader->OptionalHeader.ImageBase),0xb33f ); I think it will be useful to someone. |
The Following User Gave Reputation+1 to 0xall0c For This Useful Post: | ||
mr.exodia (03-20-2018) |
#2
|
|||
|
|||
Using this with a wrong number of arguments OR screwing up stack (e.g. using wrong calling convention) ... good luck debugging this!
|
The Following User Says Thank You to Pansemuckl For This Useful Post: | ||
Indigo (07-19-2019) |
#3
|
|||
|
|||
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. |
#4
|
||||
|
||||
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, ...). |
#5
|
|||
|
|||
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!!) |
The Following User Says Thank You to 0xall0c For This Useful Post: | ||
Indigo (07-19-2019) |
#6
|
|||
|
|||
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:
Quote:
Last edited by dosprog; 04-05-2018 at 07:24. |
The Following User Says Thank You to dosprog For This Useful Post: | ||
Indigo (07-19-2019) |
#7
|
|||
|
|||
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.
|
The Following User Says Thank You to 0xall0c For This Useful Post: | ||
Indigo (07-19-2019) |
#8
|
|||
|
|||
@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?
|
The Following User Says Thank You to mcp For This Useful Post: | ||
Indigo (07-19-2019) |
#9
|
|||
|
|||
Quote:
|
The Following User Says Thank You to 0xall0c For This Useful Post: | ||
Indigo (07-19-2019) |
#10
|
|||
|
|||
Quote:
|
The Following User Says Thank You to 0xall0c For This Useful Post: | ||
Indigo (07-19-2019) |
#11
|
|||
|
|||
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. |
The Following User Says Thank You to mcp For This Useful Post: | ||
Indigo (07-19-2019) |
#12
|
|||
|
|||
Quote:
It produces even simpler, smaller and clean code. |
#13
|
|||
|
|||
Quote:
|
The Following User Says Thank You to 0xall0c For This Useful Post: | ||
Indigo (07-19-2019) |
#14
|
|||
|
|||
Quote:
|
The Following User Says Thank You to 0xall0c For This Useful Post: | ||
Indigo (07-19-2019) |
#15
|
|||
|
|||
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...
|
The Following User Says Thank You to mcp For This Useful Post: | ||
Indigo (07-19-2019) |
|
|
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 |