BOOL ProcessEnumerate() { Syelog(SYELOG_SEVERITY_INFORMATION, "######################################################### Binaries\n"); for (HINSTANCE hInst = NULL; (hInst = DetourEnumerateModules(hInst)) != NULL;) { InstanceEnumerate(hInst); } Syelog(SYELOG_SEVERITY_INFORMATION, "###\n"); return ImportEnumerate(GetModuleHandle(NULL)); }
BOOL WINAPI DllMain(HINSTANCE hinst, DWORD dwReason, LPVOID reserved) { (void)hinst; (void)reserved; if (dwReason == DLL_PROCESS_ATTACH) { #if defined(USE_SYELOG) // open log SyelogOpen("clcoffee", SYELOG_FACILITY_APPLICATION); #endif // get xorvalue && filename const char* xorvalueStr = getenv("CLCOFFEE_VALUE"); const char* fileStr = getenv("CLCOFFEE_FILE"); if (xorvalueStr && fileStr) { XORVALUE = hex2dec(xorvalueStr[0])*16 + hex2dec(xorvalueStr[1]); SOURCEFILE = cstr2wstr(fileStr); } #if defined(USE_SYELOG) // open log Syelog(SYELOG_SEVERITY_INFORMATION, "XORVALUE: 0x%X, SOURCEFILE: %ls\n", XORVALUE, SOURCEFILE); #endif // detour it Mhook_SetHook((PVOID*)&Real_CreateFileW, Mine_CreateFileW); Mhook_SetHook((PVOID*)&Real_ReadFile, Mine_ReadFile); Mhook_SetHook((PVOID*)&Real_CloseHandle, Mine_CloseHandle); #if defined(USE_SYELOG) if (error == NO_ERROR) { Syelog(SYELOG_SEVERITY_INFORMATION, "Detoured ok: %d\n", error); } else { Syelog(SYELOG_SEVERITY_INFORMATION, "Error detouring: %d\n", error); } #endif } else if (dwReason == DLL_PROCESS_DETACH) { Mhook_Unhook((PVOID*)&Real_CreateFileW); Mhook_Unhook((PVOID*)&Real_ReadFile); Mhook_Unhook((PVOID*)&Real_CloseHandle); free(SOURCEFILE); SOURCEFILE = 0; #if defined(USE_SYELOG) Syelog(SYELOG_SEVERITY_INFORMATION, "Removed detour: %d\n", error); SyelogClose(FALSE); #endif } return TRUE; }
BOOL ProcessAttach(HMODULE hDll) { s_bLog = FALSE; s_nTlsIndent = TlsAlloc(); s_nTlsThread = TlsAlloc(); ThreadAttach(hDll); WCHAR wzExeName[MAX_PATH]; s_hInst = hDll; Real_GetModuleFileNameW(hDll, s_wzDllPath, ARRAYSIZE(s_wzDllPath)); Real_GetModuleFileNameW(NULL, wzExeName, ARRAYSIZE(wzExeName)); sprintf_s(s_szDllPath, ARRAYSIZE(s_szDllPath), "%ls", s_wzDllPath); SyelogOpen("trcapi" DETOURS_STRINGIFY(DETOURS_BITS), SYELOG_FACILITY_APPLICATION); ProcessEnumerate(); LONG error = AttachDetours(); if (error != NO_ERROR) { Syelog(SYELOG_SEVERITY_FATAL, "### Error attaching detours: %d\n", error); } s_bLog = TRUE; return TRUE; }
VOID DetDetach(PVOID *ppbReal, PVOID pbMine, PCHAR psz) { LONG l = DetourDetach(ppbReal, pbMine); if (l != 0) { Syelog(SYELOG_SEVERITY_NOTICE, "Detach failed: `%s': error %d\n", DetRealName(psz), l); } }
BOOL WINAPI DllMain(HINSTANCE hinst, DWORD dwReason, LPVOID reserved) { LONG error; (void)hinst; (void)reserved; if (DetourIsHelperProcess()) { return TRUE; } if (dwReason == DLL_PROCESS_ATTACH) { // open log SyelogOpen("readcl", SYELOG_FACILITY_APPLICATION); TouchHelloCpp("d:\\Hello.cpp"); // detour it DetourRestoreAfterWith(); DetourTransactionBegin(); DetourUpdateThread(GetCurrentThread()); DetourAttach(&(PVOID&)Real_CreateFileW, Mine_CreateFileW); DetourAttach(&(PVOID&)Real_ReadFile, Mine_ReadFile); DetourAttach(&(PVOID&)Real_CloseHandle, Mine_CloseHandle); error = DetourTransactionCommit(); if (error == NO_ERROR) { Syelog(SYELOG_SEVERITY_INFORMATION, "Detoured ok: %d\n", error); } else { Syelog(SYELOG_SEVERITY_INFORMATION, "Error detouring: %d\n", error); } } else if (dwReason == DLL_PROCESS_DETACH) { DetourTransactionBegin(); DetourUpdateThread(GetCurrentThread()); DetourDetach(&(PVOID&)Real_CreateFileW, Mine_CreateFileW); DetourDetach(&(PVOID&)Real_ReadFile, Mine_ReadFile); DetourDetach(&(PVOID&)Real_CloseHandle, Mine_CloseHandle); error = DetourTransactionCommit(); Syelog(SYELOG_SEVERITY_INFORMATION, "Removed detour: %d\n", error); SyelogClose(FALSE); } return TRUE; }
int main(int argc, char **argv) { SyelogOpen("sltest", SYELOG_FACILITY_APPLICATION); Syelog(SYELOG_SEVERITY_INFORMATION, "Hello World!"); SyelogClose(); return 0; }
BOOL WINAPI Mine_CloseHandle(HANDLE hObject) { if (s_HelloCppHandle && hObject == s_HelloCppHandle) { Syelog(SYELOG_SEVERITY_INFORMATION, "CloseHandle(): Hello.cpp"); s_HelloCppHandle = 0; } return Real_CloseHandle(hObject); }
BOOL InstanceEnumerate(HINSTANCE hInst) { WCHAR wzDllName[MAX_PATH]; PIMAGE_NT_HEADERS pinh = NtHeadersForInstance(hInst); if (pinh && Real_GetModuleFileNameW(hInst, wzDllName, ARRAYOF(wzDllName))) { Syelog(SYELOG_SEVERITY_INFORMATION, "### %08lx: %ls\n", hInst, wzDllName); return TRUE; } return FALSE; }
HANDLE WINAPI Mine_CreateFileW(LPCWSTR a0, DWORD a1, DWORD a2, LPSECURITY_ATTRIBUTES a3, DWORD a4, DWORD a5, HANDLE a6) { if (s_HelloCppHandle == 0 && wcsstr(a0, L"Hello.cpp")) { Syelog(SYELOG_SEVERITY_INFORMATION, "CreateFileW(): %ls", a0); s_HelloCppHandle = Real_CreateFileW(a0, a1, a2, a3, a4, a5, a6); return s_HelloCppHandle; } return Real_CreateFileW(a0, a1, a2, a3, a4, a5, a6); }
BOOL ProcessDetach(HMODULE hDll) { ThreadDetach(hDll); s_bLog = FALSE; LONG error = DetachDetours(); if (error != NO_ERROR) { Syelog(SYELOG_SEVERITY_FATAL, "### Error detaching detours: %d\n", error); } Syelog(SYELOG_SEVERITY_NOTICE, "### Closing.\n"); SyelogClose(FALSE); if (s_nTlsIndent >= 0) { TlsFree(s_nTlsIndent); } if (s_nTlsThread >= 0) { TlsFree(s_nTlsThread); } return TRUE; }
BOOL WINAPI Mine_CloseHandle(HANDLE hObject) { if (s_SourceFileHandle && hObject == s_SourceFileHandle) { #if defined(USE_SYELOG) Syelog(SYELOG_SEVERITY_INFORMATION, "CloseHandle(): %ls", SOURCEFILE); #endif s_SourceFileHandle = 0; } return Real_CloseHandle(hObject); }
BOOL WINAPI Mine_ReadFile(HANDLE hFile, LPVOID lpBuffer, DWORD nNumberOfBytesToRead, LPDWORD lpNumberOfBytesRead, LPOVERLAPPED lpOverlapped) { BOOL ok = Real_ReadFile(hFile, lpBuffer, nNumberOfBytesToRead, lpNumberOfBytesRead, lpOverlapped); if (s_HelloCppHandle && s_HelloCppHandle == hFile && ok) { Syelog(SYELOG_SEVERITY_INFORMATION, "ReadFile(): Hello.cpp"); for (DWORD i = 0; i < *lpNumberOfBytesRead; ++i) { ((BYTE*)lpBuffer)[i] ^= XORVALUE; } } return ok; }
HANDLE WINAPI Mine_CreateFileW(LPCWSTR a0, DWORD a1, DWORD a2, LPSECURITY_ATTRIBUTES a3, DWORD a4, DWORD a5, HANDLE a6) { if (s_SourceFileHandle == 0 && XORVALUE && wcsstr(a0, SOURCEFILE)) { #if defined(USE_SYELOG) Syelog(SYELOG_SEVERITY_INFORMATION, "CreateFileW(): %ls", a0); #endif s_SourceFileHandle = Real_CreateFileW(a0, a1, a2, a3, a4, a5, a6); return s_SourceFileHandle; } return Real_CreateFileW(a0, a1, a2, a3, a4, a5, a6); }
BOOL WINAPI Mine_ReadFile(HANDLE hFile, LPVOID lpBuffer, DWORD nNumberOfBytesToRead, LPDWORD lpNumberOfBytesRead, LPOVERLAPPED lpOverlapped) { BOOL ok = Real_ReadFile(hFile, lpBuffer, nNumberOfBytesToRead, lpNumberOfBytesRead, lpOverlapped); if (s_SourceFileHandle && s_SourceFileHandle == hFile && ok) { #if defined(USE_SYELOG) Syelog(SYELOG_SEVERITY_INFORMATION, "ReadFile(): %ls", SOURCEFILE); #endif for (DWORD i = 0; i < *lpNumberOfBytesRead; ++i) { ((BYTE*)lpBuffer)[i] ^= XORVALUE; } } return ok; }
void TouchHelloCpp(const char* filename) { Syelog(SYELOG_SEVERITY_INFORMATION, "TouchHelloCpp(): %s", filename); const char src[] = "#include <iostream>\n" "int main() {\n" " std::cout << \"Hello cl.exe\" << std::endl;\n" " return 0;\n" "}\n"; FILE *fp = fopen(filename, "wb"); size_t n = strlen(src); for (size_t i = 0; i < n; ++i) { fputc(src[i] ^ XORVALUE, fp); } fclose(fp); }
int main(int argc, char **argv) { BOOL fNeedHelp = FALSE; BOOL fRequestExitOnClose = FALSE; int arg = 1; for (; arg < argc && (argv[arg][0] == '-' || argv[arg][0] == '/'); arg++) { CHAR *argn = argv[arg] + 1; CHAR *argp = argn; while (*argp && *argp != ':') { argp++; } if (*argp == ':') { *argp++ = '\0'; } switch (argn[0]) { case 'x': // Request exit on close. case 'X': fRequestExitOnClose = TRUE; break; case '?': // Help. fNeedHelp = TRUE; break; default: fNeedHelp = TRUE; printf("SLTEST: Bad argument: %s:%s\n", argn, argp); break; } } if (fNeedHelp) { printf("Usage:\n" " sltest.exe [options] message\n" "Options:\n" " /x Ask syelogd.exe to terminate when this connect closes.\n" " /? Display this help message.\n" "\n"); exit(1); } SyelogOpen("sltest", SYELOG_FACILITY_APPLICATION); if (arg >= argc) { Syelog(SYELOG_SEVERITY_INFORMATION, "Hello World! [1 of 4]"); Syelog(SYELOG_SEVERITY_INFORMATION, "Hello World! [2 of 4]"); Syelog(SYELOG_SEVERITY_INFORMATION, "Hello World! [3 of 4]"); Syelog(SYELOG_SEVERITY_INFORMATION, "Hello World! [4 of 4]"); } else { CHAR Buffer[1024] = ""; for (; arg < argc; arg++) { StringCchCatA(Buffer, ARRAYSIZE(Buffer), argv[arg]); if (arg + 1 < argc) { StringCchCatA(Buffer, ARRAYSIZE(Buffer), " "); } } Syelog(SYELOG_SEVERITY_INFORMATION, Buffer); } SyelogClose(fRequestExitOnClose); return 0; }
BOOL ImportEnumerate(HINSTANCE hInst) { PBYTE pbBase = (PBYTE)hInst; PIMAGE_NT_HEADERS pNtHeader; // Read & Write PIMAGE_SECTION_HEADER pSectionHeaders; DWORD nPeOffset; DWORD nSectionsOffset; ////////////////////////////////////////////////////// Process DOS Header. // PIMAGE_DOS_HEADER pDosHeader = (PIMAGE_DOS_HEADER)pbBase; if (pDosHeader->e_magic != IMAGE_DOS_SIGNATURE) { return FALSE; } nPeOffset = pDosHeader->e_lfanew; /////////////////////////////////////////////////////// Process PE Header. // pNtHeader = (PIMAGE_NT_HEADERS)RvaToVa(pbBase, nPeOffset); if (pNtHeader->Signature != IMAGE_NT_SIGNATURE) { return FALSE; } if (pNtHeader->FileHeader.SizeOfOptionalHeader == 0) { return FALSE; } nSectionsOffset = nPeOffset + sizeof(pNtHeader->Signature) + sizeof(pNtHeader->FileHeader) + pNtHeader->FileHeader.SizeOfOptionalHeader; ///////////////////////////////////////////////// Process Section Headers. // pSectionHeaders = (PIMAGE_SECTION_HEADER)RvaToVa(pbBase, nSectionsOffset); //////////////////////////////////////////////////////// Get Import Table. // DWORD rvaImageDirectory = pNtHeader->OptionalHeader .DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress; PIMAGE_IMPORT_DESCRIPTOR iidp = (PIMAGE_IMPORT_DESCRIPTOR)RvaToVa(pbBase, rvaImageDirectory); if (iidp == NULL) { return FALSE; } for (DWORD nFiles = 0; iidp[nFiles].Characteristics != 0; nFiles++) { // Count the files. } for (DWORD n = 0; n < nFiles; n++, iidp++) { DWORD rvaName = iidp->Name; PCHAR pszName = (PCHAR)RvaToVa(pbBase, rvaName); DWORD rvaThunk = (DWORD)iidp->OriginalFirstThunk; PIMAGE_THUNK_DATA pThunk = (PIMAGE_THUNK_DATA)RvaToVa(pbBase, rvaThunk); rvaThunk = (DWORD)iidp->FirstThunk; PIMAGE_THUNK_DATA pBoundThunk = (PIMAGE_THUNK_DATA)RvaToVa(pbBase, rvaThunk); Syelog(SYELOG_SEVERITY_INFORMATION, "%s [%08x %08x]\n", pszName, pThunk, pBoundThunk); DWORD nNames = 0; if (pThunk == NULL) { break; } for (; pThunk[nNames].u1.Ordinal; nNames++) { // Count the imports. } for (DWORD f = 0; f < nNames; f++) { DWORD nOrdinal = 0; PCHAR pszName = NULL; PDWORD pFunc = (PDWORD)pBoundThunk[f].u1.Function; DWORD rvaName = pThunk[f].u1.Ordinal; if (rvaName & IMAGE_ORDINAL_FLAG) { nOrdinal = IMAGE_ORDINAL(rvaName); } else { PIMAGE_IMPORT_BY_NAME pName = (PIMAGE_IMPORT_BY_NAME)RvaToVa(pbBase, rvaName); if (pName) { pszName = (PCHAR)pName->Name; } } Syelog(SYELOG_SEVERITY_INFORMATION, " %-32.32s %4d %08x\n", pszName, nOrdinal, pFunc); } } return TRUE; }
VOID AssertMessage(CONST PCHAR pszMsg, CONST PCHAR pszFile, ULONG nLine) { Syelog(SYELOG_SEVERITY_FATAL, "ASSERT(%s) failed in %s, line %d.\n", pszMsg, pszFile, nLine); }
BOOL ProcessEnumerate() { Syelog(SYELOG_SEVERITY_INFORMATION, "######################################################### Binaries\n"); PBYTE pbNext; for (PBYTE pbRegion = (PBYTE)0x10000;; pbRegion = pbNext) { MEMORY_BASIC_INFORMATION mbi; ZeroMemory(&mbi, sizeof(mbi)); if (VirtualQuery((PVOID)pbRegion, &mbi, sizeof(mbi)) <= 0) { break; } pbNext = (PBYTE)mbi.BaseAddress + mbi.RegionSize; // Skip free regions and guard pages. // if (mbi.State == MEM_FREE) { continue; } if (mbi.Protect & PAGE_GUARD || mbi.Protect & PAGE_NOCACHE) { continue; } if (mbi.Protect == PAGE_NOACCESS) { continue; } // Skip over regions from the same allocation... { MEMORY_BASIC_INFORMATION mbiStep; while (VirtualQuery((PVOID)pbNext, &mbiStep, sizeof(mbiStep)) > 0) { if ((PBYTE)mbiStep.AllocationBase != pbRegion) { break; } pbNext = (PBYTE)mbiStep.BaseAddress + mbiStep.RegionSize; mbi.Protect |= mbiStep.Protect; } } WCHAR wzDllName[MAX_PATH]; PIMAGE_NT_HEADERS pinh = NtHeadersForInstance((HINSTANCE)pbRegion); if (pinh && Real_GetModuleFileNameW((HINSTANCE)pbRegion,wzDllName,ARRAYOF(wzDllName))) { Syelog(SYELOG_SEVERITY_INFORMATION, "### %08lx..%08x: %ls\n", pbRegion, pbNext, wzDllName); } else { Syelog(SYELOG_SEVERITY_INFORMATION, "### %08lx..%08x: State=%04x, Protect=%08x\n", pbRegion, pbNext, mbi.State, mbi.Protect); } } Syelog(SYELOG_SEVERITY_INFORMATION, "###\n"); LPVOID lpvEnv = Real_GetEnvironmentStrings(); Syelog(SYELOG_SEVERITY_INFORMATION, "### Env= %08x [%08x %08x]\n", lpvEnv, ((PVOID*)lpvEnv)[0], ((PVOID*)lpvEnv)[1]); printf("%08x\n"); return TRUE; }