calling Dll with another Dll in C++ - c++

I have a DLL that I want to call from within another DLL. I made a C++ MFC DLL with this code:
extern "C" INT PASCAL EXPORT Locale()
{
AFX_MANAGE_STATE(AfxGetStaticModuleState());
typedef BOOL(WINAPI* LPFNDLLGetStringLabel)( CWnd *, int, LPTSTR , CWinApp *, LPSTR , LPCTSTR );
int bRes = 0; //false;
char achEvent[ 250 ];
HINSTANCE hDLL;
hDLL = LoadLibrary( L"C:\\1.dll" );
if ( hDLL != NULL )
{
CString ocStrInfo;
ocStrInfo += "Alfa";
ocStrInfo += ";";
ocStrInfo += "Alfa";
ocStrInfo += ";";
ocStrInfo += "Alfa";
LPFNDLLGetStringLabel lpfnDllFunc;
lpfnDllFunc = (LPFNDLLGetStringLabel)GetProcAddress( hDLL, "GetStringLabel");
if ( lpfnDllFunc )
if( lpfnDllFunc( NULL, 111, (LPTSTR)ocStrInfo.GetBuffer(), AfxGetApp(), achEvent, NULL )) {
return bRes=1;
}else{
return bRes=0;
}
FreeLibrary( hDLL );
}
}
The following code is calling the second DLL, but it isn't working right:
int main(){
HINSTANCE dllHandle = LoadLibrary(L"C:\\2.dll");
if(dllHandle == NULL ){
std::cout << "alarm";
}
typedef int(*Locale)(void);
FARPROC pTest = GetProcAddress(HMODULE (dllHandle),"Locale");
if(pTest == NULL ){
std::cout << "alarm";
}
Locale con = Locale(pTest);
int r= 1;
r =con();
cout << r;
FreeLibrary(dllHandle);
getchar();
return 0;
}
But dllhandle equal with null... can anybody help me?

You might have a look at Dependency Walker. Using this tool in profile mode will show you whether the dependencies between your binaries (EXE - DLL1 - DLL2) can be resolved at runtime.
One reason might be: DLL1 cannot be started because DLL2 has not been found.
You should also take a look that the way you export Locale (extern "C" INT PASCAL EXPORT) is correct!
As already mentioned, you should also have a look at GetLastError.

