urldownloadtofile OR InternetOpenUrl not working from DLL - api

I am trying to use UrlDownloadToFile OR InternetOpenUrl to visit some link on the Internet from an DLL file. While it works on an .exe file, but it didn't work from a DLL file, and even no any error information. It just failed without any information.
Anyone could give me any help? Thanks in advance.
My code are as below:
extern "C" __declspec(dllexport) int __stdcall Hello()
{
HINTERNET hInt=NULL, hUrl=NULL;
hInt = InternetOpenA("Test Agent", INTERNET_OPEN_TYPE_DIRECT, NULL, NULL, 0);
hUrl = InternetOpenUrlA(hInt, "http://www.google.com.au", NULL, 0, INTERNET_FLAG_RELOAD | INTERNET_FLAG_PRAGMA_NOCACHE | INTERNET_FLAG_NO_CACHE_WRITE, 0);
if (hUrl)
{
InternetCloseHandle(hUrl);
}
InternetCloseHandle(hInt);
return 0;
}
BOOL APIENTRY DllMain( HMODULE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved
)
{
switch (ul_reason_for_call)
{
case DLL_PROCESS_ATTACH:
Hello();
case DLL_THREAD_ATTACH:
case DLL_THREAD_DETACH:
case DLL_PROCESS_DETACH:
break;
}
return TRUE;
}
It failed at:
hUrl = InternetOpenUrlA(hInt, "http://www.google.com.au", NULL, 0, INTERNET_FLAG_RELOAD | INTERNET_FLAG_PRAGMA_NOCACHE | INTERNET_FLAG_NO_CACHE_WRITE, 0);
Or:
typedef HRESULT (__stdcall * lpURLDownloadToFile) (LPUNKNOWN pCaller, LPCTSTR szURL, LPCTSTR szFileName, DWORD dwReserved, LPBINDSTATUSCALLBACK lpfnCB);
extern "C" __declspec(dllexport) int __stdcall Hello()
{
HMODULE hModule = LoadLibraryW(L"urlmon.dll");
lpURLDownloadToFile urlD = (lpURLDownloadToFile)GetProcAddress( hModule, "URLDownloadToFileW" );
HRESULT aa = urlD(NULL, L"http://www.google.com.au", L"C:\\Test\\a.html", 0, NULL);
return 0;
}
BOOL APIENTRY DllMain( HMODULE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved
)
{
switch (ul_reason_for_call)
{
case DLL_PROCESS_ATTACH:
Hello();
case DLL_THREAD_ATTACH:
case DLL_THREAD_DETACH:
case DLL_PROCESS_DETACH:
break;
}
return TRUE;
}
It failed at:
HRESULT aa = urlD(NULL, L"http://www.google.com.au", L"C:\\Test\\a.html", 0, NULL);
Update:
If I insert a line like "MessageBox" just above where it fails, the MessageBox will be displayed successfully.
If I insert a line like "MessageBox" just after where it fails, the MessageBox will not be displayed. And there is no any error code returned if I tried to display "hUrl" or "aa".

