I need any advice how to continue CreateFile() hooking after getting code as follows:
#include<windows.h>
#include "C:\Detours\Detours-4.0.1\include\detours.h"
static HANDLE(WINAPI* TrueCreateFileW)(LPCWSTR lpFileName, DWORD dwDesiredAccess, DWORD dwShareMode,
LPSECURITY_ATTRIBUTES lpSecurityAttributes, DWORD dwCreationDisposition, DWORD dwFlagsAndAttributes,
HANDLE hTemplateFile) = CreateFileW;
__declspec(dllexport) HANDLE WINAPI MyCreateFileW(LPCTSTR lpFileName, DWORD dwDesiredAccess, DWORD
dwShareMode,
LPSECURITY_ATTRIBUTES lpSecurityAttributes, DWORD dwCreationDisposition, DWORD dwFlagsAndAttributes,
HANDLE hTemplateFile)
{
if ((LPCTSTR)lpFileName == (LPCTSTR)L"C:\TestHook\file.txt")
{
return TrueCreateFileW((LPCTSTR)L"C:\TestHook\file.txt", dwDesiredAccess, dwShareMode, lpSecurityAttributes,
dwCreationDisposition, dwFlagsAndAttributes, hTemplateFile);
}
return TrueCreateFileW(lpFileName, dwDesiredAccess, dwShareMode, lpSecurityAttributes,
dwCreationDisposition, dwFlagsAndAttributes, hTemplateFile);
}
BOOL APIENTRY DLLMain(HMODULE hModule, DWORD reason_for_call, LPVOID lpReserved)
{
LONG error;
switch (reason_for_call)
{
case DLL_PROCESS_ATTACH:
OutputDebugString(L"Attaching HookingDLL.dll");
//OutputDebugString(strInfo);
DetourRestoreAfterWith();
DetourTransactionBegin();
DetourUpdateThread(GetCurrentThread());
DetourAttach(&(PVOID&)TrueCreateFileW, MyCreateFileW);
error = DetourTransactionCommit();
if (error == NO_ERROR)
{
OutputDebugString(L"Hooking attempt succeeded");
}
else
{
OutputDebugString(L"Hooking attempt failed");
}
break;
case DLL_THREAD_ATTACH:
break;
case DLL_THREAD_DETACH:
break;
case DLL_PROCESS_DETACH:
OutputDebugString(L"Detaching HookingDLL.dll");
DetourTransactionBegin();
DetourUpdateThread(GetCurrentThread());
DetourAttach(&(PVOID&)TrueCreateFileW, MyCreateFileW);
error = DetourTransactionCommit();
if (error == NO_ERROR)
{
OutputDebugString(L"Successfully detached hook");
}
else
{
OutputDebugString(L"Hook removal has failed");
}
break;
}
return TRUE;
}
What I need is a call of MyCreateFileW hooking when creating a new .txt file in Notepad++. Most likely, I have to add a DLL injector to aplly that hook, but in Internet I didn't find any comprehensible step-by-step guide for beginners (it's worth saying I'm a student). Could you suggest how to proceed with DLL injector in my case? Let me notice that I'm using Microsoft Detours to learn API hooking more smoothly and consistently.
You have already prepared the detour DLL. What you need do to is creating a new process and load DLLs into it with DetourCreateProcessWithDlls. Something like this:
DetourCreateProcessWithDll(NULL, "C:\\windows\\notepad.exe", NULL,
NULL, FALSE, CREATE_DEFAULT_ERROR_MODE, NULL, NULL,
&si, &pi, DetourPath, DLLPath, NULL);
You can refer to this tutorial "API Hooking with MS Detours" for more detailed information.
Related
I made a Windows Service process that can be started/stopped/paused/continued.
The service is created with CreateService() and the service starts a service controller with RegisterServiceCtrlHandlerExA().
Even though the service can subscribe to power setting notifications using RegisterPowerSettingNotification() I find that these only represent events like battery/mains for laptops, and such. Not for suspend/sleep of the OS.
How can I tell the SCM to automatically pause my service before the OS suspends/sleeps? And continue my service after it wakes up again?
This requires calling the PowerRegisterSuspendResumeNotification() function.
For this, you need to #include <powrprof.h> and link against powrprof.lib.
The callback itself looks like:
static ULONG DeviceNotifyCallbackRoutine
(
PVOID Context,
ULONG Type, // PBT_APMSUSPEND, PBT_APMRESUMESUSPEND, or PBT_APMRESUMEAUTOMATIC
PVOID Setting // Unused
)
{
LOGI("DeviceNotifyCallbackRoutine");
if (Type == PBT_APMSUSPEND)
{
turboledz_pause_all_devices();
LOGI("Devices paused.");
}
if (Type == PBT_APMRESUMEAUTOMATIC)
{
turboledz_paused = 0;
LOGI("Device unpaused.");
}
return 0;
}
static DEVICE_NOTIFY_SUBSCRIBE_PARAMETERS notifycb =
{
DeviceNotifyCallbackRoutine,
NULL,
};
And then register it with:
HPOWERNOTIFY registration;
const DWORD registered = PowerRegisterSuspendResumeNotification
(
DEVICE_NOTIFY_CALLBACK,
¬ifycb,
®istration
);
if (registered != ERROR_SUCCESS)
{
const DWORD err = GetLastError();
LOGI("PowerRegisterSuspendResumeNotification failed with error 0x%lx", err);
}
I use googletest as the main testing framework for a Qt project. QAbstractItemModelTester helps catching the most common errors in custom item model classes but I don't know how to integrate the reported failures(QTest) in a googletest unit test.
I didn't find any direct way to do this, but this is what I've done to have assertion for testing errors in QAbstractItemModelTester:
class AssertNoQtLogWarnings
{
static void messageHandlerTest(QtMsgType type, const QMessageLogContext& context, const QString& msg)
{
static bool NO_WARNING_MSG = true;
QByteArray localMsg = msg.toLocal8Bit();
const char* file = context.file ? context.file : "";
const char* function = context.function ? context.function : "";
switch (type) {
case QtDebugMsg:
fprintf(stderr, "Debug: %s (%s:%u, %s)\n", localMsg.constData(), file, context.line, function);
break;
case QtInfoMsg:
fprintf(stderr, "Info: %s (%s:%u, %s)\n", localMsg.constData(), file, context.line, function);
break;
case QtWarningMsg:
EXPECT_EQ(false, NO_WARNING_MSG) << msg.toStdString();
break;
case QtCriticalMsg:
EXPECT_EQ(false, NO_WARNING_MSG) << msg.toStdString();
break;
case QtFatalMsg:
EXPECT_EQ(false, NO_WARNING_MSG) << msg.toStdString();
break;
}
}
public:
AssertNoQtLogWarnings()
{
qInstallMessageHandler(messageHandlerTest);
}
~AssertNoQtLogWarnings()
{
//Install default message handler
qInstallMessageHandler(nullptr);
}
};
TEST(QAbstractItemModel, QAbstractItemModel)
{
//RAII object. Any warning, critical or fatal message produced in this context
//will produce a GTest fail assertion
AssertNoQtLogWarnings logQtTest;
MyAbstractItemModel model;
QAbstractItemModelTester tester(&model, QAbstractItemModelTester::FailureReportingMode::Warning);
}
I created a local server (EXE) COM project with support for ConnectionPoint events.
idl pseudo:
interface IAtlClass : IDispatch{
[id(1)] HRESULT f1();
};
library ComExeLib
{
dispinterface _IAtlClassEvents
{
methods:
[id(1)] HRESULT f2();
};
[
uuid(...
]
coclass AtlClass
{
[default] interface IAtlClass;
[default, source] dispinterface _IAtlClassEvents;
};
};
Server is built in 32 bit configuration. Client code, built in 64 bit:
HRESULT hr = CoInitialize(NULL);
IAtlClass* atlClass;
hr = CoCreateInstance(CLSID_AtlClass, NULL,
CLSCTX_LOCAL_SERVER,
IID_IAtlClass,
reinterpret_cast<void**>(&atlClass));
hr = atlClass->f1();
IConnectionPointContainer* pICPC = NULL;
hr = atlClass->QueryInterface(IID_IConnectionPointContainer, (VOID **)&pICPC);
IConnectionPoint* pICP = NULL;
hr = pICPC->FindConnectionPoint(DIID__IAtlClassEvents, &pICP);
hr = pICP->Advise((_IAtlClassEvents*)&sink, &cookie);
Sink class:
class Sink : public _IAtlClassEvents
{
public:
HRESULT STDMETHODCALLTYPE QueryInterface(
/* [in] */ REFIID riid,
/* [iid_is][out] */ void __RPC_FAR *__RPC_FAR *ppvObject)
{
if ((DIID__IAtlClassEvents == riid))
{
*ppvObject = static_cast<_IAtlClassEvents*>(this);
AddRef();
return(S_OK);
}
*ppvObject = NULL;
return(E_NOINTERFACE);
}
ULONG STDMETHODCALLTYPE AddRef(void)
{
return(InterlockedIncrement(&m_iRef));
}
ULONG STDMETHODCALLTYPE Release(void)
{
if (0 == InterlockedDecrement(&m_iRef))
{
delete this;
return(0);
}
return(m_iRef);
}
HRESULT STDMETHODCALLTYPE GetTypeInfoCount()
HRESULT STDMETHODCALLTYPE GetTypeInfo()
HRESULT STDMETHODCALLTYPE GetIDsOfNames()
HRESULT STDMETHODCALLTYPE Invoke()
};
Registered the server with ComExe.exe /RegServer and the proxy with regsvr32 ComExePS.dll, under folder C:\windows\SysWOW\ and under c:\Windows\System32.
Not sure if necessary but tried to compile the proxy stub under 64 bit as well but it will not build since auto-generated ComExe_p.c contains an #if !defined(AMD64).. so the project can only be built in 32 bit (seems related to this post only I use VS2013).
All client code commands except the last (Advise) succeed (They succeed even without registering the ComExePS.dll) . Advise invokes the sink QueryInterface method (and none but it), five time with following iid's:
{00000003-0000-0000-C000-000000000046}
{ECC8691B-C1DB-4DC0-855E-65F6C551AF49}
{00000003-0000-0000-C000-000000000046}
{0000001B-0000-0000-C000-000000000046}
{IID_IUnknown}
None of which are related to IAtlClass (some standard MS iid's - this guy was getting something similar).
Eventually Advise returns E_UNEXPECTED Catastrophic failure and the question is what am I doing wrong?
I have a large solution with 50+ unmanaged projects in it. I have recently added a project with managed code in it to the solution. The managed code accesses Windows.Devices.Sensors in a .NET dll. This dll is eventually wrapped by unmanaged code and called from another unmanaged project.
My problem is that I get the following access violation before main() even executes.
Unhandled exception at 0x744b8ea0 in myApplication.exe: 0xC0000005: Access violation.
Managed code:
#using <Windows.winmd>
using namespace Windows::Devices::Sensors;
#include <math.h>
namespace TabletSensors
{
namespace NET
{
public ref class DotNetDllClass
{
public:
DotNetDllClass()
{
Initialization();
}
~DotNetDllClass()
{
}
float* GetQuaternion()
{
OrientationSensorReading^ reading = _orientation->GetCurrentReading();
if( reading != nullptr )
{
float* quat = new float[4];
quat[0] = reading->Quaternion->X;
quat[1] = reading->Quaternion->Y;
quat[2] = reading->Quaternion->Z;
quat[3] = reading->Quaternion->W;
return quat;
}
else
{
return NULL;
}
}
private:
void Initialization()
{
_orientation = OrientationSensor::GetDefault();
if( _orientation != nullptr )
{
_orientation->ReportInterval = 16;
}
else
{
// not good ... throw exception or something
}
}
OrientationSensor^ _orientation;
};
}
}
Wrapper header file:
namespace TabletSensors
{
namespace NETWrapper
{
class DLLEXPORT_SENSORS WrapperClass
{
public:
__stdcall WrapperClass();
__stdcall ~WrapperClass();
float* __stdcall GetQuaternion();
};
}
}
Wrapper cpp file:
#define MIXSENSORS_BUILD
#include <gcroot.h>
#include "DotNetWrapper.h"
#include "DotNetDll.h"
using namespace TabletSensors::NETWrapper;
using namespace TabletSensors::NET;
static gcroot<TabletSensors::NET::DotNetDllClass^> Sensors = nullptr;
static System::UInt16 refCount = 0;
#pragma managed
inline TabletSensors::NET::DotNetDllClass^ GetSensors(void)
{
return (TabletSensors::NET::DotNetDllClass^)Sensors;
}
void Init()
{
++refCount;
if(GetSensors() == nullptr)
{
Sensors = gcnew TabletSensors::NET::DotNetDllClass();
}
}
void CleanUp()
{
if( refCount > 0 )
{
--refCount;
}
}
float* GetQuaternion_()
{
return Sensors->GetQuaternion();
}
#pragma unmanaged
TabletSensors::NETWrapper::WrapperClass::WrapperClass()
{
Init();
}
TabletSensors::NETWrapper::WrapperClass::~WrapperClass()
{
CleanUp();
}
float* TabletSensors::NETWrapper::WrapperClass::GetQuaternion()
{
float* x = new float[4];
return GetQuaternion_();
}
#pragma managed
Unmanaged project referencing my wrapper class:
#include "DotNetWrapper.h"
.
.
.
void UnmanagedProject::Update()
{
// if this line is present, I get an access violation without hitting any breakpoints.
TabletSensors::NETWrapper::WrapperClass _tabletSensors;
.
.
.
}
Since the managed code is trying to access Tablet Sensors I understand why it doesn't work on my Windows 7 desktop. What I don't understand it why it won't even allow me to debug my code at all. No breakpoints are hit before the Access Violation occurs.
What I would really like to figure out is how to use exception handling or #ifdefs to keep this crash from happening. But I have had very little luck.
Any ideas?
The fix is to Delay Load the managed DLL. The allows the application to run until that DLL is explicitly called. Thanks to Ben Voight for his answer here: https://stackoverflow.com/a/28467701/1454861
I'm developing a driver for monitoring process creation, I wrote a simple code to do it. I use the PsSetCreateProcessNotifyRoutineEx. But this doesn't work ! I exactly following Microsoft help on this link
#include <ntddk.h>
NTSTATUS DriverEntry(
IN PDRIVER_OBJECT DriverObject,
IN PUNICODE_STRING RegistryPath
);
VOID UnloadRoutine(
IN PDRIVER_OBJECT DriverObject
);
VOID CreateProcessNotifyEx(
__inout PEPROCESS Process,
__in HANDLE ProcessId,
__in_opt PPS_CREATE_NOTIFY_INFO CreateInfo
);
VOID CreateProcessNotifyEx(
__inout PEPROCESS Process,
__in HANDLE ProcessId,
__in_opt PPS_CREATE_NOTIFY_INFO CreateInfo
)
{
if (CreateInfo)
{
if(CreateInfo->FileOpenNameAvailable==TRUE)
{
DbgPrintEx(
DPFLTR_IHVDRIVER_ID,
DPFLTR_INFO_LEVEL,
"PID : 0x%X (%d) ImageName :%wZ CmdLine : %wZ \n",
ProcessId,ProcessId,
CreateInfo->ImageFileName,
CreateInfo->CommandLine
);
}
}
}
VOID UnloadRoutine(IN PDRIVER_OBJECT DriverObject)
{
PsSetCreateProcessNotifyRoutineEx((PCREATE_PROCESS_NOTIFY_ROUTINE_EX) CreateProcessNotifyEx, TRUE);
DbgPrintEx( DPFLTR_IHVDRIVER_ID, DPFLTR_INFO_LEVEL,"Unloaded\n");
}
NTSTATUS DriverEntry(IN PDRIVER_OBJECT DriverObject, IN PUNICODE_STRING RegistryPath)
{
NTSTATUS status = PsSetCreateProcessNotifyRoutineEx((PCREATE_PROCESS_NOTIFY_ROUTINE_EX)CreateProcessNotifyEx, FALSE);
if(!NT_SUCCESS(status))
{
DbgPrintEx( DPFLTR_IHVDRIVER_ID, DPFLTR_ERROR_LEVEL,"Faild to PsSetCreateProcessNotifyRoutineEx .status : 0x%X \n",status);
}
DriverObject->DriverUnload = UnloadRoutine;
DbgPrintEx( DPFLTR_IHVDRIVER_ID, DPFLTR_INFO_LEVEL,"Load\n");
return STATUS_SUCCESS;
}
This drive load and run correctly but when run a program(new process), Doesn't happen any thing and can't register PsSetCreateProcessNotifyRoutineEx and i got 0xC0000022 Error (Access Denied).
Any idea ?
Always i have to find my answer ;)
For passing this problem only need to add this value LINKER_FLAGS=/integritycheck to SOURCE file !
Before :
TARGETNAME=ProcView
TARGETPATH=.
TARGETTYPE=DRIVER
SOURCES=ProcView.c
Now :
TARGETNAME=ProcView
TARGETPATH=.
TARGETTYPE=DRIVER
LINKER_FLAGS=/integritycheck
SOURCES=ProcView.c