Skip to content

Commit 6cc67ce

Browse files
committed
Merge pull request #21 from psieg/dx2
DX scanning
2 parents 7889671 + 350b93a commit 6cc67ce

File tree

1 file changed

+168
-105
lines changed

1 file changed

+168
-105
lines changed

Software/grab/D3D10Grabber.cpp

Lines changed: 168 additions & 105 deletions
Original file line numberDiff line numberDiff line change
@@ -55,46 +55,152 @@ using namespace std;
5555
using namespace WinUtils;
5656

5757
namespace {
58-
class D3D10GrabberWorker: public QObject {
59-
Q_OBJECT
58+
class D3D10GrabberWorker : public QObject {
59+
Q_OBJECT
60+
61+
public:
62+
D3D10GrabberWorker(QObject *parent, LPSECURITY_ATTRIBUTES lpsa);
63+
bool init();
64+
~D3D10GrabberWorker();
65+
private:
66+
HANDLE m_frameGrabbedEvent;
67+
signals:
68+
void frameGrabbed();
69+
public slots:
70+
void runLoop();
71+
72+
public:
73+
bool stop = false;
74+
private:
75+
LPSECURITY_ATTRIBUTES m_lpsa;
76+
};
77+
78+
const unsigned kBytesPerPixel = 4;
79+
80+
D3D10GrabberWorker::D3D10GrabberWorker(QObject *parent, LPSECURITY_ATTRIBUTES lpsa) :
81+
QObject(parent),
82+
m_lpsa(lpsa)
83+
{
84+
}
6085

61-
public:
62-
D3D10GrabberWorker(QObject *parent, LPSECURITY_ATTRIBUTES lpsa);
63-
~D3D10GrabberWorker();
64-
private:
65-
HANDLE m_frameGrabbedEvent;
66-
signals:
67-
void frameGrabbed();
68-
public slots:
69-
void runLoop();
86+
bool D3D10GrabberWorker::init() {
87+
if (NULL == (m_frameGrabbedEvent = CreateEventW(m_lpsa, false, false, HOOKSGRABBER_FRAMEGRABBED_EVENT_NAME))) {
88+
qCritical() << Q_FUNC_INFO << "unable to create frameGrabbedEvent";
89+
return false;
90+
}
7091

71-
public:
72-
bool stop = false;
73-
};
92+
return true;
93+
}
94+
95+
D3D10GrabberWorker::~D3D10GrabberWorker() {
96+
if (m_frameGrabbedEvent)
97+
CloseHandle(m_frameGrabbedEvent);
98+
}
7499

75-
const unsigned kBytesPerPixel = 4;
100+
void D3D10GrabberWorker::runLoop() {
101+
while (!stop) {
102+
if (WAIT_OBJECT_0 == WaitForSingleObject(m_frameGrabbedEvent, 50)) {
103+
emit frameGrabbed();
104+
if (!ResetEvent(m_frameGrabbedEvent)) {
105+
qCritical() << Q_FUNC_INFO << "couldn't reset frameGrabbedEvent";
106+
}
107+
}
108+
}
109+
}
110+
} // namespace
76111

