I'm having some issues with Minhook. When the modified function returns a value, application getting crashed. And I don't quite understand what the problem is.
As I understand it, the hooked function must return the original function with parameters, these parameters can be changed in the hook function.
This is the function I want to hook, taken from decompiler. I did not copied the function code because you would most likely be tired of scrolling through the page:
__int64 __fastcall SendPacket(int eNetMessageType, _QWORD *a2, __int64 _ENetPeer);
This is the original function that I have already moved to my code:
void(__thiscall* SendPacket)(int, long double*, __int64);
And this is the modified (hooked) function:
void __fastcall SendPacketLog(int eNetMessageType, long double* a2, __int64 _ENetPeer) {
std::cout << "[SendPacketLog]\nType: " << eNetMessageType << "\nUnknown: " << a2 << "\nENetPeer: " << _ENetPeer << "\n\n";
return SendPacket(eNetMessageType, a2, _ENetPeer);
}
The modified function should simply log the parameters of the function and then return the original function in the end. I manage to get the log, which is what the modified function should do, but immediately after that the game crashes.
In general, I can guess about the incorrect transfer of variables from the disassembler (From C and assembly to C ++, but at first glance everything is correct).
I attached a debugger to the process and when I crashed I got an error: "access violation while executing at address"
I also tried to return the value 0. Someone suggested this to me, but it did not help, it just saved from crashes, but broke the application.
Related
I am studying C++ by book and was trying to test simple coding for a looped game combat. A switch inside a while loop.
damage = greatsword[0] + player[1] - enemy[2]; endl;
error: statement cannot resolve address of overloaded function|
I have this error in 4 different code lines and in each one it has 'damage' so I assume its some problem with that. I have damage declared as an int and set to 0 before trying to change it to the attack value. I can provide more of the code if needed. I also tried changing the name from x to dmg to see if that was the problem
You have a trailing endl; which you probably did not mean to include. std::endl is a function which is used when printing to an output stream; usually you'll see cout << ... << endl;, but otherwise it should not be used.
std::endl, as used as a stream manipulator, is actually a function.
You probably achieve a similar or related error message by doing this
void f(); // don't need to define f()
int main()
{
f; // should be f() to call the function
}
So remove the statement endl;
I'm loading a delphi dll in c++. When I use functions with char* as buffers (char* given as parameter to the procedure) I get only trash data.
When I have functions that return char* all is fine.
I'm new to c++ and I spend a lot of time trying to crack this. Please help.
Everything is explained in code below. I have put there 3 functions to show exacly what I mean.
Example function that has problem with buffer is:
DLL_PingConnection(var avXml:PChar):Boolean; - it returns true/false, as parameter it takes buffer and the function is done in buffer there should be valid xml (but there is only trash)
#include <windows.h> //this will load delphi dll
#include <iostream>
#include <fstream>
#include <stdlib.h>
#include <string.h>
using namespace std;
// ------------------------------------------------ pointers on functions inside Delphi DLL (32 bits)
typedef bool(*TYPE_DLL_SetLicense)(char*, char*); //initialize dll stuff - I load licence from a file into char* - everything works fine
typedef bool(*TYPE_DLL_PingConnection)(char*); //the char* is buffer - I give empty char* as parameter and I should get correct xml with serwer data - I GET ONLY TRASH :(
typedef char*(*TYPE_DLL_ERR_DESCRIPTION)(void); //this function does not use buffer it returns char* - everything works fine
//so as you see problem is with buffers and function like this: DLL_PingConnection(buffer)
int main()
{
// ------------------------------------------------ Loading the library
HINSTANCE hGetProcIDDLL = LoadLibrary("C:\\full_path\\SOMEDLL.dll");
//checking the library
if (hGetProcIDDLL == NULL) {std::cout << "Could NOT load the dynamic library" << std::endl;return EXIT_FAILURE;}
else{std::cout << "dynamic library loaded" << std::endl;}
// ------------------------------------------------ START: resolving functions adresses
TYPE_DLL_SetLicense DLL_SetLicense = (TYPE_DLL_SetLicense)GetProcAddress(hGetProcIDDLL, "DLL_SetLicense");
if (!DLL_SetLicense) {std::cout << "Could NOT locate the function: DLL_SetLicense" << std::endl;return EXIT_FAILURE;}
else{std::cout << "Function DLL_SetLicense located" << std::endl;}
TYPE_DLL_PingConnection DLL_PingConnection = (TYPE_DLL_PingConnection)GetProcAddress(hGetProcIDDLL, "DLL_PingConnection");
if (!DLL_PingConnection) {std::cout << "Could NOT locate the function: DLL_PingConnection" << std::endl;return EXIT_FAILURE;}
else{std::cout << "Function DLL_PingConnection located" << std::endl;}
TYPE_DLL_ERR_DESCRIPTION DLL_ERR_DESCRIPTION = (TYPE_DLL_ERR_DESCRIPTION)GetProcAddress(hGetProcIDDLL, "DLL_ERR_DESCRIPTION");
if (!DLL_ERR_DESCRIPTION) {std::cout << "Could NOT locate the function: DLL_ERR_DESCRIPTION" << std::endl;return EXIT_FAILURE;}
else{std::cout << "Function DLL_ERR_DESCRIPTION located" << std::endl;}
std::cout << "\n\nInitialization over. \n\n" << std::endl;
// ------------------------------------------------ START: calling functions from delphi dll
//DLL_SetLicence - this function take buffer as parameter, but dont return anything into the buffer. All works fine.
//start - we read licence from file
char buffer_licence[1242];
memset(buffer_licence,0,sizeof(buffer_licence));
//I read content of buffer_licence usinf ifstream from the file here (but I don't put the code, to keep sample minimal)
//we set licence with dll function
bool is_licence = DLL_SetLicense(buffer_licence,(char*)"");
//the output
if (is_licence == TRUE)
std::cout << "Licence has been set\n";
else
std::cout << "Licence has been NOT set\n";
//DLL_PingConnection - it takes empty buffer as parameter, it should save xml into buffer but it saves only trash.
//we try to save ping to the file - buffer
char buffor_ping_xml[2000];
memset(buffor_ping_xml,0,sizeof(buffor_ping_xml));
//this should gieve proper xml, but it returns only trash.... please help
bool is_ping = DLL_PingConnection(buffor_ping_xml);
if(is_ping)
{
std::cout << "DLL_PingConnection True\n"; //function returned true, so it worked correct.
std::cout << buffor_ping_xml; //but in the buffer is trash that I show on the screen. I also tried to put buffor_ping_xml info the file (diferent ways) but always result was trash just like on screen.
}
else
{
std::cout << "DLL_PingConnection False: \n";
}
//DLL_ERR_DESCRIPTION - if will automaticly return error description if there is any error to report. No buffer, no problems.
std::cout << buffor_ping_xml; //the data on screet is fine, so is in file and everywhere else.
return EXIT_SUCCESS;
}
PingConnection function will return only this instead of good xml.
EDIT:
Oroginally I used Netbeans + MinGW, but as suggested in comments I have used alternative compilers: Borland builder c++ 6.0, and Embarcadero RAD Studio XE3 (C++ Builder). The problems stayed the same even thou I used all calling convention types Remy Lebeau mentioned.
typedef bool(*TYPE_DLL_PingConnection)(char*); //standard calling convention default for compiler - returns trash
typedef bool(__cdecl *TYPE_DLL_PingConnection)(char*); //returns trash also
typedef bool(__stdcall *TYPE_DLL_PingConnection)(char*); //doesnt write anything to the buffer
typedef bool(__fastcall *TYPE_DLL_PingConnection)(char*); //returns trash
I have encountered small problem under c++ builder. I can't clean buffer under this enviroment:
memset(buffer,0,sizeof(buffer)); // will crash the program under c++ builder
Trying to use 'char *&' will crash the program also.
typedef bool(__cdecl *TYPE_DLL_PingConnection)(char*&);
OR
typedef bool(__stdcall *TYPE_DLL_PingConnection)(char*&);
OR
typedef bool(__fastcall *TYPE_DLL_PingConnection)(char*&);
char * buffer;
bool is_ping = DLL_PingConnection(buffer);
Using char ** will cause type mismatch with buffer.
EDIT2:
As requested by David Heffernan I attach sample of documentation. Important parts are trasnated to english. Rest is just structure of xlm that PIngConnection should return. Not much of help there - entire documentation is like this.
PS: I asked similar question here: Trash characters when using buffers in c++ - code based on WxWidgets (I though WxWidgets creates the problem, but it doesn't. Maybe someone will find WxWidgets code usefull thou).
EDIT 3:
I managed to get some more information about dll.
Delphi version is 7.
For sure calling type is stdcall. ( DLL_PingConnection: function(var avXml: PChar): Boolean; stdcall; )
This is how a function from this dll is called in delphi:
lPointer := nil; //pointer
lOSOZPointer := nil; //pointer
lpXML := nil; //pChar
lpXML:=StringToPChar(lXML);
lPointer := lpXML;
lWynik:=OSOZ_GetServerDataTime(lpXML);
if lWynik then
begin
lOSOZPointer := lpXML;
//akcja na wyniku
end;
if lPointer <> nil then begin
Freemem(lPointer);
end;
if lOSOZPointer <> nil then begin
OSOZ_FreeMem(lOSOZPointer);
end;
DLL_PingConnection(var avXml:PChar):Boolean;
This is not a full declaration. Obviously, it is a function since it has a Boolean return type. But does it also declare a calling convention as well - stdcall (__stdcall in C/C++) or cdecl (__cdecl in C/C++)? If not, then it is using Delphi's default register convention instead (which is __fastcall in Borland/CodeGear/Embarcadero C++ compilers only, but has no equivalent in any other C/C++ compiler). Your existing typedefs are using your C++ compiler's default calling convention, which is usually __cdecl. Calling convention mismatches are the most common problem with using DLLs, as it causes mismanagement of the call stack, which affects how parameters are passed, accessed, and cleaned up.
Also, what version of Delphi was the DLL written in? PChar is PAnsiChar (char* in C++) in Delphi 2007, but is PWideChar (wchar_t* in C++) in Delphi 2009 and later. Chances are, since the data is XML, then PAnsiChar/char* is likely being used.
Also, the PChar parameter is being passed as a var in the Delphi declaration, which is the same as a pointer in C and a reference in C++.
You need these important pieces of information in order to use this DLL function in C/C++ code. Unless the documentation explictly states these details, or the DLL has a C/C++ .h/.hpp file showing the actual declaration, then the best you can do is guess, and there are several variations possible given the incomplete declaration you have shown so far:
(char*& can be replaced with char** if needed):
typedef bool (__cdecl *TYPE_DLL_PingConnection)(char*&);
typedef bool (__stdcall *TYPE_DLL_PingConnection)(char*&);
typedef bool (__fastcall *TYPE_DLL_PingConnection)(char*&);
typedef bool (__cdecl *TYPE_DLL_PingConnection)(wchar_t*&);
typedef bool (__stdcall *TYPE_DLL_PingConnection)(wchar_t*&);
typedef bool (__fastcall *TYPE_DLL_PingConnection)(wchar_t*&);
If the DLL functions are using cdecl or stdcall, then you are OK, as most C/C++ compilers support those calling conventions. However, if the DLL functions are using register instead, and if you are not using a Borland/CodeGear/Embarcadero C++ compiler, then you are SOL. You would have to wrap the DLL inside another Delphi-written DLL that exports wrapper functions that use more portable signatures.
I currently have a function that is meant to return T (templated function). So I always assumed it MUST return a value, but I recently stumbled across something.
#define PRINTERROR(msg) \
std::cout << msg << "\n\tFILE: " << __FILE__ << "\n\tLINE: " << __LINE__ << "\n\tTIME: " << __TIME__ << std::endl << std::endl;
and this...
template<class T>
T& Container_Vector<T>::GetFirstItem()
{
#ifdef CONTAINER_VECTOR_ERROR_CHECKING_ON
if (m_iCurrentSize > 0)
{
return m_pItems[0];
}
else
{
PRINTERROR("ERROR: Attempting to retrieve item from an empty vector container");
}
#else
return m_pItems[0];
#endif
}
When I step through the code trying to test if the msg gets outputted and error checking is on the first check(m_iCurrentSize > 0) fails, the message is printed and then it appears to jump to the end of the function "}" and return nothing?
Usually I'd get a compile error saying it has to return something. What's going on here and is it ok?
While it doesn't actually step through onto anything that returns T it does return something, a random memory address maybe.
You are missing a return after the PRINTERROR in the #ifdef block. Not doing so results in an undefined behavior. You must return an appropriate value at the end of the function.
(Such logical error can be caught at compile time with appropriates flags set. For example, in g++ you can use -Wall.)
First of all, the preprocessing takes place before the compilation. To your compiler, the code looks like -
If CONTAINER_VECTOR_ERROR_CHECKING_ON is defined:
template<class T>
T& Container_Vector<T>::GetFirstItem()
{
if (m_iCurrentSize > 0)
{
return m_pItems[0];
}
else
{
PRINTERROR("ERROR: Attempting to retrieve item from an empty vector container");
}
}
if CONTAINER_VECTOR_ERROR_CHECKING_ON is NOT defined:
template<class T>
T& Container_Vector<T>::GetFirstItem()
{
return m_pItems[0];
}
Your first case doesn't have a return on all branches, you should get a warning at least. MSVS doesn't report a compilation error, but it does return a warning. The random number you're getting is simply the last value present in the return register before the function exits.
Omitting to return a value from a function unfortunately is not a compile error.
A compiler may emit a diagnostic message (for example g++ does if compiling with -Wall option) but it's not mandatory.
Omitting to return a value is something that compiler writers are free to assume a programmer will never do, and if a program does it the standard says that the compiler is free to ignore the problem and whatever happens happens (undefined behavior). It's always a programmer fault.
On x86 architecture normally the net effect is just that you will get some strange value if the function is returning a true "native" type (e.g. a char or an int) that fits in a register and you may instead get memory corruption or a crash if the function is for example returning a class instance (e.g. std::string). Note however that any speculation about what happens in case of undefined behavior is just that... i.e. pure speculation as indeed anything may happen for the C++ language specification.
That's undefined behavior, if CONTAINER_VECTOR_ERROR_CHECKING_ON is defined and !( m_iCurrentSize > 0 ) then you are not returing anything. You may get a warning, but not an error since you do have one conditional return. In such case the function returns garbage, and the stack is probably corrupted after that.
Without copying all of the source in here, I am hitting a pcap_callback function from pcap_dispatch. The caplen seems to show the correct length (being that it is always something) but the len always equals 0. Is this field no longer populated? Is this maybe an error condition I am not capturing?
Here is a snippet...
void myCallback ( const struct pcap_pkthdr *header, const u_char *packet, void* buffer )
{
if ( (uint16_t)(header->len) != (uint16_t)(header->caplen) )
/* Some Error */
streamObj << "Caplen (" << (uint16_t)(header->caplen) << " != "
<< ") Packet Len (" << (uint16_t)(header->len) << ")";
...
}
The header->len value always comes back as zero. If more info is needed, just let me know.
This was found on a SUSE Linux 11SP1 server running libpcap.so.0.9.8 with a 2.6.32 kernel. The issue is only present after upgrading from SUSE Linux 10SP3 with libpcap.so.0.9.3.
EDIT:
This appears to only be an issue with libpcap.so.0.9.8. I repointed the link in /usr/lib/ to use libpcap.so.0.9.3 and the problem disappeared.
The three arguments to a callback function for pcap_dispatch() are, in order:
The "user data" pointer passed to pcap_dispatch();
A pointer to a struct pcap_pkthdr;
A pointer to the raw packet data.
Therefore, myCallback is not a valid callback function, and can't be passed to pcap_dispatch(), as it's expecting the first argument to be the pointer to the struct pcap_pkthdr. Unless you have another function that's the real callback, which then calls myCallback with the appropriate arguments, the code in question won't work, and should get at least a warning from a C or C++ compiler.
I am fairly new to c++ and I am a bit stumped by this problem. I am trying to assign a variable from a call to a method in another class but it always segfaults. My code compiles with no warnings and I have checked that all variables are correct in gdb but the function call itself seems to cause a segfault. The code I am using is roughly like the following:
class History{
public:
bool test_history();
};
bool History::test_history(){
std::cout<<"test"; //this line never gets executed
//more code goes in here
return true;
}
class Game{
private:
bool some_function();
public:
History game_actions_history;
};
bool Game::some_function(){
return game_actions_history.test_history();
}
Any tips or advice is greatly appreciated!
EDIT: I edited the code so there is no more local_variable and the value returns directly. But it still segfaults. As for posting the actual code, it's fairly large, what parts should I post?
From what I can see there's nothing wrong with the code you've displayed. However, segfaults often are a good indication that you've got corrupted memory. It's happening some place else besides what you've shown and only happens to impact the code here. I'd look any place you're dealing with arrays, pointers, or any manual memory interactions.
I have used valgrind succesfully with a lot of segfaults.
and have you tried to run gdb with the coredump caused by the segfault? from man gdb:
gdb program core
To create a coredump you might have to set:
ulimit -c unlimited
Shot in the dark. (Game*)this is NULL ?
The code is fine but the example is too incomplete to say what's wrong. Some things I'd suggest:
Add printouts to each class's destructor and constructor:
Game::Game() { cerr << this << " Game::Game" << endl; }
Game::Game(Game const&) { cerr << this << " Game::Game(Game const&)" << endl; }
Game::~Game() { cerr << this << " Game::~Game" << endl; }
bool Game::some_function() { cerr << this << " Game::some_function()" << endl; ... }
This will reveal:
Null object pointers.
Bad/deleted class pointers.
Second, for debugging, I'd strongly recommended sending printouts to cerr instead of cout. cout is usually buffered (for efficiency) before being output, cerr is not (at least, this used to be the case). If your program quits without executing its error handlers, at_exit, etc..., you are more likely to see the output if it is unbuffered and printed immediately.
Thirdly, if your class declarations live in a header, the class definitions, live in one cpp file and the code that uses the class in yet another, you may get this kind of crash if either of the cpp files were not recompiled after you changed the header.
Some other possibilities are:
stack overflow: you've allocated a lot of memory on the stack because of deep recursion or are allocating objects containing large arrays of data as local variables (i.e. not created or the heap with new or malloc))
corrupted class vtable (usually only possible due to dependency errors in your build tools),
corrupted object vtable pointer: possible through misuse of pointers: using pointers to deleted memory, or incorrectly writing to an in-use address. Not likely in your example because there are no virtual functions.
maintaining a pointer or reference to an object allocated on the stack that has been deleted: the printout code above will uncover this case.
I am wondering because you have defined some_function() in private of the Game class. So the code structure which you have mentioned above will also throw error for that.