If i have a global variable int A=0 in the C file. And I have the function in C:
int a()
{
A++;
return A;
}
if I call a() once in the Java application, I will have a return A=1. And if I call a() again, I will have a return of A=2; So I guess the global variable is fixed into a memory when the native library is loaded into the java application? Please let me know if my guess is correct or not. Thanks
Related
I have been working on this simply hobbyist OS, and I have decided to add some C++ support. Here is the simple script I wrote. When I compile it, I get this message:
cp.o: In function `caller':
test.cpp:(.text+0x3a): undefined reference to `__stack_chk_fail'
Here is the script:
class CPP {
public:
int a;
void test(void);
};
void CPP::test(void) {
// Code here
}
int caller() {
CPP caller;
caller.test();
return CPP.a;
}
Try it like this.
class CPP {
public:
int a;
void test(void);
};
void CPP::test(void) {
CPP::a = 4;
}
int caller() {
CPP caller;
caller.test();
return caller.a;
}
int main(){
int called = caller();
std::cout << called << std::endl;
return 0;
}
It seems to me that the linker you are using can't find the library containing a security function crashing the program upon detecting stack smashing. (It may be that the compiler doesn't include the function declaration for some reason? I am not familiar who actually defies this specific function.) Try compiling with -fno-stack-protector or equivalent.
What is the compiler used? A workaround might be defining the function as something like exit(1); or similar. That would produce the intended effect yet fix the problem for now.
I created a test program to show how this actually plays out. Test program:
int main(){
int a[50]; // To have the compiler manage the stack
return 0;
}
With only -O0 as the flag ghidra decompiles this to:
undefined8 main(void){
long in_FS_OFFSET;
if (*(long *)(in_FS_OFFSET + 0x28) != *(long *)(in_FS_OFFSET + 0x28)) {
/* WARNING: Subroutine does not return */
__stack_chk_fail();
}
return 0;
}
With -fno-stack-protector:
undefined8 main(void){
return 0;
}
The array was thrown out by ghidra in decompilation, but we see that the stack protection is missing if you use the flag. There are also some messed up parts of this in ghidra (e.g. int->undefined8), but this is standard in decompilation.
Consequences of using the flag
Compiling without stack protection is not good per se, but it shouldn't affect you in much. If you write some code (that the compiler shouts you about) you can create a buffer overflowable program, which should not be that big of an issue in my optinion.
Alternative
Alternatively have a look at this. They are talking about embedded systems, but the topic seems appropriate.
Why is the code there
Look up stack smashing, but to my knowledge I will try to explain. When the program enters a function (main in this case) it stores the location of the next instruction in the stack.
If you write an OS you probably know what the stack is, but for completeness: The stack is just some memory onto which you can push and off which you can pop data. You always pop the last pushed thing off the stack. C++ and other languages also use the stack as a way to store local variables. The stack is at the end of memory and when you push something, the new thing will be further forward rather than back, it fills up 'backwards'.
You can initialise buffers as a local variable e.g. char[20]. If you filled the buffer without checking the length you might overfill this, and overwrite things in the stack other than the buffer. The return address of the next instruction is in the stack as well. So if we have a program like this:
int test(){
int a;
char buffer[20];
int c;
// someCode;
}
Then the stack will look something like this at someCode:
[ Unused space, c, buffer[0], buffer[1] ..., buffer[19], a, Return Address, variables of calling function ]
Now if I filled the buffer without checking the length I can overwrite a (which is a problem as I can modify how the program runs) or even the return address (which is a major flaw as I might be able to execute malicious shellcode, by injecting it into the buffer). To avoid this compilers insert a 'stack cookie' between a and the return address. If that variable is changed then the program should terminate before calling return, and that is what __stack_chk_fail() is for. It seems that it is defined in some library as well so you might not be able use this, despite technically the compiler being the one that uses this.
I am having static bool variable in c++ class
In **
list.hh
**
namespace U
{
class list
{
public:
static bool mode;
};
}
In **
list.cc
**
The definition declared
namespace U
{
bool list::mode = false;
}
Now I am going to access these boolean in boolc.c "C" file
In boolc.c
#include<U/list.hh>
If( (U::list:mode) == true)
return "enabled";
else
return "disabled";
I could not able to compile this file as it is saying "bool" is not supported in C. More over "list.hh" file not found error. How to correct these issue?
namespace and classes are unknown in C, you cannot compile a file containing including list.hh with a C compiler, compile all in C++
#include<U/list.hh>
More over "list.hh" file not found error
note normaly when we #include a user file it is given between "", but you just miss something like a -I option to allow the compiler/preprocessor to find the file, but again the main problem is not here
One possibility is to get the address of the U::list::mode variable and pass that to the C code. In the C++ code you would then do something like this:
bool* ptr = &U::list::mode;
some_c_function(ptr);
and in the C code implementing some_c_function you would then have access to the pointer so you could check the value of U::list::mode there, although in the C code you would not write U::list::mode but instead you would write something like *ptr which would refer to the same memory location so it would effectively be the same as U::list::mode allowing you to check that value from within your C code.
This is what I did.
I created a struct and a static function in my C++ code
struct ItemDefinition {
int64_t price;
};
int static getPrice(lua_State* L) {
ItemDefinition* def = (ItemDefinition*)lua_touserdata(L, 1);
printf("%p\n", def);
printf("%d\n", def->price);
return 0;
}
I also registered the function in lua and initialized an ItemDefination object.
ItemDefinition def;
def.price = 120;
lua_pushlightuserdata(lua_state_, (ItemDefinition*)&def);
lua_setglobal(lua_state_, "def");
luaL_Reg module[] = {{"getPrice", &getPrice}, {NULL, NULL}};
from my Lua script, I just simply call the function
getPrice(def)
if works fine if I just print out the def's address. So I'm sure the function get called successfully. However, if I'm trying to get def->price, I will get an error from address sanitizer "==283789==ERROR stack use after return"
I'm not familiar with both c++ and lua. Could you please help where the problem could be?
Resolve the issue, NVM. It's actually because the pointer issue.
Given knowledge of the prototype of a function and its address in memory, is it possible to call this function from another process or some piece of code that knows nothing but the prototype and memory address? If possible, how can a returned type be handled back in the code?
On modern operating systems, each process has its own address space and addresses are only valid within a process. If you want to execute code in some other process, you either have to inject a shared library or attach your program as a debugger.
Once you are in the other program's address space, this code invokes a function at an arbitrary address:
typedef int func(void);
func* f = (func*)0xdeadbeef;
int i = f();
Yes - you're describing a function pointer. Here's a simple example;
int (*func)(void) = (int (*)(void))0x12345678;
int x = func();
It probably won't work between processes - in most operating systems, processes don't have access to each other's memory.
When you need a direct call:
((void(*)(void))0x1234)();
All previous answers are nice but much too long:
int i = ((int (*)(void))0xdeadbeef)();
// ========== --> addr of the function to call
// ============= --> type of the function to call
// ========================= --> ... we get a ptr to that fct
// ============================= --> ... and we call the function
In most OP, every process has its own memory, so you can't.
Sample code:
a.c:
#include <stdio.h>
int r() {return 2;}
int main() {
printf("%p\n",r);
while(1);
}
b.c:
#include <stdio.h>
int main() {
int a,(*b)();
scanf("%p",&b);
a=b();
printf("%d\n",a);
return 0;
}
this get segmentation fault.
It is definitely possible, but there are restrictions. Each process will have its own block of memory which other processes can't interfere with. Now, you will notice, I wrote it is definitely possible, this is through DLL injection (or code injection).
We can use the typedef keyword to achieve this. Now, I see you've marked the answer as 'Answered' and it seems you've gotten on fine, this is just a notice for anyone else that may be interested.
Is there some kind of tool i can give a c++ header to and have it change the API/lib/interface into a C interface as well as generate the C functions to cast and call the C++ code?
I think SWiG might do most of that.
I don't know of a tool that can do this automatically, it can get pretty tricky if you have classes as arguments to the public functions in your API.
But if your API is simple and mostly using native types, then you can do this by hand with not too much work. Here is a quick example of a C wrapper for a C++ class. Let's say this is the C++ class to wrap, let's call it test.h:
class Test {
public:
Test();
int do_something(char* arg);
bool is_valid(); // optional, but recommended (see below)
};
This is your C header test_c.h:
typedef void* TestHandle;
TestHandle newTest();
int deleteTest(TestHandle h);
int Test_do_something(TestHandle h, char* arg);
And your C implementation will be a C++ file with C functions, let's say test_c.cpp:
extern "C" TestHandle newTest()
{
return (void*)new Test();
}
extern "C" int deleteTest(TestHandle h)
{
Test* this = static_cast<Test*>(h);
if (!this->is_valid())
return -1; // here we define -1 as "invalid handle" error
delete this;
return 0; // here we define 0 as the "ok" error code
}
extern "C" int Test_do_something(TestHandle h, char* arg)
{
Test* this = static_cast<Test*>(h);
if (!this->is_valid())
return -1; // here we define -1 as "invalid handle" error
return this->do_something(arg);
}
The is_valid() method is there to guarantee that you were not given a bad handle. For example, you can store a magic number in all your instances, then is_valid() just ensures the magic number is there.