For troubleshooting library dependencies in windows you could monitor your program with procmon. See (http://technet.microsoft.com/en-ca/sysinternals/bb896645.aspx)

Related

GetModuleFileNameExA won't work like it should when I try to link the function on runtime from psapi.dll (windows)

I'm experimenting with loading functions from dlls during run-time on windows. I tried doing a program that would print it's own modules, based on this one: https://learn.microsoft.com/en-us/windows/win32/psapi/enumerating-all-modules-for-a-process.
I need two functions to do what i want: EnumProcessModules and GetModuleFileNameExA. I managed to get both of them from psapi.dll on runtime, however GetModuleFileNameExA just doesn't work like it should and I can't tell why
this is the functional script I have written:
#include <windows.h>
#include <stdio.h>
#include <stdlib.h>
#include <psapi.h>
typedef DWORD (__cdecl *EnumModules)(HANDLE hprocess, HMODULE *moduleHandles, DWORD cb, LPDWORD lpcNeeded);
typedef DWORD (__cdecl *GetModuleName)(HANDLE hprocess, HMODULE hmodule, LPSTR name, DWORD size);
void ErrorMessage(const char *message){
fprintf(stderr, message);
exit(EXIT_FAILURE);
}
int PrintModules( HANDLE pHandle )
{
HMODULE hMods[1024];
DWORD cbNeeded;
unsigned int i;
if (NULL == pHandle)
return EXIT_FAILURE;
// Loads the lib
HMODULE psapiLib = LoadLibrary("C:\\Windows\\SysWOW64\\psapi.dll");
if(! psapiLib) ErrorMessage("Error loading psapi.dll\n");
// Get the functions we need from the lib
EnumModules getModules = (EnumModules)GetProcAddress(psapiLib, "EnumProcessModules");
GetModuleName getModuleName = (GetModuleName)GetProcAddress(psapiLib, "GetModuleFileNameExA");
if(!getModules) ErrorMessage("Error finding EnumProcessModules from psapi.dll\n");
if(!getModuleName) ErrorMessage("Error finding GetModuleFileNameExA from psapi.dll\n");
// Get a list of all the modules in this process.
if( getModules(pHandle, hMods, sizeof(hMods), &cbNeeded))
{
for ( i = 0; i < (cbNeeded / sizeof(HMODULE)); i++ )
{
LPSTR szModName;
szModName = malloc(1024 * sizeof(LPSTR));
// Get the full path to the module's file.
// change GetModuleFileNameExA with getModuleName to see the error
if ( GetModuleFileNameExA( pHandle, hMods[i], szModName, 1024 * sizeof(char))){
// Print the module name and handle value.
printf(("\t%s (0x%08X)\n"), szModName, hMods[i] );
}
free(szModName);
}
}
return 0;
}
int main( void )
{
HANDLE myHandle = GetCurrentProcess();
PrintModules(myHandle);
CloseHandle(myHandle);
return 0;
}
If I change this part
if ( GetModuleFileNameExA( pHandle, hMods[i], szModName, 1024 * sizeof(char))){
// Print the module name and handle value.
printf(("\t%s (0x%08X)\n"), szModName, hMods[i] );
}
to this
if ( getModuleName( pHandle, hMods[i], szModName, 1024 * sizeof(char))){
// Print the module name and handle value.
printf(("\t%s (0x%08X)\n"), szModName, hMods[i] );
}
so it would use my function instead, taking the need to link the psapi.dll on load-time away, it just does't work. It will either segfault or not print anything. I have tried modiffing how i present the buffer, tried using widechar or Tchar but nothing seems to work.
This is the output I have with the functional script:
working script ouput
and this is the output i have with my function:
non functional script output
The funny part is that one of the functions, the getModules (which points to EnumProcessModules) worked perfectly fine! I just can't understand what's going on.
You should change this line of code
typedef DWORD (__cdecl *EnumModules)(HANDLE hprocess, HMODULE *moduleHandles, DWORD cb, LPDWORD lpcNeeded);
to this.
typedef DWORD(__stdcall* EnumModules)(HANDLE hprocess, HMODULE* moduleHandles, DWORD cb, LPDWORD lpcNeeded);
for more info you can reference this

Getting the window title from a process name

I am trying to write a program that can get the window title of a process.
Before I describe the problem, here is the code:
#include <Windows.h>
#include <string>
#include <Psapi.h>
#include <algorithm>
std::string window_title;
std::string search_for;
BOOL CALLBACK EnumWindowCallback(HWND hWindow, LPARAM param)
{
if ( IsWindow( hWindow ) == TRUE )
{
DWORD pid = 0;
if ( GetWindowThreadProcessId( hWindow, &pid ) != 0 )
{
HANDLE hProcess;
hProcess = OpenProcess( PROCESS_ALL_ACCESS, FALSE, pid );
if ( hProcess != 0 )
{
std::string path;
CHAR name[MAX_PATH];
GetModuleFileNameExA( hProcess, NULL, name, sizeof(name) / sizeof(CHAR) );
path = name;
unsigned int slash = path.find_last_of('\\');
if ( slash != std::string::npos ){
std::string proc_name = path.substr( slash + 1, path.length() );
std::transform(proc_name.begin(), proc_name.end(), proc_name.begin(), ::tolower);
if ( proc_name == search_for )
{
CHAR finalTitle[MAX_PATH];
ZeroMemory( finalTitle, sizeof(finalTitle) );
SendMessageA( hWindow, WM_GETTEXT, (WPARAM)sizeof(CHAR)/sizeof(MAX_PATH), (LPARAM)finalTitle );
window_title = finalTitle;
return FALSE;
}
}
}
}
}
return TRUE;
};
const char* __stdcall GetWinTitleByProcessName( const char* title )
{
search_for = title;
std::transform(search_for.begin(), search_for.end(), search_for.begin(), ::tolower);
if ( EnumWindows( (WNDENUMPROC)EnumWindowCallback, 0 ) == FALSE )
{
return window_title.c_str();
}
return "NOTFOUND";
}
int WINAPI WinMain( HINSTANCE, HINSTANCE, LPSTR, int )
{
MessageBoxA( NULL, GetWinTitleByProcessName("chrome.exe"), "Test", MB_OK);
}
The program works so far, until I want to get the actual title of the window.
I tried GetWindowText and SendMessage, as shown here.
Both methods return empty strings.
How can I get the window title?
The following code works for a similar problem. In my case I am looking for the windows handle of an application so that I can parent a dll. I identify the app by its caption. Its C++Builder code so some parts may be unfamiliar. I'll comment the differences I spot. The main one is the use of Application, I'm not sure what the non-Embarcadero equivalent is, but each running instance of code has an Application instance that manages the message loop and so on. I set my dll's Application->Handle to the calling apps hWnd to keep it off the taskbar, among other things. This code works on xp, vista 32 and win7 64.
void HideDLL() {
if (Application->Handle == 0) {
SearchObject *so = new SearchObject();
so->Caption = L"MyCallingApp";
so->Handle = 0;
EnumWindows((WNDENUMPROC)EnumWindowsProc, (long)so);
Application->Handle = so->Handle;
delete so;
}
}
BOOL CALLBACK EnumWindowsProc(HWND hWnd, LPARAM lparam) {
bool result;
SearchObject *so = (SearchObject*)lparam;
wchar_t *caption = new wchar_t[STR_DEFAULT];
GetWindowTextW(hWnd, caption, STR_DEFAULT);
// String is an Embarcadero type representing UnicodeString
String Caption = caption;
// Pos is a wrapper around strstr I think
// the actual caption in my case is decorated with some other stuff
// I only know that it will start with the name of the app
if (Caption.Pos(so->Caption) > 0) {
so->Handle = hWnd;
result = false;
} else {
result = true;
}
delete caption;
return result;
}
Hope this helps.
It seems that (WPARAM)sizeof(CHAR)/sizeof(MAX_PATH) would return you zero, because sizeof(char) will be defenetly smaller then the max path, so you say to WinAPI that your variable has zero length, that's why it returns empty string to you.
Specify there MAX_PATH value instead.

vc++ dll call by vc++ application by ordinal no

How to call vc++ dll in vc++.
in .h file
typedef int (*LPVAR)(char * ptr_f, char *CC);
HINSTANCE hDLL;
in .cpp file
hDLL = NULL;
LPVAR var;
hDLL = LoadLibrary("Pro.dll");
if( hDLL == NULL )
AfxMessageBox("Could not load the DLL");
else
{
var = (LPVAR)GetProcAddress(hDLL, "#2"); //2 is ordinal no
char *ch,*a;
ch = (char*)malloc(100*sizeof(char));
a = (char*)malloc(10*sizeof(char));
int c = var(ch,a);
}
Check that var is not NULL after calling GetProcAddress.
You may have more success using MAKEINTRESOURCE, like this:
var = (LPVAR)GetProcAddress(hDLL, MAKEINTRESOURCE(2));
Remember to call free for the pointers returned by malloc, and call FreeLibrary when you have finished with hDLL.

Get path of current module after using RemoteThread

I need to get the current path of the module where my code executed (dll). I've made a dll injection from .NET into a native process and used RemoteThread.
I have tried getcwd, GetCurrentDirectory, GetModuleHandle.
Also tried this solution. But it doesn't work either. I get an empty string with the length of MAX_PATH.
https://stackoverflow.com/questions/6719140/get-path-of-current-module-after-using-remotethread/6719210#6719210
I already opened a thread but I can not login to my email to get the id.
Sorry but anyway thanks for your answer. I will rate this time!
C# Injection
public static IntPtr InjectLibrary(
Process targetProcess,
string libraryPath)
{
var libaryPathBytes = Encoding.GetBytes();
var hProc = NativeMethods.OpenProcess()
var hMemory = NativeMethods.VirtualAllocEx()
NativeMethods.WriteProcessMemory()
var hLoadLib = NativeMethods.GetProcAddress()
var hThread = NativeMethods.CreateRemoteThread()
return hThread;
}
Native Library
BOOL APIENTRY DllMain( HMODULE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved
)
{
switch (ul_reason_for_call)
{
case DLL_PROCESS_ATTACH:
{
DWORD threadId;
CreateThread( NULL, 0, Bootstrap, NULL, 0, &threadId);
break;
}
case DLL_THREAD_ATTACH:
case DLL_THREAD_DETACH:
case DLL_PROCESS_DETACH:
break;
}
return TRUE;
}
DWORD WINAPI Bootstrap(LPVOID arg) {
DWORD currentProcessID = GetCurrentProcessId();
HANDLE snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, currentProcessID);
MODULEENTRY32 entry;
Module32First(snapshot, &entry);
MessageBox(NULL, entry.szLibPath, L"", MB_OK);//entry.szLibPath is empty string with the length if MAX_PATH like □□□□□□□□□□□□□□□□□□□□□□□....
HMODULE module = entry.hModule;
wchar_t currentPath[MAX_PATH];
GetModuleFileName(module, currentPath, MAX_PATH);
MessageBox(NULL, currentPath, L"", MB_OK);//currentPath isempty string with the length if MAX_PATH like □□□□□□□□□□□□□□□□□□□□□□□....
//all other options give me the same string or the executable path
return 0;
}
There's a "hidden" tool helper library mentionned by Raymond Chen that gets around several quirks in the Win32 APi. It seems you can use that to fetch the handle to the first module associated to a process (presumably the original executable). You can use that handle to get the path to the executable.
Looks something like:
// Get a listing of modules loaded in the process.
DWORD process = ...;
HANDLE snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, process);
// Get the handle to the first module loaded by that process.
MODULEENTRY32 entry;
Module32First(snapshot, &entry);
HANDLE module = entry.hModule;
// Get the path to the executable/DLL file containing the module.
GetModuleFileName(module, ...);
Edit: I've tried a complete example. You get an empty string using GetModuleFileName() because the module handle was not loaded using the LoadLibrary() function call.
However, it seems the MODULEENTRY32 structure already provides the full path to the module in its szExePath member. The following example works for me:
#include <Windows.h>
#include <TlHelp32.h>
#include <iostream>
int main ( int, char ** )
{
// Substitute `process` with appropriate process ID.
const ::DWORD process = ::GetCurrentProcessId();
const ::HANDLE snapshot =
::CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, process);
if ( snapshot == INVALID_HANDLE_VALUE ) {
std::cerr << "Couldn't get snapshot!" << std::endl;
return (EXIT_FAILURE);
}
// Get 1st module info.
::MODULEENTRY32W module;
::ZeroMemory(&module, sizeof(module));
module.dwSize = sizeof(module);
const ::BOOL result = Module32FirstW(snapshot, &module);
if ( result == FALSE )
{
// Handle errors.
const ::DWORD error = ::GetLastError();
std::cerr
<< "Couldn't get 1st module (" << error << ")."
<< std::endl;
return (EXIT_FAILURE);
}
std::wcout
<< module.szExePath << std::endl;
// Cleanup.
::CloseHandle(snapshot);
return (EXIT_SUCCESS);
}

