diff --git a/a/dllmain.cpp b/a/dllmain.cpp index b0a1f18..d02e6ea 100644 --- a/a/dllmain.cpp +++ b/a/dllmain.cpp @@ -2,6 +2,8 @@ #include #include #include +#include +#include #pragma comment(lib,"ws2_32.lib") #pragma comment(lib,"wintrust.lib") @@ -85,6 +87,11 @@ int exception(int exception_type) { throw '1'; case 2: throw std::exception("2"); + case 3: + { + std::string s = "foo"; + s.at(10); + } default: throw (DWORD64)-1; } @@ -98,6 +105,10 @@ int exception(int exception_type) { 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; diff --git a/test/test.cpp b/test/test.cpp index dcb4256..29a047a 100644 --- a/test/test.cpp +++ b/test/test.cpp @@ -18,7 +18,89 @@ static PVOID ReadDllFile(LPCSTR FileName) { return buffer; } -int main() { +int test_a_dll() { + 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"); + } + + 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; +} + +int test_user32() { HMODULE hModule; NTSTATUS status; PVOID buffer = ReadDllFile("C:\\Windows\\System32\\user32.dll"); @@ -49,3 +131,8 @@ int main() { return 0; } + +int main() { + test_a_dll(); + return 0; +}