I have an app that uses a modified version of Lua 5.2. Lua is embedded in an exe and as far I can see (with Dependency Walker) there are no export symbols for its Lua functions. I have no sources of this app. I need to write C module for Lua to use with this app.
I successfully require it in the Lua file that this app processes, but as soon as I'm trying to call any lua_* function app crashes with Access violation error.
Is there a way to find addresses/names of embedded Lua functions and call them?
I asked app developers if I'm allowed to do this, they don't seem to care. The only thing is that modification of the app itself is prohibited.
UPD: As far as I can see, I get Access violation because I'm trying to use Lua proxy lib and it fails to pass calls to exe Lua C functions.
If I'm not using Proxy DLL, I get Multiple VMs detected. Any way to solve this?
My Lua C module code:
#if defined(WIN32) || defined(_WIN32)
# define LUA_BUILD_AS_DLL /* for #define LUA_API __declspec(dllimport) */
#endif
#ifdef __cplusplus
extern "C" {
#endif
#include <lua.h>
#include <lauxlib.h>
#ifdef __cplusplus
}
#endif
#if defined(WIN32) || defined(_WIN32)
# ifdef __cplusplus
# define MY_LUA_API extern "C" __declspec(dllexport)
# else
# define MY_LUA_API __declspec(dllexport)
# endif
#else
# define MY_LUA_API extern "C"
#endif
using namespace std;
static int Lmytest_test(lua_State *L) {
// Check the arguments.
int argn = lua_gettop(L);
if (argn != 1 || !lua_isstring(L, 1)) {
lua_pushstring(L, "Give me one string argument please!");
lua_error(L);
}
lua_pushstring(L, "Hello world!");
return 2;
}
static const struct luaL_Reg lib[] = {
{ "test", Lmytest_test },
{ NULL, NULL }
};
MY_LUA_API int luaopen_mytest(lua_State* L) {
printf("Before newlib\n");
#if LUA_VERSION_NUM >= 502
luaL_newlib(L, lib);
#else
lua_createtable(L, 0, sizeof(lib) / sizeof(lib[0]));
luaL_register(L, NULL, lib);
#endif
printf("After newlib\n");
return 1;
}
For those who ask what is Lua proxy lib:
http://lua-users.org/wiki/LuaProxyDll
http://lua-users.org/wiki/LuaProxyDllTwo
http://lua-users.org/wiki/LuaProxyDllThree
http://lua-users.org/wiki/LuaProxyDllFour
I need to write C module for Lua to use with this app.
Well... you can't.
If their program does not export Lua's DLL interface, and it doesn't load Lua's DLL, then that means it statically linked with Lua. Unless you actually hack the executable, your DLL module will be talking to a Lua implementation that the main executable is not using. That's why you got a runtime crash; two different pieces of code talking to the same memory doesn't work out.
By statically linking to Lua, the developers of the application made it essentially impossible for users to write their own C modules for their uses of Lua without hacking the binary.
Is there a way to find addresses/names of embedded Lua functions and call them?
Not without a decompiler or really good assembly skills. And thanks to link-time optimization, even those may fail you, since some Lua APIs may have been inlined.
You most certainly can write a C dll and if the Lua environment is a properly compatible Lua system, then you should be able to achieve what you are looking to do. There are a number of things you need to check though:
Find out exactly what Lua version is running in the system you use.
This will let you determine what type of library you will need to compile against.
print( _VERSION )
Check other dll modules this Lua environment is using. Use dependency walker or similar. They should be using the luaopen_() type entry point. If this is the case, then your entry point above should be ok.
Check what you are passing to your methods. You cannot pass lightdata (pointers) between the Lua and your dll - mainly because their allocations will be in a different space. You will get access violations from this.
Check for any external libraries that the Lua system may be using. It is common that you will find a lua5.1.dll or similar. You need to be linking with this to ensure the methods you use, will be within the same application process space.
Often problems like this are more likely that the Lua implementation has been modified, and Lua bytecode and interfaces are not consistent, so very difficult to build against.
Hope this helps.
Btw. Use dependency walker to look into exe's and dll's for available methods. Lua uses the stdcall name mangling, so they are always visible.
http://www.dependencywalker.com/
Related
I am currently attempting to integrate the AzureStorageCPP into Unreal Engine 4 by using this documentation page. What I am doing is to create a custom C++ DLL wrapper around AzureStorageCPP, and then have Unreal Link this DLL in Unreal Code.
I installed the AzureStorageCPP as DLLs, via vcpkg. On completion, wastorage.dll is one of the important DLLs that needs to be linked.
The C++ DLL wrapper I wrote around AzureStorageCPP is below:
#include "was/storage_account.h"
#include "was/blob.h"
void UploadFileToAzure(char* FileName)
{
azure::storage::cloud_storage_account storage_account = azure::storage::cloud_storage_account::parse(U("DefaultEndpointsProtocol=https;AccountName=test;AccountKey=test"));
}
As far as I can tell, azure::storage::cloud_storage_account::parse lives in wastorage.dll
The issue is that when this parsing code is executed as a C++ Console, it runs just fine. The ConnectionString is passed correctly down the callstack to wastorage.dll, and the connection string is not garbage.
Here is the view one level down the callstack from the code above.
However, if I put the code into the C++ wrapper DLL I made called AzureStorage.DLL, link it into Unreal, and call from there, with the same call stack the string becomes garbage when it gets passed into wastorage.dll to parse.
I thought this might be related to this issue, but I still don't understand how to fix this, as I don't control the Parse method that is from AzureStorage.
Here is how I created the C++ DLL wrapper header, the source is already shown above:
AzureStorage.h
#pragma once
#define AZURESTORAGEDLL_API _declspec(dllexport)
#ifdef __cplusplus //if C++ is used convert it to C to prevent C++'s name mangling of method names
extern "C"
{
#endif
void AZURESTORAGEDLL_API UploadFileToAzure(char* FileName);
#ifdef __cplusplus
}
#endif
Searching for JNI, I've always found something like:
Method in C/C++, call in Java
Method in Java, call in C/C++
But never method in C/C++, call in C/C++ using JNI.
I ask that, because I have a 3rd party Java library, which has some C/C++ libraries, and I've always used Java to call them. And I would like now, to create some program using C instead of Java. Unfortunately they don't provide the any API in C/C++, only in Java.
Is it possible, if yes how can I try to do it?
Thank you in advance!
The JNI methods are always publicly exposed with an extern C signature.
This means that you could just link to the JNI dll directly if you have the method signature. (which you can easily get if you look at the Java class native method signature).
But you will have to make sure you give the method the environment it expects.
This means pass the "this" object and environment object.
You'll have to make sure that the class loader object has the right packages loaded in it. In most cases JNI code assumes the environment that called the method has the right class loader in it already (because the java method was called...).
And there's also an issue with local references that JNI code might assume are released automatically from the stack (which doesn't happen in C++ native threads).
Anyway, it would look like this:
//MyClass.java
class MyClass
{
native void Blah();
}
//method signature, some header file:
#ifdef __cplusplus
extern "C" {
#endif
JNIEXPORT void JNICALL Java_MyClass_Blah
(JNIEnv *, jobject);
#ifdef __cplusplus
}
#endif
//Call the function, C++ code
Java_MyClass_Blah(myEnv, myClassInstanve);
I know how to use explicit linking for a dll that doesn't contain class but how can link a dll contains class, example:
class math{
public:
int sum(int,int);
};
to load it:
typedef int(*func)(int,int);
int main{
HINSTANCE hDLL; // Handle to DLL
hDLL = LoadLibrary("math.dll");
func add=(func)GetProcAddress(hDLL, "sum");
add(4,5);
return 0;
}
if i do this it stop working and exit the program , if i remove the class it works
GetProcAddress can load up exported symbols form the DLL, provided you called it with the correct name.
In your case the function is not exported in the first place. And if it was, it is surely not called "sum" but some gibberish with 20-40 characters.
For using DLLs with C++ code you'll want to drop the GetProcAddress way entirely, and rely only on the implib that maps the names fine.
For that you add __declspec(dllexport) to the class (preferably with dllimport at the client), and add your DLL project as project reference. Alternatively add the .lib that was created along with the DLL to the client project.
C++ compilers use name mangling to uniquely distinguish identifiers in your program. This mangling causes the name to be significantly different than the plain identifiers you use in your program. Because of this using GetProcAddress is typically impractical for accessing code written in C++ that resides in a DLL. Instead I recommend using __declspec(dllexport) and __declspec(dllimport) to provide painless access to the code residing in your DLL.
In your DLL's project you will want to add a preprocessor definition with a name such as "EXPORT_CLASSES" or one unique to the DLL. This will be used by your DLL and program to determine if a particular declaration should be exported by the DLL or imported by the program.
dllstuff.h
#ifdef EXPORT_CLASSES
#define IMPORT_EXPORT __declspec(dllexport)
#else
#define IMPORT_EXPORT __declspec(dllimport)
#endif
You will then change the class declaration for math to use this. When the DLL is compiled IMPORT_EXPORT will be equal to __declspec(dllexport) and will instruct the compiler and linker that the definitions for this class should be made publicly available (ie. through the DLL's export table).
mathclass.h
#include "dllstuff.h"
class IMPORT_EXPORT math
{
public:
int sum(int, int);
};
Now all you have to do in your main application is include the mathclass.h any time you want to use the math class. You can now instantiate an instance of math and access it's member functions.
#include "mathclass.h"
int main()
{
math m;
int result = m.sum(1, 2);
}
This of course is just a basic description of the process. There are plenty of articles floating around the web (including SO) with provide much more detailed information.
I have a library (dll) originally written in MSVS that I need to make cross platform (Mac/Win). I started using XCode but with the new Embarcadero C++ builder XE3 I am thinking that one development environment would be a better way to go.
The host application is written in Delphi so more reason to move it to one set of tools.
For my existing code everything is cdecl but I cannot get this to work on C++ builder. If I convert it to stdcall then it works fine but as I understand it I need to use cdecl when using the library under OSX.
In MSVC I export my functions like this:
extern "C" __declspec(dllexport) int Init(char * init_dir, DebugCallbackFunc f, DeviceCallbackFunc f1)
In C++ Builder I am exporting like this:
extern "C" __declspec( dllexport ) int _cdecl Init(char * init_dir, DebugCallbackFunc f, DeviceCallbackFunc f1)
The problem is that the Delphi host application always returns NULL with GetProcAddress when I use cdecl but works fine if I change it to stdcall.
TUDMXInit = function(p: PAnsiChar; f: TDebugCallbackFunc; f1: TDeviceCallbackFunc): integer; cdecl;
I would also appreciate an example of the best way to handle the '_' that is suppose to prefix the exported function under OSX. Should I just use conditionals to add this at the front of all functions?
Thanks in advance.
Martin
The usual way of doing this is to use macros. declspec and cdecl/stdcall are Windows specific.
The call in OSX(and other Unix) you want is
extern "C" int Init(char * init_dir, DebugCallbackFunc f, DeviceCallbackFunc f1)
So the usual way is to define a macro e.g. DLL_EXPORT see the Boost libraries for examples
e.g. from Serialisation or a simpler description from Tcl
Assuming WINDOWS is defined in your build for Windows libraries
#ifdef WINDOWS
#define DLLEXPORT __declspec( dllexport )
#else
#define DLLEXPORT
#endif
Also you can make this define behave correctly for when building the DLL as here or calling the DLL when you need __declspec( dllimport )
The way I handle such differences is always the same basic idea: look at how each compiler does it, and come up with a macro or a set of macros that can generate all the required forms without being too cumbersome to use.
For your _cdecl, a simple macro like "EXPORT_CDECL" would seem to suffice; you can then set this to expand to nothing, "_cdecl", or "stdcall" as required by the compiler.
You can also use something like this to add something to names, such as #define EXPORT_NAME(Name) _##Name
You can, of course, also make a "big" macro that takes the individual components (return type, function name, function parameters) and spits out the entire result-line.
I have a (big and complex) C++ program with its own classes and methods.(obviously)
I would like to load at runtime a dll. From the main program i want to call a function inside the dll passing a class instance , and this function will use the method of this class.
In pseudo code
Main program:
class MyClass{
myattr1();
myattr2();
mymethod1();
mymethod2();
}
void main(){
MyClass* object = &(new MyClass())
handle_of_the_dll = *some function that load the dll*
dllfunc = getfunc(handle_of_the_dll, "interesting_function")
dllfunc(object)
[...etc...]
and the dll
#ifdef __cplusplus
extern C {
#endif
#ifdef BUILD_DLL
#define EXPORT __declspec(dllexport)
#else
#define EXPORT __declspec(dllimport)
#endif
#include all the needed headers from main program, where the class is defined
EXPORT void interesting_functionn(MyClass object){
object.mymethod1();
}
#ifdef __cplusplus
}
#endif
Is this valid/doable/right?
EDIT:
i know that this would be a poor design for a general program, but this method is intended to give the users the ability to use their custom dll that can access the api of the main program. Something like Cpython modules
It is valid and doable. Generate a sample DLL in visual C++ and the code will have all the bases covered. Replace the static linking in the client with LoadLibrary and GetProcAdress.
Name mangling could be an issue, DependencyWalker will help you there.
Keep a low profile with emory management. For example, if you use a memory manager on one side but not on the other, your begging for trouble.
I'd say it's possible, but with all due respect, it looks like bad design to me. There is a circular dependency between the main program and the dll: the program calls functions from the dll, and viceversa. In an ideal design, the main program would consume some dll functions, and the dll wouldn't know anything about the main program, or in general, about its clients.
Perhaps you should isolate the functions from the main program that the dll needs to use in a common dll or static lib which both the program and dll use.
As long as the methods are declared virtual and you pass the object by reference or pointer there should be no problems. If however you want to access non-virtual methods of the class you will need to put it's implementation in a separate DLL.