Retrieving DLL name, not calling application name

I've written two COM classes in C++, contained in a single MFC DLL. They're being loaded as plugins by a 3rd party application.
How can I get the file name, and version number, of the DLL from within those classes?
The main dll entry gives you the handle of your dll.
extern "C" int APIENTRY
DllMain(HINSTANCE hInstance, DWORD dwReason, LPVOID lpReserved)
and
GetModuleFileName(hInstance, buffer, MAX_PATH);
can be used to get the filename of the dll.
GetFileVersionInfoSize
GetFileVersionInfo
will be used to get the file version.
TCHAR fileName[MAX_PATH + 1];
GetModuleFileName(hInstance, fileName, MAX_PATH);
Where hInstance is the one you get in the DllMain function. Don't use GetModuleHandle(0), because that returns the HINSTANCE of the host application.
CString GetCallingFilename(bool includePath)
{
CString filename;
GetModuleFileName(AfxGetInstanceHandle(), filename.GetBuffer(MAX_PATH), MAX_PATH);
filename.ReleaseBuffer();
if( !includePath )
{
int filenameStart = filename.ReverseFind('\\') + 1;
if( filenameStart > 0 )
{
filename = filename.Mid(filenameStart);
}
}
return filename;
}
CString GetCallingVersionNumber(const CString& filename)
{
DWORD fileHandle, fileVersionInfoSize;
UINT bufferLength;
LPTSTR lpData;
VS_FIXEDFILEINFO *pFileInfo;
fileVersionInfoSize = GetFileVersionInfoSize(filename, &fileHandle);
if( !fileVersionInfoSize )
{
return "";
}
lpData = new TCHAR[fileVersionInfoSize];
if( !lpData )
{
return "";
}
if( !GetFileVersionInfo(filename, fileHandle, fileVersionInfoSize, lpData) )
{
delete [] lpData;
return "";
}
if( VerQueryValue(lpData, "\\", (LPVOID*)&pFileInfo, (PUINT)&bufferLength) )
{
WORD majorVersion = HIWORD(pFileInfo->dwFileVersionMS);
WORD minorVersion = LOWORD(pFileInfo->dwFileVersionMS);
WORD buildNumber = HIWORD(pFileInfo->dwFileVersionLS);
WORD revisionNumber = LOWORD(pFileInfo->dwFileVersionLS);
CString fileVersion;
fileVersion.Format("%d.%d.%d.%d", majorVersion, minorVersion, buildNumber, revisionNumber);
delete [] lpData;
return fileVersion;
}
delete [] lpData;
return "";
}