When I try and get a proc address for a function called print, it is able to load the ManualLinking.dll but not the function. The error code that windows gives is 127. The client app is almost a direct copy paste from windows.
DLL:
#include"pch.h"
#include<string>
#include<iostream>
__declspec(dllexport) void __stdcall print(std::string data) {
std::cout << data << std::endl;
}
CPP:
#include <windows.h>
#include<iostream>
#include"Header.h"
#include<string>
typedef void(__stdcall* MYPROC)(std::string data);
int main(void)
{
HINSTANCE hinstLib;
MYPROC ProcAdd;
BOOL fFreeResult, fRunTimeLinkSuccess = FALSE;
// Get a handle to the DLL module.
hinstLib = LoadLibrary(TEXT("ManualLinking.dll"));
// If the handle is valid, try to get the function address.
if (hinstLib != NULL)
{
ProcAdd = (MYPROC)GetProcAddress(hinstLib, "print");
// If the function address is valid, call the function.
if (NULL != ProcAdd)
{
fRunTimeLinkSuccess = TRUE;
(ProcAdd)("Message sent to the DLL function\n");
}
// Free the DLL module.
fFreeResult = FreeLibrary(hinstLib);
}
// If unable to call the DLL function, use an alternative.
if (!fRunTimeLinkSuccess) {
printf("Message printed from executable\n");
std::cout << GetLastError() << std::endl;
}
std::cin.get();
return 0;
}
You need to replace DLL code with:
#include"pch.h"
#include<string>
#include<iostream>
extern "C"{
__declspec(dllexport) void __stdcall print(std::string data) {
std::cout << data << std::endl;
}
}
If you still have same error, please, check if the executable can actually find the .dll
/*...*/
if (hinstLib != NULL)
{
ProcAdd = (MYPROC)GetProcAddress(hinstLib, "print");
// If the function address is valid, call the function.
if (NULL != ProcAdd)
{
fRunTimeLinkSuccess = TRUE;
(ProcAdd)("Message sent to the DLL function\n");
}
// Free the DLL module.
fFreeResult = FreeLibrary(hinstLib);
}
else
{
std::cout << "Cannot find dll" << std::endl;
}
/*...*/
Related
I want to modify bytecode of java method of target process. I tried to inject this shared library into java process using this injector and it works, but res is always -1 (unknown error) and I have no idea why.
libinject.so
#include <jni.h>
#include <iostream>
struct Initializer {
Initializer() {
jsize count;
JavaVM *vm;
JNIEnv *env;
if (JNI_GetCreatedJavaVMs(&vm, 1, &count) != JNI_OK || count == 0) {
std::cout << "No JavaVMS found!" << std::endl;
return;
}
jint res = vm->GetEnv((void **) &env, JNI_VERSION_1_8);
if (res == JNI_EDETACHED) {
res = vm->AttachCurrentThread((void **) &env, nullptr);
}
// res == -1 :(
}
};
Initializer initializer;
I can't figure out where's the problem. Also I was using the same exact code but with DllMain on Windows and it worked..
I want to list all the file type associations app names. My code:
#include <windows.h>
#include <shlwapi.h>
#include <ShlObj.h>
#include <iostream>
#pragma comment(lib, "shlwapi.lib")
int main()
{
IQueryAssociations *iQueryAssoc = nullptr;
HRESULT assocHRes = AssocCreate(CLSID_QueryAssociations, IID_IQueryAssociations, reinterpret_cast<void**>(&iQueryAssoc));
if (assocHRes == S_OK) {
HWND hWnd = GetConsoleWindow();
LPCWSTR pszAssoc = L".xls";
HRESULT initAssocHRes = iQueryAssoc->Init(NULL, pszAssoc, NULL, hWnd);
if (initAssocHRes == S_OK) {
TCHAR buffer[1024];
DWORD bufferSize = 1024;
HRESULT getStrAssocHRes = iQueryAssoc->GetString(ASSOCF_NONE, ASSOCSTR_FRIENDLYAPPNAME, NULL, buffer, &bufferSize);
if (getStrAssocHRes == S_OK) {
std::wcout << "App name: " << std::wstring(buffer).c_str() << std::endl;
} else {
std::wcout << "iQueryAssoc GetString failed!" << std::endl;
}
} else {
std::wcout << "iQueryAssoc Init failed!" << std::endl;
}
} else {
std::wcout << "AssocCreate failed!" << std::endl;
}
iQueryAssoc->Release();
system("PAUSE");
return 0;
}
My code works but it displays app name only for the ".xls" extension. I think, I need to use the while (iQueryAssoc->QueryInterface()) to get all of them. Is there any example how to use it? Should I call init method first and then QueryInterface method or just call QueryInterface method without init method?
Additionally, I have found the SHAssocEnumHandlers method:
IEnumAssocHandlers *pEnumHandlers = nullptr;
IAssocHandler *assocHandler = nullptr;
HRESULT initAssocHRes = SHAssocEnumHandlers(NULL, ASSOC_FILTER_NONE, &pEnumHandlers);
if (initAssocHRes == S_OK) {
while (pEnumHandlers->Next(1, &assocHandler, nullptr) == S_OK) {
std::cout << "Test..." << std::endl;
}
} else {
std::cout << "Failed: " << initAssocHRes << std::endl;
}
But for me, it fails with the following error: Failed: -2147024882 E_OUTOFMEMORY - Failed to allocate necessary memory. I think, the issue with: IEnumAssocHandlers are null and not initialized. What method should I use to initialize the IEnumAssocHandlers? Thank you.
I have found, these lines of code leads to E_OUTOFMEMORY issue:
IEnumAssocHandlers *pEnumHandlers = NULL;
HRESULT initAssocHRes = SHAssocEnumHandlers(NULL, ASSOC_FILTER_RECOMMENDED, &pEnumHandlers);
Also, I got this warning:
Any ideas? Thank you.
Updated code:
#include <windows.h>
#include <shlwapi.h>
#include <ShlObj.h>
#include <iostream>
#include "hresinfo.h"
#pragma comment(lib, "shlwapi.lib")
#pragma comment(lib, "shell32.lib")
int main()
{
IEnumAssocHandlers *pEnumHandlers = nullptr;
HRESULT initAssocHRes = SHAssocEnumHandlers(NULL, ASSOC_FILTER_NONE, reinterpret_cast<IEnumAssocHandlers**>(&pEnumHandlers));
if (initAssocHRes == S_OK) {
IAssocHandler *pAssocHandler = nullptr;
LPWSTR pszName = nullptr;
while (pEnumHandlers->Next(1, &pAssocHandler, NULL) == S_OK) {
if (pAssocHandler) {
pAssocHandler->GetUIName(&pszName);
printf_s("%S \n", pszName);
}
}
if (pAssocHandler) {
pAssocHandler->Release();
}
} else {
HRESInfo::getErrorMsg(initAssocHRes);
}
if (pEnumHandlers) {
pEnumHandlers->Release();
}
system("PAUSE");
return 0;
}
Screenshot:
You don't say which call is actually failing (so please do so), but if you look at the documentation for IEnumAssocHandlers::Next, it doesn't say anywhere that the third parameter (pceltFetched) can be nullptr, so I would change your code to:
if (initAssocHRes == S_OK) {
ULONG handlers_retrieved = 0;
while (pEnumHandlers->Next(1, &assocHandler, &handlers_retrieved) == S_OK) {
...
Also first parameter to SHAssocEnumHandlers must not be null:
wchar_t *extension = L".jpg";
HRESULT initAssocHRes = SHAssocEnumHandlers(extension, ...
I load a dll in my c++ code but when run it I get error :
dll:
`extern "C" __declspec(dllexport) int Add(int a,int b)
{
return a+b;
}`
my console file:
typedef int(__stdcall *f_funci) (int , int);
int main()
{
HINSTANCE hGetProcIDDLL = LoadLibrary("ConsoleApplication1.dll");
if (!hGetProcIDDLL) {
std::cout << "could not load the dynamic library" << std::endl;
system("pause");
return EXIT_FAILURE;
}
f_funci funci = 0;
funci = (f_funci)GetProcAddress(hGetProcIDDLL, "Add");
if (!funci) {
std::cout << "could not locate the function" << std::endl;
system("pause");
return EXIT_FAILURE;
}
int t = 0;
t= (*funci)(2, 3);
std::cout << "funci() returned "<<t<< std::endl;
system("pause");
return EXIT_SUCCESS;
}
this error:enter image description here
The __stdcall changes how a function is called.
Call for __stdcall on x86...
push b;
push a;
call fnAdd; # stack is restored by the callee. with ret 8
Call for __cdecl
push b;
push a;
call fnAdd;
add esp, 8 # restore stack.
This has to be matched in the function with the correct ret or ret 8.
In your case the __stdcall is causing the values a and b interfering with the registers which maintain the frame of the function.
In visual studio 2015 environment, I just made simple Win32 console application program project to study MFC. (Also, I check on adding common header file of MFC in project Wizard process)
And Here is main part of this project..
#include "stdafx.h"
#include "Practice02.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#endif
CWinApp theApp;
using namespace std;
int main()
{
int nRetCode = 0;
HMODULE hModule = ::GetModuleHandle(nullptr);
if (hModule != nullptr)
{
if (!AfxWinInit(hModule, nullptr, ::GetCommandLine(), 0))
{
wprintf(L"error: sample\n");
nRetCode = 1;
}
else
{
CString temp(L"Hello");
cout << temp << endl;
}
}
else
{
wprintf(L"Fatal Error: GetModuleHandle failure\n");
nRetCode = 1;
}
return nRetCode;
}
My intention is to make simple program which prints CString object containing "hello" value on cmd screen.
However, after start this project, I only see the address value of this object.
(EX. 0039841 or 003913E1 etc...)
Where should I modify this code to print real value of CString object?
Use following :
std::wcout << temp.GetString();
I do have a simple test-case here (C++) which does LoadLibrary, GetProcAddress & calls the function (ProcAdd).
The signature is "char* ProcAdd(char*)".
Now I do get the string correctly in the executable, but once I do "FreeLibrary", it's gone... (obviously because I just did a return "hello").
The thing is, that I have another dll (.NET, C#) where the signature is "[return: MarshalAs LPSTR]string ProcAdd([MarshalAs LPSTR] string)".
Now this function ALSO returns a string, but when I do "FreeLibrary", the string is still accessible within my executable?!
How does that come, and how could I mimic the same behaviour?
(and yes, I know I can store it in another variable, but I would like to understand what is happening and how I can reproduce this .NET behaviour).
Thanks a lot!
As requested the code:
C++ exe:
int main( void )
{
HINSTANCE hinstLib;
MYPROC ProcAdd;
BOOL fFreeResult, fRunTimeLinkSuccess = FALSE;
void * val = NULL;
// Get a handle to the DLL module.
// hinstLib = LoadLibrary(TEXT("C:\\Users\\steven\\temp\\myMyMy.orig.dll"));
hinstLib = LoadLibrary(TEXT("C:\\Users\\steven\\temp\\myMyMy.proxy.dll"));
// If the handle is valid, try to get the function address.
if (hinstLib != NULL)
{
ProcAdd = (MYPROC) GetProcAddress(hinstLib, "ProcAdd");
// If the function address is valid, call the function.
if (NULL != ProcAdd)
{
fRunTimeLinkSuccess = TRUE;
val = (ProcAdd) ("0987654321");
}
// Free the DLL module.
fFreeResult = FreeLibrary(hinstLib);
}
// If unable to call the DLL function, use an alternative.
if (! fRunTimeLinkSuccess)
printf("Message printed from executable\n");
return 0;
}
C++ dll:
#include <Windows.h>
#include <iostream>
#include <fstream>
static const char tmp[] = "hello";
extern "C" const char * __stdcall ProcAdd(const char * param1) {
FILE * fp = fopen("C:\\tmp\\ProcAdd.txt", "a");
if ( fp ) {
fprintf(fp, "param1: '%s'\r\n", param1);
fclose(fp);
}
// return strdup("hello");
// return "hello";
return tmp;
}
C# dll:
[return: MarshalAs(UnmanagedType.LPStr)]
public static string ProcAdd([MarshalAs(UnmanagedType.LPStr)] string param1)
{
string str;
try
{
str = new WebClient().DownloadString("http://www.salvania.be/test.php?param1=" + param1);
}
catch (Exception exception1)
{
str = "Error-DLL";
}
return str;
}
Working return:
// http://stackoverflow.com/questions/14406818/heapcreate-and-heapalloc-confuse
HANDLE winHandle = HeapCreate( 0, sizeof(tmp), sizeof(tmp) );
char* s = (char*)HeapAlloc( winHandle, 0, sizeof(tmp) + 1 );
strcpy((char*)s, tmp);
s[sizeof(tmp)] = 0;
If you just return "hello", that hello string may come from the data segment of the shared library, and may be unloaded after the life-time of the library.
To ensure the returned string live after the life-time of the library, you may store it on heap or otherwise provide a buffer from the caller.