Don't do that in DllMain. See DllMain entry point
The entry-point function should perform only simple initialization or
termination tasks. It must not call the LoadLibrary or LoadLibraryEx
function (or a function that calls these functions), because this may
create dependency loops in the DLL load order. This can result in a
DLL being used before the system has executed its initialization code.
EDIT, as you want to inject the Dll and run code in it.
One way to make an injected Dll to start executing code, without relying on DllMain is as follow:
Use a message hook, limited to one thread.
Find a HWND belonging to the process you want to inject. For Internet Explorer, you may enumerate the Top Level Windows, using EnumWindows A main IE Windows has a class IEframe. Use EnumChildWindows to find a window of class Internet_Explorer Server. Use GetWindowThreadProcessId to get the associated TID (Thread Identifier).
Use SetWindowsHookEx to install a thread hook. You may choose a WH_CALLWNDPROC
or a WH_GETMESSAGE hook. Pass the TID obtained in 1. Your DLL is injected, and is processing messages.
Use PostMessage or SendMessage or PostThreadMessage, depending on the hook type you choose in 2, with a registered message. See RegisterWindowMessage
In your hook function, filter for the registered message (obtain it's value in your DllMain and store it in a global variable) and when this message is received, call your custom code.
Warning: this technique is well suited for short living code, you are in a hook function. That's maybe not the place for downloading from the Internet.
Another way is to create a thread in DllMain, using _beginthreadex
In the thread, you may have a classic RegisterClass / CreateWindow / GetMessage/ DispatchMessage sequence, and your EXE will be able to Send/Post messages to your Dll.
Warning: depending on how you injected the Dll, you must be very carreful about premature unloading of your Dll. If the thread still runs, there may be crashes. Being clean and stable with theses things is not easy. But, if you are just playing/experimenting, don't bother and just LoadLibrary (not in DllMain) you own library a second time, it will stay here forever.
You can mix the two techniques, that is: use a thread message hook to inject the Dll and start a thread in the hook function.

Related

C++/WinRT: CoreApplication::Run(IFrameworkViewSource const&) is throwing E_INVALIDARG

I'm trying to figure out why at this point in the code I'm getting an E_INVALIDARG hresult:
// main.cpp
class App : public implements<App, IFrameworkView>
{
// stuff ...
};
class AppFactory : public implements<AppFactory, IFrameworkViewSource>
{
public:
IFrameworkView CreateView()
{
return make<App>();
}
};
int WINAPI wWinMain(
_In_ HINSTANCE,
_In_ HINSTANCE,
_In_ LPWSTR,
_In_ int)
{
init_apartment();
auto vpf = make<AppFactory>();
CoreApplication::Run(vpf); // <-- throwing E_INVALIDARG somewhere inside CoreApplication::Run
uninit_apartment();
return S_OK;
}
I'd have expected a compile error if I didn't do something required by a class inheriting implements<AppFractory, IFrameworkViewSource>, but as far as I know I'm checking (static) boxes.
fwiw the exception is triggered here:
// Windows.ApplicationModel.Core.h
template <typename D> auto consume_Windows_ApplicationModel_Core_ICoreApplication<D>::Run(winrt::Windows::ApplicationModel::Core::IFrameworkViewSource const& viewSource) const
{
check_hresult(WINRT_IMPL_SHIM(winrt::Windows::ApplicationModel::Core::ICoreApplication)->Run(*(void**)(&viewSource)));
}
The thing inside check_result(...) is what's returning E_INVALIDARG, and subsequently triggering the exception. I'm not a super expert at writing windows applications, largely still in the "copy the template and hope it works while trying to understand something" phase. If there's some kind of tool I should be using to understand what the actual argument I'm passing is that is invalid, I'd appreciate some kind of pointer. I would think if I'm not passing the correct thing here, the strong type check of the argument would trigger a compile error and I'd have an opportunity to address the issue.
Honestly I'm lost here, would appreciate a hint towards where to look to resolve my issue. Thank you.
Update:
Don't know if this is relevant but in the Output tab in VS a line prints out:
Exception thrown at 0x00007FFA6D9A4FD9 (KernelBase.dll) in MyProgram.exe: WinRT originate error - 0x80070057 : 'serverName'.
I have no idea what this is... "serverName"? I don't even see a mention of this in the CoreApplication::Run docs.

DLL Code injection to third party process using QueueUserAPC

I want to inject my dll in to 64 bit application and I have tried the logic explained in the given link using QueueUserAPC. I am getting success message for every API but when I see in ProcessExplorer I am not able to see my dll in the process.
Below is my code :
bool FindProcess(PCWSTR exeName, DWORD& pid, vector<DWORD>& tids) {
auto hSnapshot = ::CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS | TH32CS_SNAPTHREAD, 0);
if (hSnapshot == INVALID_HANDLE_VALUE)
return false;
pid = 0;
PROCESSENTRY32 pe = { sizeof(pe) };
if (::Process32First(hSnapshot, &pe)) {
do {
if (_wcsicmp(pe.szExeFile, exeName) == 0) {
pid = pe.th32ProcessID;
THREADENTRY32 te = { sizeof(te) };
if (::Thread32First(hSnapshot, &te)) {
do {
if (te.th32OwnerProcessID == pid) {
tids.push_back(te.th32ThreadID);
}
} while (::Thread32Next(hSnapshot, &te));
}
break;
}
} while (::Process32Next(hSnapshot, &pe));
}
::CloseHandle(hSnapshot);
return pid > 0 && !tids.empty();}
void main(){
DWORD pid;
vector<DWORD> tids;
if (FindProcess(L"DataGrid.exe", pid, tids))
{
printf("OpenProcess\n");
HANDLE hProcess = ::OpenProcess(PROCESS_VM_WRITE | PROCESS_VM_OPERATION, FALSE, pid);
printf("VirtualAllocEx\n");
auto p = ::VirtualAllocEx(hProcess, nullptr, 1 << 12, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE);
wchar_t buffer[] = L"C:\\Users\\sbhuma\\Documents\\Visual Studio 2015\\Projects\\GalaxyHook\\Debug\\GalaxyHook.dll";
printf("WriteProcessMemory\n");
::WriteProcessMemory(hProcess, p, buffer, sizeof(buffer), nullptr);
for (const auto& tid : tids)
{
printf("OpenThread\n");
HANDLE hThread = ::OpenThread(THREAD_SET_CONTEXT, FALSE, tid);
if (hThread)
{
printf("GetProcAddress\n");
DWORD word = ::QueueUserAPC((PAPCFUNC)::GetProcAddress(GetModuleHandle(L"kernel32"), "LoadLibraryW"), hThread, (ULONG_PTR)p);
if (word)
{
printf("insdie if\n");
}
printf("End of IF\n");
}
}
printf("VirtualFreeEx\n");
::VirtualFreeEx(hProcess, p, 0, MEM_RELEASE | MEM_DECOMMIT);
}}
Any help related to inject the dll in to 64 bit application is helpful as I am new to this topic.
Regards,
Sowmya.
First of all, ensure you’re building your injector app as 64 bit.
One possible reason is you’re releasing the buffer too early. QueueUserAPC doesn’t wait; it enqueues the call and returns immediately. Can be your injector process ends running that for loop, calls VirtualFreeEx, then your target process receives the APC, tries to load your DLL but the name buffer is already released by then, so LoadLibrary fails. To verify, comment out the call to VirtualFreeEx. If your DLL will load OK, one way to fix the memory leak is use a named event, CreateEvent in injector app before any calls to QueueUserAPC(), OpenEvent, SetEvent and CloseHandle in DllMain(DLL_PROCESS_ATTACH) of the DLL you’re injecting, WaitForSingleObject in injector app before VirtualFreeEx, I recommend using a timeout for the wait, CloseHandle at the end. As a side effect, your injector app will be able to find out, and report somewhere, whether the injection was successful.
Another possible reason is your target app never enters alertable state. Not all apps use APC, there’re multiple alternative methods to implement asynchronous stuff in Windows. So, not all apps ever call these SleepEx / WaitForMultipleObjectsEx functions. Such app will never receive that APC. If that’s the case, you should use another method of DLL injection. DataGrid.exe name hints your target app is probably a GUI app. You can EnumWindows or FindWindow to find its top-level window, GetWindowThreadProcessId to get thread ID who owns that window, SetWindowsHookEx to inject your DLL into the target process.