77-
D3D10GrabberWorker::D3D10GrabberWorker(QObject *parent, LPSECURITY_ATTRIBUTES lpsa) : QObject(parent) {
78-
if (NULL == (m_frameGrabbedEvent = CreateEventW(lpsa, false, false, HOOKSGRABBER_FRAMEGRABBED_EVENT_NAME))) {
79-
qCritical() << Q_FUNC_INFO << "unable to create frameGrabbedEvent";
112+
namespace {
113+
class D3D10GrabberInjector : public QObject {
114+
Q_OBJECT
115+
116+
public:
117+
D3D10GrabberInjector(QObject *parent, bool injectD3D9);
118+
bool init();
119+
~D3D10GrabberInjector();
120+
public slots:
121+
void infectCleanDxProcesses();
122+
public:
123+
void sanitizeProcesses();
124+
private:
125+
QList<DWORD> m_lastSeenDxProcesses;
126+
ILibraryInjector * m_libraryInjector;
127+
WCHAR m_hooksLibPath[300];
128+
WCHAR m_unhookLibPath[300];
129+
WCHAR m_systemrootPath[300];
130+
bool m_injectD3D9;
131+
};
132+
133+
D3D10GrabberInjector::D3D10GrabberInjector(QObject *parent, bool injectD3D9) : QObject(parent),
134+
m_libraryInjector(NULL),
135+
m_injectD3D9(injectD3D9)
136+
{
80137
}
81-
}
82138

83-
D3D10GrabberWorker::~D3D10GrabberWorker() {
84-
if (m_frameGrabbedEvent)
85-
CloseHandle(m_frameGrabbedEvent);
86-
}
139+
bool D3D10GrabberInjector::init() {
140+
AcquirePrivileges();
141+
142+
GetModuleFileName(NULL, m_hooksLibPath, SIZEOF_ARRAY(m_hooksLibPath));
143+
PathRemoveFileSpec(m_hooksLibPath);
144+
wcscat(m_hooksLibPath, L"\\");
145+
wcscat(m_hooksLibPath, lightpackHooksDllName);
87146

88-
void D3D10GrabberWorker::runLoop() {
89-
while(!stop) {
90-
if (WAIT_OBJECT_0 == WaitForSingleObject(m_frameGrabbedEvent, 50)) {
91-
emit frameGrabbed();
92-
if (!ResetEvent(m_frameGrabbedEvent)) {
93-
qCritical() << Q_FUNC_INFO << "couldn't reset frameGrabbedEvent";
147+
GetModuleFileName(NULL, m_unhookLibPath, SIZEOF_ARRAY(m_hooksLibPath));
148+
PathRemoveFileSpec(m_unhookLibPath);
149+
wcscat(m_unhookLibPath, L"\\");
150+
wcscat(m_unhookLibPath, lightpackUnhookDllName);
151+
152+
GetWindowsDirectoryW(m_systemrootPath, SIZEOF_ARRAY(m_systemrootPath));
153+
154+
HRESULT hr = CoInitialize(0);
155+
// hr = InitComSecurity();
156+
// hr = CoCreateInstanceAsAdmin(NULL, CLSID_ILibraryInjector, IID_ILibraryInjector, reinterpret_cast<void **>(&m_libraryInjector));
157+
hr = CoCreateInstance(CLSID_ILibraryInjector, NULL, CLSCTX_INPROC_SERVER, IID_ILibraryInjector, reinterpret_cast<void **>(&m_libraryInjector));
158+
if (FAILED(hr)) {
159+
qCritical() << Q_FUNC_INFO << "Can't create libraryinjector. D3D10Grabber wasn't initialised. Please try to register server: regsvr32 libraryinjector.dll";
160+
CoUninitialize();
161+
return false;
162+
}
163+
164+
// Remove any injections from previous runs
165+
sanitizeProcesses();
166+
167+
return true;
168+
}
169+
170+
D3D10GrabberInjector::~D3D10GrabberInjector() {
171+
if (m_libraryInjector) {
172+
m_libraryInjector->Release();
173+
CoUninitialize();
174+
}
175+
}
176+
177+
void D3D10GrabberInjector::infectCleanDxProcesses() {
178+
QList<DWORD> processes = QList<DWORD>();
179+
if (m_injectD3D9)
180+
getDxProcessesIDs(&processes, m_systemrootPath);
181+
else
182+
getDxgiProcessesIDs(&processes, m_systemrootPath);
183+
foreach(DWORD procId, processes) {
184+
// Require the process to have run for at least one full timer tick,
185+
// hoping when injection happens their swapchain is already setup
186+
if (m_lastSeenDxProcesses.contains(procId)) {
187+
DEBUG_LOW_LEVEL << Q_FUNC_INFO << "Infecting DX process " << procId;
188+
m_libraryInjector->Inject(procId, m_hooksLibPath);
94189
}
95190
}
191+
m_lastSeenDxProcesses.clear();
192+
m_lastSeenDxProcesses.append(processes);
96193
}
97-
}
194+
195+
void D3D10GrabberInjector::sanitizeProcesses() {
196+
QList<DWORD> processes = QList<DWORD>();
197+
getHookedProcessesIDs(&processes, m_systemrootPath);
198+
foreach(DWORD procId, processes) {
199+
DEBUG_LOW_LEVEL << Q_FUNC_INFO << "Sanitizing process " << procId;
200+
m_libraryInjector->Inject(procId, m_unhookLibPath);
201+
}
202+
}
203+
98204
} // namespace
99205

100206
class D3D10GrabberImpl: public QObject
@@ -109,7 +215,6 @@ class D3D10GrabberImpl: public QObject
109215
m_memMap(NULL),
110216
m_lastFrameId(0),
111217
m_isInited(false),
112-
m_libraryInjector(NULL),
113218
m_isFrameGrabbedDuringLastSecond(false),
114219
m_context(context),
115220
m_getHwndCb(getHwndCb),
@@ -164,32 +269,6 @@ class D3D10GrabberImpl: public QObject
164269
if(m_isInited)
165270
return true;
166271

167-
AcquirePrivileges();
168-
169-
GetModuleFileName(NULL, m_hooksLibPath, SIZEOF_ARRAY(m_hooksLibPath));
170-
PathRemoveFileSpec(m_hooksLibPath);
171-
wcscat(m_hooksLibPath, L"\\");
172-
wcscat(m_hooksLibPath, lightpackHooksDllName);
173-
174-
GetModuleFileName(NULL, m_unhookLibPath, SIZEOF_ARRAY(m_hooksLibPath));
175-
PathRemoveFileSpec(m_unhookLibPath);
176-
wcscat(m_unhookLibPath, L"\\");
177-
wcscat(m_unhookLibPath, lightpackUnhookDllName);
178-
179-
GetWindowsDirectoryW(m_systemrootPath, SIZEOF_ARRAY(m_systemrootPath));
180-
181-
HRESULT hr = CoInitialize(0);
182-
// hr = InitComSecurity();
183-
// hr = CoCreateInstanceAsAdmin(NULL, CLSID_ILibraryInjector, IID_ILibraryInjector, reinterpret_cast<void **>(&m_libraryInjector));
184-
hr = CoCreateInstance(CLSID_ILibraryInjector, NULL, CLSCTX_INPROC_SERVER, IID_ILibraryInjector, reinterpret_cast<void **>(&m_libraryInjector));
185-
if (FAILED(hr)) {
186-
qCritical() << Q_FUNC_INFO << "Can't create libraryinjector. D3D10Grabber wasn't initialised. Please try to register server: regsvr32 libraryinjector.dll";
187-
return false;
188-
}
189-
190-
// Remove any injections from previous runs
191-
sanitizeProcesses();
192-
193272
#if 0
194273
// TODO: Remove this code or use |sa| in initIPC()
195274
SECURITY_ATTRIBUTES sa;
@@ -262,23 +341,40 @@ class D3D10GrabberImpl: public QObject
262341

263342
#endif
264343

265-
m_thread.reset(new QThread());
266-
m_thread->start();
267-
this->moveToThread(m_thread.data());
268-
269-
m_processesScanAndInfectTimer.reset(new QTimer(this));
270-
m_processesScanAndInfectTimer->setInterval(5000);
271-
m_processesScanAndInfectTimer->setSingleShot(false);
272-
connect(m_processesScanAndInfectTimer.data(), SIGNAL(timeout()), this, SLOT(infectCleanDxProcesses()) );
273-
m_processesScanAndInfectTimer->start();
344+
m_injectorThread.reset(new QThread());
345+
m_injector.reset(new D3D10GrabberInjector(NULL, m_injectD3D9));
346+
if (!m_injector->init()) {
347+
qCritical(Q_FUNC_INFO " Init D3D10GrabberInjector failed. D3D10Grabber wasn't initialised.");
348+
m_injector.reset();
349+
return false;
350+
}
351+
m_injector->moveToThread(m_injectorThread.data());
352+
m_injectorThread->start();
353+
//TODO:
354+
//connect(m_worker.data(), SIGNAL(frameGrabbed()), this, SIGNAL(frameGrabbed()), Qt::QueuedConnection);
274355

275356
m_workerThread.reset(new QThread());
276357
m_worker.reset(new D3D10GrabberWorker(NULL, NULL));
358+
if (!m_worker->init()) {
359+
qCritical(Q_FUNC_INFO " Init D3D10GrabberWorker failed. D3D10Grabber wasn't initialised.");
360+
m_worker.reset();
361+
m_injector.reset();
362+
m_injectorThread->quit();
363+
m_injectorThread->wait();
364+
m_injectorThread.reset();
365+
return false;
366+
}
277367
m_worker->moveToThread(m_workerThread.data());
278368
m_workerThread->start();
279369
connect(m_worker.data(), SIGNAL(frameGrabbed()), this, SIGNAL(frameGrabbed()), Qt::QueuedConnection);
280370
QMetaObject::invokeMethod(m_worker.data(), "runLoop", Qt::QueuedConnection);
281371

372+
m_processesScanAndInfectTimer.reset(new QTimer(this));
373+
m_processesScanAndInfectTimer->setInterval(5000);
374+
m_processesScanAndInfectTimer->setSingleShot(false);
375+
connect(m_processesScanAndInfectTimer.data(), SIGNAL(timeout()), m_injector.data(), SLOT(infectCleanDxProcesses()));
376+
m_processesScanAndInfectTimer->start();
377+
282378
m_checkIfFrameGrabbedTimer.reset(new QTimer());
283379
m_checkIfFrameGrabbedTimer->setSingleShot(false);
284380
m_checkIfFrameGrabbedTimer->setInterval(1000);
@@ -391,26 +487,6 @@ class D3D10GrabberImpl: public QObject
391487
void frameGrabbed();
392488

393489
private slots:
394-
void infectCleanDxProcesses(void) {
395-
if (m_isInited && m_libraryInjector) {
396-
QList<DWORD> processes = QList<DWORD>();
397-
if (m_injectD3D9)
398-
getDxProcessesIDs(&processes, m_systemrootPath);
399-
else
400-
getDxgiProcessesIDs(&processes, m_systemrootPath);
401-
foreach (DWORD procId, processes) {
402-
// Require the process to have run for at least one full timer tick,
403-
// hoping when injection happens their swapchain is already setup
404-
if (m_lastSeenDxProcesses.contains(procId)) {
405-
qDebug() << Q_FUNC_INFO << "Infecting DX process " << procId;
406-
m_libraryInjector->Inject(procId, m_hooksLibPath);
407-
}
408-
}
409-
m_lastSeenDxProcesses.clear();
410-
m_lastSeenDxProcesses.append(processes);
411-
}
412-
}
413-
414490
void handleIfFrameGrabbed() {
415491
if (!m_isFrameGrabbedDuringLastSecond) {
416492
if (m_isStarted) {
@@ -422,14 +498,6 @@ private slots:
422498
}
423499

424500
private:
425-
void sanitizeProcesses() {
426-
QList<DWORD> processes = QList<DWORD>();
427-
getHookedProcessesIDs(&processes, m_systemrootPath);
428-
foreach(DWORD procId, processes) {
429-
qDebug() << Q_FUNC_INFO << "Sanitizing process " << procId;
430-
m_libraryInjector->Inject(procId, m_unhookLibPath);
431-
}
432-
}
433501

434502
QRgb getColor(const QRect &widgetRect)
435503
{
@@ -597,16 +665,15 @@ private slots:
597665
disconnect(m_worker.data());
598666
m_worker->stop = true;
599667

600-
m_thread->quit();
668+
m_injector->sanitizeProcesses();
669+
601670
m_workerThread->quit();
602-
m_thread->wait();
671+
m_injectorThread->quit();
603672
m_workerThread->wait();
673+
m_injectorThread->wait();
604674

605-
sanitizeProcesses();
606675

607676
disconnect(this, SLOT(handleIfFrameGrabbed()));
608-
if (m_libraryInjector)
609-
m_libraryInjector->Release();
610677
freeIPC();
611678
CoUninitialize();
612679
m_isInited = false;
@@ -619,20 +686,16 @@ private slots:
619686
UINT m_lastFrameId;
620687
MONITORINFO m_monitorInfo;
621688
QScopedPointer<QTimer> m_processesScanAndInfectTimer;
622-
QList<DWORD> m_lastSeenDxProcesses;
623689
bool m_isInited;
624-
ILibraryInjector * m_libraryInjector;
625-
WCHAR m_hooksLibPath[300];
626-
WCHAR m_unhookLibPath[300];
627-
WCHAR m_systemrootPath[300];
628690
bool m_isFrameGrabbedDuringLastSecond;
629691
GrabberContext *m_context;
630692
GetHwndCallback_t m_getHwndCb;
631693

632694
QScopedPointer<QTimer> m_checkIfFrameGrabbedTimer;
633695
QScopedPointer<D3D10GrabberWorker> m_worker;
634696
QScopedPointer<QThread> m_workerThread;
635-
QScopedPointer<QThread> m_thread;
697+
QScopedPointer<D3D10GrabberInjector> m_injector;
698+
QScopedPointer<QThread> m_injectorThread;
636699
HOOKSGRABBER_SHARED_MEM_DESC m_memDesc;
637700
D3D10Grabber &m_owner;
638701
bool m_injectD3D9;

0 commit comments

Comments
 (0)