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.
Related
In a micro-controller programmed using C/C++ all the addresses are known before the program starts. I can use an elf file that is generated when compiling to find those with gdb, for example:
gdb "elfFile.elf" -ex "print &variableName" -ex quit
This is useful to get variables in real-time by asking the micro-controller for a variable address from an external tool that can be used to log and plot data. The tool gets the variable address from the elf file and then just asks the micro-controller to read the data at address &variableName for n bytes.
I have ported some of the micro-controller code to Windows for testing purposes and it is running correctly. I would like to add the log functionality and for this purpose I need to be able to get a variable address programmatically from a running exe file. The address of variables is not known until the program starts in Windows (perhaps the offset is known though). I am using Visual Studio Express 2017 and I intend to get addresses of the program I compile myself, not any program from outside. From inside Visual Studio I can see any variable with the debugger so I hope there's gotta be a debugger exe file I can call from outside and attach to my program and read the variable addresses in a similar fashion as I did with gdb.
Any help? Thank you
You could inject a dll with CreateRemoteProcess, and read the variable address there.
But you're looking for a program called OllyDbg.
Also, you could download and install MinGW & msys, then you can build GDB for Windows from source. But then you have to use MinGW on Windows to compile the program. (Mingw creates native Win32/Win64 programs - no need for Cygwin)
I don't have the C-Sources anymore for CreateRemoteThread, but I can give you the C# source:
// Inject(DLL_NAME, "Engine");
void Inject(string strDLLtoInject, string strEngine)
{
CheckIfDebugger();
//String pszLibFileRemote = Application.StartupPath + "\\"+ strDLLtoInject;
//String pszLibFileRemote = Application.StartupPath + "\\"+ strDLLtoInject;
//String strPathOfSharedObjectToInject = System.IO.Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location) + System.IO.Path.DirectorySeparatorChar + strDLLtoInject;
String strPathOfSharedObjectToInject = m_strTempPath + strDLLtoInject;
//System.Windows.Forms.MessageBox.Show(strPathOfSharedObjectToInject);
System.Diagnostics.Process[] TargetProcess = System.Diagnostics.Process.GetProcessesByName(strEngine);
if (TargetProcess.Length > 0)
{
System.IntPtr pTargetProcess = WinAPI.OpenProcess(WinAPI.CREATE_THREAD_ACCESS, false, TargetProcess[0].Id);
if (pTargetProcess != System.IntPtr.Zero)
{
CheckIfDebugger();
int iLoadLibraryAaddress = WinAPI.GetProcAddress(WinAPI.GetModuleHandleA("Kernel32.dll"), "LoadLibraryA");
if (iLoadLibraryAaddress != 0)
{
int iSharedObjectNameBufferSize = 1 + strPathOfSharedObjectToInject.Length;
int iSharedObjectNameAddress = WinAPI.VirtualAllocEx(pTargetProcess, 0, iSharedObjectNameBufferSize, 4096, 4);
if (iSharedObjectNameAddress != 0)
{
CheckIfDebugger();
int iReturnValue = WinAPI.WriteProcessMemory(pTargetProcess, iSharedObjectNameAddress, strPathOfSharedObjectToInject, iSharedObjectNameBufferSize, 0);
if (iReturnValue != 0)
WinAPI.CreateRemoteThread(pTargetProcess, 0, 0, iLoadLibraryAaddress, iSharedObjectNameAddress, 0, 0);
else
MsgBox("WriteProcessMemory failed.", "Error");
CheckIfDebugger();
} // End if (iSharedObjectNameAddress != null)
else
MsgBox("VirtualAllocEx failed.", "Error");
}// End if (iLoadLibraryAaddress != null)
else
MsgBox("GetProcAddress or GetModuleHandleA failed.", "Error");
CheckIfDebugger();
WinAPI.CloseHandle(pTargetProcess);
} // End if (pTargetProcess != System.IntPtr.Zero)
else
MsgBox("OpenProcess failed.", "Error");
CheckIfDebugger();
} // End if (TargetProcess.Length > 0)
else
MsgBox("GetProcessesByName failed.", "Error");
CheckIfDebugger();
} // End Sub Inject
Here's the WinAPI calls:
class WinAPI
{
public const int CREATE_THREAD_ACCESS = 0x1F0FFF;
[System.Runtime.InteropServices.DllImport("kernel32.dll")]
public static extern IntPtr OpenProcess(int dwDesiredAccess, bool bInheritHandle, int dwProcessId);
[System.Runtime.InteropServices.DllImport("Kernel32", EntryPoint = "GetModuleHandleA", ExactSpelling = true, CharSet = System.Runtime.InteropServices.CharSet.Ansi, SetLastError = true)]
public static extern int GetModuleHandleA(string lpModuleName);
[System.Runtime.InteropServices.DllImport("kernel32", ExactSpelling = true, CharSet = System.Runtime.InteropServices.CharSet.Ansi, SetLastError = true)]
public static extern int GetProcAddress(int hModule, string lpProcName);
[System.Runtime.InteropServices.DllImport("kernel32", ExactSpelling = true, CharSet = System.Runtime.InteropServices.CharSet.Ansi, SetLastError = true)]
public static extern int VirtualAllocEx(System.IntPtr hProcess, int lpAddress, int dwSize, int flAllocationType, int flProtect);
[System.Runtime.InteropServices.DllImport("kernel32", ExactSpelling = true, CharSet = System.Runtime.InteropServices.CharSet.Ansi, SetLastError = true)]
public static extern int WriteProcessMemory(System.IntPtr hProcess, int lpBaseAddress, string lpBuffer, int nSize, int lpNumberOfBytesWritten);
[System.Runtime.InteropServices.DllImport("kernel32", ExactSpelling = true, CharSet = System.Runtime.InteropServices.CharSet.Ansi, SetLastError = true)]
public static extern int CreateRemoteThread(System.IntPtr hProcess, int lpThreadAttributes, int dwStackSize, int lpStartAddress, int lpParameter, int dwCreationFlags, int lpThreadId);
[System.Runtime.InteropServices.DllImport("kernel32", EntryPoint = "CloseHandle")]
public static extern int CloseHandle(System.IntPtr hObject);
// http://www.pinvoke.net/default.aspx/kernel32/GetVersion.html
[System.Runtime.InteropServices.DllImport("kernel32.dll")]
public static extern uint GetVersion();
[System.Runtime.InteropServices.DllImport("kernel32.dll", CharSet = System.Runtime.InteropServices.CharSet.Auto, ExactSpelling = true)]
internal static extern bool IsDebuggerPresent();
} // End class WinAPI
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)
I have this little code in C++ Visual Studio 2012 for calling static function from dll file build with cygwin, and this code below totally works. the problem is, sometimes it crashes on the function call, or outputs result values as usually to the console, but debugger in Visual Studio is not moving forward. Odd behaviour. I guess maybe I'm not cleaning up correctly after I exit the application? First time I load VS, it works, but after some debug and crashes, this starts happening.
PFN_HELLO fnHello;
HMODULE hLib, h = LoadLibrary(TEXT("cygwin1.dll"));
PFN_CYGWIN_DLL_INIT init = (PFN_CYGWIN_DLL_INIT) GetProcAddress(h,"cygwin_dll_init");
init();
hLib = LoadLibrary (TEXT("cyghello.dll"));
if (NULL == hLib)
{
DWORD _err = GetLastError();
//return 1;
}
//typedef LRESULT (WINAPI *PFN)(HWND, UINT, WPARAM, LPARAM);
// PFN MySendMessageW;
//MySendMessageW = (PFN) GetProcAddress(hLib,"runMainRoutine");
fnHello = (PFN_HELLO) GetProcAddress (hLib, "runMainRoutine#4");
if (NULL == fnHello)
{
DWORD _err = GetLastError();
//return 1;
}
char* _bablabla = fnHello(_input);
FreeLibrary(h);
FreeLibrary(hLib);
return _bablabla;
For anyone who ever returns char* from DLL static function, you have to allocate char[] not in dll, but in your application (caller).
I want to hook functions that are called from a loaded DLL on Run time, i used the class CAPIHook from the book "Windows Via C/C++" (the DLL Injecting done by Install System Wide hook and The hooking by Modify IAT) but this code work only if the DLL name/symbols exist in the IAT in the executable file. (i.e. for Implicit DLL Linking)
this is DLL code:
CAPIHook::CAPIHook(PSTR pszCalleeModName, PSTR pszFuncName, PROC pfnHook) {
// Note: the function can be hooked only if the exporting module
// is already loaded. A solution could be to store the function
// name as a member; then, in the hooked LoadLibrary* handlers, parse
// the list of CAPIHook instances, check if pszCalleeModName
// is the name of the loaded module to hook its export table and
// re-hook the import tables of all loaded modules.
m_pNext = sm_pHead; // The next node was at the head
sm_pHead = this; // This node is now at the head
// Save information about this hooked function
m_pszCalleeModName = pszCalleeModName;
m_pszFuncName = pszFuncName;
m_pfnHook = pfnHook;
m_pfnOrig = GetProcAddressRaw(GetModuleHandleA(pszCalleeModName), m_pszFuncName);
// If function does not exit,... bye bye
// This happens when the module is not already loaded
if (m_pfnOrig == NULL)
{
wchar_t szPathname[MAX_PATH];
GetModuleFileNameW(NULL, szPathname, _countof(szPathname));
wchar_t sz[1024];
StringCchPrintfW(sz, _countof(sz),
TEXT("[%4u - %s] impossible to find %S\r\n"),
GetCurrentProcessId(), szPathname, pszFuncName);
OutputDebugString(sz);
return;
}
// Hook this function in all currently loaded modules
ReplaceIATEntryInAllMods(m_pszCalleeModName, m_pfnOrig, m_pfnHook);
}
this is the hook functions:
HMODULE WINAPI CAPIHook::LoadLibraryA(PCSTR pszModulePath) {
HMODULE hmod = ::LoadLibraryA(pszModulePath);
FixupNewlyLoadedModule(hmod, 0);
return(hmod);
}
HMODULE WINAPI CAPIHook::LoadLibraryW(PCWSTR pszModulePath) {
HMODULE hmod = ::LoadLibraryW(pszModulePath);
FixupNewlyLoadedModule(hmod, 0);
return(hmod);
}
HMODULE WINAPI CAPIHook::LoadLibraryExA(PCSTR pszModulePath,
HANDLE hFile, DWORD dwFlags) {
HMODULE hmod = ::LoadLibraryExA(pszModulePath, hFile, dwFlags);
FixupNewlyLoadedModule(hmod, dwFlags);
return(hmod);
}
HMODULE WINAPI CAPIHook::LoadLibraryExW(PCWSTR pszModulePath,
HANDLE hFile, DWORD dwFlags) {
HMODULE hmod = ::LoadLibraryExW(pszModulePath, hFile, dwFlags);
FixupNewlyLoadedModule(hmod, dwFlags);
return(hmod);
}
the method for replacing IAT:
void CAPIHook::ReplaceIATEntryInOneMod(PCSTR pszCalleeModName,
PROC pfnCurrent, PROC pfnNew, HMODULE hmodCaller) {
// Get the address of the module's import section
ULONG ulSize;
// An exception was triggered by Explorer (when browsing the content of
// a folder) into imagehlp.dll. It looks like one module was unloaded...
// Maybe some threading problem: the list of modules from Toolhelp might
// not be accurate if FreeLibrary is called during the enumeration.
PIMAGE_IMPORT_DESCRIPTOR pImportDesc = NULL;
__try {
pImportDesc = (PIMAGE_IMPORT_DESCRIPTOR) ImageDirectoryEntryToData(
hmodCaller, TRUE, IMAGE_DIRECTORY_ENTRY_IMPORT, &ulSize);
}
__except (InvalidReadExceptionFilter(GetExceptionInformation())) {
// Nothing to do in here, thread continues to run normally
// with NULL for pImportDesc
}
if (pImportDesc == NULL)
return; // This module has no import section or is no longer loaded
// Find the import descriptor containing references to callee's functions
for (; pImportDesc->Name; pImportDesc++) {
PSTR pszModName = (PSTR) ((PBYTE) hmodCaller + pImportDesc->Name);
if (lstrcmpiA(pszModName, pszCalleeModName) == 0) {
// Get caller's import address table (IAT) for the callee's functions
PIMAGE_THUNK_DATA pThunk = (PIMAGE_THUNK_DATA)
((PBYTE) hmodCaller + pImportDesc->FirstThunk);
// Replace current function address with new function address
for (; pThunk->u1.Function; pThunk++) {
// Get the address of the function address
PROC* ppfn = (PROC*) &pThunk->u1.Function;
// Is this the function we're looking for?
BOOL bFound = (*ppfn == pfnCurrent);
if (bFound) {
if (!WriteProcessMemory(GetCurrentProcess(), ppfn, &pfnNew,
sizeof(pfnNew), NULL) && (ERROR_NOACCESS == GetLastError())) {
DWORD dwOldProtect;
if (VirtualProtect(ppfn, sizeof(pfnNew), PAGE_WRITECOPY,
&dwOldProtect)) {
WriteProcessMemory(GetCurrentProcess(), ppfn, &pfnNew,
sizeof(pfnNew), NULL);
VirtualProtect(ppfn, sizeof(pfnNew), dwOldProtect,
&dwOldProtect);
}
}
return; // We did it, get out
}
}
} // Each import section is parsed until the right entry is found and patched
}
}
the author added comments to add this functionality, but I am not sure how to do it
Note: the function can be hooked only if the exporting module
is already loaded. A solution could be to store the function
name as a member; then, in the hooked LoadLibrary* handlers, parse
the list of CAPIHook instances, check if pszCalleeModName
is the name of the loaded module to hook its export table and
re-hook the import tables of all loaded modules.
he also write this on the book, but again i don't know what to do
A possible solution is to use the hooked LoadLibrary* functions to
detect when a module is exporting an unpatched hooked function and
then execute two actions:
Hook again the import table of the module already loaded because it is
now possible to call GetProcAddress and get a pointer to the original
implementation of the function to hook. Notice that the name of the
function needs to be stored as a class member and set in the
constructor.
Directly update this hooked function in the Export Address Table of
the exporting module as shown by the implementation of the
ReplaceEATEntryInOneMod function. That way, all new modules calling
the hooked function will call our handler
i try to modify the IAT after loading the DLL, but my hooking function is not called
HMODULE WINAPI CAPIHook::LoadLibraryW(PCWSTR pszModulePath) {
HMODULE hmod = ::LoadLibraryW(pszModulePath);
if (StrCmpIW(pszModulePath, myDLLUnicodeName.c_str()) == 0 ) {
PROC proc = GetProcAddressRaw(GetModuleHandleA(myDLLName.c_str()), myFunctionName.c_str());
if ( proc != NULL ) {
for (CAPIHook* p = sm_pHead; p != NULL; p = p->m_pNext) {
if (StrCmpIA(p->m_pszCalleeModName, myDLLName.c_str()) == 0) {
MessageBox(NULL, L"This is the New Dynamic DLL", L"Test!", 0);
ReplaceIATEntryInAllMods(p->m_pszCalleeModName, proc , p->m_pfnHook);
}
}
}
}
FixupNewlyLoadedModule(hmod, 0);
return(hmod);
}
so, how to modify this code to handle dynamic loading case ?
I've done this before.
What you want is EAT hooking instead of IAT. Also, hook the ::LoadLibrary API itself so you know when the DLL is loaded, and hook the requested api from the DLL after it is loaded.
There are some examples on the Internet on how to do this. Here is one I found just now:
http://board.cheat-project.com/showthread.php?t=10633
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 "";
}