What APIs are used to write output to command prompt?

Im using OllyDbg to reverse engineer an executable for my lab assignment. My professor has asked a question asking for the APIs responsible for writing output to the command prompt. The DLLS used were ntdll, kernel32, msvcr100
There are more than a couple of ways to achieve this but the famous two are WriteConsole and WriteFile.
From MSDN documentation:
WriteConsole
Writes a character string to a console screen buffer beginning at the
current cursor location.
BOOL WINAPI WriteConsole(
_In_ HANDLE hConsoleOutput,
_In_ const VOID *lpBuffer,
_In_ DWORD nNumberOfCharsToWrite,
_Out_ LPDWORD lpNumberOfCharsWritten,
_Reserved_ LPVOID lpReserved
);
WriteFile
Writes data to the specified file or input/output (I/O) device. This
function is designed for both synchronous and asynchronous operation.
BOOL WINAPI WriteFile(
_In_ HANDLE hFile,
_In_ LPCVOID lpBuffer,
_In_ DWORD nNumberOfBytesToWrite,
_Out_opt_ LPDWORD lpNumberOfBytesWritten,
_Inout_opt_ LPOVERLAPPED lpOverlapped
);
...
...
Characters can be written to the screen buffer using WriteFile with a
handle to console output. The exact behavior of the function is
determined by the console mode. The data is written to the current
cursor position. The cursor position is updated after the write
operation.

Bizarre hook behavior 32/64 bit

