So I am writing a wrapper for main and still provide a main like functionality, so user can define int main() or int main(argc, argv) and both works fine. I am able to do that for some compilers with inline assembly with pushing argc & argv onto stack before calling the user's main. However for x64 VC++, there is no inline assembly, so any suggestions on how I can achieve this?
Thanks!
I see two obvious choices: either write your code in assembly language, contained in an assembly language file, or else write your code in C++ without any inline assembly:
void my_entry_point() {
int argc = foo();
int argv = bar();
int ret = main(argc, argv);
exit_to_os(ret);
}
Related
I have a C program that I need to interface with a C++ library (ROS). Normally, it's not too difficult to interface C code with C++ code with a wrapper using extern "C" and using the C++ compiler to link, but I've never had to do it where main was in the C portion.
The C++ FAQ indicates that this is a bad thing:
Here are some high points (though some compiler-vendors might not require all these; check with your compiler-vendor’s documentation):
You must use your C++ compiler when compiling main() (e.g., for static initialization)
But I see another source saying it should be okay these days:
At one time, most C++ compilers required that function main be compiled by the C++ compiler. That requirement is not common today, ...
Why would it matter whether main is in the C portion or the C++ portion? How much trouble would I be in if I try to link code where it's in the C portion using common linkers today (mainly GCC's and Clang's)?
One easy way to work around this is to rename your C main() and call it from a new C++ main()
As in:
// in ypur current C main module
int my_c_main(int argc, char* argv[]) /* renamed, was main() */
{
/* ... */
]
// in a c++ module...
int main(int argc, char* argv[])
{
extern "C" int my_c_main(int argc, char* argv[]);
// if your c main() requires environment variables passed in envp,
// You can allocate space for strings and an array here and pass
// the environment variables you'll need, as the third parameter
// to my_c_main(), or pass environ, if your system has
// it defined in unistd.h
return my_c_main(argc, argv);
}
Consider a C++ program made of two CPP files, one of which contains a function named "func()" and the other contains main:
void func();
int main(int argc, char *argv[]) {
....
func();
...
}
Note that main does not send argc and argv to func.
Is there any other way by which func can access the command-line arguments? Maybe through some system call?
I have code
#include <stdlib.h>
void *gg = malloc(55);
int main(int argc, char **argv)
{
return 0;
}
gcc fail to compile but g++ works.
So, I just want to make sure that the malloc calling happens before main is exectued.
What you do is allowed in C++. The C++ standard has a whole section on "Dynamic initialization of non-local variables".
Looking at the assembly generated by GCC for your code is instructive:
Here the initializers are called through two generated functions, _GLOBAL__sub_I_gg (which is called before main) which in turn calls __static_initialization_and_destruction_0.
It is within the body of the latter function you will find the call to malloc.
I want to monitor an external program using dll injection
I managed to follow this tutorial and it work
http://www.codeproject.com/Articles/4118/API-Monitoring-Unleashed
Now i want to be able to monitor any function in the external program without knowing
it signature
I want to be able to copy the parameters sent to the original function and pass them to wrapper function and than back to the original
How it can be done?
I rather not use assembly language because i am not used to it.
Here is some code to demonstrate what i am trying to do:
#include "stdafx.h"
void (*pointerToOriginalFunctionForOverride)(...);
void (*copyPointerOfOriginalFucntion)(...);
//let say we dont know the signature of this function
void _cdecl originalFunction(char *s)
{
printf("%s",s);
}
void functionWrapper(void *first)
{
printf("Some debug info\n");
//HERE IS MY PROBLEM
copyPointerOfOriginalFucntion(?????????????);
}
int _tmain(int argc, _TCHAR* argv[])
{
pointerToOriginalFunctionForOverride = (void (*)(...))(&functionWrapper);
copyPointerOfOriginalFucntion = (void (*)(...))(&originalFunction);
//let say this line runs from an external program that we injected a dll into
pointerToOriginalFunctionForOverride("some text in external program");
}
This is impossible at the C++ level (also your code is disgusting C, not really C++). Your example code won't even work for functionWrapper as all variadic arguments must be passed on the stack, but the ABI calls for regular arguments (the first few) to be passed in a register.
You will have to go down to assembly.
thanks to to the answer here
http://www.rohitab.com/discuss/topic/39969-hook-function-without-knowing-signature/
I guess, you almost there with your code... you just need to make your trampoline function not >damaging the stack... firstly the function should be declared naked (without default prologue, in >studio I believe it would be something like __declspec(naked) or something)... secondly you need to >think about do you need to do something after the call to original function... if not, I think it is >better just to simply make a jmp instead of call (using inline assembler or something)...
Here is my code. used vs2012 on windows 7 64bit but 32bit compile. simple win32 console app . hope it helps anyone else
#include "stdafx.h"
void originalFunction(int x,int y,int z)
{
printf("running originalFunction with x=%d\n",x);
}
__declspec(naked) void trampolineFunction()
{
__asm jmp [originalFunction]
}
int _tmain(int argc, _TCHAR* argv[])
{
((void (*)(...))trampolineFunction)(7,8,9);
getchar();
return 0;
}
In Visual Studio 2003 using pure C, old-style function
declarations do not show as global member
i.e. void func(blah) int blah;{...}
This shows as a global member in the members dropdown:
void func(int blah)
{
...
}
This compiles, but old-style does not appear in the global
members dropdown:
void func(blah)
int blah;
{
...
}
I am trying to use the new 'Calling Graph' functionality to
analyse code, but as most of our legacy code uses the
old-style function parameters, those functions are not
recognized are not shown as Global Members, and therefore do
not appear in the 'Calling Graph'.
Is there any way to let the "call graph" analysis process
old-style function declarations correctly?
Maybe you want to consider to just change the old style function signatures. There shouldn't be any issues with that.
EDIT:
For an automatic conversion of your source files from old style syntax to ANSI-C style, take a look at the cproto tool. Maybe that could save you some time if you decide to go that direction.
This is an excerpt from the docs:
-f n
Set the style of generated function prototypes where n is a
number from 0 to 3. For example,
consider the function definition
main (argc, argv)
int argc;
char *argv[];
{
}
If the value is 0, then no prototypes are generated. When set to
1, the output is:
int main(/*int argc, char *argv[]*/);
For a value of 2, the output has the form:
int main(int /*argc*/, char */*argv*/[]);
The default value is 3. It produces the full function prototype:
int main(int argc, char *argv[]);
I'm not sure but maybe the engine uses regexs to trace routine signatures and the old C style isn't implemented.