Load function with parameters from dll - c++

I load a dll in my c++ code but when run it I get error :
dll:
`extern "C" __declspec(dllexport) int Add(int a,int b)
{
return a+b;
}`
my console file:
typedef int(__stdcall *f_funci) (int , int);
int main()
{
HINSTANCE hGetProcIDDLL = LoadLibrary("ConsoleApplication1.dll");
if (!hGetProcIDDLL) {
std::cout << "could not load the dynamic library" << std::endl;
system("pause");
return EXIT_FAILURE;
}
f_funci funci = 0;
funci = (f_funci)GetProcAddress(hGetProcIDDLL, "Add");
if (!funci) {
std::cout << "could not locate the function" << std::endl;
system("pause");
return EXIT_FAILURE;
}
int t = 0;
t= (*funci)(2, 3);
std::cout << "funci() returned "<<t<< std::endl;
system("pause");
return EXIT_SUCCESS;
}
this error:enter image description here

The __stdcall changes how a function is called.
Call for __stdcall on x86...
push b;
push a;
call fnAdd; # stack is restored by the callee. with ret 8
Call for __cdecl
push b;
push a;
call fnAdd;
add esp, 8 # restore stack.
This has to be matched in the function with the correct ret or ret 8.
In your case the __stdcall is causing the values a and b interfering with the registers which maintain the frame of the function.

Related

Using Dll to assign a function to the Pointer-Member-Function of a structure passed to it

I have two projects in my Solution (Visual Studio)
I want to assign the function
void _OnCycle()
{
printf("Success\n");
}
in the Dll( main.cpp ) to the pointer member function OnCycle of the structure PluginCallbacks.
extern "C" unsigned int PluginInit(PluginFuncs * pluginFuncs, PluginCallbacks * pluginCalls, PluginInfo * pluginInfo) {
pluginCalls->OnCycle = _OnCycle;
return 1;
}
But program is crashing. Entire code below.
//Project: ConsoleApplication1
//file: Dll1/ConsoleApplication1/ConsoleApplication1.cpp
#include <iostream>
#include "plugin.h"
#include <windows.h>
typedef unsigned int (__stdcall *PluginInit)(PluginFuncs* pluginFuncs, PluginCallbacks* pluginCalls, PluginInfo* pluginInfo);
int main()
{
std::cout << "Loading first dll\n";
HINSTANCE hGetProcIDDLL = LoadLibrary("../Release/Dll1.dll");
if (!hGetProcIDDLL) {
std::cout << "could not load the dynamic library" << std::endl;
return EXIT_FAILURE;
}
// resolve function address here
PluginInit funci = (PluginInit)GetProcAddress(hGetProcIDDLL, "PluginInit");
if (!funci) {
std::cout << "could not locate the function" << std::endl;
return EXIT_FAILURE;
}
PluginFuncs a;
PluginCallbacks b;
PluginInfo c;
std::cout << "PluginInit(a,b,c) returned " << funci(&a,&b, &c) << "\n";
std::cout << "Now going to call OnCycle\n";
b.OnCycle();
std::cout << "Done";
return EXIT_SUCCESS;
}
//Project: ConsoleApplication1
//file: Dll1/ConsoleApplication1/plugin.h
#pragma once
#include <stdint.h>
## Heading ##
typedef struct _Settings {
uint32_t structSize;
uint32_t flags;
} Settings;
typedef struct _PluginInfo {
uint32_t structSize;
char name[32];
} PluginInfo;
typedef struct _PluginFuncs {
uint32_t structSize;
uint32_t(*GetVersion) (void);
}PluginFuncs;
typedef struct {
uint32_t structSize;
void (*OnCycle) ();
}PluginCallbacks;
and second project
//Project: Dll1
//file: Dll1/Dll1/main.cpp
#include "plugin.h"
#include "main.h"
#include "stdio.h"
void _OnCycle() {
printf("Success\n");
}
extern "C" unsigned int PluginInit(PluginFuncs * pluginFuncs, PluginCallbacks * pluginCalls, PluginInfo * pluginInfo) {
printf("PluginInit called\n");
pluginCalls->OnCycle = _OnCycle;
return 1;
}
//Project: Dll1
//file: Dll1/Dll1/main.h
#define EXPORT __declspec(dllexport)
#include "plugin.h"
#ifdef __cplusplus
extern "C" {
#endif
EXPORT unsigned int PluginInit(PluginFuncs* pluginFuncs, PluginCallbacks* pluginCalls, PluginInfo* pluginInfo);
#ifdef __cplusplus
}
#endif
//Project: Dll1
//file: Dll1/Dll1/plugin.h
#pragma once
#include <stdint.h>
typedef struct _Settings {
uint32_t structSize;
uint32_t flags;
} Settings;
typedef struct _PluginInfo {
uint32_t structSize;
char name[32];
} PluginInfo;
typedef struct _PluginFuncs {
uint32_t structSize;
uint32_t(*GetVersion) (void);
}PluginFuncs;
typedef struct {
uint32_t structSize;
void (*OnCycle) ();
}PluginCallbacks;
It builds but crashes on execution.
//Output
C:\Users\[hidden]\source\repos\Dll1\Release>ConsoleAPplication1
Loading first dll
PluginInit called
PluginInit(a,b,c) returned 1
Now going to call OnCycle
C:\Users\[hidden]\source\repos\Dll1\Release>
See, it crashes as 'Done' message not printed.
How this is to be done correctly.?
It seems my problem is solved by creating a pointer, malloc'ing it and passing it to dll.
Here is the piece of code
PluginFuncs* a = NULL;
PluginCallbacks* b = NULL;
PluginInfo* c = NULL;
a = (PluginFuncs*)malloc(sizeof(PluginFuncs));
b = (PluginCallbacks*)malloc(sizeof(PluginCallbacks));
c= (PluginInfo*)malloc(sizeof(PluginInfo));
std::cout << "PluginInit(a,b,c) returned " << funci(a,b, c) << "\n";
std::cout << "Now going to call OnCycle\n";
if (b && b->OnCycle)
b->OnCycle();
std::cout << "Done";
and output
Loading first dll
PluginInit(a,b,c) returned 1
Now going to call OnCycle
Success
Done
Thanks