I'm using a local hook (WH_KEYBOARD) with ms word (OpusApp). Well, as far as I know a 32bit app with a 32bit DLL must work only with 32bit target applications. The weird thing is that the program only works with 64bits apps!!! That is it, only with 64bits APPS! For example, it works with IE 64 but not with IE 32!
The app and dll are 32bit compiled with radstudio XE2, I confirmed the version into PE header.
In 32bit OSs, the app and dll doesn´t work.
I found no solutions on net and see no starting point to solve this weird problem.
The DLL code:
// Exported functions
extern "C" __declspec(dllexport)bool __stdcall InstallMouseHook(unsigned long, void *);
extern "C" __declspec(dllexport)bool __stdcall RemoveMouseHook();
// Callback Procedure Declaration
LRESULT CALLBACK HookProc(int code, WPARAM wParam, LPARAM lParam);
// Global variables
HHOOK HookHandle;
HINSTANCE DllInstance;
typedef void (__stdcall *CALLIT)(int,WPARAM,LPARAM);
CALLIT callIt = NULL;
int WINAPI DllEntryPoint(HINSTANCE hinst, unsigned long reason, void*)
{
DllInstance=hinst;
return 1;
}
bool __stdcall InstallMouseHook(unsigned long pid, void *function)
{
callIt = ( CALLIT ) function;
if (function == NULL) {
ShowMessage("function is null!");
} else if (callIt == NULL) {
ShowMessage("callIt is null!");
}
HookHandle=SetWindowsHookEx(WH_KEYBOARD ,reinterpret_cast<HOOKPROC> (HookProc),DllInstance,pid);
if (HookHandle==NULL)return false;
else return true;
}
bool __stdcall RemoveMouseHook()
{
if(UnhookWindowsHookEx(HookHandle)==0)
{
return false;
}
else return true;
}
LRESULT CALLBACK HookProc(int code, WPARAM wParam, LPARAM lParam)
{
if (code<0) {
return CallNextHookEx(HookHandle,code,wParam,lParam);
}
if (callIt != NULL) {
callIt(code,wParam,lParam);
} else {
ShowMessage("HookProc - no function to execute OR 32/64 bits problem!");
}
//Call the next hook in the chain
return CallNextHookEx(HookHandle,code,wParam,lParam);
}
The EXE calling code:
void __fastcall TfrmMouseHook::btnHookAppDllClick(TObject *Sender)
{
HWND hWindow;
unsigned long pid;
String s = "MouseHookDLL.dll";
DllHandle=LoadLibrary(s.w_str());
MOUSEHOOKFCT_2 InstHook=reinterpret_cast<MOUSEHOOKFCT_2> (GetProcAddress(DllHandle,"InstallMouseHook"));
hWindow = FindWindow(ComboBox1->Text.w_str(),NULL);
if (!hWindow) {
msg("hWindow fail");
return;
}
pid = GetWindowThreadProcessId(hWindow ,0);
if (!pid) {
msg("pid fail");
return;
}
if(!InstHook(pid, (void *) callIt )) {
msg("Unable to install hook!");
} else {
msg(" #### hook INSTALLED! ####");
}
}
CALLIT callIt(code,wParam,lParam) {
frmMouseHook->msg("hook callit: code="+IntToStr(code) +" wparam="+IntToStr(wParam)+" lparam="+IntToStr(lParam) );
}
Call IT is a function pointer to a hooker app function.
Any ideas will be very wellcome!
It is physically impossible for a 32-bit app to install a 32-bit hook DLL and have it executed in 64-bit processes. A 32-bit DLL simply cannot be injected into a 64-bit process. Period. MSDN says this in multiple places, including in the SetWindowsHookEx() documentation:
SetWindowsHookEx can be used to inject a DLL into another process. A
32-bit DLL cannot be injected into a 64-bit process, and a 64-bit DLL
cannot be injected into a 32-bit process. If an application requires
the use of hooks in other processes, it is required that a 32-bit
application call SetWindowsHookEx to inject a 32-bit DLL into 32-bit
processes, and a 64-bit application call SetWindowsHookEx to inject a
64-bit DLL into 64-bit processes. The 32-bit and 64-bit DLLs must have
different names.
Because hooks run in the context of an application, they must match
the "bitness" of the application. If a 32-bit application installs a
global hook on 64-bit Windows, the 32-bit hook is injected into each
32-bit process (the usual security boundaries apply). In a 64-bit
process, the threads are still marked as "hooked." However, because a
32-bit application must run the hook code, the system executes the
hook in the hooking app's context; specifically, on the thread that
called SetWindowsHookEx. This means that the hooking application must
continue to pump messages or it might block the normal functioning of
the 64-bit processes.
If a 64-bit application installs a global hook on 64-bit Windows, the
64-bit hook is injected into each 64-bit process, while all 32-bit
processes use a callback to the hooking application.
The fact that you say your app and DLL do not work on 32-bit OS versions suggests your hooking code is flawed to begin with. But you have not shown enough code to diagnose that one way or the other.
What happens? Besides MSDN or anyone else says, there are some bug in XE6, compiling DLL in newer versions of IDE make this behavior disappears, in fact, the new DLL crash and hook nothing.
As Remy noted, by test I passed a function pointer to the DLL, one wrong thing to do but, when added with the wrong thing done by Embarcadero, sort of functioned.
By now, and I know people will get mad, I put both methods (the wrong and the correct hooks) in the same DLL and in my application and... get crazy... could hook into 32 and 64 bits app with only one DLL.
Don't believe? Install XE6 and try!
And Works in windows 10 as well in windows 7.

