how can I hook the LoadLibraryA API? I am googling a lot but I can't find any piece of code that helps me doing what I want to.

I just want to intercept it and display in a message box what is the name of the DLL that the program is trying to load.

is there a way I can do that?

Thanks.

Example: I would do it in a DLL. Then, inject this dll in my test app and then use an injector to inject a dll. The DLL must intercept that and display the dll name.

It is dirty, but it is possible (everything is possible). I have no specific clue to give you but I can give you the basic strategy. First, this is an interesting article on dynamic linked libraries (mainly written about Linux's "shared objects" which are the same as DLLs in windows), it gives a good overview of the underlying mechanics. Now, I think you can observe that the function LoadLibrary is from the windows API. So, how to tap into it? Well, if you can modify the executable file before running the program, then you should be able to find the dynamic linking entry (called an ELF header in Linux) which corresponds to the LoadLibrary function. Essentially, you can modify that entry in the executable file to point to a custom version of LoadLibrary that you implemented in another DLL and that forwards the call to the real LoadLibrary function while recording or issuing a message box telling the DLL that was loaded. Essentially, you will have to right a little tool program of some sort that rewrites the linking table of the executable, or maybe there are some already available in the world-wide-web.

This is not necessarily very easy, certainly not safe, and very naughty, but that's the only solution I can think of. I hope this is for a virtuous reason and that you are not some shameless hacker!

EDIT: If all you want is the name of the DLLs that an executable will load using LoadLibrary, then any decent disassembler will get you those names quite easily with a few clever searches and browsing the static data section.

No, I'm not a hacker lol. Its just for a game. I have it done in Delphi, using that MagicApiHook component. But I'd like to upgrade to C++, but I cant find any kind of component like MagicApiHook to C++.

I have a few codes here, but none of then works as they should.

I didn't know about MagicApiHook, but a quick google search for it revealed this thread which posts the source code for it. Just translate it to C++. I have done quite a bit of Delphi programming too and it is very easy to translate. The other alternative is to compile it to a DLL and use it in a C++ project, I guess that should be easy enough for you to do.

Well, thats an idea. thanks for the answer, I'll try and post the results later.

First of all, the calling convention of the DLL functions need to be declared as "stdcall;" to be easily imported to C++.

Second, in both functions ApiHook and ApiUnHook, the parameter MainApi is declared as "var Pointer" which I'm not sure how it translates to C++ (probably to void**). It appears that the assumption that "var Pointer" is equivalent to "void**" is pretty safe, so you might just leave it and try as is. If it doesn't work, you can modify both functions such that the MainApi parameter is a "^Pointer". Check carefully that you change it everywhere that MainApi is used in those functions.

Once that is done, you have two options: run-time or load-time linking.
load-time:
I'm pretty sure that Delphi can output a .lib for the DLL you compile (which is necessary for load-time linking). If you can find that option and generate the .lib file, then all you need in C++ is a simple header file with this content:

extern "C" bool __stdcall ApiHook(char* ModName, char* ApiName, void* FuncAddr, void* HookedApi, void** MainApi, int codigo);
extern "C" bool __stdcall ApiUnHook(char* ModName, char* ApiName, void* FuncAddr, void* HookedApi, void** MainApi, int codigo);

Include that header and add the .lib file to the compilation process for your C++ code. And that should be it. You will use the functions in C++ essentially the same as the code you posted in Delphi, with some "reinterpret_cast<>()" for getting around the hard-typing of C++ vs soft-typing of Delphi.

run-time linking:
If you cannot find a way to get a ".lib" file for the Delphi DLL, then run-time linking is the easiest. This just means using LoadLibrary, GetProcAddress and FreeLibrary. They are all the same functions as their Delphi counterparts and are used the same way. You would use them as:

#include "windows.h"

typedef bool __stdcall (*ApiHookFPtr)(char* ModName, char* ApiName, void* FuncAddr, void* HookedApi, void** MainApi, int codigo);
typedef bool __stdcall (*ApiUnHookFPtr)(char* ModName, char* ApiName, void* FuncAddr, void* HookedApi, void** MainApi, int codigo);

int main() {
  HMODULE dll_hdl = LoadLibrary("myApiHook.dll");
  
  ApiHookFPtr ApiHook = reinterpret_cast<ApiHookFPtr>(GetProcAddress(dll_hdl,"ApiHook"));
  ApiUnHookFPtr ApiUnHook = reinterpret_cast<ApiUnHookFPtr>(GetProcAddress(dll_hdl,"ApiUnHook"));

  //use the functions.
  
  FreeLibrary(dll_hdl);
};

I may have got something wrong in the above since it has been a while since I have touched DLLs and windows, but I think you can manage with that.

Well, this Delphi code:

var
  MessageBox_Next : function(handle:HWND;tipe:Integer): Cardinal; stdcall;
       
function MessageBox_CallBack(handle:HWND;tipe:Integer): Cardinal; stdcall;
begin
  Result:=MessageBox_Next(handle,3);
end;

ApiHook('user32.dll','ShowWindowA',nil,@MessageBox_CallBack,@MessageBox_Next);

Would be literally translated to:

unsigned int __stdcall (*MessageBox_Next)(HWND handle, int tipe);

unsigned int __stdcall MessageBox_CallBack(HWND handle, int tipe) {
  if(MessageBox_Next)
    return MessageBox_Next(handle,3);
  else
    return 0;
};

int main() {
  //..
  ApiHook("user32.dll","ShowWindowA",NULL,MessageBox_CallBack,&MessageBox_Next,0);
  //..
};

I would suggest you get some more skills in C++, because the above is very simple C++ code that you should easily be able to write yourself if you doing something as advanced as DLL hooks.

I got these erros:

invalid conversion from `unsigned int (*)(HWND__*, const CHAR*, const CHAR*, UINT)' to `void*'

invalid conversion from `unsigned int (**)(HWND__*, const CHAR*, const CHAR*, UINT)' to `void**'
both in line 27.

Actually, i'm trying to hook MessageBox. Here is my code:

#include "windows.h"

typedef bool __stdcall (*ApiHookFPtr)(char* ModName, char* ApiName, void* FuncAddr, void* HookedApi, void** MainApi, int codigo);
typedef bool __stdcall (*ApiUnHookFPtr)(char* ModName, char* ApiName, void* FuncAddr, void* HookedApi, void** MainApi, int codigo);

unsigned int __stdcall (*MessageBox_Next)(HWND handle, LPCSTR a,LPCSTR b,UINT x);


unsigned int __stdcall MessageBox_CallBack(HWND handle, LPCSTR a,LPCSTR b,UINT x) 
{
    if(MessageBox_Next)
    {
    return MessageBox_Next(handle, a,b, x);
    }else{
    return 0;
    }

}

int main() {
  HMODULE dll_hdl = LoadLibrary("Project2.dll");
  
  ApiHookFPtr ApiHook = reinterpret_cast<ApiHookFPtr>(GetProcAddress(dll_hdl,"ApiHook"));
  ApiUnHookFPtr ApiUnHook = reinterpret_cast<ApiUnHookFPtr>(GetProcAddress(dll_hdl,"ApiUnHook"));

  //use the functions.
  ApiHook("user32.dll","MessageBoxA",NULL,&MessageBox_CallBack,&MessageBox_Next,585);
  
  MessageBoxA( 0,"jj","jjj",MB_OK);
  
  system("pause");
  return 1;
  FreeLibrary(dll_hdl);
}

Well, I fixed it like this:

ApiHook("user32.dll","MessageBoxA",NULL,(void*)&MessageBox_CallBack,(void**)&MessageBox_Next,585);

The callback function:

unsigned int __stdcall MessageBox_CallBack(HWND handle, LPCSTR a,LPCSTR b,UINT x) 
{
    if(MessageBox_Next)
    {
        return 0;
    }else{
    return 0;
    }

}

After hooking, I call MessageBox. It shouldnt appear, but the messagebox still works. What am I doing wrong?

You should check that ApiHook returns true. Beyond that, I can't help you to find the source of the error. sorry.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.