C++ How to pass static function as a callback if it is declared in a separate file?

Context
In the separate file in class Utils, there are two static functions: quote_sql() and default_callback(). Both functions are working fine if called directly. However if you pass default_callback() as a pointer to sqlite3_exec, it won't be invoked.
Code
// sqlite_common.hpp
class Utils {
public:
static std::string quote_sql(const std::string str)
{
std::string quote = "'";
std::string result = quote + str + quote;
return result;
}
static int default_callback(void* used, int argc, char** argv, char** azColName)
{
std::cout << "Callback is called.\n";
bool* status = static_cast<bool*>(used);
*status = true;
for(int i = 0; i < argc; i++)
{
printf("%s = %s\n", azColName[i], argv[i] ? argv[i] : "NULL");
}
std::cout << "\n";
return 0;
}
};
// main.cpp
void signup_func()
{
// quote_sql() is working as it should
std::string sql =
"INSERT INTO User (Login, Password) VALUES ("
+ Utils::quote_sql(login) + "," + Utils::quote_sql(password) + ");";
// here default callback is never called even when it should have been
char* zErrMsg;
bool status = false; // status is just the first argument of callback
int rc = sqlite3_exec(db, sql.c_str(), Utils::default_callback, &status, &zErrMsg);
// however this will output "Callback is called."
default_callback(0, 0, 0, 0);
// this also doesn't work
auto callback = &Utils::default_callback;
int rc = sqlite3_exec(db, sql.c_str(), callback, &status, &zErrMsg);
// declaring default_callback outside of a class doesn't work either
// in fact that's how it was in the first place
// the only case when it works is when I define callback in main.cpp
}
What I want?
I want to be able to store default_callback() in a separate file and pass it into functions around the program with it executing where it should.
Edit
This code works somehow. Similar situation: static callback function is in a seperate file passed by pointer but works just fine.
// main.cpp
#include <iostream>
#include "callback.hpp"
int do_action(int a, int b, int(*action)(int, int))
{
return action(a, b);
}
int main()
{
auto callback = ∑
// will output 4 as it should
std::cout << do_action(2, 2, callback) << "\n";
return 0;
}
// callback.hpp
static int sum(int a, int b)
{
return a + b;
}

I'm getting error 127 when trying to get function address

When I try and get a proc address for a function called print, it is able to load the ManualLinking.dll but not the function. The error code that windows gives is 127. The client app is almost a direct copy paste from windows.
DLL:
#include"pch.h"
#include<string>
#include<iostream>
__declspec(dllexport) void __stdcall print(std::string data) {
std::cout << data << std::endl;
}
CPP:
#include <windows.h>
#include<iostream>
#include"Header.h"
#include<string>
typedef void(__stdcall* MYPROC)(std::string data);
int main(void)
{
HINSTANCE hinstLib;
MYPROC ProcAdd;
BOOL fFreeResult, fRunTimeLinkSuccess = FALSE;
// Get a handle to the DLL module.
hinstLib = LoadLibrary(TEXT("ManualLinking.dll"));
// If the handle is valid, try to get the function address.
if (hinstLib != NULL)
{
ProcAdd = (MYPROC)GetProcAddress(hinstLib, "print");
// If the function address is valid, call the function.
if (NULL != ProcAdd)
{
fRunTimeLinkSuccess = TRUE;
(ProcAdd)("Message sent to the DLL function\n");
}
// Free the DLL module.
fFreeResult = FreeLibrary(hinstLib);
}
// If unable to call the DLL function, use an alternative.
if (!fRunTimeLinkSuccess) {
printf("Message printed from executable\n");
std::cout << GetLastError() << std::endl;
}
std::cin.get();
return 0;
}
You need to replace DLL code with:
#include"pch.h"
#include<string>
#include<iostream>
extern "C"{
__declspec(dllexport) void __stdcall print(std::string data) {
std::cout << data << std::endl;
}
}
If you still have same error, please, check if the executable can actually find the .dll
/*...*/
if (hinstLib != NULL)
{
ProcAdd = (MYPROC)GetProcAddress(hinstLib, "print");
// If the function address is valid, call the function.
if (NULL != ProcAdd)
{
fRunTimeLinkSuccess = TRUE;
(ProcAdd)("Message sent to the DLL function\n");
}
// Free the DLL module.
fFreeResult = FreeLibrary(hinstLib);
}
else
{
std::cout << "Cannot find dll" << std::endl;
}
/*...*/

