diff --git a/MemoryModule/MmpTls.cpp b/MemoryModule/MmpTls.cpp
index 8d07b81..cfb529d 100644
--- a/MemoryModule/MmpTls.cpp
+++ b/MemoryModule/MmpTls.cpp
@@ -454,7 +454,7 @@ BOOL NTAPI PreHookNtSetInformationProcess() {
}
NTSTATUS NTAPI HookNtSetInformationProcess(
- _In_ HANDLE ProcessHandle,
+ _In_opt_ HANDLE ProcessHandle,
_In_ PROCESSINFOCLASS ProcessInformationClass,
_In_reads_bytes_(ProcessInformationLength) PVOID ProcessInformation,
_In_ ULONG ProcessInformationLength) {
@@ -468,7 +468,6 @@ NTSTATUS NTAPI HookNtSetInformationProcess(
);
}
-
auto ProcessTlsInformation = PPROCESS_TLS_INFORMATION(ProcessInformation);
auto hProcess = ProcessHandle ? ProcessHandle : NtCurrentProcess();
auto TlsLength = ProcessInformationLength;
@@ -556,9 +555,12 @@ NTSTATUS NTAPI HookNtSetInformationProcess(
PMMP_TLSP_RECORD j = CONTAINING_RECORD(entry, MMP_TLSP_RECORD, InMmpThreadLocalStoragePointer);
if (ProcessTlsInformation->OperationType == ProcessTlsReplaceVector) {
- if (j->TlspMmpBlock[ProcessTlsInformation->TlsVectorLength] == ProcessTlsInformation->ThreadData->TlsVector[ProcessTlsInformation->TlsVectorLength]) {
+ if (j->TlspMmpBlock[ProcessTlsInformation->TlsVectorLength] == ProcessTlsInformation->ThreadData[i].TlsVector[ProcessTlsInformation->TlsVectorLength]) {
found = true;
+ //auto tlsp = CONTAINING_RECORD(ProcessTlsInformation->ThreadData[i].TlsVector, TLS_VECTOR, TLS_VECTOR::ModuleTlsData);
+ //assert(tlsp->Length >= ProcessTlsInformation->TlsVectorLength);
+
// Copy old data to new pointer
RtlCopyMemory(
ProcessTlsInformation->ThreadData[i].TlsVector,
@@ -767,17 +769,29 @@ NTSTATUS NTAPI MmpHandleTlsData(_In_ PLDR_DATA_TABLE_ENTRY lpModuleEntry) {
return STATUS_NO_MEMORY;
}
- status = NtSetInformationProcess(
+ status = HookNtSetInformationProcess(
nullptr, // hack
PROCESSINFOCLASS::ProcessTlsInformation,
ProcessTlsInformation,
(ULONG)Length
);
+ ThreadCount = 0;
for (DWORD i = 0; i < ProcessTlsInformation->ThreadDataCount; ++i) {
+ if (!ProcessTlsInformation->ThreadData[i].Flags) {
+ ++ThreadCount;
+ }
+
RtlFreeHeap(RtlProcessHeap(), 0, ProcessTlsInformation->ThreadData[i].TlsModulePointer);
}
+ if (ThreadCount) {
+ EnterCriticalSection(&MmpGlobalDataPtr->MmpTls->MmpTlspLock);
+ MmpGlobalDataPtr->MmpTls->MmpActiveThreadCount -= ThreadCount;
+ assert(MmpGlobalDataPtr->MmpTls->MmpActiveThreadCount > 0);
+ LeaveCriticalSection(&MmpGlobalDataPtr->MmpTls->MmpTlspLock);
+ }
+
RtlFreeHeap(RtlProcessHeap(), 0, ProcessTlsInformation);
return status;
}
diff --git a/a/a.vcxproj b/a/a.vcxproj
index 64c97ec..2bdc7fc 100644
--- a/a/a.vcxproj
+++ b/a/a.vcxproj
@@ -172,7 +172,11 @@
+
+
+
+
diff --git a/a/a.vcxproj.filters b/a/a.vcxproj.filters
index c622f7a..3cd8839 100644
--- a/a/a.vcxproj.filters
+++ b/a/a.vcxproj.filters
@@ -21,6 +21,18 @@
Source Files
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
diff --git a/a/dllmain.cpp b/a/dllmain.cpp
index d40eb91..5f782f0 100644
--- a/a/dllmain.cpp
+++ b/a/dllmain.cpp
@@ -1,46 +1,10 @@
-// dllmain.cpp : Defines the entry point for the DLL application.
#include
-#include
#include
-#include
-#include
#pragma comment(lib,"ws2_32.lib")
#pragma comment(lib,"wintrust.lib")
#pragma comment(lib,"ntdll.lib")
-typedef NTSTATUS(NTAPI* PUSER_THREAD_START_ROUTINE)(_In_ PVOID ThreadParameter);
-
-#define NtCurrentProcess() (HANDLE)-1
-
-#ifdef _WIN64
-#define NtCurrentThreadLocalStoragePointer() *(LPVOID*)(LPBYTE(NtCurrentTeb()) + 0x58)
-#else
-#define NtCurrentThreadLocalStoragePointer() *(LPVOID*)(LPBYTE(NtCurrentTeb()) + 0x2C)
-#endif
-
-typedef struct _CLIENT_ID {
- VOID* UniqueProcess;
- VOID* UniqueThread;
-}CLIENT_ID, * PCLIENT_ID;
-
-extern "C"
-NTSYSAPI
-NTSTATUS
-NTAPI
-RtlCreateUserThread(
- _In_ HANDLE Process,
- _In_opt_ PSECURITY_DESCRIPTOR ThreadSecurityDescriptor,
- _In_ BOOLEAN CreateSuspended,
- _In_opt_ ULONG ZeroBits,
- _In_opt_ SIZE_T MaximumStackSize,
- _In_opt_ SIZE_T CommittedStackSize,
- _In_ PUSER_THREAD_START_ROUTINE StartAddress,
- _In_opt_ PVOID Parameter,
- _Out_opt_ PHANDLE Thread,
- _Out_opt_ PCLIENT_ID ClientId
-);
-
BOOL APIENTRY DllMain( HMODULE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved
@@ -60,131 +24,7 @@ BOOL APIENTRY DllMain( HMODULE hModule,
return TRUE;
}
-/*
- exception type
- 0 int
- 1 char
- 2 std::exception
- ... DWORD64
-*/
-
-int exception(int exception_type) {
- //int a = 0;
- //__try {
- // *(PDWORD)(nullptr) = -1;
- // a = 2;
- //}
- //__except (EXCEPTION_EXECUTE_HANDLER) {
- // printf("-----------\n");
- // getchar();
- // a = 1;
- //}
- try {
- switch (exception_type) {
- case 0:
- throw 0;
- case 1:
- throw '1';
- case 2:
- throw std::exception("2");
- case 3:
- {
- std::string s = "foo";
- s.at(10);
- }
- default:
- throw (DWORD64)-1;
- }
- return 0;
- }
- catch (int val) {
- printf("exception code = %d\n", val);
- return val;
- }
- catch (char val) {
- printf("exception code = %c\n", val);
- return val - '0';
- }
- catch (const std::out_of_range& e) {
- printf("%s\n", e.what());
- return 3;
- }
- catch (std::exception val) {
- printf("exception code = %s\n", val.what());
- return 2;
- }
- catch (...) {
- printf("exception catched!!\n");
- return 0;
- }
- //return a;
-}
-
int __test__() {
printf("HelloWorld!\n");
return 0;
}
-
-static thread_local int x = 0xffccffdd;
-NTSTATUS WINAPI Thread(PVOID) {
- printf("[1] ThreadLocalStoragePointer = %p\n", NtCurrentThreadLocalStoragePointer());
- return x == 0xffccffdd ? 0 : 1;
-}
-
-int thread() {
- x = 2;
- printf("[0] ThreadLocalStoragePointer = %p\n", NtCurrentThreadLocalStoragePointer());
- HANDLE hThread;// = CreateThread(nullptr, 0, Thread, nullptr, 0, nullptr);
- RtlCreateUserThread(NtCurrentProcess(), nullptr, FALSE, 0, 0, 0, Thread, nullptr, &hThread, nullptr);
- DWORD ret = -1;
- if (hThread) {
- WaitForSingleObject(hThread, 0xffffffff);
- GetExitCodeThread(hThread, &ret);
- CloseHandle(hThread);
- return ret;
- }
- return -1;
-}
-
-DWORD Value;
-volatile LPDWORD lpAddr;
-
-LONG WINAPI Filter(_In_ struct _EXCEPTION_POINTERS* ExceptionInfo) {
-
- if (ExceptionInfo->ExceptionRecord->ExceptionCode == STATUS_ACCESS_VIOLATION) {
-
- lpAddr = &Value;
-
- // +++++++
- // begin compiler specific
- // +++++++
-
- //ExceptionInfo->ContextRecord->Rip -= 7;
- ExceptionInfo->ContextRecord->Rax = (ULONG_PTR)lpAddr;
-
- // +++++++
- // end compiler specific
- // +++++++
-
- return EXCEPTION_CONTINUE_EXECUTION;
- }
-
- return EXCEPTION_CONTINUE_SEARCH;
-}
-
-int unhandled_exception() {
- auto filter = SetUnhandledExceptionFilter(Filter);
- auto ff = SetUnhandledExceptionFilter(filter);
-
- if (ff != Filter) {
- printf("%p\t%p\t%p\nfailed\n", filter, ff, Filter);
- return 0;
- }
-
- filter = SetUnhandledExceptionFilter(Filter);
- lpAddr = nullptr;
- *lpAddr = 1;
- SetUnhandledExceptionFilter(filter);
-
- return 1234;
-}
diff --git a/a/exception.cpp b/a/exception.cpp
new file mode 100644
index 0000000..515db56
--- /dev/null
+++ b/a/exception.cpp
@@ -0,0 +1,63 @@
+#include
+#include
+#include
+
+/*
+ exception type
+ 0 int
+ 1 char
+ 2 std::exception
+ ... DWORD64
+*/
+
+int exception(int exception_type) {
+ //int a = 0;
+ //__try {
+ // *(PDWORD)(nullptr) = -1;
+ // a = 2;
+ //}
+ //__except (EXCEPTION_EXECUTE_HANDLER) {
+ // printf("-----------\n");
+ // getchar();
+ // a = 1;
+ //}
+ try {
+ switch (exception_type) {
+ case 0:
+ throw 0;
+ case 1:
+ throw '1';
+ case 2:
+ throw std::exception("2");
+ case 3:
+ {
+ std::string s = "foo";
+ s.at(10);
+ }
+ default:
+ throw (DWORD64)-1;
+ }
+ return 0;
+ }
+ catch (int val) {
+ printf("exception code = %d\n", val);
+ return val;
+ }
+ catch (char val) {
+ printf("exception code = %c\n", val);
+ return val - '0';
+ }
+ catch (const std::out_of_range& e) {
+ printf("%s\n", e.what());
+ return 3;
+ }
+ catch (std::exception val) {
+ printf("exception code = %s\n", val.what());
+ return 2;
+ }
+ catch (...) {
+ printf("exception catched!!\n");
+ return 0;
+ }
+ //return a;
+}
\ No newline at end of file
diff --git a/a/gdiplus.cpp b/a/gdiplus.cpp
new file mode 100644
index 0000000..ed65830
--- /dev/null
+++ b/a/gdiplus.cpp
@@ -0,0 +1,83 @@
+#include
+#include
+#include
+using namespace Gdiplus;
+#pragma comment (lib,"Gdiplus.lib")
+
+VOID OnPaint(HDC hdc)
+{
+ Graphics graphics(hdc);
+ Pen pen(Color(255, 0, 0, 255));
+ graphics.DrawLine(&pen, 0, 0, 200, 100);
+}
+
+LRESULT CALLBACK WndProc(HWND hWnd, UINT message,
+ WPARAM wParam, LPARAM lParam)
+{
+ HDC hdc;
+ PAINTSTRUCT ps;
+
+ switch (message)
+ {
+ case WM_PAINT:
+ hdc = BeginPaint(hWnd, &ps);
+ OnPaint(hdc);
+ EndPaint(hWnd, &ps);
+ return 0;
+ case WM_DESTROY:
+ PostQuitMessage(0);
+ return 0;
+ default:
+ return DefWindowProc(hWnd, message, wParam, lParam);
+ }
+}
+
+int WINAPI GdiplusTest()
+{
+ HWND hWnd;
+ MSG msg;
+ WNDCLASS wndClass;
+ GdiplusStartupInput gdiplusStartupInput;
+ ULONG_PTR gdiplusToken;
+
+ // Initialize GDI+.
+ GdiplusStartup(&gdiplusToken, &gdiplusStartupInput, NULL);
+
+ wndClass.style = CS_HREDRAW | CS_VREDRAW;
+ wndClass.lpfnWndProc = WndProc;
+ wndClass.cbClsExtra = 0;
+ wndClass.cbWndExtra = 0;
+ wndClass.hInstance = GetModuleHandle(nullptr);
+ wndClass.hIcon = LoadIcon(NULL, IDI_APPLICATION);
+ wndClass.hCursor = LoadCursor(NULL, IDC_ARROW);
+ wndClass.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
+ wndClass.lpszMenuName = NULL;
+ wndClass.lpszClassName = TEXT("GettingStarted");
+
+ RegisterClass(&wndClass);
+
+ hWnd = CreateWindow(
+ TEXT("GettingStarted"), // window class name
+ TEXT("Getting Started"), // window caption
+ WS_OVERLAPPEDWINDOW, // window style
+ CW_USEDEFAULT, // initial x position
+ CW_USEDEFAULT, // initial y position
+ CW_USEDEFAULT, // initial x size
+ CW_USEDEFAULT, // initial y size
+ NULL, // parent window handle
+ NULL, // window menu handle
+ wndClass.hInstance, // program instance handle
+ NULL); // creation parameters
+
+ ShowWindow(hWnd, SW_SHOW);
+ UpdateWindow(hWnd);
+
+ while (GetMessage(&msg, NULL, 0, 0))
+ {
+ TranslateMessage(&msg);
+ DispatchMessage(&msg);
+ }
+
+ GdiplusShutdown(gdiplusToken);
+ return msg.wParam;
+}
diff --git a/a/m.def b/a/m.def
index 8959306..545acdc 100644
--- a/a/m.def
+++ b/a/m.def
@@ -5,4 +5,5 @@ thread
Socket = ws2_32.WSASocketW
VerifyTruse = wintrust.WinVerifyTrust
test_user32
-unhandled_exception
\ No newline at end of file
+unhandled_exception
+GdiplusTest
\ No newline at end of file
diff --git a/a/thread.cpp b/a/thread.cpp
new file mode 100644
index 0000000..8b4fb74
--- /dev/null
+++ b/a/thread.cpp
@@ -0,0 +1,55 @@
+#include
+#include
+
+typedef NTSTATUS(NTAPI* PUSER_THREAD_START_ROUTINE)(_In_ PVOID ThreadParameter);
+
+#define NtCurrentProcess() (HANDLE)-1
+
+#ifdef _WIN64
+#define NtCurrentThreadLocalStoragePointer() *(LPVOID*)(LPBYTE(NtCurrentTeb()) + 0x58)
+#else
+#define NtCurrentThreadLocalStoragePointer() *(LPVOID*)(LPBYTE(NtCurrentTeb()) + 0x2C)
+#endif
+
+typedef struct _CLIENT_ID {
+ VOID* UniqueProcess;
+ VOID* UniqueThread;
+}CLIENT_ID, * PCLIENT_ID;
+
+extern "C"
+NTSYSAPI
+NTSTATUS
+NTAPI
+RtlCreateUserThread(
+ _In_ HANDLE Process,
+ _In_opt_ PSECURITY_DESCRIPTOR ThreadSecurityDescriptor,
+ _In_ BOOLEAN CreateSuspended,
+ _In_opt_ ULONG ZeroBits,
+ _In_opt_ SIZE_T MaximumStackSize,
+ _In_opt_ SIZE_T CommittedStackSize,
+ _In_ PUSER_THREAD_START_ROUTINE StartAddress,
+ _In_opt_ PVOID Parameter,
+ _Out_opt_ PHANDLE Thread,
+ _Out_opt_ PCLIENT_ID ClientId
+);
+
+static thread_local int x = 0xffccffdd;
+NTSTATUS WINAPI Thread(PVOID) {
+ printf("[1] ThreadLocalStoragePointer = %p\n", NtCurrentThreadLocalStoragePointer());
+ return x == 0xffccffdd ? 0 : 1;
+}
+
+int thread() {
+ x = 2;
+ printf("[0] ThreadLocalStoragePointer = %p\n", NtCurrentThreadLocalStoragePointer());
+ HANDLE hThread;// = CreateThread(nullptr, 0, Thread, nullptr, 0, nullptr);
+ RtlCreateUserThread(NtCurrentProcess(), nullptr, FALSE, 0, 0, 0, Thread, nullptr, &hThread, nullptr);
+ DWORD ret = -1;
+ if (hThread) {
+ WaitForSingleObject(hThread, 0xffffffff);
+ GetExitCodeThread(hThread, &ret);
+ CloseHandle(hThread);
+ return ret;
+ }
+ return -1;
+}
\ No newline at end of file
diff --git a/a/unhandled_exception.cpp b/a/unhandled_exception.cpp
new file mode 100644
index 0000000..f442ed2
--- /dev/null
+++ b/a/unhandled_exception.cpp
@@ -0,0 +1,49 @@
+#include
+#include
+
+#ifdef _WIN64
+DWORD Value;
+volatile LPDWORD lpAddr;
+
+LONG WINAPI Filter(_In_ struct _EXCEPTION_POINTERS* ExceptionInfo) {
+
+ if (ExceptionInfo->ExceptionRecord->ExceptionCode == STATUS_ACCESS_VIOLATION) {
+
+ lpAddr = &Value;
+
+ // +++++++
+ // begin compiler specific
+ // +++++++
+
+ //ExceptionInfo->ContextRecord->Rip -= 7;
+ ExceptionInfo->ContextRecord->Rax = (ULONG_PTR)lpAddr;
+
+ // +++++++
+ // end compiler specific
+ // +++++++
+
+ return EXCEPTION_CONTINUE_EXECUTION;
+ }
+
+ return EXCEPTION_CONTINUE_SEARCH;
+}
+#endif
+
+int unhandled_exception() {
+#ifdef _WIN64
+ auto filter = SetUnhandledExceptionFilter(Filter);
+ auto ff = SetUnhandledExceptionFilter(filter);
+
+ if (ff != Filter) {
+ printf("%p\t%p\t%p\nfailed\n", filter, ff, Filter);
+ return 0;
+ }
+
+ filter = SetUnhandledExceptionFilter(Filter);
+ lpAddr = nullptr;
+ *lpAddr = 1;
+ SetUnhandledExceptionFilter(filter);
+#endif
+
+ return 1234;
+}
diff --git a/test/test.cpp b/test/test.cpp
index d4c6ca5..606369e 100644
--- a/test/test.cpp
+++ b/test/test.cpp
@@ -39,107 +39,21 @@ static void DisplayStatus() {
int test() {
LPVOID buffer = ReadDllFile("a.dll");
- HMEMORYMODULE m1 = nullptr, m2 = m1;
- HMODULE hModule = nullptr;
- FARPROC pfn = nullptr;
- DWORD MemoryModuleFeatures = 0;
-
- typedef int(*_exception)(int code);
- _exception exception = nullptr;
- HRSRC hRsrc;
- DWORD SizeofRes;
- HGLOBAL gRes;
- char str[10];
-
- LdrQuerySystemMemoryModuleFeatures(&MemoryModuleFeatures);
- if (MemoryModuleFeatures != MEMORY_FEATURE_ALL) {
- printf("not support all features on this version of windows.\n");
+ HMODULE hm = LoadLibraryMemory(buffer);
+ FARPROC fp = GetProcAddress(hm, "GdiplusTest");
+ bool c = true;
+ while (c) {
+ fp();
}
-
- if (!NT_SUCCESS(LdrLoadDllMemoryExW(&m1, nullptr, 0, buffer, 0, L"kernel64", nullptr))) goto end;
- LoadLibraryW(L"wininet.dll");
- if (!NT_SUCCESS(LdrLoadDllMemoryExW(&m2, nullptr, 0, buffer, 0, L"kernel128", nullptr))) goto end;
-
- //forward export
- hModule = (HMODULE)m1;
- pfn = (decltype(pfn))(GetProcAddress(hModule, "Socket")); //ws2_32.WSASocketW
- pfn = (decltype(pfn))(GetProcAddress(hModule, "VerifyTruse")); //wintrust.WinVerifyTrust
- hModule = (HMODULE)m2;
- pfn = (decltype(pfn))(GetProcAddress(hModule, "Socket"));
- pfn = (decltype(pfn))(GetProcAddress(hModule, "VerifyTruse"));
-
- //exception
- hModule = (HMODULE)m1;
- exception = (_exception)GetProcAddress(hModule, "exception");
- if (exception) {
- for (int i = 0; i < 5; ++i)exception(i);
- }
-
- //tls
- pfn = GetProcAddress(hModule, "thread");
- if (pfn && pfn()) {
- printf("thread test failed.\n");
- }
-
- //resource
- if (!LoadStringA(hModule, 101, str, 10)) {
- printf("load string failed.\n");
- }
- else {
- printf("%s\n", str);
- }
- if (!(hRsrc = FindResourceA(hModule, MAKEINTRESOURCEA(102), "BINARY"))) {
- printf("find binary resource failed.\n");
- }
- else {
- if ((SizeofRes = SizeofResource(hModule, hRsrc)) != 0x10) {
- printf("invalid res size.\n");
- }
- else {
- if (!(gRes = LoadResource(hModule, hRsrc))) {
- printf("load res failed.\n");
- }
- else {
- if (!LockResource(gRes))printf("lock res failed.\n");
- else {
- printf("resource test success.\n");
- }
- }
- }
- }
-
-end:
- delete[]buffer;
- if (m1)LdrUnloadDllMemory(m1);
- FreeLibrary(LoadLibraryW(L"wininet.dll"));
- FreeLibrary(GetModuleHandleW(L"wininet.dll"));
- if (m2)LdrUnloadDllMemory(m2);
-
+
return 0;
}
-void test_cf() {
- auto buffer = ReadDllFile("CoreFoundation.dll");
-
- if (buffer) {
- HMODULE hm = LoadLibraryMemory(buffer);
- delete[]buffer;
-
- if (hm) {
- printf("Load success: %p\n", hm);
- FreeLibraryMemory(hm);
- }
- else {
- printf("Load fail: %d\n", GetLastError());
- }
- }
-
- return;
-}
-
int main() {
DisplayStatus();
- test_cf();
+ test();
+
+ WaitForSingleObject(NtCurrentProcess(), INFINITE);
return 0;
}