How to pass variables to function exported by a DLL, I get error LNK2001

I have to pass a HWND variable from the main program to a function exported by a DLL. Variable is called mainHwnd and DLL is defined in this way:
mydll.h
#ifdef MYDLL_EXPORTS
#define MYDLL_API extern "C" __declspec(dllexport)
#else
#define MYDLL_API extern "C" __declspec(dllimport)
#endif
MYDLL_API HWND mainHwnd;
MYDLL_API void testFunction(void);
MYDLL_API LRESULT CALLBACK mouseProc(int nCode, WPARAM wParam, LPARAM lParam);
mydll.cpp
#include "stdafx.h"
#include "mydll.h"
#include <string>
#define CLASSNAMELEN 5
MYDLL_API HWND mainHwnd = 0;
// This is an example of an exported function.
MYDLL_API void testFunction(void)
{
MessageBox(NULL, (LPCWSTR)L"Test", (LPCWSTR)L"Test", MB_OK);
}
MYDLL_API LRESULT CALLBACK mouseProc(int nCode, WPARAM wParam, LPARAM lParam)
{
// processes the message
if(nCode >= 0)
{
if(wParam != NULL && (wParam == WM_RBUTTONDOWN || wParam == WM_RBUTTONUP))
{
std::wstring s;
MessageBox(NULL, (LPCWSTR)L"Captured mouse right button", (LPCWSTR)L"Test", MB_OK);
MOUSEHOOKSTRUCT *m = (MOUSEHOOKSTRUCT*) lParam;
GetClassName(m->hwnd, (LPWSTR) s.c_str(), CLASSNAMELEN);
if(s == L"Edit")
SendMessage(mainHwnd, WM_APP, 0, (LPARAM) lParam);
}
}
// calls next hook in chain
return CallNextHookEx(NULL, nCode, wParam, lParam);
}
main program
MYDLL_API HWND mainHwnd;
...
case WM_CREATE:
{
// now it will load DLL and set up hook procedure for mouse events
// declares local variables
HOOKPROC hkprcMouseProc;
HINSTANCE hinstDLL;
HHOOK hhookMouseProc;
// loads DLL
if((hinstDLL = LoadLibrary(TEXT("C:\\Users\\Francesco\\Dropbox\\poli\\bi\\not\\pds\\sp\\wk5\\lsp5\\Debug\\mydll.dll"))) == NULL)
{
MessageBox(hWnd, (LPCWSTR)L"Error loading DLL", (LPCWSTR)L"Error", MB_OK | MB_ICONERROR);
break;
}
// saves main window handle for DLL functions
mainHwnd = hWnd;
...
Compiling I get
error LNK2001: unresolved external symbol __imp__mainHwnd
while using dumpbin /exports mydll.dll I get that global variable name is mangled as:
mainHwnd = _mainHwnd
I went through a lot of pages on google with no results. Maybe there is a conceptual error..
Thanks
When you're loading the DLL at run-time using LoadLibrary, you cannot access its symbols directly in your code. (This is because these symbols have to be fixed up when your code module is loaded, at which time LoadLibrary has not been called yet, so there is nothing to resolve them against. The linker can detect that this will be the case at compile time, so it friendlily refuses to create an .exe that would just fail immediately anyway).
For dynamically loaded DLLs, you need to use GetProcAddress to retrieve the address of the variable at run time. (Despite its name, it will work for either exported variables or exported functions, and you'd better be sure to treat the result as the right thing!)
But I suspect you don't really want to be loading the DLL at run time. Why don't you just link the main application with the generated import library?