self-modifying under windows issue overwrite

I am writting a self-mutation code , and its original value before overwrite is 1,but after the overwrite should be 42. I think I am missing some aspecs because I got 1 on both original and mutation overwrite. my complete code looks like this gist link , but the original source was written under *unix https://shanetully.com/2013/12/writing-a-self-mutating-x86_64-c-program/
#include <windows.h>
#include <iostream>
using namespace std;
int getpagesize();
void foo(void);
int change_page_permissions_of_address(void *addr);
int getpagesize() {
SYSTEM_INFO si;
GetSystemInfo(&si);
return unsigned(si.dwPageSize);
}
void foo(void) {
int i = 0;
i++;
printf("i: %d\n", i);
}
int change_page_permissions_of_address(void *addr) {
// Get total function size
int page_size = getpagesize();
DWORD dwOldProtect;
// Obtain the addresses for the functions so we can calculate size.
uintptr_t tmp = (uintptr_t)addr-(uintptr_t)addr%page_size;
addr = (void*)tmp;
// We need to give ourselves access to modifify data at the given address
if (VirtualProtect(addr, page_size, PAGE_EXECUTE_READWRITE, &dwOldProtect) == -1) {
return -1;
}
return 0;
}
int main() {
void *foo_addr = (void*)foo;
if (change_page_permissions_of_address(foo_addr) == -1) {
printf("Error while changing page permissions of foo(): %s\n");
return 1;
}
// Call the unmodified foo()
puts("Calling foo...");
foo();
// Change the immediate value in the addl instruction in foo() to 42
unsigned char *instruction = (unsigned char*)foo_addr + 18;
*instruction = 0x2A;
puts("Calling foo..., but I am the self-modifying");
foo();
cin.get();
return 0;
}
Check of VirtualProtect is incorrect as it returns FALSE, not -1 in case of an error. Also I suspect that you will need to obtain a pointer to a starting page of the region of pages that foo belongs to and it is not clear where did you get offset 18 from.

Run-Time Check Failure #0 – The value of ESP was not properly saved across a function call

I use windows 7, when I build a C++ win32 console project to exe and run it, error occurs:
This program is to open the testengine and read some data from the bluetooth chip(CSR3026).
#include <iostream>
#include <windows.h>
using namespace std;
int main()
{
int iHandle = 0;
int iTimeout = 0;
typedef int (*tepsread)(int handle, int keyId, int valueLen, int *value, int *readLen);
typedef int (*opentestengine)(int transport, char* transportDevice, int dataRate, int retryTimeOut, int usbTimeOut);
typedef int (*closetestengine)(int handle);
char data[50] = {0};
int v;
int r;
HINSTANCE hDLL = LoadLibrary(L"TestEngine.dll");
opentestengine openTestEngine = (opentestengine)GetProcAddress(hDLL, "openTestEngine");
closetestengine closeTestEngine = (closetestengine)GetProcAddress(hDLL, "closeTestEngine");
do
{
cout << "Trying to connect..." << endl;
iHandle = openTestEngine(2, "COM5", 115200, 1000, 0);
iTimeout += 1000;
} while(iHandle == 0 && iTimeout < 5000);
if(iHandle != 0)
{
cout << "Connected!" << endl;
// Perform all your testing here
tepsread pFun = (tepsread)GetProcAddress(hDLL, "tePsRead");
cout << pFun(iHandle, 10191, 32, &v, &r) << endl;
closeTestEngine(iHandle);
}
FreeLibrary(hDLL);
cout << v << endl;
return v;
}
1 open the testengine via serial port 5 to communicate with the chip.
2 Call tePsRead function in testengine.dll to read value in 10191 from chip.
I have changed to the __cdecl calling convention, but the same error remmains:
enter image description here
The error message says you call a function after you cast it wrongly to change its signature
So the signature of at least one of the function openTestEngine, closeTestEngine or tePsRead is not the one you suppose
So
tePsRead is not int tePsRead(int, int, int, int *, int *);
and/or openTestEngine is not int openTestEngine(int, char*, int, int, int);
and/or closeTestEngine is not int closeTestEngine(int);