├── .gitignore ├── CAPE ├── CAPE.c ├── CAPE.h ├── Debugger.c ├── Debugger.h ├── GetThreadId.c ├── Output.c ├── Scylla │ ├── ApiReader.cpp │ ├── ApiReader.h │ ├── Architecture.h │ ├── DeviceNameResolver.cpp │ ├── DeviceNameResolver.h │ ├── IATReferenceScan.cpp │ ├── IATReferenceScan.h │ ├── IATSearch.cpp │ ├── IATSearch.h │ ├── ImportRebuilder.cpp │ ├── ImportRebuilder.h │ ├── ImportsHandling.cpp │ ├── ImportsHandling.h │ ├── NativeWinApi.cpp │ ├── NativeWinApi.h │ ├── PeParser.cpp │ ├── PeParser.h │ ├── ProcessAccessHelp.cpp │ ├── ProcessAccessHelp.h │ ├── StringConversion.cpp │ ├── StringConversion.h │ ├── SystemInformation.cpp │ ├── SystemInformation.h │ └── Thunks.h ├── ScyllaHarness.cpp ├── w64wow64 │ ├── internal.h │ ├── w64wow64.c │ ├── w64wow64.h │ ├── w64wow64defs.h │ └── windef.h └── wow64_fix.c ├── LICENSE.txt ├── Makefile ├── README.md ├── alloc.c ├── alloc.h ├── bson ├── LICENSE ├── bson.c ├── bson.h ├── bson.sln ├── bson.vcxproj ├── bson.vcxproj.filters ├── encoding.c ├── encoding.h └── numbers.c ├── capstone-config.mk ├── config.c ├── config.h ├── cuckoomon.c ├── cuckoomon.sln ├── cuckoomon.vcxproj ├── cuckoomon.vcxproj.filters ├── distorm ├── COPYING ├── include │ ├── distorm.h │ └── mnemonics.h └── src │ ├── config.h │ ├── decoder.c │ ├── decoder.h │ ├── distorm.c │ ├── instructions.c │ ├── instructions.h │ ├── insts.c │ ├── insts.h │ ├── mnemonics.c │ ├── operands.c │ ├── operands.h │ ├── prefix.c │ ├── prefix.h │ ├── textdefs.c │ ├── textdefs.h │ ├── wstring.c │ ├── wstring.h │ └── x86defs.h ├── hook_crypto.c ├── hook_file.c ├── hook_file.h ├── hook_misc.c ├── hook_network.c ├── hook_process.c ├── hook_reg.c ├── hook_reg_native.c ├── hook_services.c ├── hook_sleep.c ├── hook_sleep.h ├── hook_socket.c ├── hook_special.c ├── hook_sync.c ├── hook_thread.c ├── hook_window.c ├── hooking.c ├── hooking.h ├── hooking_32.c ├── hooking_64.c ├── hooks.h ├── ignore.c ├── ignore.h ├── install.sh ├── loader └── loader │ ├── Loader.c │ ├── Loader.h │ ├── loader.vcxproj │ └── loader.vcxproj.filters ├── log.c ├── log.h ├── lookup.c ├── lookup.h ├── misc.c ├── misc.h ├── ntapi.h ├── pipe.c ├── pipe.h ├── tests ├── Makefile ├── apc-inject.c ├── apihooks.c ├── bind-port.c ├── blacklist.c ├── child-sleep.c ├── crash.c ├── create-file.c ├── delete-file.c ├── getcursorpos.c ├── logging.c ├── lookup.c ├── migrate-process.c ├── mitigate-process.c ├── mousebutton-count.c ├── open-protected-pid.c ├── peb-check.c ├── sleep.c ├── sleep2.c ├── startup-time.c ├── suspended-process.c ├── test-dns.c ├── test-lasterr.c ├── test-lde.c ├── unhook.c ├── wininet.c └── write-file.c ├── unhook.c ├── unhook.h ├── utf8.c └── utf8.h /.gitignore: -------------------------------------------------------------------------------- 1 | logtbl.c 2 | Debug/ 3 | cuckoomon.opensdf 4 | cuckoomon.sdf 5 | cuckoomon.v11.suo 6 | cuckoomon.v12.suo 7 | bson/bson.sdf 8 | bson/bson.v11.suo 9 | bson/bson.v12.suo 10 | bson/bson.vcxproj.user 11 | logtbl.pyc 12 | cuckoomon.vcxproj.user 13 | bson/Release 14 | objects 15 | Release 16 | tests/logging-test.* 17 | *.suo 18 | *.opendb 19 | *.VC.db 20 | .vs/* 21 | -------------------------------------------------------------------------------- /CAPE/CAPE.h: -------------------------------------------------------------------------------- 1 | /* 2 | CAPE - Config And Payload Extraction 3 | Copyright(C) 2015-2017 Context Information Security. (kevin.oreilly@contextis.com) 4 | 5 | This program is free software : you can redistribute it and / or modify 6 | it under the terms of the GNU General Public License as published by 7 | the Free Software Foundation, either version 3 of the License, or 8 | (at your option) any later version. 9 | 10 | This program is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.See the 13 | GNU General Public License for more details. 14 | 15 | You should have received a copy of the GNU General Public License 16 | along with this program.If not, see . 17 | */ 18 | extern HMODULE s_hInst; 19 | extern WCHAR s_wzDllPath[MAX_PATH]; 20 | extern CHAR s_szDllPath[MAX_PATH]; 21 | 22 | //Global debugger switch 23 | #define DEBUGGER_ENABLED 0 24 | 25 | PVOID GetHookCallerBase(); 26 | PVOID GetPageAddress(PVOID Address); 27 | PVOID GetAllocationBase(PVOID Address); 28 | BOOL TranslatePathFromDeviceToLetter(__in TCHAR *DeviceFilePath, __out TCHAR* DriveLetterFilePath, __inout LPDWORD lpdwBufferSize); 29 | BOOL DumpPEsInRange(LPVOID Buffer, SIZE_T Size); 30 | BOOL DumpRegion(PVOID Address); 31 | int DumpMemory(LPVOID Buffer, SIZE_T Size); 32 | int DumpCurrentProcessNewEP(LPVOID NewEP); 33 | int DumpCurrentProcess(); 34 | int DumpProcess(HANDLE hProcess, LPVOID ImageBase); 35 | int DumpPE(LPVOID Buffer); 36 | int ScanForNonZero(LPVOID Buffer, SIZE_T Size); 37 | int ScanPageForNonZero(LPVOID Address); 38 | int ScanForPE(LPVOID Buffer, SIZE_T Size, LPVOID* Offset); 39 | int ScanForDisguisedPE(LPVOID Buffer, SIZE_T Size, LPVOID* Offset); 40 | int IsDisguisedPEHeader(LPVOID Buffer); 41 | int DumpImageInCurrentProcess(LPVOID ImageBase); 42 | void DumpSectionViewsForPid(DWORD Pid); 43 | 44 | SYSTEM_INFO SystemInfo; 45 | PVOID CallingModule; 46 | 47 | typedef struct InjectionSectionView 48 | { 49 | HANDLE SectionHandle; 50 | PVOID LocalView; 51 | SIZE_T ViewSize; 52 | int TargetProcessId; 53 | struct InjectionSectionView *NextSectionView; 54 | } INJECTIONSECTIONVIEW, *PINJECTIONSECTIONVIEW; 55 | 56 | PINJECTIONSECTIONVIEW AddSectionView(HANDLE SectionHandle, PVOID LocalView, SIZE_T ViewSize); 57 | PINJECTIONSECTIONVIEW GetSectionView(HANDLE SectionHandle); 58 | BOOL DropSectionView(PINJECTIONSECTIONVIEW SectionView); 59 | void DumpSectionViewsForPid(DWORD Pid); 60 | void DumpSectionView(PINJECTIONSECTIONVIEW SectionView); 61 | 62 | typedef struct InjectionInfo 63 | { 64 | int ProcessId; 65 | HANDLE ProcessHandle; 66 | DWORD_PTR ImageBase; 67 | DWORD_PTR EntryPoint; 68 | BOOL WriteDetected; 69 | BOOL ImageDumped; 70 | LPVOID BufferBase; 71 | LPVOID StackPointer; 72 | unsigned int BufferSizeOfImage; 73 | HANDLE SectionHandle; 74 | // struct InjectionSectionView *SectionViewList; 75 | struct InjectionInfo *NextInjectionInfo; 76 | } INJECTIONINFO, *PINJECTIONINFO; 77 | 78 | struct InjectionInfo *InjectionInfoList; 79 | 80 | PINJECTIONINFO GetInjectionInfo(DWORD ProcessId); 81 | PINJECTIONINFO CreateInjectionInfo(DWORD ProcessId); 82 | 83 | struct InjectionSectionView *SectionViewList; 84 | 85 | // 86 | // MessageId: STATUS_SUCCESS 87 | // 88 | // MessageText: 89 | // 90 | // STATUS_SUCCESS 91 | // 92 | #define STATUS_SUCCESS ((NTSTATUS)0x00000000L) 93 | 94 | // 95 | // MessageId: STATUS_BAD_COMPRESSION_BUFFER 96 | // 97 | // MessageText: 98 | // 99 | // The specified buffer contains ill-formed data. 100 | // 101 | #define STATUS_BAD_COMPRESSION_BUFFER ((NTSTATUS)0xC0000242L) 102 | 103 | #define PE_HEADER_LIMIT 0x200 // Range to look for PE header within candidate buffer 104 | 105 | #define SIZE_OF_LARGEST_IMAGE ((ULONG)0x77000000) 106 | 107 | #pragma comment(lib, "Wininet.lib") 108 | 109 | #define DATA 0 110 | #define EXECUTABLE 1 111 | #define DLL 2 112 | 113 | #define PLUGX_SIGNATURE 0x5658 // 'XV' 114 | 115 | typedef struct CapeMetadata 116 | { 117 | char* ProcessPath; 118 | char* ModulePath; 119 | DWORD Pid; 120 | DWORD DumpType; 121 | char* TargetProcess; // For injection 122 | DWORD TargetPid; // " 123 | PVOID Address; // For shellcode/modules 124 | SIZE_T Size; // " 125 | } CAPEMETADATA, *PCAPEMETADATA; 126 | 127 | struct CapeMetadata *CapeMetaData; 128 | 129 | BOOL SetCapeMetaData(DWORD DumpType, DWORD TargetPid, HANDLE hTargetProcess, PVOID Address); 130 | 131 | enum { 132 | PROCDUMP = 0, 133 | 134 | COMPRESSION = 1, 135 | 136 | INJECTION_PE = 3, 137 | INJECTION_SHELLCODE = 4, 138 | //INJECTION_RUNPE = 5, 139 | 140 | EXTRACTION_PE = 8, 141 | EXTRACTION_SHELLCODE = 9, 142 | 143 | PLUGX_PAYLOAD = 0x10, 144 | PLUGX_CONFIG = 0x11, 145 | 146 | EVILGRAB_PAYLOAD = 0x14, 147 | EVILGRAB_DATA = 0x15, 148 | 149 | SEDRECO_DATA = 0x20, 150 | 151 | URSNIF_CONFIG = 0x24, 152 | URSNIF_PAYLOAD = 0x25, 153 | 154 | CERBER_CONFIG = 0x30, 155 | CERBER_PAYLOAD = 0x31, 156 | 157 | DATADUMP = 0x66 158 | }; 159 | 160 | HANDLE EvilGrabRegHandle; 161 | -------------------------------------------------------------------------------- /CAPE/Debugger.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #pragma once 3 | 4 | #define DEBUGGER_LAUNCHER 0 5 | #define DisableThreadSuspend 0 6 | 7 | #define BP_EXEC 0x00 8 | #define BP_WRITE 0x01 9 | #define BP_RESERVED 0x02 10 | #define BP_READWRITE 0x03 11 | 12 | #define NUMBER_OF_DEBUG_REGISTERS 4 13 | #define MAX_DEBUG_REGISTER_DATA_SIZE 4 14 | #define DEBUG_REGISTER_DATA_SIZES {1, 2, 4} 15 | #define DEBUG_REGISTER_LENGTH_MASKS {0xFFFFFFFF, 0, 1, 0xFFFFFFFF, 3} 16 | 17 | #define EXECUTABLE_FLAGS (PAGE_EXECUTE | PAGE_EXECUTE_READ | PAGE_EXECUTE_READWRITE | PAGE_EXECUTE_WRITECOPY) 18 | #define WRITABLE_FLAGS (PAGE_READWRITE | PAGE_WRITECOPY | PAGE_EXECUTE_READWRITE | PAGE_EXECUTE_WRITECOPY | PAGE_WRITECOMBINE) 19 | 20 | #define EXTRACTION_MIN_SIZE 0x1001 21 | 22 | #if (NTDDI_VERSION <= NTDDI_WINBLUE) 23 | typedef struct _EXCEPTION_REGISTRATION_RECORD { 24 | struct _EXCEPTION_REGISTRATION_RECORD *Next; 25 | PEXCEPTION_ROUTINE Handler; 26 | } EXCEPTION_REGISTRATION_RECORD; 27 | 28 | typedef EXCEPTION_REGISTRATION_RECORD *PEXCEPTION_REGISTRATION_RECORD; 29 | #endif 30 | 31 | typedef struct BreakpointInfo 32 | { 33 | HANDLE ThreadHandle; 34 | int Register; 35 | int Size; 36 | LPVOID Address; 37 | DWORD Type; 38 | LPVOID Callback; 39 | } BREAKPOINTINFO, *PBREAKPOINTINFO; 40 | 41 | typedef BOOL (cdecl *BREAKPOINT_HANDLER)(PBREAKPOINTINFO, struct _EXCEPTION_POINTERS*); 42 | 43 | typedef struct ThreadBreakpoints 44 | { 45 | DWORD ThreadId; 46 | HANDLE ThreadHandle; 47 | BREAKPOINTINFO BreakpointInfo[4]; 48 | struct ThreadBreakpoints *NextThreadBreakpoints; 49 | } THREADBREAKPOINTS, *PTHREADBREAKPOINTS; 50 | 51 | typedef struct TrackedRegion 52 | { 53 | PVOID BaseAddress; 54 | PVOID ProtectAddress; 55 | SIZE_T RegionSize; 56 | ULONG Protect; 57 | MEMORY_BASIC_INFORMATION MemInfo; 58 | BOOL Committed; 59 | PVOID LastAccessAddress; 60 | PVOID LastWriteAddress; 61 | PVOID LastReadAddress; 62 | BOOL WriteDetected; 63 | BOOL ReadDetected; 64 | PVOID LastAccessBy; 65 | PVOID LastWrittenBy; 66 | PVOID LastReadBy; 67 | BOOL PagesDumped; 68 | BOOL CanDump; 69 | BOOL Guarded; 70 | unsigned int WriteCounter; 71 | // under review 72 | BOOL WriteBreakpointSet; 73 | BOOL PeImageDetected; 74 | BOOL AllocationBaseExecBpSet; 75 | BOOL AllocationWriteDetected; 76 | // 77 | PVOID ExecBp; 78 | unsigned int ExecBpRegister; 79 | PVOID MagicBp; 80 | unsigned int MagicBpRegister; 81 | BOOL BreakpointsSet; 82 | BOOL BreakpointsSaved; 83 | struct ThreadBreakpoints *TrackedRegionBreakpoints; 84 | struct TrackedRegion *NextTrackedRegion; 85 | } TRACKEDREGION, *PTRACKEDREGION; 86 | 87 | struct TrackedRegion *TrackedRegionList; 88 | 89 | typedef BOOL (cdecl *SINGLE_STEP_HANDLER)(struct _EXCEPTION_POINTERS*); 90 | typedef BOOL (cdecl *GUARD_PAGE_HANDLER)(struct _EXCEPTION_POINTERS*); 91 | typedef BOOL (cdecl *SAMPLE_HANDLER)(struct _EXCEPTION_POINTERS*); 92 | 93 | typedef void (WINAPI *PWIN32ENTRY)(); 94 | 95 | #ifdef __cplusplus 96 | extern "C" { 97 | #endif 98 | 99 | BOOL DebuggerInitialised; 100 | 101 | // Global variables for submission options 102 | void *CAPE_var1, *CAPE_var2, *CAPE_var3, *CAPE_var4; 103 | PVOID bp0, bp1, bp2, bp3; 104 | 105 | LONG WINAPI CAPEExceptionFilter(struct _EXCEPTION_POINTERS* ExceptionInfo); 106 | PVOID CAPEExceptionFilterHandle; 107 | SAMPLE_HANDLER SampleVectoredHandler; 108 | PEXCEPTION_ROUTINE SEH_TopLevelHandler; 109 | LPTOP_LEVEL_EXCEPTION_FILTER OriginalExceptionHandler; 110 | BOOL VECTORED_HANDLER; 111 | BOOL GuardPagesDisabled; 112 | 113 | DWORD ChildProcessId; 114 | DWORD ChildThreadId; 115 | DWORD_PTR DebuggerEP; 116 | PWIN32ENTRY OEP; 117 | 118 | int launch_debugger(void); 119 | 120 | // Set 121 | BOOL SetBreakpoint(int Register, int Size, LPVOID Address, DWORD Type, PVOID Callback); 122 | BOOL SetThreadBreakpoint(DWORD ThreadId, int Register, int Size, LPVOID Address, DWORD Type, PVOID Callback); 123 | BOOL ContextSetThreadBreakpoint(PCONTEXT Context, int Register, int Size, LPVOID Address, DWORD Type, PVOID Callback); 124 | BOOL ContextSetDebugRegister(PCONTEXT Context, int Register, int Size, LPVOID Address, DWORD Type); 125 | BOOL SetThreadBreakpoints(PTHREADBREAKPOINTS ThreadBreakpoints); 126 | BOOL ContextSetBreakpoint(PTHREADBREAKPOINTS ThreadBreakpoints); 127 | BOOL ContextUpdateCurrentBreakpoint(PCONTEXT Context, int Size, LPVOID Address, DWORD Type, PVOID Callback); 128 | BOOL SetNextAvailableBreakpoint(DWORD ThreadId, unsigned int* Register, int Size, LPVOID Address, DWORD Type, PVOID Callback); 129 | BOOL SetSingleStepMode(PCONTEXT Context, PVOID Handler); 130 | BOOL SetResumeFlag(PCONTEXT Context); 131 | BOOL SetZeroFlag(PCONTEXT Context); 132 | BOOL ClearZeroFlag(PCONTEXT Context); 133 | PTHREADBREAKPOINTS CreateThreadBreakpoints(DWORD ThreadId); 134 | 135 | // Get 136 | BOOL GetNextAvailableBreakpoint(DWORD ThreadId, unsigned int* Register); 137 | PTHREADBREAKPOINTS GetThreadBreakpoints(DWORD ThreadId); 138 | BOOL ContextGetNextAvailableBreakpoint(PCONTEXT Context, unsigned int* Register); 139 | BOOL ContextSetNextAvailableBreakpoint(PCONTEXT Context, unsigned int* Register, int Size, LPVOID Address, DWORD Type, PVOID Callback); 140 | int CheckDebugRegister(HANDLE hThread, int Register); 141 | BOOL CheckDebugRegisters(HANDLE hThread, PCONTEXT pContext); 142 | int ContextCheckDebugRegister(CONTEXT Context, int Register); 143 | BOOL ContextCheckDebugRegisters(PCONTEXT pContext); 144 | HANDLE GetThreadHandle(DWORD ThreadId); 145 | 146 | // Clear 147 | BOOL ClearBreakpoint(DWORD ThreadId, int Register); 148 | BOOL ClearBreakpointsInRange(DWORD ThreadId, PVOID BaseAddress, SIZE_T Size); 149 | BOOL ContextClearBreakpoint(PCONTEXT Context, PBREAKPOINTINFO pBreakpointInfo); 150 | BOOL ContextClearCurrentBreakpoint(PCONTEXT Context); 151 | BOOL ContextClearAllBreakpoints(PCONTEXT Context); 152 | BOOL ClearAllBreakpoints(); 153 | BOOL ClearSingleStepMode(PCONTEXT Context); 154 | 155 | // Misc 156 | BOOL InitNewThreadBreakpoints(DWORD ThreadId); 157 | BOOL InitialiseDebugger(void); 158 | BOOL DebugNewProcess(unsigned int ProcessId, unsigned int ThreadId, DWORD CreationFlags); 159 | BOOL SendDebuggerMessage(PVOID Input); 160 | BOOL StepOverExecutionBreakpoint(PCONTEXT Context, PBREAKPOINTINFO pBreakpointInfo); 161 | BOOL ResumeAfterExecutionBreakpoint(PCONTEXT Context, PBREAKPOINTINFO pBreakpointInfo); 162 | 163 | void ShowStack(DWORD_PTR StackPointer, unsigned int NumberOfRecords); 164 | 165 | BOOL IsInTrackedRegions(PVOID Address); 166 | PTRACKEDREGION CreateTrackedRegions(); 167 | PTRACKEDREGION GetTrackedRegion(PVOID Address); 168 | PTRACKEDREGION AddTrackedRegion(PVOID Address, SIZE_T RegionSize, ULONG Protect); 169 | BOOL DropTrackedRegion(PTRACKEDREGION TrackedRegion); 170 | BOOL ActivateGuardPages(PTRACKEDREGION TrackedRegion); 171 | BOOL ActivateGuardPagesOnProtectedRange(PTRACKEDREGION TrackedRegion); 172 | BOOL DeactivateGuardPages(PTRACKEDREGION TrackedRegion); 173 | BOOL ActivateSurroundingGuardPages(PTRACKEDREGION TrackedRegion); 174 | 175 | #ifdef __cplusplus 176 | } 177 | #endif -------------------------------------------------------------------------------- /CAPE/GetThreadId.c: -------------------------------------------------------------------------------- 1 | /* 2 | CAPE - Config And Payload Extraction 3 | Copyright(C) 2015, 2016 Context Information Security. (kevin.oreilly@contextis.com) 4 | 5 | This program is free software : you can redistribute it and / or modify 6 | it under the terms of the GNU General Public License as published by 7 | the Free Software Foundation, either version 3 of the License, or 8 | (at your option) any later version. 9 | 10 | This program is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.See the 13 | GNU General Public License for more details. 14 | 15 | You should have received a copy of the GNU General Public License 16 | along with this program.If not, see . 17 | */ 18 | #include 19 | 20 | #define STATUS_SUCCESS ((NTSTATUS) 0x00000000) 21 | typedef LONG NTSTATUS; 22 | typedef LONG KPRIORITY; 23 | typedef PVOID PTEB; 24 | 25 | // 26 | // Thread Information Classes 27 | // 28 | 29 | typedef enum _THREADINFOCLASS 30 | { 31 | ThreadBasicInformation, 32 | ThreadTimes, 33 | ThreadPriority, 34 | ThreadBasePriority, 35 | ThreadAffinityMask, 36 | ThreadImpersonationToken, 37 | ThreadDescriptorTableEntry, 38 | ThreadEnableAlignmentFaultFixup, 39 | ThreadEventPair_Reusable, 40 | ThreadQuerySetWin32StartAddress, 41 | ThreadZeroTlsCell, 42 | ThreadPerformanceCount, 43 | ThreadAmILastThread, 44 | ThreadIdealProcessor, 45 | ThreadPriorityBoost, 46 | ThreadSetTlsArrayAddress, 47 | ThreadIsIoPending, 48 | ThreadHideFromDebugger, 49 | ThreadBreakOnTermination, 50 | ThreadSwitchLegacyState, 51 | ThreadIsTerminated, 52 | MaxThreadInfoClass 53 | } THREADINFOCLASS; 54 | 55 | typedef struct _CLIENT_ID 56 | { 57 | HANDLE UniqueProcess; 58 | HANDLE UniqueThread; 59 | } CLIENT_ID, *PCLIENT_ID; 60 | 61 | // 62 | // Thread Information Structures 63 | // 64 | 65 | // 66 | // Basic Thread Information 67 | // NtQueryInformationThread using ThreadBasicInfo 68 | // 69 | 70 | typedef struct _THREAD_BASIC_INFORMATION 71 | { 72 | NTSTATUS ExitStatus; 73 | PTEB TebBaseAddress; 74 | CLIENT_ID ClientId; 75 | ULONG_PTR AffinityMask; 76 | KPRIORITY Priority; 77 | LONG BasePriority; 78 | } THREAD_BASIC_INFORMATION; 79 | typedef THREAD_BASIC_INFORMATION *PTHREAD_BASIC_INFORMATION; 80 | 81 | typedef NTSTATUS (__stdcall *pfnNtQueryInformationThread) 82 | ( 83 | __in HANDLE ThreadHandle, 84 | __in THREADINFOCLASS ThreadInformationClass, 85 | __out_bcount(ThreadInformationLength) PVOID ThreadInformation, 86 | __in ULONG ThreadInformationLength, 87 | __out_opt PULONG ReturnLength 88 | ); 89 | 90 | pfnNtQueryInformationThread NtQueryInformationThread; 91 | 92 | //************************************************************************************** 93 | DWORD MyGetThreadId 94 | //************************************************************************************** 95 | ( 96 | _In_ HANDLE Thread 97 | ) 98 | { 99 | THREAD_BASIC_INFORMATION ThreadBasicInfo; 100 | THREADINFOCLASS ThreadInfoClass; 101 | HMODULE hModule; 102 | 103 | if (Thread == NULL) 104 | return 0; 105 | 106 | hModule = LoadLibrary("ntdll.dll"); 107 | NtQueryInformationThread = (pfnNtQueryInformationThread) GetProcAddress(hModule, "NtQueryInformationThread"); 108 | if (NtQueryInformationThread == NULL) 109 | return 0; 110 | 111 | ThreadInfoClass = ThreadBasicInformation; 112 | if (NtQueryInformationThread(Thread, ThreadInfoClass, &ThreadBasicInfo, sizeof(ThreadBasicInfo), NULL) != STATUS_SUCCESS) 113 | { 114 | FreeLibrary(hModule); 115 | return 0; 116 | } 117 | 118 | FreeLibrary(hModule); 119 | 120 | return (DWORD)(UINT_PTR)ThreadBasicInfo.ClientId.UniqueThread; 121 | } 122 | -------------------------------------------------------------------------------- /CAPE/Scylla/ApiReader.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | #include "ProcessAccessHelp.h" 7 | #include "Thunks.h" 8 | 9 | typedef std::pair API_Pair; 10 | 11 | class ApiReader : public ProcessAccessHelp 12 | { 13 | public: 14 | static stdext::hash_multimap apiList; //api look up table 15 | 16 | static std::map * moduleThunkList; //store found apis 17 | 18 | static DWORD_PTR minApiAddress; 19 | static DWORD_PTR maxApiAddress; 20 | 21 | /* 22 | * Read all APIs from target process 23 | */ 24 | void readApisFromModuleList(); 25 | 26 | bool isApiAddressValid(DWORD_PTR virtualAddress); 27 | ApiInfo * getApiByVirtualAddress(DWORD_PTR virtualAddress, bool * isSuspect); 28 | void readAndParseIAT(DWORD_PTR addressIAT, DWORD sizeIAT, std::map &moduleListNew ); 29 | void addFoundApiToModuleList(DWORD_PTR iatAddress, ApiInfo * apiFound, bool isNewModule, bool isSuspect); 30 | void clearAll(); 31 | bool isInvalidMemoryForIat( DWORD_PTR address ); 32 | void parseModuleWithOwnProcess( ModuleInfo * module ); 33 | private: 34 | bool readExportTableAlwaysFromDisk; 35 | void parseIAT(DWORD_PTR addressIAT, BYTE * iatBuffer, SIZE_T size); 36 | 37 | void addApi(char *functionName, WORD hint, WORD ordinal, DWORD_PTR va, DWORD_PTR rva, bool isForwarded, ModuleInfo *moduleInfo); 38 | void addApiWithoutName(WORD ordinal, DWORD_PTR va, DWORD_PTR rva,bool isForwarded, ModuleInfo *moduleInfo); 39 | inline bool isApiForwarded(DWORD_PTR rva, PIMAGE_NT_HEADERS pNtHeader); 40 | void handleForwardedApi(DWORD_PTR vaStringPointer,char *functionNameParent,DWORD_PTR rvaParent, WORD ordinalParent, ModuleInfo *moduleParent); 41 | void parseModule(ModuleInfo *module); 42 | void parseModuleWithProcess(ModuleInfo * module); 43 | 44 | void parseExportTable(ModuleInfo *module, PIMAGE_NT_HEADERS pNtHeader, PIMAGE_EXPORT_DIRECTORY pExportDir, DWORD_PTR deltaAddress); 45 | 46 | ModuleInfo * findModuleByName(CHAR *name); 47 | 48 | void findApiByModuleAndOrdinal(ModuleInfo * module, WORD ordinal, DWORD_PTR * vaApi, DWORD_PTR * rvaApi); 49 | void findApiByModuleAndName(ModuleInfo * module, char * searchFunctionName, DWORD_PTR * vaApi, DWORD_PTR * rvaApi); 50 | void findApiByModule(ModuleInfo * module, char * searchFunctionName, WORD ordinal, DWORD_PTR * vaApi, DWORD_PTR * rvaApi); 51 | 52 | bool isModuleLoadedInOwnProcess( ModuleInfo * module ); 53 | bool isPeAndExportTableValid(PIMAGE_NT_HEADERS pNtHeader); 54 | void findApiInProcess( ModuleInfo * module, char * searchFunctionName, WORD ordinal, DWORD_PTR * vaApi, DWORD_PTR * rvaApi ); 55 | bool findApiInExportTable(ModuleInfo *module, PIMAGE_EXPORT_DIRECTORY pExportDir, DWORD_PTR deltaAddress, char * searchFunctionName, WORD ordinal, DWORD_PTR * vaApi, DWORD_PTR * rvaApi); 56 | 57 | BYTE * getHeaderFromProcess(ModuleInfo * module); 58 | BYTE * getExportTableFromProcess(ModuleInfo * module, PIMAGE_NT_HEADERS pNtHeader); 59 | 60 | void setModulePriority(ModuleInfo * module); 61 | void setMinMaxApiAddress(DWORD_PTR virtualAddress); 62 | 63 | void parseModuleWithMapping(ModuleInfo *moduleInfo); //not used 64 | 65 | bool addModuleToModuleList(const CHAR * moduleName, DWORD_PTR firstThunk); 66 | bool addFunctionToModuleList(ApiInfo * apiFound, DWORD_PTR va, DWORD_PTR rva, WORD ordinal, bool valid, bool suspect); 67 | bool addNotFoundApiToModuleList(DWORD_PTR iatAddressVA, DWORD_PTR apiAddress); 68 | 69 | void addUnknownModuleToModuleList(DWORD_PTR firstThunk); 70 | bool isApiBlacklisted( const char * functionName ); 71 | bool isWinSxSModule( ModuleInfo * module ); 72 | 73 | ApiInfo * getScoredApi(stdext::hash_map::iterator it1,size_t countDuplicates, bool hasName, bool hasUnicodeAnsiName, bool hasNoUnderlineInName, bool hasPrioDll,bool hasPrio0Dll,bool hasPrio1Dll, bool hasPrio2Dll, bool firstWin ); 74 | 75 | }; 76 | -------------------------------------------------------------------------------- /CAPE/Scylla/Architecture.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | #ifdef _WIN64 6 | 7 | #define ARCHITECTURE_S "x64" 8 | #define PRINTF_DWORD_PTR_S "%I64X" 9 | #define PRINTF_DWORD_PTR_FULL_S "%016I64X" 10 | #define PRINTF_DWORD_PTR_HALF_S "%08I64X" 11 | #define PRINTF_INTEGER_S "%I64u" 12 | 13 | #else 14 | 15 | #define ARCHITECTURE_S "x86" 16 | #define PRINTF_DWORD_PTR_S "%X" 17 | #define PRINTF_DWORD_PTR_FULL_S "%08X" 18 | #define PRINTF_DWORD_PTR_HALF_S "%08X" 19 | #define PRINTF_INTEGER_S "%u" 20 | 21 | #endif 22 | 23 | #define ARCHITECTURE TEXT(ARCHITECTURE_S) 24 | #define PRINTF_DWORD_PTR TEXT(PRINTF_DWORD_PTR_S) 25 | #define PRINTF_DWORD_PTR_FULL TEXT(PRINTF_DWORD_PTR_FULL_S) 26 | #define PRINTF_DWORD_PTR_HALF TEXT(PRINTF_DWORD_PTR_HALF_S) 27 | #define PRINTF_INTEGER TEXT(PRINTF_INTEGER_S) 28 | -------------------------------------------------------------------------------- /CAPE/Scylla/DeviceNameResolver.cpp: -------------------------------------------------------------------------------- 1 | 2 | #include "DeviceNameResolver.h" 3 | #include "NativeWinApi.h" 4 | 5 | DeviceNameResolver::DeviceNameResolver() 6 | { 7 | NativeWinApi::initialize(); 8 | initDeviceNameList(); 9 | } 10 | 11 | DeviceNameResolver::~DeviceNameResolver() 12 | { 13 | deviceNameList.clear(); 14 | } 15 | 16 | void DeviceNameResolver::initDeviceNameList() 17 | { 18 | WCHAR shortName[3] = {0}; 19 | WCHAR longName[MAX_PATH] = {0}; 20 | HardDisk hardDisk; 21 | 22 | shortName[1] = TEXT(':'); 23 | 24 | deviceNameList.reserve(3); 25 | 26 | for ( TCHAR shortD = TEXT('a'); shortD <= TEXT('z'); shortD++ ) 27 | { 28 | shortName[0] = shortD; 29 | if (QueryDosDeviceW( shortName, longName, MAX_PATH ) > 0) 30 | { 31 | hardDisk.shortName[0] = _totupper(shortD); 32 | hardDisk.shortName[1] = TEXT(':'); 33 | hardDisk.shortName[2] = 0; 34 | 35 | hardDisk.longNameLength = wcslen(longName); 36 | 37 | 38 | wcscpy_s(hardDisk.longName, longName); 39 | deviceNameList.push_back(hardDisk); 40 | } 41 | } 42 | 43 | fixVirtualDevices(); 44 | } 45 | 46 | bool DeviceNameResolver::resolveDeviceLongNameToShort(const WCHAR * sourcePath, WCHAR * targetPath) 47 | { 48 | for (unsigned int i = 0; i < deviceNameList.size(); i++) 49 | { 50 | if (!_wcsnicmp(deviceNameList[i].longName, sourcePath, deviceNameList[i].longNameLength) && sourcePath[deviceNameList[i].longNameLength] == TEXT('\\')) 51 | { 52 | wcscpy_s(targetPath, MAX_PATH, deviceNameList[i].shortName); 53 | wcscat_s(targetPath, MAX_PATH, sourcePath + deviceNameList[i].longNameLength); 54 | return true; 55 | } 56 | } 57 | 58 | return false; 59 | } 60 | 61 | void DeviceNameResolver::fixVirtualDevices() 62 | { 63 | const USHORT BufferSize = MAX_PATH * 2 * sizeof(WCHAR); 64 | WCHAR longCopy[MAX_PATH] = {0}; 65 | OBJECT_ATTRIBUTES oa = {0}; 66 | UNICODE_STRING unicodeInput = {0}; 67 | UNICODE_STRING unicodeOutput = {0}; 68 | HANDLE hFile = 0; 69 | ULONG retLen = 0; 70 | HardDisk hardDisk; 71 | 72 | unicodeOutput.Buffer = (PWSTR)malloc(BufferSize); 73 | if (!unicodeOutput.Buffer) 74 | return; 75 | 76 | for (unsigned int i = 0; i < deviceNameList.size(); i++) 77 | { 78 | wcscpy_s(longCopy, deviceNameList[i].longName); 79 | 80 | NativeWinApi::RtlInitUnicodeString(&unicodeInput, longCopy); 81 | InitializeObjectAttributes(&oa, &unicodeInput, 0, 0, 0); 82 | 83 | if(NT_SUCCESS(NativeWinApi::NtOpenSymbolicLinkObject(&hFile, SYMBOLIC_LINK_QUERY, &oa))) 84 | { 85 | unicodeOutput.Length = BufferSize; 86 | unicodeOutput.MaximumLength = unicodeOutput.Length; 87 | ZeroMemory(unicodeOutput.Buffer, unicodeOutput.Length); 88 | 89 | if (NT_SUCCESS(NativeWinApi::NtQuerySymbolicLinkObject(hFile, &unicodeOutput, &retLen))) 90 | { 91 | hardDisk.longNameLength = wcslen(unicodeOutput.Buffer); 92 | wcscpy_s(hardDisk.shortName, deviceNameList[i].shortName); 93 | wcscpy_s(hardDisk.longName, unicodeOutput.Buffer); 94 | deviceNameList.push_back(hardDisk); 95 | } 96 | 97 | NativeWinApi::NtClose(hFile); 98 | } 99 | } 100 | 101 | free(unicodeOutput.Buffer); 102 | } 103 | 104 | -------------------------------------------------------------------------------- /CAPE/Scylla/DeviceNameResolver.h: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | 4 | #pragma once 5 | 6 | #include 7 | #include 8 | #include 9 | 10 | class HardDisk { 11 | public: 12 | WCHAR shortName[3]; 13 | WCHAR longName[MAX_PATH]; 14 | size_t longNameLength; 15 | }; 16 | 17 | class DeviceNameResolver 18 | { 19 | public: 20 | DeviceNameResolver(); 21 | ~DeviceNameResolver(); 22 | bool resolveDeviceLongNameToShort(const WCHAR * sourcePath, WCHAR * targetPath); 23 | private: 24 | std::vector deviceNameList; 25 | 26 | void initDeviceNameList(); 27 | void fixVirtualDevices(); 28 | }; 29 | 30 | -------------------------------------------------------------------------------- /CAPE/Scylla/IATReferenceScan.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | #include "ProcessAccessHelp.h" 4 | #include "PeParser.h" 5 | #include "ApiReader.h" 6 | 7 | enum IATReferenceType { 8 | IAT_REFERENCE_PTR_JMP, 9 | IAT_REFERENCE_PTR_CALL, 10 | IAT_REFERENCE_DIRECT_JMP, 11 | IAT_REFERENCE_DIRECT_CALL, 12 | IAT_REFERENCE_DIRECT_MOV, 13 | IAT_REFERENCE_DIRECT_PUSH, 14 | IAT_REFERENCE_DIRECT_LEA 15 | }; 16 | 17 | class IATReference 18 | { 19 | public: 20 | DWORD_PTR addressVA; //Address of reference 21 | DWORD_PTR targetPointer; //Place inside IAT 22 | DWORD_PTR targetAddressInIat; //WIN API? 23 | BYTE instructionSize; 24 | IATReferenceType type; 25 | }; 26 | 27 | 28 | class IATReferenceScan 29 | { 30 | public: 31 | 32 | IATReferenceScan() 33 | { 34 | apiReader = 0; 35 | IatAddressVA = 0; 36 | IatSize = 0; 37 | ImageBase = 0; 38 | ImageSize = 0; 39 | iatBackup = 0; 40 | ScanForDirectImports = false; 41 | ScanForNormalImports = true; 42 | } 43 | 44 | ~IATReferenceScan() 45 | { 46 | iatReferenceList.clear(); 47 | iatDirectImportList.clear(); 48 | 49 | if (iatBackup) 50 | { 51 | free(iatBackup); 52 | } 53 | } 54 | 55 | bool ScanForDirectImports; 56 | bool ScanForNormalImports; 57 | bool JunkByteAfterInstruction; 58 | ApiReader * apiReader; 59 | 60 | void startScan(DWORD_PTR imageBase, DWORD imageSize, DWORD_PTR iatAddress, DWORD iatSize); 61 | //void patchNewIatBaseMemory(DWORD_PTR newIatBaseAddress); 62 | //void patchNewIatBaseFile(DWORD_PTR newIatBaseAddress); 63 | 64 | void patchNewIat(DWORD_PTR stdImagebase, DWORD_PTR newIatBaseAddress, PeParser * peParser); 65 | void patchDirectJumpTable( DWORD_PTR imageBase, DWORD directImportsJumpTableRVA, PeParser * peParser, BYTE * jmpTableMemory, DWORD newIatBase); 66 | void patchDirectImportsMemory(bool junkByteAfterInstruction); 67 | int numberOfFoundDirectImports(); 68 | int numberOfFoundUniqueDirectImports(); 69 | int numberOfDirectImportApisNotInIat(); 70 | int getSizeInBytesOfJumpTableInSection(); 71 | //static FileLog directImportLog; 72 | void printDirectImportLog(); 73 | void changeIatBaseOfDirectImports( DWORD newIatBaseAddressRVA ); 74 | DWORD addAdditionalApisToList(); 75 | private: 76 | DWORD_PTR NewIatAddressRVA; 77 | 78 | DWORD_PTR IatAddressVA; 79 | DWORD IatSize; 80 | DWORD_PTR ImageBase; 81 | DWORD ImageSize; 82 | 83 | 84 | DWORD_PTR * iatBackup; 85 | 86 | std::vector iatReferenceList; 87 | std::vector iatDirectImportList; 88 | 89 | void scanMemoryPage( PVOID BaseAddress, SIZE_T RegionSize ); 90 | void analyzeInstruction( _DInst * instruction ); 91 | void findNormalIatReference( _DInst * instruction ); 92 | void getIatEntryAddress( IATReference* ref ); 93 | void findDirectIatReferenceCallJmp( _DInst * instruction ); 94 | bool isAddressValidImageMemory( DWORD_PTR address ); 95 | void patchReferenceInMemory( IATReference * ref ); 96 | void patchReferenceInFile( IATReference* ref ); 97 | void patchDirectImportInMemory( IATReference * iter ); 98 | DWORD_PTR lookUpIatForPointer( DWORD_PTR addr ); 99 | void findDirectIatReferenceMov( _DInst * instruction ); 100 | void findDirectIatReferencePush( _DInst * instruction ); 101 | void checkMemoryRangeAndAddToList( IATReference * ref, _DInst * instruction ); 102 | void findDirectIatReferenceLea( _DInst * instruction ); 103 | void patchDirectImportInDump32( int patchPreFixBytes, int instructionSize, DWORD patchBytes, BYTE * memory, DWORD memorySize, bool generateReloc, DWORD patchOffset, DWORD sectionRVA ); 104 | void patchDirectImportInDump64( int patchPreFixBytes, int instructionSize, DWORD_PTR patchBytes, BYTE * memory, DWORD memorySize, bool generateReloc, DWORD patchOffset, DWORD sectionRVA ); 105 | void patchDirectJumpTableEntry(DWORD_PTR targetIatPointer, DWORD_PTR stdImagebase, DWORD directImportsJumpTableRVA, PeParser * peParser, BYTE * jmpTableMemory, DWORD newIatBase ); 106 | 107 | 108 | }; 109 | 110 | /* 111 | PE64 112 | ---------- 113 | 000000013FF82D87 FF15 137C0A00 CALL QWORD [RIP+0xA7C13] 114 | Result: 000000014002A9A0 115 | 116 | 000000013F65C952 FF25 F8EA0B00 JMP QWORD [RIP+0xBEAF8] 117 | Result: 000000013F71B450 118 | 119 | PE32 120 | ---------- 121 | 0120FFA5 FF15 8C6D2601 CALL DWORD [0x01266D8C] 122 | 123 | 0120FF52 FF25 D4722601 JMP DWORD [0x012672D4] 124 | */ 125 | 126 | -------------------------------------------------------------------------------- /CAPE/Scylla/IATSearch.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "ApiReader.h" 4 | #include 5 | 6 | class IATSearch : protected ApiReader 7 | { 8 | public: 9 | 10 | DWORD_PTR memoryAddress; 11 | SIZE_T memorySize; 12 | 13 | bool searchImportAddressTableInProcess(DWORD_PTR startAddress, DWORD_PTR* addressIAT, DWORD* sizeIAT, bool advanced); 14 | 15 | private: 16 | 17 | DWORD_PTR findAPIAddressInIAT(DWORD_PTR startAddress); 18 | bool findIATAdvanced(DWORD_PTR startAddress,DWORD_PTR* addressIAT, DWORD* sizeIAT); 19 | DWORD_PTR findNextFunctionAddress(); 20 | DWORD_PTR findIATPointer(); 21 | //DWORD_PTR findAddressFromWORDString(char * stringBuffer); 22 | //DWORD_PTR findAddressFromNormalCALLString(char * stringBuffer); 23 | bool isIATPointerValid(DWORD_PTR iatPointer, bool checkRedirects); 24 | 25 | bool findIATStartAndSize(DWORD_PTR address, DWORD_PTR * addressIAT, DWORD * sizeIAT); 26 | 27 | DWORD_PTR findIATStartAddress( DWORD_PTR baseAddress, DWORD_PTR startAddress, BYTE * dataBuffer ); 28 | DWORD findIATSize( DWORD_PTR baseAddress, DWORD_PTR iatAddress, BYTE * dataBuffer, DWORD bufferSize ); 29 | 30 | void findIATPointers(std::set & iatPointers); 31 | void findExecutableMemoryPagesByStartAddress( DWORD_PTR startAddress, DWORD_PTR* baseAddress, SIZE_T* memorySize ); 32 | void filterIATPointersList( std::set & iatPointers ); 33 | void getMemoryBaseAndSizeForIat( DWORD_PTR address, DWORD_PTR* baseAddress, DWORD* baseSize ); 34 | }; 35 | -------------------------------------------------------------------------------- /CAPE/Scylla/ImportRebuilder.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include "PeParser.h" 5 | #include "Thunks.h" 6 | #include "IATReferenceScan.h" 7 | 8 | 9 | class ImportRebuilder : public PeParser { 10 | public: 11 | ImportRebuilder(const CHAR * file) : PeParser(file, true) 12 | { 13 | pImportDescriptor = 0; 14 | pThunkData = 0; 15 | pImportByName = 0; 16 | 17 | numberOfImportDescriptors = 0; 18 | sizeOfImportSection = 0; 19 | sizeOfApiAndModuleNames = 0; 20 | importSectionIndex = 0; 21 | useOFT = false; 22 | sizeOfOFTArray = 0; 23 | newIatInSection = false; 24 | BuildDirectImportsJumpTable = false; 25 | sizeOfJumpTable = 0; 26 | } 27 | 28 | ImportRebuilder(const DWORD_PTR moduleBase) : PeParser(moduleBase, true) 29 | { 30 | pImportDescriptor = 0; 31 | pThunkData = 0; 32 | pImportByName = 0; 33 | 34 | numberOfImportDescriptors = 0; 35 | sizeOfImportSection = 0; 36 | sizeOfApiAndModuleNames = 0; 37 | importSectionIndex = 0; 38 | useOFT = false; 39 | sizeOfOFTArray = 0; 40 | newIatInSection = false; 41 | BuildDirectImportsJumpTable = false; 42 | sizeOfJumpTable = 0; 43 | } 44 | 45 | bool rebuildImportTable(const CHAR * newFilePath, std::map & moduleList); 46 | void enableOFTSupport(); 47 | void enableNewIatInSection(DWORD_PTR iatAddress, DWORD iatSize); 48 | 49 | IATReferenceScan * iatReferenceScan; 50 | bool BuildDirectImportsJumpTable; 51 | private: 52 | PIMAGE_IMPORT_DESCRIPTOR pImportDescriptor; 53 | PIMAGE_THUNK_DATA pThunkData; 54 | PIMAGE_IMPORT_BY_NAME pImportByName; 55 | 56 | size_t numberOfImportDescriptors; 57 | size_t sizeOfImportSection; 58 | size_t sizeOfApiAndModuleNames; 59 | size_t importSectionIndex; 60 | 61 | //OriginalFirstThunk Array in Import Section 62 | size_t sizeOfOFTArray; 63 | bool useOFT; 64 | bool newIatInSection; 65 | DWORD_PTR IatAddress; 66 | 67 | DWORD IatSize; 68 | 69 | DWORD sizeOfJumpTable; 70 | 71 | DWORD directImportsJumpTableRVA; 72 | BYTE * JMPTableMemory; 73 | DWORD newIatBaseAddressRVA; 74 | 75 | 76 | DWORD fillImportSection(std::map & moduleList); 77 | BYTE * getMemoryPointerFromRVA(DWORD_PTR dwRVA); 78 | 79 | bool createNewImportSection(std::map & moduleList); 80 | bool buildNewImportTable(std::map & moduleList); 81 | void setFlagToIATSection(DWORD_PTR iatAddress); 82 | size_t addImportToImportTable( ImportThunk * pImport, PIMAGE_THUNK_DATA pThunk, PIMAGE_IMPORT_BY_NAME pImportByName, DWORD sectionOffset); 83 | size_t addImportDescriptor(ImportModuleThunk * pImportModule, DWORD sectionOffset, DWORD sectionOffsetOFTArray); 84 | 85 | void calculateImportSizes(std::map & moduleList); 86 | 87 | void addSpecialImportDescriptor(DWORD_PTR rvaFirstThunk, DWORD sectionOffsetOFTArray); 88 | void patchFileForNewIatLocation(); 89 | void changeIatBaseAddress( std::map & moduleList ); 90 | void patchFileForDirectImportJumpTable(); 91 | }; -------------------------------------------------------------------------------- /CAPE/Scylla/ImportsHandling.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | 7 | class ImportThunk; 8 | class ImportModuleThunk; 9 | 10 | class ImportsHandling 11 | { 12 | public: 13 | std::map moduleList; 14 | std::map moduleListNew; 15 | 16 | ImportsHandling(); 17 | ~ImportsHandling(); 18 | 19 | unsigned int thunkCount() const { return m_thunkCount; } 20 | unsigned int invalidThunkCount() const { return m_invalidThunkCount; } 21 | unsigned int suspectThunkCount() const { return m_suspectThunkCount; } 22 | 23 | void clearAllImports(); 24 | void selectImports(bool invalid, bool suspect); 25 | 26 | void scanAndFixModuleList(); 27 | 28 | private: 29 | DWORD numberOfFunctions; 30 | 31 | unsigned int m_thunkCount; 32 | unsigned int m_invalidThunkCount; 33 | unsigned int m_suspectThunkCount; 34 | 35 | CHAR stringBuffer[600]; 36 | 37 | void updateCounts(); 38 | 39 | bool findNewModules(std::map & thunkList); 40 | 41 | bool addModuleToModuleList(const CHAR * moduleName, DWORD_PTR firstThunk); 42 | void addUnknownModuleToModuleList(DWORD_PTR firstThunk); 43 | bool addNotFoundApiToModuleList(const ImportThunk * apiNotFound); 44 | bool addFunctionToModuleList(const ImportThunk * apiFound); 45 | bool isNewModule(const CHAR * moduleName); 46 | }; 47 | -------------------------------------------------------------------------------- /CAPE/Scylla/NativeWinApi.cpp: -------------------------------------------------------------------------------- 1 | #include "NativeWinApi.h" 2 | 3 | def_NtCreateThreadEx NativeWinApi::NtCreateThreadEx = 0; 4 | def_NtDuplicateObject NativeWinApi::NtDuplicateObject = 0; 5 | def_NtOpenProcess NativeWinApi::NtOpenProcess = 0; 6 | def_NtOpenThread NativeWinApi::NtOpenThread = 0; 7 | def_NtQueryObject NativeWinApi::NtQueryObject = 0; 8 | def_NtQueryInformationFile NativeWinApi::NtQueryInformationFile = 0; 9 | def_NtQueryInformationProcess NativeWinApi::NtQueryInformationProcess = 0; 10 | def_NtQueryInformationThread NativeWinApi::NtQueryInformationThread = 0; 11 | def_NtQuerySystemInformation NativeWinApi::NtQuerySystemInformation = 0; 12 | def_NtQueryVirtualMemory NativeWinApi::NtQueryVirtualMemory = 0; 13 | def_NtResumeProcess NativeWinApi::NtResumeProcess = 0; 14 | def_NtResumeThread NativeWinApi::NtResumeThread = 0; 15 | def_NtSetInformationThread NativeWinApi::NtSetInformationThread = 0; 16 | def_NtSuspendProcess NativeWinApi::NtSuspendProcess = 0; 17 | def_NtTerminateProcess NativeWinApi::NtTerminateProcess = 0; 18 | 19 | def_NtOpenSymbolicLinkObject NativeWinApi::NtOpenSymbolicLinkObject = 0; 20 | def_NtQuerySymbolicLinkObject NativeWinApi::NtQuerySymbolicLinkObject = 0; 21 | 22 | def_RtlNtStatusToDosError NativeWinApi::RtlNtStatusToDosError = 0; 23 | def_NtClose NativeWinApi::NtClose = 0; 24 | 25 | void NativeWinApi::initialize() 26 | { 27 | if (RtlNtStatusToDosError) 28 | { 29 | return; 30 | } 31 | 32 | HMODULE hModuleNtdll = GetModuleHandle("ntdll.dll"); 33 | 34 | if (!hModuleNtdll) 35 | { 36 | return; 37 | } 38 | 39 | NtCreateThreadEx = (def_NtCreateThreadEx)GetProcAddress(hModuleNtdll, "NtCreateThreadEx"); 40 | NtDuplicateObject = (def_NtDuplicateObject)GetProcAddress(hModuleNtdll, "NtDuplicateObject"); 41 | NtOpenProcess = (def_NtOpenProcess)GetProcAddress(hModuleNtdll, "NtOpenProcess"); 42 | NtOpenThread = (def_NtOpenThread)GetProcAddress(hModuleNtdll, "NtOpenThread"); 43 | NtQueryObject = (def_NtQueryObject)GetProcAddress(hModuleNtdll, "NtQueryObject"); 44 | NtQueryInformationFile = (def_NtQueryInformationFile)GetProcAddress(hModuleNtdll, "NtQueryInformationFile"); 45 | NtQueryInformationProcess = (def_NtQueryInformationProcess)GetProcAddress(hModuleNtdll, "NtQueryInformationProcess"); 46 | NtQueryInformationThread = (def_NtQueryInformationThread)GetProcAddress(hModuleNtdll, "NtQueryInformationThread"); 47 | NtQuerySystemInformation = (def_NtQuerySystemInformation)GetProcAddress(hModuleNtdll, "NtQuerySystemInformation"); 48 | NtQueryVirtualMemory = (def_NtQueryVirtualMemory)GetProcAddress(hModuleNtdll, "NtQueryVirtualMemory"); 49 | NtResumeProcess = (def_NtResumeProcess)GetProcAddress(hModuleNtdll, "NtResumeProcess"); 50 | NtResumeThread = (def_NtResumeThread)GetProcAddress(hModuleNtdll, "NtResumeThread"); 51 | NtSetInformationThread = (def_NtSetInformationThread)GetProcAddress(hModuleNtdll, "NtSetInformationThread"); 52 | NtSuspendProcess = (def_NtSuspendProcess)GetProcAddress(hModuleNtdll, "NtSuspendProcess"); 53 | NtTerminateProcess = (def_NtTerminateProcess)GetProcAddress(hModuleNtdll, "NtTerminateProcess"); 54 | NtOpenSymbolicLinkObject = (def_NtOpenSymbolicLinkObject)GetProcAddress(hModuleNtdll, "NtOpenSymbolicLinkObject"); 55 | NtQuerySymbolicLinkObject = (def_NtQuerySymbolicLinkObject)GetProcAddress(hModuleNtdll, "NtQuerySymbolicLinkObject"); 56 | 57 | RtlNtStatusToDosError = (def_RtlNtStatusToDosError)GetProcAddress(hModuleNtdll, "RtlNtStatusToDosError"); 58 | NtClose = (def_NtClose)GetProcAddress(hModuleNtdll, "NtClose"); 59 | } 60 | 61 | 62 | PPEB NativeWinApi::getCurrentProcessEnvironmentBlock() 63 | { 64 | return getProcessEnvironmentBlockAddress(GetCurrentProcess()); 65 | } 66 | 67 | PPEB NativeWinApi::getProcessEnvironmentBlockAddress(HANDLE processHandle) 68 | { 69 | ULONG lReturnLength = 0; 70 | PROCESS_BASIC_INFORMATION processBasicInformation; 71 | 72 | if ((NtQueryInformationProcess(processHandle,ProcessBasicInformation,&processBasicInformation,sizeof(PROCESS_BASIC_INFORMATION),&lReturnLength) >= 0) && (lReturnLength == sizeof(PROCESS_BASIC_INFORMATION))) 73 | { 74 | //printf("NtQueryInformationProcess success %d\n",sizeof(PROCESS_BASIC_INFORMATION)); 75 | 76 | return processBasicInformation.PebBaseAddress; 77 | } 78 | else 79 | { 80 | //printf("NtQueryInformationProcess failed %d vs %d\n",lReturnLength,sizeof(PROCESS_BASIC_INFORMATION)); 81 | return 0; 82 | } 83 | } -------------------------------------------------------------------------------- /CAPE/Scylla/PeParser.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | //#include "DumpSectionGui.h" 6 | 7 | #define CAPE_OUTPUT_FILE "CapeOutput.bin" 8 | extern "C" char* GetName(); 9 | 10 | class PeFileSection { 11 | public: 12 | IMAGE_SECTION_HEADER sectionHeader; 13 | BYTE * data; 14 | DWORD dataSize; 15 | DWORD normalSize; 16 | 17 | PeFileSection() 18 | { 19 | ZeroMemory(§ionHeader, sizeof(IMAGE_SECTION_HEADER)); 20 | data = 0; 21 | dataSize = 0; 22 | normalSize = 0; 23 | } 24 | }; 25 | 26 | class PeSection 27 | { 28 | public: 29 | CHAR name[IMAGE_SIZEOF_SHORT_NAME + 1]; 30 | DWORD_PTR virtualAddress; 31 | DWORD virtualSize; 32 | DWORD rawAddress; 33 | DWORD rawSize; 34 | DWORD characteristics; 35 | 36 | bool isDumped; 37 | 38 | bool highlightVirtualSize(); 39 | }; 40 | 41 | class PeParser 42 | { 43 | public: 44 | PeParser(const CHAR * file, bool readSectionHeaders = true); 45 | PeParser(const DWORD_PTR moduleBase, bool readSectionHeaders = true); 46 | 47 | ~PeParser(); 48 | 49 | bool isValidPeFile(); 50 | bool isPE64(); 51 | bool isPE32(); 52 | 53 | bool isTargetFileSamePeFormat(); 54 | 55 | WORD getNumberOfSections(); 56 | std::vector & getSectionHeaderList(); 57 | 58 | bool hasExportDirectory(); 59 | bool hasTLSDirectory(); 60 | bool hasRelocationDirectory(); 61 | bool hasOverlayData(); 62 | 63 | DWORD getEntryPoint(); 64 | 65 | bool getSectionNameUnicode(const int sectionIndex, CHAR * output, const int outputLen); 66 | 67 | DWORD getSectionHeaderBasedFileSize(); 68 | DWORD getSectionHeaderBasedSizeOfImage(); 69 | 70 | bool readPeSectionsFromProcess(); 71 | bool readPeSectionsFromFile(); 72 | bool savePeFileToDisk(const CHAR * newFile); 73 | bool savePeFileToHandle(HANDLE FileHandle); 74 | bool saveCompletePeToDisk(const CHAR * newFile); 75 | bool saveCompletePeToHandle(HANDLE FileHandle); 76 | void removeDosStub(); 77 | void alignAllSectionHeaders(); 78 | void fixPeHeader(); 79 | void setDefaultFileAlignment(); 80 | bool dumpProcess(DWORD_PTR modBase, DWORD_PTR entryPoint, const CHAR * dumpFilePath); 81 | bool dumpProcess(DWORD_PTR modBase, DWORD_PTR entryPoint, const CHAR * dumpFilePath, std::vector & sectionList); 82 | bool dumpProcessToHandle(DWORD_PTR modBase, DWORD_PTR entryPoint, HANDLE FileHandle); 83 | 84 | void setEntryPointVa(DWORD_PTR entryPoint); 85 | void setEntryPointRva(DWORD entryPoint); 86 | 87 | static bool updatePeHeaderChecksum(const CHAR * targetFile, DWORD fileSize); 88 | BYTE * getSectionMemoryByIndex(int index); 89 | DWORD getSectionMemorySizeByIndex(int index); 90 | int convertRVAToOffsetVectorIndex(DWORD_PTR dwRVA); 91 | DWORD_PTR convertOffsetToRVAVector(DWORD_PTR dwOffset); 92 | DWORD_PTR convertRVAToOffsetVector(DWORD_PTR dwRVA); 93 | DWORD_PTR convertRVAToOffsetRelative(DWORD_PTR dwRVA); 94 | DWORD getSectionAddressRVAByIndex( int index ); 95 | 96 | PIMAGE_NT_HEADERS getCurrentNtHeader(); 97 | std::vector listPeSection; 98 | 99 | DWORD dumpSize; 100 | 101 | protected: 102 | PeParser(); 103 | 104 | 105 | static const DWORD FileAlignmentConstant = 0x200; 106 | 107 | const CHAR * filename; 108 | DWORD_PTR moduleBaseAddress; 109 | 110 | /************************************************************************/ 111 | /* PE FILE */ 112 | /* */ 113 | /* IMAGE_DOS_HEADER 64 0x40 */ 114 | /* IMAGE_NT_HEADERS32 248 0xF8 */ 115 | /* IMAGE_NT_HEADERS64 264 0x108 */ 116 | /* IMAGE_SECTION_HEADER 40 0x28 */ 117 | /************************************************************************/ 118 | 119 | PIMAGE_DOS_HEADER pDosHeader; 120 | BYTE * pDosStub; //between dos header and section header 121 | DWORD dosStubSize; 122 | PIMAGE_NT_HEADERS32 pNTHeader32; 123 | PIMAGE_NT_HEADERS64 pNTHeader64; 124 | BYTE * overlayData; 125 | DWORD overlaySize; 126 | /************************************************************************/ 127 | 128 | BYTE * fileMemory; 129 | BYTE * headerMemory; 130 | 131 | HANDLE hFile; 132 | HANDLE hInfoFile; 133 | DWORD fileSize; 134 | 135 | bool readPeHeaderFromFile(bool readSectionHeaders); 136 | bool readPeHeaderFromProcess(bool readSectionHeaders); 137 | 138 | bool hasDirectory(const int directoryIndex); 139 | bool getSectionHeaders(); 140 | void getDosAndNtHeader(BYTE * memory, LONG size); 141 | DWORD calcCorrectPeHeaderSize( bool readSectionHeaders ); 142 | DWORD getInitialHeaderReadSize( bool readSectionHeaders ); 143 | bool openFileHandle(); 144 | void closeFileHandle(); 145 | void initClass(); 146 | 147 | DWORD isMemoryNotNull( BYTE * data, int dataSize ); 148 | bool openWriteFileHandle( const CHAR * newFile ); 149 | bool writeZeroMemoryToFile(HANDLE hFile, DWORD fileOffset, DWORD size); 150 | 151 | bool readPeSectionFromFile( DWORD readOffset, PeFileSection & peFileSection ); 152 | bool readPeSectionFromProcess( DWORD_PTR readOffset, PeFileSection & peFileSection ); 153 | 154 | bool readSectionFromProcess(const DWORD_PTR readOffset, PeFileSection & peFileSection ); 155 | bool readSectionFromFile(const DWORD readOffset, PeFileSection & peFileSection ); 156 | bool readSectionFrom(const DWORD_PTR readOffset, PeFileSection & peFileSection, const bool isProcess); 157 | 158 | 159 | DWORD_PTR getStandardImagebase(); 160 | 161 | bool addNewLastSection(const CHAR * sectionName, DWORD sectionSize, BYTE * sectionData); 162 | DWORD alignValue(DWORD badValue, DWORD alignTo); 163 | 164 | void setNumberOfSections(WORD numberOfSections); 165 | 166 | void removeIatDirectory(); 167 | bool getFileOverlay(); 168 | }; 169 | -------------------------------------------------------------------------------- /CAPE/Scylla/ProcessAccessHelp.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | 7 | /************************************************************************/ 8 | /* distorm */ 9 | /************************************************************************/ 10 | #include 11 | #include 12 | 13 | // The number of the array of instructions the decoder function will use to return the disassembled instructions. 14 | // Play with this value for performance... 15 | #define MAX_INSTRUCTIONS (200) 16 | 17 | /************************************************************************/ 18 | 19 | class ApiInfo; 20 | 21 | class ModuleInfo 22 | { 23 | public: 24 | 25 | CHAR fullPath[MAX_PATH]; 26 | DWORD_PTR modBaseAddr; 27 | DWORD modBaseSize; 28 | 29 | bool isAlreadyParsed; 30 | bool parsing; 31 | 32 | /* 33 | for iat rebuilding with duplicate entries: 34 | 35 | ntdll = low priority 36 | kernelbase = low priority 37 | SHLWAPI = low priority 38 | 39 | kernel32 = high priority 40 | 41 | priority = 1 -> normal/high priority 42 | priority = 0 -> low priority 43 | */ 44 | int priority; 45 | 46 | std::vector apiList; 47 | 48 | ModuleInfo() 49 | { 50 | modBaseAddr = 0; 51 | modBaseSize = 0; 52 | priority = 1; 53 | isAlreadyParsed = false; 54 | parsing = false; 55 | } 56 | 57 | const CHAR * getFilename() const 58 | { 59 | const CHAR* slash = strrchr(fullPath, L'\\'); 60 | if(slash) 61 | { 62 | return slash+1; 63 | } 64 | return fullPath; 65 | } 66 | }; 67 | 68 | class ApiInfo 69 | { 70 | public: 71 | 72 | char name[MAX_PATH]; 73 | WORD hint; 74 | DWORD_PTR va; 75 | DWORD_PTR rva; 76 | WORD ordinal; 77 | bool isForwarded; 78 | ModuleInfo * module; 79 | }; 80 | 81 | class ProcessAccessHelp 82 | { 83 | public: 84 | 85 | static HANDLE hProcess; //OpenProcess handle to target process 86 | 87 | static DWORD_PTR targetImageBase; 88 | static DWORD_PTR targetSizeOfImage; 89 | static DWORD_PTR maxValidAddress; 90 | 91 | static ModuleInfo * selectedModule; 92 | 93 | static std::vector moduleList; //target process module list 94 | static std::vector ownModuleList; //own module list 95 | 96 | static const size_t PE_HEADER_BYTES_COUNT = 2000; 97 | 98 | static BYTE fileHeaderFromDisk[PE_HEADER_BYTES_COUNT]; 99 | 100 | 101 | //for decomposer 102 | static _DInst decomposerResult[MAX_INSTRUCTIONS]; 103 | static unsigned int decomposerInstructionsCount; 104 | static _CodeInfo decomposerCi; 105 | 106 | //distorm :: Decoded instruction information. 107 | static _DecodedInst decodedInstructions[MAX_INSTRUCTIONS]; 108 | static unsigned int decodedInstructionsCount; 109 | #ifdef _WIN64 110 | static const _DecodeType dt = Decode64Bits; 111 | #else 112 | static const _DecodeType dt = Decode32Bits; 113 | #endif 114 | 115 | /* 116 | * Open a new process handle 117 | */ 118 | static bool openProcessHandle(DWORD dwPID); 119 | 120 | static HANDLE NativeOpenProcess(DWORD dwDesiredAccess, DWORD dwProcessId); 121 | 122 | static void closeProcessHandle(); 123 | 124 | /* 125 | * Get all modules from a process 126 | */ 127 | static bool getProcessModules(HANDLE hProcess, std::vector &moduleList); 128 | 129 | 130 | /* 131 | * file mapping view with different access level 132 | */ 133 | static LPVOID createFileMappingViewRead(const CHAR * filePath); 134 | static LPVOID createFileMappingViewFull(const CHAR * filePath); 135 | 136 | /* 137 | * Create a file mapping view of a file 138 | */ 139 | static LPVOID createFileMappingView(const CHAR * filePath, DWORD accessFile, DWORD flProtect, DWORD accessMap); 140 | 141 | /* 142 | * Read memory from target process 143 | */ 144 | static bool readMemoryFromProcess(DWORD_PTR address, SIZE_T size, LPVOID dataBuffer); 145 | static bool writeMemoryToProcess(DWORD_PTR address, SIZE_T size, LPVOID dataBuffer); 146 | 147 | /* 148 | * Read memory from target process and ignore no data pages 149 | */ 150 | static bool readMemoryPartlyFromProcess(DWORD_PTR address, SIZE_T size, LPVOID dataBuffer); 151 | 152 | /* 153 | * Read memory from file 154 | */ 155 | static bool readMemoryFromFile(HANDLE hFile, LONG offset, DWORD size, LPVOID dataBuffer); 156 | 157 | /* 158 | * Write memory to file 159 | */ 160 | static bool writeMemoryToFile(HANDLE hFile, LONG offset, DWORD size, LPCVOID dataBuffer); 161 | 162 | 163 | /* 164 | * Write memory to new file 165 | */ 166 | static bool writeMemoryToNewFile(const CHAR * file,DWORD size, LPCVOID dataBuffer); 167 | 168 | /* 169 | * Write memory to file end 170 | */ 171 | static bool writeMemoryToFileEnd(HANDLE hFile, DWORD size, LPCVOID dataBuffer); 172 | 173 | /* 174 | * Disassemble Memory 175 | */ 176 | static bool disassembleMemory(BYTE * dataBuffer, SIZE_T bufferSize, DWORD_PTR startOffset); 177 | 178 | static bool decomposeMemory(BYTE * dataBuffer, SIZE_T bufferSize, DWORD_PTR startAddress); 179 | 180 | /* 181 | * Search for pattern 182 | */ 183 | static DWORD_PTR findPattern(DWORD_PTR startOffset, DWORD size, BYTE * pattern, const char * mask); 184 | 185 | /* 186 | * Get process ID by process name 187 | */ 188 | static DWORD getProcessByName(const CHAR * processName); 189 | 190 | /* 191 | * Get memory region from address 192 | */ 193 | static bool getMemoryRegionFromAddress(DWORD_PTR address, DWORD_PTR * memoryRegionBase, SIZE_T * memoryRegionSize); 194 | 195 | 196 | /* 197 | * Read PE Header from file 198 | */ 199 | static bool readHeaderFromFile(BYTE * buffer, DWORD bufferSize, const CHAR * filePath); 200 | 201 | static bool readHeaderFromCurrentFile(const CHAR * filePath); 202 | 203 | /* 204 | * Get real sizeOfImage value 205 | */ 206 | static SIZE_T getSizeOfImageProcess(HANDLE processHandle, DWORD_PTR moduleBase); 207 | 208 | /* 209 | * Get real sizeOfImage value current process 210 | */ 211 | static bool getSizeOfImageCurrentProcess(); 212 | 213 | static LONGLONG getFileSize(HANDLE hFile); 214 | static LONGLONG getFileSize(const CHAR * filePath); 215 | 216 | static DWORD getEntryPointFromFile(const CHAR * filePath); 217 | 218 | static bool createBackupFile(const CHAR * filePath); 219 | 220 | static DWORD getModuleHandlesFromProcess(const HANDLE hProcess, HMODULE ** hMods ); 221 | 222 | static void setCurrentProcessAsTarget(); 223 | 224 | static bool suspendProcess(); 225 | static bool resumeProcess(); 226 | static bool terminateProcess(); 227 | static bool isPageExecutable( DWORD Protect ); 228 | static bool isPageAccessable( DWORD Protect ); 229 | static SIZE_T getSizeOfImageProcessNative( HANDLE processHandle, DWORD_PTR moduleBase ); 230 | }; 231 | -------------------------------------------------------------------------------- /CAPE/Scylla/StringConversion.cpp: -------------------------------------------------------------------------------- 1 | #include "StringConversion.h" 2 | //#include 3 | #include 4 | #include 5 | 6 | const char* StringConversion::ToASCII(const wchar_t* str, char* buf, size_t bufsize) 7 | { 8 | //wcstombs(buf, str, bufsize); 9 | ATL::CW2A str_a = str; 10 | strncpy_s(buf, bufsize, str_a, bufsize); 11 | buf[bufsize - 1] = '\0'; 12 | return buf; 13 | } 14 | 15 | const wchar_t* StringConversion::ToUTF16(const char* str, wchar_t* buf, size_t bufsize) 16 | { 17 | //mbstowcs_s(buf, str, bufsize); 18 | ATL::CA2W str_w = str; 19 | wcsncpy_s(buf, bufsize, str_w, bufsize); 20 | buf[bufsize - 1] = L'\0'; 21 | return buf; 22 | } 23 | -------------------------------------------------------------------------------- /CAPE/Scylla/StringConversion.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | class StringConversion 4 | { 5 | public: 6 | 7 | static const char* ToASCII(const wchar_t* str, char* buf, size_t bufsize); 8 | static const wchar_t* ToUTF16(const char* str, wchar_t* buf, size_t bufsize); 9 | }; 10 | -------------------------------------------------------------------------------- /CAPE/Scylla/SystemInformation.cpp: -------------------------------------------------------------------------------- 1 | #include "SystemInformation.h" 2 | 3 | OPERATING_SYSTEM SystemInformation::currenOS = UNKNOWN_OS; 4 | 5 | bool SystemInformation::getSystemInformation() 6 | { 7 | OSVERSIONINFOEX osvi = {0}; 8 | SYSTEM_INFO si = {0}; 9 | def_GetNativeSystemInfo _GetNativeSystemInfo = 0; 10 | 11 | osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX); 12 | if (!GetVersionEx((OSVERSIONINFO*) &osvi)) 13 | { 14 | return false; 15 | } 16 | 17 | if ((osvi.dwMajorVersion < 5) || ((osvi.dwMajorVersion == 5) && (osvi.dwMinorVersion == 0))) 18 | { 19 | return false; 20 | } 21 | 22 | _GetNativeSystemInfo = (def_GetNativeSystemInfo)GetProcAddress(GetModuleHandle("kernel32.dll"), "GetNativeSystemInfo"); 23 | if (_GetNativeSystemInfo) 24 | { 25 | _GetNativeSystemInfo(&si); 26 | } 27 | else 28 | { 29 | GetSystemInfo(&si); 30 | } 31 | 32 | bool isX64 = si.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_AMD64; 33 | bool isX86 = si.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_INTEL; 34 | 35 | DWORD major = osvi.dwMajorVersion; 36 | DWORD minor = osvi.dwMinorVersion; 37 | 38 | if(isX64 && major == 5 && minor == 2) 39 | { 40 | currenOS = WIN_XP_64; 41 | } 42 | else if(isX86 && major == 5 && minor == 1) 43 | { 44 | currenOS = WIN_XP_32; 45 | } 46 | else if(isX64 && major == 6 && minor == 0) 47 | { 48 | currenOS = WIN_VISTA_64; 49 | } 50 | else if(isX86 && major == 6 && minor == 0) 51 | { 52 | currenOS = WIN_VISTA_32; 53 | } 54 | else if(isX64 && major == 6 && minor == 1) 55 | { 56 | currenOS = WIN_7_64; 57 | } 58 | else if(isX86 && major == 6 && minor == 1) 59 | { 60 | currenOS = WIN_7_32; 61 | } 62 | else if(isX64 && major == 6 && minor == 2) 63 | { 64 | currenOS = WIN_8_64; 65 | } 66 | else if(isX86 && major == 6 && minor == 2) 67 | { 68 | currenOS = WIN_8_32; 69 | } 70 | else 71 | { 72 | currenOS = UNKNOWN_OS; 73 | } 74 | 75 | return (currenOS != UNKNOWN_OS); 76 | } 77 | -------------------------------------------------------------------------------- /CAPE/Scylla/SystemInformation.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | enum OPERATING_SYSTEM { 6 | UNKNOWN_OS, 7 | WIN_XP_32, 8 | WIN_XP_64, 9 | WIN_VISTA_32, 10 | WIN_VISTA_64, 11 | WIN_7_32, 12 | WIN_7_64, 13 | WIN_8_32, 14 | WIN_8_64 15 | }; 16 | 17 | typedef void (WINAPI *def_GetNativeSystemInfo)(LPSYSTEM_INFO lpSystemInfo); 18 | 19 | class SystemInformation 20 | { 21 | public: 22 | 23 | static OPERATING_SYSTEM currenOS; 24 | static bool getSystemInformation(); 25 | }; 26 | -------------------------------------------------------------------------------- /CAPE/Scylla/Thunks.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | 6 | // WTL 7 | //#include 8 | //#include 9 | //#include // CTreeItem 10 | 11 | class ImportThunk 12 | { 13 | public: 14 | CHAR moduleName[MAX_PATH]; 15 | char name[MAX_PATH]; 16 | DWORD_PTR va; 17 | DWORD_PTR rva; 18 | WORD ordinal; 19 | DWORD_PTR apiAddressVA; 20 | WORD hint; 21 | bool valid; 22 | bool suspect; 23 | 24 | // CTreeItem hTreeItem; 25 | DWORD_PTR key; 26 | 27 | void invalidate(); 28 | }; 29 | 30 | class ImportModuleThunk 31 | { 32 | public: 33 | CHAR moduleName[MAX_PATH]; 34 | std::map thunkList; 35 | 36 | DWORD_PTR firstThunk; 37 | 38 | // CTreeItem hTreeItem; 39 | DWORD_PTR key; 40 | 41 | DWORD_PTR getFirstThunk() const; 42 | bool isValid() const; 43 | }; 44 | -------------------------------------------------------------------------------- /CAPE/w64wow64/internal.h: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | * WOW64Ext Library 4 | * 5 | * Copyright (c) 2012 ReWolf 6 | * http://blog.rewolf.pl/ 7 | * 8 | * This program is free software: you can redistribute it and/or modify 9 | * it under the terms of the GNU Lesser General Public License as published 10 | * by the Free Software Foundation, either version 3 of the License, or 11 | * (at your option) any later version. 12 | * 13 | * This program is distributed in the hope that it will be useful, 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | * GNU Lesser General Public License for more details. 17 | * 18 | * You should have received a copy of the GNU Lesser General Public License 19 | * along with this program. If not, see . 20 | * 21 | */ 22 | #pragma once 23 | 24 | #define EMIT(a) __asm __emit (a) 25 | 26 | #define X64_Start_with_CS(_cs) \ 27 | { \ 28 | EMIT(0x6A) EMIT(_cs) /* push _cs */ \ 29 | EMIT(0xE8) EMIT(0) EMIT(0) EMIT(0) EMIT(0) /* call $+5 */ \ 30 | EMIT(0x83) EMIT(4) EMIT(0x24) EMIT(5) /* add dword [esp], 5 */ \ 31 | EMIT(0xCB) /* retf */ \ 32 | } 33 | 34 | #define X64_End_with_CS(_cs) \ 35 | { \ 36 | EMIT(0xE8) EMIT(0) EMIT(0) EMIT(0) EMIT(0) /* call $+5 */ \ 37 | EMIT(0xC7) EMIT(0x44) EMIT(0x24) EMIT(4) EMIT(_cs) EMIT(0) EMIT(0) EMIT(0) /* mov dword [rsp + 4], _cs */ \ 38 | EMIT(0x83) EMIT(4) EMIT(0x24) EMIT(0xD) /* add dword [rsp], 0xD */ \ 39 | EMIT(0xCB) /* retf */ \ 40 | } 41 | 42 | #define X64_Start() X64_Start_with_CS(0x33) 43 | #define X64_End() X64_End_with_CS(0x23) 44 | 45 | #define _RAX 0 46 | #define _RCX 1 47 | #define _RDX 2 48 | #define _RBX 3 49 | #define _RSP 4 50 | #define _RBP 5 51 | #define _RSI 6 52 | #define _RDI 7 53 | #define _R8 8 54 | #define _R9 9 55 | #define _R10 10 56 | #define _R11 11 57 | #define _R12 12 58 | #define _R13 13 59 | #define _R14 14 60 | #define _R15 15 61 | 62 | #define X64_Push(r) EMIT(0x48 | ((r) >> 3)) EMIT(0x50 | ((r) & 7)) 63 | #define X64_Pop(r) EMIT(0x48 | ((r) >> 3)) EMIT(0x58 | ((r) & 7)) 64 | 65 | #define REX_W EMIT(0x48) __asm 66 | 67 | //to fool M$ inline asm compiler I'm using 2 DWORDs instead of DWORD64 68 | //use of DWORD64 will generate wrong 'pop word ptr[]' and it will break stack 69 | union reg64 70 | { 71 | DWORD64 v; 72 | DWORD dw[2]; 73 | }; 74 | -------------------------------------------------------------------------------- /CAPE/w64wow64/w64wow64.h: -------------------------------------------------------------------------------- 1 | /* 2 | W64oWoW64 3 | Copyright (C) 2012 George Nicolaou 4 | 5 | This file is part of W64oWoW64. 6 | 7 | W64oWoW64 is free software: you can redistribute it and/or modify 8 | it under the terms of the GNU General Public License as published by 9 | the Free Software Foundation, either version 3 of the License, or 10 | (at your option) any later version. 11 | 12 | W64oWoW64 is distributed in the hope that it will be useful, 13 | but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | GNU General Public License for more details. 16 | 17 | You should have received a copy of the GNU General Public License 18 | along with W64oWoW64. If not, see . 19 | */ 20 | #pragma once 21 | 22 | #include 23 | 24 | #ifndef STATUS_SUCCESS 25 | # define STATUS_SUCCESS 0 26 | #endif 27 | 28 | #ifndef __W64WOW64_H_ 29 | #define __W64WOW64_H_ 30 | 31 | unsigned __int64 X64Call( DWORD64 lvpFunctionPtr, int nArgc, ... ); 32 | void __cdecl SetLastErrorFromX64Call(DWORD64 status); 33 | DWORD64 GetProcAddress64( DWORD64 lvpBaseAddress, char * lpszProcName ); 34 | DWORD64 LoadLibrary64A( char * lpcLibraryName ); 35 | DWORD64 GetModuleBase64( wchar_t * lwcModuleName ); 36 | 37 | DWORD64 VirtualAllocEx64(HANDLE hProcess, DWORD64 lpAddress, SIZE_T dwSize, DWORD flAllocationType, DWORD flProtect); 38 | BOOL VirtualFreeEx64(HANDLE hProcess, DWORD64 lpAddress, SIZE_T dwSize, DWORD flNewProtect, DWORD* lpflOldProtect); 39 | BOOL VirtualProtectEx64(HANDLE hProcess, DWORD64 lpAddress, SIZE_T dwSize, DWORD flNewProtect, DWORD* lpflOldProtect); 40 | BOOL ReadProcessMemory64(HANDLE hProcess, DWORD64 lpBaseAddress, LPVOID lpBuffer, SIZE_T nSize, SIZE_T *lpNumberOfBytesRead); 41 | BOOL WriteProcessMemory64(HANDLE hProcess, DWORD64 lpBaseAddress, LPVOID lpBuffer, SIZE_T nSize, SIZE_T *lpNumberOfBytesWritten); 42 | 43 | extern BOOL InitializeW64oWoW64(void); 44 | #endif -------------------------------------------------------------------------------- /CAPE/w64wow64/w64wow64defs.h: -------------------------------------------------------------------------------- 1 | /* 2 | W64oWoW64 3 | Copyright (C) 2012 George Nicolaou 4 | 5 | This file is part of W64oWoW64. 6 | 7 | W64oWoW64 is free software: you can redistribute it and/or modify 8 | it under the terms of the GNU General Public License as published by 9 | the Free Software Foundation, either version 3 of the License, or 10 | (at your option) any later version. 11 | 12 | W64oWoW64 is distributed in the hope that it will be useful, 13 | but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | GNU General Public License for more details. 16 | 17 | You should have received a copy of the GNU General Public License 18 | along with W64oWoW64. If not, see . 19 | */ 20 | #define GETTEB() \ 21 | { \ 22 | EMIT(0x65) EMIT(0x48) EMIT(0x8b) EMIT(0x04) EMIT(0x25) EMIT(0x30) EMIT(0x00) EMIT(0x00) EMIT(0x00) \ 23 | } 24 | 25 | 26 | typedef struct { 27 | void * LdrGetKnownDllSectionHandle; 28 | void * NtMapViewOfSection; 29 | void * NtFreeVirtualMemory; 30 | void * NtUnmapViewOfSection; 31 | void * LoadLibraryA; 32 | } FUNCTIONPTRS; 33 | 34 | BOOL InitializeW64oWoW64( void ); -------------------------------------------------------------------------------- /CAPE/w64wow64/windef.h: -------------------------------------------------------------------------------- 1 | /* 2 | W64oWoW64 3 | Copyright (C) 2012 George Nicolaou 4 | 5 | This file is part of W64oWoW64. 6 | 7 | W64oWoW64 is free software: you can redistribute it and/or modify 8 | it under the terms of the GNU General Public License as published by 9 | the Free Software Foundation, either version 3 of the License, or 10 | (at your option) any later version. 11 | 12 | W64oWoW64 is distributed in the hope that it will be useful, 13 | but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | GNU General Public License for more details. 16 | 17 | You should have received a copy of the GNU General Public License 18 | along with W64oWoW64. If not, see . 19 | */ 20 | #include 21 | 22 | typedef struct _CLIENT_ID64 23 | { 24 | DWORD64 UniqueProcess; 25 | DWORD64 UniqueThread; 26 | } CLIENT_ID64, *PCLIENT_ID64; 27 | 28 | 29 | typedef struct _PEB_LDR_DATA 30 | { 31 | ULONG Length; 32 | UCHAR Initialized; 33 | DWORD64 SsHandle; 34 | LIST_ENTRY64 InLoadOrderModuleList; 35 | LIST_ENTRY64 InMemoryOrderModuleList; 36 | LIST_ENTRY64 InInitializationOrderModuleList; 37 | DWORD64 EntryInProgress; 38 | } PEB_LDR_DATA, *PPEB_LDR_DATA; 39 | 40 | 41 | typedef struct _PEB64 42 | { 43 | UCHAR InheritedAddressSpace; 44 | UCHAR ReadImageFileExecOptions; 45 | UCHAR BeingDebugged; 46 | UCHAR BitField; 47 | ULONG ImageUsesLargePages: 1; 48 | ULONG IsProtectedProcess: 1; 49 | ULONG IsLegacyProcess: 1; 50 | ULONG IsImageDynamicallyRelocated: 1; 51 | ULONG SpareBits: 4; 52 | DWORD64 Mutant; 53 | DWORD64 ImageBaseAddress; 54 | PPEB_LDR_DATA Ldr; 55 | } PEB64, *PPEB64; 56 | 57 | typedef struct _LSA_UNICODE_STRING { 58 | USHORT Length; 59 | USHORT MaximumLength; 60 | DWORD64 Buffer; 61 | } UNICODE_STRING64, * PUNICODE_STRING64; 62 | 63 | typedef struct _TEB64 64 | { 65 | NT_TIB64 NtTib; 66 | DWORD64 EnvironmentPointer; 67 | CLIENT_ID64 ClientId; 68 | DWORD64 ActiveRpcHandle; 69 | DWORD64 ThreadLocalStoragePointer; 70 | PPEB64 ProcessEnvironmentBlock; 71 | } TEB64, *PTEB64; 72 | 73 | typedef struct _LDR_DATA_TABLE_ENTRY64 74 | { 75 | LIST_ENTRY64 InLoadOrderLinks; 76 | LIST_ENTRY64 InMemoryOrderLinks; 77 | LIST_ENTRY64 InInitializationOrderLinks; 78 | DWORD64 DllBase; 79 | DWORD64 EntryPoint; 80 | ULONG SizeOfImage; 81 | UNICODE_STRING64 FullDllName; 82 | UNICODE_STRING64 BaseDllName; 83 | ULONG Flags; 84 | WORD LoadCount; 85 | } LDR_DATA_TABLE_ENTRY54, *PLDR_DATA_TABLE_ENTRY64; 86 | 87 | #define LDRP_PROCESS_ATTACH_CALLED 0x000080000 88 | #define LDRP_ENTRY_PROCESSED 0x000004000 89 | 90 | typedef enum _SECTION_INHERIT { 91 | ViewShare = 1, 92 | ViewUnmap = 2 93 | } SECTION_INHERIT, * PSECTION_INHERIT; -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | MAKEFLAGS = -j8 2 | CFLAGS = -Wall -std=c99 -s -O2 -Wno-strict-aliasing -static 3 | DLL = -shared 4 | DIRS = -Idistorm/include -Ibson 5 | LIBS = -lws2_32 -lshlwapi 6 | OBJDIR = objects 7 | 8 | # Passes DBG=1 on as -DCUCKOODBG=1 9 | ifdef DBG 10 | CFLAGS += -DCUCKOODBG=$(DBG) 11 | endif 12 | 13 | ifneq ($(OS),Windows_NT) 14 | CC = i686-w64-mingw32-gcc 15 | else 16 | CC = gcc 17 | endif 18 | 19 | DISTORM3 = $(wildcard distorm/src/*.c) 20 | DISTORM3OBJ = $(DISTORM3:distorm/src/%.c=$(OBJDIR)/distorm3.2/%.o) 21 | 22 | CUCKOOSRC = $(wildcard *.c) 23 | CUCKOOOBJ = $(CUCKOOSRC:%.c=$(OBJDIR)/%.o) 24 | 25 | BSONSRC = bson/bson.c bson/encoding.c bson/numbers.c 26 | BSONOBJ = $(OBJDIR)/bson/bson.o $(OBJDIR)/bson/encoding.o $(OBJDIR)/bson/numbers.o 27 | 28 | default: $(OBJDIR) cuckoomon.dll 29 | 30 | $(OBJDIR): 31 | mkdir $@ $@/bson $@/distorm3.2 32 | 33 | $(OBJDIR)/distorm3.2/%.o: distorm/src/%.c 34 | $(CC) $(CFLAGS) $(DIRS) -c $^ -o $@ 35 | 36 | $(OBJDIR)/bson/%.o: bson/%.c 37 | $(CC) $(CFLAGS) $(DIRS) -c $^ -o $@ 38 | 39 | $(OBJDIR)/%.o: %.c 40 | $(CC) $(CFLAGS) $(DIRS) -c $^ -o $@ 41 | 42 | cuckoomon.dll: $(CUCKOOOBJ) $(DISTORM3OBJ) $(BSONOBJ) 43 | $(CC) $(CFLAGS) $(DLL) $(DIRS) -o $@ $^ $(LIBS) 44 | 45 | clean: 46 | rm -rf $(OBJDIR) cuckoomon.dll 47 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ## capemon: The monitor DLLs for CAPE: Config And Payload Extraction (https://github.com/ctxis/CAPE). 2 | 3 | Much of the functionality of CAPE is contained within the monitor DLLs; the CAPE debugger and the different CAPE 'packages' are implemented within the DLLs. This repository is organised in branches for each of the packages. 4 | 5 | The 'standard' package is in the capemon branch. 6 | 7 | The three 'behavioural' packages are contained within the following branches: 8 | 9 | - Compression 10 | - Extraction 11 | - Injection 12 | 13 | These are designed to dump malware payloads associated with the respective behaviours. 14 | 15 | Additional malware-specific packages are within the following branches: 16 | 17 | - Cerber 18 | - EvilGrab 19 | - PlugX 20 | - Sedreco 21 | 22 | These allow for the extraction of both payloads and malware configuration from the respective malware families. 23 | 24 | There is also a UPX package to dynamically unpack 'hacked' UPX binaries. 25 | 26 | CAPE is an extension of Cuckoo specifically designed to extract payloads and configuration from malware. It is derived from spender-sandbox, which is derived from Cuckoo Sandbox, so thanks to Brad Spengler, Claudio Guarnieri, and the countless other Cuckoo contributors without whom this work would not be possible. 27 | -------------------------------------------------------------------------------- /alloc.c: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright(C) 2014,2015 Optiv, Inc. (brad.spengler@optiv.com) 3 | 4 | This program is free software : you can redistribute it and / or modify 5 | it under the terms of the GNU General Public License as published by 6 | the Free Software Foundation, either version 3 of the License, or 7 | (at your option) any later version. 8 | 9 | This program is distributed in the hope that it will be useful, 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.See the 12 | GNU General Public License for more details. 13 | 14 | You should have received a copy of the GNU General Public License 15 | along with this program.If not, see . 16 | */ 17 | 18 | #include "hooking.h" 19 | #include "alloc.h" 20 | #include 21 | 22 | #ifdef USE_PRIVATE_HEAP 23 | void *cm_alloc(size_t size) 24 | { 25 | void *ret; 26 | lasterror_t lasterror; 27 | 28 | get_lasterrors(&lasterror); 29 | ret = HeapAlloc(g_heap, 0, size); 30 | set_lasterrors(&lasterror); 31 | return ret; 32 | } 33 | 34 | void *cm_calloc(size_t count, size_t size) 35 | { 36 | void *ret; 37 | lasterror_t lasterror; 38 | 39 | get_lasterrors(&lasterror); 40 | ret = HeapAlloc(g_heap, HEAP_ZERO_MEMORY, count * size); 41 | set_lasterrors(&lasterror); 42 | return ret; 43 | } 44 | 45 | void *cm_realloc(void *ptr, size_t size) 46 | { 47 | void *ret; 48 | lasterror_t lasterror; 49 | get_lasterrors(&lasterror); 50 | ret = HeapReAlloc(g_heap, 0, ptr, size); 51 | set_lasterrors(&lasterror); 52 | return ret; 53 | } 54 | 55 | void cm_free(void *ptr) 56 | { 57 | lasterror_t lasterror; 58 | get_lasterrors(&lasterror); 59 | HeapFree(g_heap, 0, ptr); 60 | set_lasterrors(&lasterror); 61 | } 62 | #else 63 | void *cm_alloc(size_t size) 64 | { 65 | PVOID BaseAddress = NULL; 66 | SIZE_T RegionSize = size + CM_ALLOC_METASIZE + 0x1000; 67 | struct cm_alloc_header *hdr; 68 | DWORD oldprot; 69 | LONG status; 70 | lasterror_t lasterror; 71 | 72 | get_lasterrors(&lasterror); 73 | status = pNtAllocateVirtualMemory(GetCurrentProcess(), &BaseAddress, 0, &RegionSize, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE); 74 | 75 | if (status < 0) { 76 | set_lasterrors(&lasterror); 77 | return NULL; 78 | } 79 | hdr = (struct cm_alloc_header *)BaseAddress; 80 | hdr->Magic = CM_ALLOC_MAGIC; 81 | hdr->Used = size + CM_ALLOC_METASIZE; 82 | hdr->Max = RegionSize - 0x1000; 83 | 84 | // add a guard page to the end of every allocation 85 | assert(VirtualProtect((PCHAR)BaseAddress + RegionSize - 0x1000, 0x1000, PAGE_NOACCESS, &oldprot)); 86 | set_lasterrors(&lasterror); 87 | return (PCHAR)BaseAddress + CM_ALLOC_METASIZE; 88 | } 89 | 90 | void cm_free(void *ptr) 91 | { 92 | PVOID BaseAddress; 93 | SIZE_T RegionSize; 94 | LONG status; 95 | struct cm_alloc_header *hdr; 96 | lasterror_t lasterror; 97 | 98 | get_lasterrors(&lasterror); 99 | hdr = GET_CM_ALLOC_HEADER(ptr); 100 | 101 | assert(hdr->Magic == CM_ALLOC_MAGIC); 102 | BaseAddress = (PVOID)hdr; 103 | RegionSize = 0; 104 | status = pNtFreeVirtualMemory(GetCurrentProcess(), &BaseAddress, &RegionSize, MEM_RELEASE); 105 | assert(status >= 0); 106 | set_lasterrors(&lasterror); 107 | } 108 | 109 | void *cm_realloc(void *ptr, size_t size) 110 | { 111 | struct cm_alloc_header *hdr; 112 | char *buf; 113 | 114 | hdr = GET_CM_ALLOC_HEADER(ptr); 115 | 116 | assert(hdr->Magic == CM_ALLOC_MAGIC); 117 | 118 | if (hdr->Max >= (size + CM_ALLOC_METASIZE)) { 119 | hdr->Used = size + CM_ALLOC_METASIZE; 120 | return ptr; 121 | } 122 | buf = cm_alloc(size); 123 | if (buf == NULL) 124 | return buf; 125 | memcpy(buf, ptr, hdr->Used - CM_ALLOC_METASIZE); 126 | cm_free(ptr); 127 | return buf; 128 | } 129 | 130 | #endif -------------------------------------------------------------------------------- /alloc.h: -------------------------------------------------------------------------------- 1 | #ifndef __ALLOC_H 2 | #define __ALLOC_H 3 | 4 | #include 5 | 6 | typedef NTSTATUS(WINAPI * _NtAllocateVirtualMemory)( 7 | _In_ HANDLE ProcessHandle, 8 | _Inout_ PVOID *BaseAddress, 9 | _In_ ULONG_PTR ZeroBits, 10 | _Inout_ PSIZE_T RegionSize, 11 | _In_ ULONG AllocationType, 12 | _In_ ULONG Protect); 13 | typedef NTSTATUS(WINAPI * _NtProtectVirtualMemory)( 14 | _In_ HANDLE ProcessHandle, 15 | _Inout_ PVOID *BaseAddress, 16 | _Inout_ PSIZE_T NumberOfBytesToProtect, 17 | _In_ ULONG NewAccessProtection, 18 | _In_ PULONG OldAccessProtection); 19 | typedef NTSTATUS(WINAPI * _NtFreeVirtualMemory)( 20 | _In_ HANDLE ProcessHandle, 21 | _Inout_ PVOID *BaseAddress, 22 | _Inout_ PSIZE_T RegionSize, 23 | _In_ ULONG FreeType); 24 | 25 | extern _NtAllocateVirtualMemory pNtAllocateVirtualMemory; 26 | extern _NtProtectVirtualMemory pNtProtectVirtualMemory; 27 | extern _NtFreeVirtualMemory pNtFreeVirtualMemory; 28 | 29 | #define USE_PRIVATE_HEAP 30 | 31 | #ifdef USE_PRIVATE_HEAP 32 | extern HANDLE g_heap; 33 | #else 34 | struct cm_alloc_header { 35 | DWORD Magic; 36 | SIZE_T Used; 37 | SIZE_T Max; 38 | }; 39 | 40 | #define CM_ALLOC_METASIZE (sizeof(struct cm_alloc_header)) 41 | #define GET_CM_ALLOC_HEADER(x) (struct cm_alloc_header *)((PCHAR)(x) - CM_ALLOC_METASIZE) 42 | #define CM_ALLOC_MAGIC 0xdeadc01d 43 | 44 | #endif 45 | 46 | extern void *cm_alloc(size_t size); 47 | extern void *cm_realloc(void *ptr, size_t size); 48 | extern void cm_free(void *ptr); 49 | #ifdef USE_PRIVATE_HEAP 50 | extern void *cm_calloc(size_t count, size_t size); 51 | #else 52 | static __inline void *cm_calloc(size_t count, size_t size) 53 | { 54 | char *buf = cm_alloc(count * size); 55 | if (buf) 56 | memset(buf, 0, count * size); 57 | return buf; 58 | } 59 | #endif 60 | 61 | static __inline char *cm_strdup(const char *ptr) 62 | { 63 | char *buf = cm_alloc(strlen(ptr) + 1); 64 | if (buf) 65 | strcpy(buf, ptr); 66 | return buf; 67 | } 68 | 69 | #define calloc cm_calloc 70 | #define malloc cm_alloc 71 | #define free cm_free 72 | #define realloc cm_realloc 73 | #define strdup cm_strdup 74 | 75 | #endif -------------------------------------------------------------------------------- /bson/bson.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio 2013 4 | VisualStudioVersion = 12.0.30501.0 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "bson", "bson.vcxproj", "{0DA99545-93E9-4C1B-861B-C4DAB5360AA8}" 7 | EndProject 8 | Global 9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 10 | Debug|Win32 = Debug|Win32 11 | Release|Win32 = Release|Win32 12 | EndGlobalSection 13 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 14 | {0DA99545-93E9-4C1B-861B-C4DAB5360AA8}.Debug|Win32.ActiveCfg = Debug|Win32 15 | {0DA99545-93E9-4C1B-861B-C4DAB5360AA8}.Debug|Win32.Build.0 = Debug|Win32 16 | {0DA99545-93E9-4C1B-861B-C4DAB5360AA8}.Release|Win32.ActiveCfg = Release|Win32 17 | {0DA99545-93E9-4C1B-861B-C4DAB5360AA8}.Release|Win32.Build.0 = Release|Win32 18 | EndGlobalSection 19 | GlobalSection(SolutionProperties) = preSolution 20 | HideSolutionNode = FALSE 21 | EndGlobalSection 22 | EndGlobal 23 | -------------------------------------------------------------------------------- /bson/bson.vcxproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | Debug 6 | Win32 7 | 8 | 9 | Debug 10 | x64 11 | 12 | 13 | Release 14 | Win32 15 | 16 | 17 | Release 18 | x64 19 | 20 | 21 | 22 | {0DA99545-93E9-4C1B-861B-C4DAB5360AA8} 23 | Win32Proj 24 | 10.0.17134.0 25 | 26 | 27 | 28 | StaticLibrary 29 | true 30 | v141 31 | MultiByte 32 | 33 | 34 | StaticLibrary 35 | true 36 | v141_xp 37 | MultiByte 38 | 39 | 40 | StaticLibrary 41 | false 42 | v141_xp 43 | MultiByte 44 | true 45 | 46 | 47 | StaticLibrary 48 | false 49 | v141_xp 50 | MultiByte 51 | true 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | true 71 | 72 | 73 | true 74 | 75 | 76 | true 77 | 78 | 79 | true 80 | 81 | 82 | 83 | WIN32;_DEBUG;MONGO_HAVE_STDINT;MONGO_STATIC_BUILD;_LIB;%(PreprocessorDefinitions) 84 | MultiThreadedDebug 85 | Level3 86 | ProgramDatabase 87 | Disabled 88 | CompileAsC 89 | 90 | 91 | MachineX86 92 | true 93 | Windows 94 | 95 | 96 | 97 | 98 | WIN32;_DEBUG;MONGO_HAVE_STDINT;MONGO_STATIC_BUILD;_LIB;%(PreprocessorDefinitions) 99 | MultiThreadedDebug 100 | Level3 101 | ProgramDatabase 102 | Disabled 103 | CompileAsC 104 | 105 | 106 | true 107 | Windows 108 | 109 | 110 | 111 | 112 | WIN32;NDEBUG;MONGO_HAVE_STDINT;MONGO_STATIC_BUILD;_LIB;%(PreprocessorDefinitions) 113 | MultiThreaded 114 | Level3 115 | ProgramDatabase 116 | NoExtensions 117 | /Qsafe_fp_loads %(AdditionalOptions) 118 | 119 | 120 | MachineX86 121 | true 122 | Windows 123 | true 124 | true 125 | 126 | 127 | 128 | 129 | 130 | WIN32;NDEBUG;MONGO_HAVE_STDINT;MONGO_STATIC_BUILD;_LIB;%(PreprocessorDefinitions) 131 | MultiThreaded 132 | Level3 133 | ProgramDatabase 134 | 135 | 136 | true 137 | Windows 138 | true 139 | true 140 | 141 | 142 | 143 | 144 | 145 | 146 | 147 | 148 | 149 | 150 | 151 | 152 | 153 | 154 | 155 | -------------------------------------------------------------------------------- /bson/bson.vcxproj.filters: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF} 6 | cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx 7 | 8 | 9 | {93995380-89BD-4b04-88EB-625FBE52EBFB} 10 | h;hh;hpp;hxx;hm;inl;inc;xsd 11 | 12 | 13 | {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} 14 | rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav 15 | 16 | 17 | 18 | 19 | Source Files 20 | 21 | 22 | Source Files 23 | 24 | 25 | Source Files 26 | 27 | 28 | 29 | 30 | Header Files 31 | 32 | 33 | Header Files 34 | 35 | 36 | -------------------------------------------------------------------------------- /bson/encoding.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2009-2012 10gen, Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | /* 18 | * Portions Copyright 2001 Unicode, Inc. 19 | * 20 | * Disclaimer 21 | * 22 | * This source code is provided as is by Unicode, Inc. No claims are 23 | * made as to fitness for any particular purpose. No warranties of any 24 | * kind are expressed or implied. The recipient agrees to determine 25 | * applicability of information provided. If this file has been 26 | * purchased on magnetic or optical media from Unicode, Inc., the 27 | * sole remedy for any claim will be exchange of defective media 28 | * within 90 days of receipt. 29 | * 30 | * Limitations on Rights to Redistribute This Code 31 | * 32 | * Unicode, Inc. hereby grants the right to freely use the information 33 | * supplied in this file in the creation of products supporting the 34 | * Unicode Standard, and to make copies of this file in any form 35 | * for internal or external distribution as long as this notice 36 | * remains attached. 37 | */ 38 | 39 | 40 | #include "bson.h" 41 | #include "encoding.h" 42 | 43 | /* 44 | * Index into the table below with the first byte of a UTF-8 sequence to 45 | * get the number of trailing bytes that are supposed to follow it. 46 | */ 47 | static const char trailingBytesForUTF8[256] = { 48 | 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 49 | 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 50 | 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 51 | 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 52 | 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 53 | 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 54 | 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 55 | 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 3,3,3,3,3,3,3,3,4,4,4,4,5,5,5,5 56 | }; 57 | 58 | /* --------------------------------------------------------------------- */ 59 | 60 | /* 61 | * Utility routine to tell whether a sequence of bytes is legal UTF-8. 62 | * This must be called with the length pre-determined by the first byte. 63 | * The length can be set by: 64 | * length = trailingBytesForUTF8[*source]+1; 65 | * and the sequence is illegal right away if there aren't that many bytes 66 | * available. 67 | * If presented with a length > 4, this returns 0. The Unicode 68 | * definition of UTF-8 goes up to 4-byte sequences. 69 | */ 70 | static int isLegalUTF8( const unsigned char *source, int length ) { 71 | unsigned char a; 72 | const unsigned char *srcptr = source + length; 73 | switch ( length ) { 74 | default: 75 | return 0; 76 | /* Everything else falls through when "true"... */ 77 | case 4: 78 | if ( ( a = ( *--srcptr ) ) < 0x80 || a > 0xBF ) return 0; 79 | case 3: 80 | if ( ( a = ( *--srcptr ) ) < 0x80 || a > 0xBF ) return 0; 81 | case 2: 82 | if ( ( a = ( *--srcptr ) ) > 0xBF ) return 0; 83 | switch ( *source ) { 84 | /* no fall-through in this inner switch */ 85 | case 0xE0: 86 | if ( a < 0xA0 ) return 0; 87 | break; 88 | case 0xF0: 89 | if ( a < 0x90 ) return 0; 90 | break; 91 | case 0xF4: 92 | if ( a > 0x8F ) return 0; 93 | break; 94 | default: 95 | if ( a < 0x80 ) return 0; 96 | } 97 | case 1: 98 | if ( *source >= 0x80 && *source < 0xC2 ) return 0; 99 | if ( *source > 0xF4 ) return 0; 100 | } 101 | return 1; 102 | } 103 | 104 | /* If the name is part of a db ref ($ref, $db, or $id), then return true. */ 105 | static int bson_string_is_db_ref( const unsigned char *string, const size_t length ) { 106 | int result = 0; 107 | 108 | if( length >= 4 ) { 109 | if( string[1] == 'r' && string[2] == 'e' && string[3] == 'f' ) 110 | result = 1; 111 | } 112 | else if( length >= 3 ) { 113 | if( string[1] == 'i' && string[2] == 'd' ) 114 | result = 1; 115 | else if( string[1] == 'd' && string[2] == 'b' ) 116 | result = 1; 117 | } 118 | 119 | return result; 120 | } 121 | 122 | static int bson_validate_string( bson *b, const unsigned char *string, 123 | const size_t length, const char check_utf8, const char check_dot, 124 | const char check_dollar ) { 125 | 126 | size_t position = 0; 127 | int sequence_length = 1; 128 | 129 | if( check_dollar && string[0] == '$' ) { 130 | if( !bson_string_is_db_ref( string, length ) ) 131 | b->err |= BSON_FIELD_INIT_DOLLAR; 132 | } 133 | 134 | while ( position < length ) { 135 | if ( check_dot && *( string + position ) == '.' ) { 136 | b->err |= BSON_FIELD_HAS_DOT; 137 | } 138 | 139 | if ( check_utf8 ) { 140 | sequence_length = trailingBytesForUTF8[*( string + position )] + 1; 141 | if ( ( position + sequence_length ) > length ) { 142 | b->err |= BSON_NOT_UTF8; 143 | return BSON_ERROR; 144 | } 145 | if ( !isLegalUTF8( string + position, sequence_length ) ) { 146 | b->err |= BSON_NOT_UTF8; 147 | return BSON_ERROR; 148 | } 149 | } 150 | position += sequence_length; 151 | } 152 | 153 | return BSON_OK; 154 | } 155 | 156 | 157 | int bson_check_string( bson *b, const char *string, 158 | const size_t length ) { 159 | 160 | return bson_validate_string( b, ( const unsigned char * )string, length, 1, 0, 0 ); 161 | } 162 | 163 | int bson_check_field_name( bson *b, const char *string, 164 | const size_t length ) { 165 | 166 | return bson_validate_string( b, ( const unsigned char * )string, length, 1, 1, 1 ); 167 | } 168 | -------------------------------------------------------------------------------- /bson/encoding.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2009-2012 10gen, Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #ifndef BSON_ENCODING_H_ 18 | #define BSON_ENCODING_H_ 19 | 20 | MONGO_EXTERN_C_START 21 | 22 | /** 23 | * Check that a field name is valid UTF8, does not start with a '$', 24 | * and contains no '.' characters. Set bson bit field appropriately. 25 | * Note that we don't need to check for '\0' because we're using 26 | * strlen(3), which stops at '\0'. 27 | * 28 | * @param b The bson object to which field name will be appended. 29 | * @param string The field name as char*. 30 | * @param length The length of the field name. 31 | * 32 | * @return BSON_OK if valid UTF8 and BSON_ERROR if not. All BSON strings must be 33 | * valid UTF8. This function will also check whether the string 34 | * contains '.' or starts with '$', since the validity of this depends on context. 35 | * Set the value of b->err appropriately. 36 | */ 37 | int bson_check_field_name( bson *b, const char *string, 38 | const size_t length ); 39 | 40 | /** 41 | * Check that a string is valid UTF8. Sets the buffer bit field appropriately. 42 | * 43 | * @param b The bson object to which string will be appended. 44 | * @param string The string to check. 45 | * @param length The length of the string. 46 | * 47 | * @return BSON_OK if valid UTF-8; otherwise, BSON_ERROR. 48 | * Sets b->err on error. 49 | */ 50 | bson_bool_t bson_check_string( bson *b, const char *string, 51 | const size_t length ); 52 | 53 | MONGO_EXTERN_C_END 54 | #endif 55 | -------------------------------------------------------------------------------- /bson/numbers.c: -------------------------------------------------------------------------------- 1 | /* Copyright 2009-2012 10gen Inc. 2 | * 3 | * Licensed under the Apache License, Version 2.0 (the "License"); 4 | * you may not use this file except in compliance with the License. 5 | * You may obtain a copy of the License at 6 | * 7 | * http://www.apache.org/licenses/LICENSE-2.0 8 | * 9 | * Unless required by applicable law or agreed to in writing, software 10 | * distributed under the License is distributed on an "AS IS" BASIS, 11 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | * See the License for the specific language governing permissions and 13 | * limitations under the License. 14 | */ 15 | 16 | /* all the numbers that fit in a 4 byte string */ 17 | const char bson_numstrs[1000][4] = { 18 | "0", "1", "2", "3", "4", "5", "6", "7", "8", "9", 19 | "10", "11", "12", "13", "14", "15", "16", "17", "18", "19", 20 | "20", "21", "22", "23", "24", "25", "26", "27", "28", "29", 21 | "30", "31", "32", "33", "34", "35", "36", "37", "38", "39", 22 | "40", "41", "42", "43", "44", "45", "46", "47", "48", "49", 23 | "50", "51", "52", "53", "54", "55", "56", "57", "58", "59", 24 | "60", "61", "62", "63", "64", "65", "66", "67", "68", "69", 25 | "70", "71", "72", "73", "74", "75", "76", "77", "78", "79", 26 | "80", "81", "82", "83", "84", "85", "86", "87", "88", "89", 27 | "90", "91", "92", "93", "94", "95", "96", "97", "98", "99", 28 | 29 | "100", "101", "102", "103", "104", "105", "106", "107", "108", "109", 30 | "110", "111", "112", "113", "114", "115", "116", "117", "118", "119", 31 | "120", "121", "122", "123", "124", "125", "126", "127", "128", "129", 32 | "130", "131", "132", "133", "134", "135", "136", "137", "138", "139", 33 | "140", "141", "142", "143", "144", "145", "146", "147", "148", "149", 34 | "150", "151", "152", "153", "154", "155", "156", "157", "158", "159", 35 | "160", "161", "162", "163", "164", "165", "166", "167", "168", "169", 36 | "170", "171", "172", "173", "174", "175", "176", "177", "178", "179", 37 | "180", "181", "182", "183", "184", "185", "186", "187", "188", "189", 38 | "190", "191", "192", "193", "194", "195", "196", "197", "198", "199", 39 | 40 | "200", "201", "202", "203", "204", "205", "206", "207", "208", "209", 41 | "210", "211", "212", "213", "214", "215", "216", "217", "218", "219", 42 | "220", "221", "222", "223", "224", "225", "226", "227", "228", "229", 43 | "230", "231", "232", "233", "234", "235", "236", "237", "238", "239", 44 | "240", "241", "242", "243", "244", "245", "246", "247", "248", "249", 45 | "250", "251", "252", "253", "254", "255", "256", "257", "258", "259", 46 | "260", "261", "262", "263", "264", "265", "266", "267", "268", "269", 47 | "270", "271", "272", "273", "274", "275", "276", "277", "278", "279", 48 | "280", "281", "282", "283", "284", "285", "286", "287", "288", "289", 49 | "290", "291", "292", "293", "294", "295", "296", "297", "298", "299", 50 | 51 | "300", "301", "302", "303", "304", "305", "306", "307", "308", "309", 52 | "310", "311", "312", "313", "314", "315", "316", "317", "318", "319", 53 | "320", "321", "322", "323", "324", "325", "326", "327", "328", "329", 54 | "330", "331", "332", "333", "334", "335", "336", "337", "338", "339", 55 | "340", "341", "342", "343", "344", "345", "346", "347", "348", "349", 56 | "350", "351", "352", "353", "354", "355", "356", "357", "358", "359", 57 | "360", "361", "362", "363", "364", "365", "366", "367", "368", "369", 58 | "370", "371", "372", "373", "374", "375", "376", "377", "378", "379", 59 | "380", "381", "382", "383", "384", "385", "386", "387", "388", "389", 60 | "390", "391", "392", "393", "394", "395", "396", "397", "398", "399", 61 | 62 | "400", "401", "402", "403", "404", "405", "406", "407", "408", "409", 63 | "410", "411", "412", "413", "414", "415", "416", "417", "418", "419", 64 | "420", "421", "422", "423", "424", "425", "426", "427", "428", "429", 65 | "430", "431", "432", "433", "434", "435", "436", "437", "438", "439", 66 | "440", "441", "442", "443", "444", "445", "446", "447", "448", "449", 67 | "450", "451", "452", "453", "454", "455", "456", "457", "458", "459", 68 | "460", "461", "462", "463", "464", "465", "466", "467", "468", "469", 69 | "470", "471", "472", "473", "474", "475", "476", "477", "478", "479", 70 | "480", "481", "482", "483", "484", "485", "486", "487", "488", "489", 71 | "490", "491", "492", "493", "494", "495", "496", "497", "498", "499", 72 | 73 | "500", "501", "502", "503", "504", "505", "506", "507", "508", "509", 74 | "510", "511", "512", "513", "514", "515", "516", "517", "518", "519", 75 | "520", "521", "522", "523", "524", "525", "526", "527", "528", "529", 76 | "530", "531", "532", "533", "534", "535", "536", "537", "538", "539", 77 | "540", "541", "542", "543", "544", "545", "546", "547", "548", "549", 78 | "550", "551", "552", "553", "554", "555", "556", "557", "558", "559", 79 | "560", "561", "562", "563", "564", "565", "566", "567", "568", "569", 80 | "570", "571", "572", "573", "574", "575", "576", "577", "578", "579", 81 | "580", "581", "582", "583", "584", "585", "586", "587", "588", "589", 82 | "590", "591", "592", "593", "594", "595", "596", "597", "598", "599", 83 | 84 | "600", "601", "602", "603", "604", "605", "606", "607", "608", "609", 85 | "610", "611", "612", "613", "614", "615", "616", "617", "618", "619", 86 | "620", "621", "622", "623", "624", "625", "626", "627", "628", "629", 87 | "630", "631", "632", "633", "634", "635", "636", "637", "638", "639", 88 | "640", "641", "642", "643", "644", "645", "646", "647", "648", "649", 89 | "650", "651", "652", "653", "654", "655", "656", "657", "658", "659", 90 | "660", "661", "662", "663", "664", "665", "666", "667", "668", "669", 91 | "670", "671", "672", "673", "674", "675", "676", "677", "678", "679", 92 | "680", "681", "682", "683", "684", "685", "686", "687", "688", "689", 93 | "690", "691", "692", "693", "694", "695", "696", "697", "698", "699", 94 | 95 | "700", "701", "702", "703", "704", "705", "706", "707", "708", "709", 96 | "710", "711", "712", "713", "714", "715", "716", "717", "718", "719", 97 | "720", "721", "722", "723", "724", "725", "726", "727", "728", "729", 98 | "730", "731", "732", "733", "734", "735", "736", "737", "738", "739", 99 | "740", "741", "742", "743", "744", "745", "746", "747", "748", "749", 100 | "750", "751", "752", "753", "754", "755", "756", "757", "758", "759", 101 | "760", "761", "762", "763", "764", "765", "766", "767", "768", "769", 102 | "770", "771", "772", "773", "774", "775", "776", "777", "778", "779", 103 | "780", "781", "782", "783", "784", "785", "786", "787", "788", "789", 104 | "790", "791", "792", "793", "794", "795", "796", "797", "798", "799", 105 | 106 | "800", "801", "802", "803", "804", "805", "806", "807", "808", "809", 107 | "810", "811", "812", "813", "814", "815", "816", "817", "818", "819", 108 | "820", "821", "822", "823", "824", "825", "826", "827", "828", "829", 109 | "830", "831", "832", "833", "834", "835", "836", "837", "838", "839", 110 | "840", "841", "842", "843", "844", "845", "846", "847", "848", "849", 111 | "850", "851", "852", "853", "854", "855", "856", "857", "858", "859", 112 | "860", "861", "862", "863", "864", "865", "866", "867", "868", "869", 113 | "870", "871", "872", "873", "874", "875", "876", "877", "878", "879", 114 | "880", "881", "882", "883", "884", "885", "886", "887", "888", "889", 115 | "890", "891", "892", "893", "894", "895", "896", "897", "898", "899", 116 | 117 | "900", "901", "902", "903", "904", "905", "906", "907", "908", "909", 118 | "910", "911", "912", "913", "914", "915", "916", "917", "918", "919", 119 | "920", "921", "922", "923", "924", "925", "926", "927", "928", "929", 120 | "930", "931", "932", "933", "934", "935", "936", "937", "938", "939", 121 | "940", "941", "942", "943", "944", "945", "946", "947", "948", "949", 122 | "950", "951", "952", "953", "954", "955", "956", "957", "958", "959", 123 | "960", "961", "962", "963", "964", "965", "966", "967", "968", "969", 124 | "970", "971", "972", "973", "974", "975", "976", "977", "978", "979", 125 | "980", "981", "982", "983", "984", "985", "986", "987", "988", "989", 126 | "990", "991", "992", "993", "994", "995", "996", "997", "998", "999", 127 | }; 128 | -------------------------------------------------------------------------------- /capstone-config.mk: -------------------------------------------------------------------------------- 1 | # This file contains all customized compile options for Capstone. 2 | # Modify it before building step. Consult docs/README for details. 3 | 4 | ################################################################################ 5 | # Specify which archs you want to compile in. By default, we build all archs. 6 | 7 | CAPSTONE_ARCHS ?= x86 8 | 9 | 10 | ################################################################################ 11 | # Comment out the line below ('CAPSTONE_USE_SYS_DYN_MEM = yes'), or change it to 12 | # 'CAPSTONE_USE_SYS_DYN_MEM = no' if do NOT use malloc/calloc/realloc/free/ 13 | # vsnprintf() provided by system for internal dynamic memory management. 14 | # 15 | # NOTE: in that case, specify your own malloc/calloc/realloc/free/vsnprintf() 16 | # functions in your program via API cs_option(), using CS_OPT_MEM option type. 17 | 18 | CAPSTONE_USE_SYS_DYN_MEM ?= yes 19 | 20 | 21 | ################################################################################ 22 | # Change 'CAPSTONE_DIET = no' to 'CAPSTONE_DIET = yes' to make the library 23 | # more compact: use less memory & smaller in binary size. 24 | # This setup will remove the @mnemonic & @op_str data, plus semantic information 25 | # such as @regs_read/write & @group. The amount of binary size reduced is 26 | # up to 50% in some individual archs. 27 | # 28 | # NOTE: we still keep all those related fileds @mnemonic, @op_str, @regs_read, 29 | # @regs_write, @groups, etc in fields in cs_insn structure regardless, but they 30 | # will not be updated (i.e empty), thus become irrelevant. 31 | 32 | CAPSTONE_DIET ?= yes 33 | 34 | 35 | ################################################################################ 36 | # Change 'CAPSTONE_X86_REDUCE = no' to 'CAPSTONE_X86_REDUCE = yes' to remove 37 | # non-critical instruction sets of X86, making the binary size smaller by ~60%. 38 | # This is desired in special cases, such as OS kernel, where these kind of 39 | # instructions are not used. 40 | # 41 | # The list of instruction sets to be removed includes: 42 | # - Floating Point Unit (FPU) 43 | # - MultiMedia eXtension (MMX) 44 | # - Streaming SIMD Extensions (SSE) 45 | # - 3DNow 46 | # - Advanced Vector Extensions (AVX) 47 | # - Fused Multiply Add Operations (FMA) 48 | # - eXtended Operations (XOP) 49 | # - Transactional Synchronization Extensions (TSX) 50 | # 51 | # Due to this removal, the related instructions are nolonger supported. 52 | # 53 | # By default, Capstone is compiled with 'CAPSTONE_X86_REDUCE = no', 54 | # thus supports complete X86 instructions. 55 | 56 | CAPSTONE_X86_REDUCE ?= yes 57 | 58 | 59 | ################################################################################ 60 | # Change 'CAPSTONE_STATIC = yes' to 'CAPSTONE_STATIC = no' to avoid building 61 | # a static library. 62 | 63 | CAPSTONE_STATIC ?= yes 64 | 65 | 66 | ################################################################################ 67 | # Change 'CAPSTONE_SHARED = yes' to 'CAPSTONE_SHARED = no' to avoid building 68 | # a shared library. 69 | 70 | CAPSTONE_SHARED ?= no 71 | -------------------------------------------------------------------------------- /config.h: -------------------------------------------------------------------------------- 1 | #ifndef __CONFIG_H 2 | #define __CONFIG_H 3 | 4 | /* 5 | Cuckoo Sandbox - Automated Malware Analysis 6 | Copyright (C) 2010-2012 Cuckoo Sandbox Developers 7 | 8 | This program is free software: you can redistribute it and/or modify 9 | it under the terms of the GNU General Public License as published by 10 | the Free Software Foundation, either version 3 of the License, or 11 | (at your option) any later version. 12 | 13 | This program is distributed in the hope that it will be useful, 14 | but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | GNU General Public License for more details. 17 | 18 | You should have received a copy of the GNU General Public License 19 | along with this program. If not, see . 20 | */ 21 | 22 | #define EXCLUSION_MAX 128 23 | 24 | struct _g_config { 25 | // name of the pipe to communicate with cuckoo 26 | wchar_t pipe_name[MAX_PATH]; 27 | 28 | char logserver[MAX_PATH]; 29 | 30 | // results directory, has to be hidden 31 | char results[MAX_PATH]; 32 | 33 | // results directory, has to be hidden 34 | wchar_t w_results[MAX_PATH]; 35 | 36 | // analyzer directory, has to be hidden 37 | char analyzer[MAX_PATH]; 38 | 39 | // analyzer directory, has to be hidden 40 | wchar_t w_analyzer[MAX_PATH]; 41 | 42 | // cuckoomon DLL directory 43 | wchar_t dllpath[MAX_PATH]; 44 | 45 | // file of interest 46 | wchar_t *file_of_interest; 47 | 48 | // URL of interest 49 | wchar_t *url_of_interest; 50 | 51 | // Referrer for initial URL request 52 | wchar_t *w_referrer; 53 | char *referrer; 54 | 55 | // if this mutex exists then we're shutting down 56 | char shutdown_mutex[MAX_PATH]; 57 | 58 | // event set by analyzer when our process is potentially going to be terminated 59 | // cuckoomon itself will flush logs at this point, but the analyzer may take additional 60 | // actions, like process dumping 61 | char terminate_event_name[MAX_PATH]; 62 | 63 | // is this the first process or not? 64 | int first_process; 65 | 66 | // do we want to ignore "file of interest" and other forms of log reduction? 67 | int full_logs; 68 | 69 | // should we attempt anti-anti-sandbox/VM tricks ? 70 | int no_stealth; 71 | 72 | // how many milliseconds since startup 73 | unsigned int startup_time; 74 | 75 | // system volume serial number (for reproducing Milicenso) 76 | unsigned int serial_number; 77 | 78 | // system32 create time (for reproducing Milicenso) 79 | FILETIME sys32_ctime; 80 | 81 | // system volume information create time (for reproducing Milicenso) 82 | FILETIME sysvol_ctime; 83 | 84 | // do we force sleep-skipping despite threads? 85 | int force_sleepskip; 86 | 87 | // do we force flushing of each log? 88 | int force_flush; 89 | 90 | // Debugging level (1 = display exceptions, 2 = display all exceptions) 91 | int debug; 92 | 93 | // Default hook type (may be overridden for specific functions) 94 | int hook_type; 95 | 96 | // Disable hook content 97 | int disable_hook_content; 98 | 99 | // server ip and port 100 | //unsigned int host_ip; 101 | //unsigned short host_port; 102 | 103 | BOOLEAN suspend_logging; 104 | 105 | char *excluded_apinames[EXCLUSION_MAX]; 106 | wchar_t *excluded_dllnames[EXCLUSION_MAX]; 107 | char *base_on_apiname[EXCLUSION_MAX]; 108 | char *dump_on_apinames[EXCLUSION_MAX]; 109 | 110 | // should we dump each process on exit/analysis timeout? 111 | int procdump; 112 | int procmemdump; 113 | 114 | // should we attempt import reconstruction on each process dump? (slow) 115 | int import_reconstruction; 116 | 117 | // should we terminate processes after dumping on terminate_event? 118 | int terminate_processes; 119 | }; 120 | 121 | extern struct _g_config g_config; 122 | 123 | int read_config(void); 124 | 125 | #endif 126 | -------------------------------------------------------------------------------- /cuckoomon.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio 14 4 | VisualStudioVersion = 14.0.25420.1 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "cuckoomon", "cuckoomon.vcxproj", "{15C69A24-71D1-4A1A-B39B-0466181ACD7E}" 7 | ProjectSection(ProjectDependencies) = postProject 8 | {0DA99545-93E9-4C1B-861B-C4DAB5360AA8} = {0DA99545-93E9-4C1B-861B-C4DAB5360AA8} 9 | EndProjectSection 10 | EndProject 11 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "bson", "bson\bson.vcxproj", "{0DA99545-93E9-4C1B-861B-C4DAB5360AA8}" 12 | EndProject 13 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "loader", "loader\loader\loader.vcxproj", "{52D1444F-0B18-4F98-BC62-3D11046190CC}" 14 | EndProject 15 | Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{B260DD6D-6C2D-4FD4-B07D-EAE4AA5658C4}" 16 | ProjectSection(SolutionItems) = preProject 17 | README.md = README.md 18 | EndProjectSection 19 | EndProject 20 | Global 21 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 22 | Debug|Mixed Platforms = Debug|Mixed Platforms 23 | Debug|Win32 = Debug|Win32 24 | Debug|x64 = Debug|x64 25 | Release|Mixed Platforms = Release|Mixed Platforms 26 | Release|Win32 = Release|Win32 27 | Release|x64 = Release|x64 28 | EndGlobalSection 29 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 30 | {15C69A24-71D1-4A1A-B39B-0466181ACD7E}.Debug|Mixed Platforms.ActiveCfg = Debug|Win32 31 | {15C69A24-71D1-4A1A-B39B-0466181ACD7E}.Debug|Mixed Platforms.Build.0 = Debug|Win32 32 | {15C69A24-71D1-4A1A-B39B-0466181ACD7E}.Debug|Win32.ActiveCfg = Debug|Win32 33 | {15C69A24-71D1-4A1A-B39B-0466181ACD7E}.Debug|Win32.Build.0 = Debug|Win32 34 | {15C69A24-71D1-4A1A-B39B-0466181ACD7E}.Debug|x64.ActiveCfg = Debug|x64 35 | {15C69A24-71D1-4A1A-B39B-0466181ACD7E}.Debug|x64.Build.0 = Debug|x64 36 | {15C69A24-71D1-4A1A-B39B-0466181ACD7E}.Release|Mixed Platforms.ActiveCfg = Release|Win32 37 | {15C69A24-71D1-4A1A-B39B-0466181ACD7E}.Release|Mixed Platforms.Build.0 = Release|Win32 38 | {15C69A24-71D1-4A1A-B39B-0466181ACD7E}.Release|Win32.ActiveCfg = Release|Win32 39 | {15C69A24-71D1-4A1A-B39B-0466181ACD7E}.Release|Win32.Build.0 = Release|Win32 40 | {15C69A24-71D1-4A1A-B39B-0466181ACD7E}.Release|x64.ActiveCfg = Release|x64 41 | {15C69A24-71D1-4A1A-B39B-0466181ACD7E}.Release|x64.Build.0 = Release|x64 42 | {0DA99545-93E9-4C1B-861B-C4DAB5360AA8}.Debug|Mixed Platforms.ActiveCfg = Debug|Win32 43 | {0DA99545-93E9-4C1B-861B-C4DAB5360AA8}.Debug|Mixed Platforms.Build.0 = Debug|Win32 44 | {0DA99545-93E9-4C1B-861B-C4DAB5360AA8}.Debug|Win32.ActiveCfg = Debug|Win32 45 | {0DA99545-93E9-4C1B-861B-C4DAB5360AA8}.Debug|Win32.Build.0 = Debug|Win32 46 | {0DA99545-93E9-4C1B-861B-C4DAB5360AA8}.Debug|x64.ActiveCfg = Debug|x64 47 | {0DA99545-93E9-4C1B-861B-C4DAB5360AA8}.Debug|x64.Build.0 = Debug|x64 48 | {0DA99545-93E9-4C1B-861B-C4DAB5360AA8}.Release|Mixed Platforms.ActiveCfg = Release|Win32 49 | {0DA99545-93E9-4C1B-861B-C4DAB5360AA8}.Release|Mixed Platforms.Build.0 = Release|Win32 50 | {0DA99545-93E9-4C1B-861B-C4DAB5360AA8}.Release|Win32.ActiveCfg = Release|Win32 51 | {0DA99545-93E9-4C1B-861B-C4DAB5360AA8}.Release|Win32.Build.0 = Release|Win32 52 | {0DA99545-93E9-4C1B-861B-C4DAB5360AA8}.Release|x64.ActiveCfg = Release|x64 53 | {0DA99545-93E9-4C1B-861B-C4DAB5360AA8}.Release|x64.Build.0 = Release|x64 54 | {52D1444F-0B18-4F98-BC62-3D11046190CC}.Debug|Mixed Platforms.ActiveCfg = Debug|Win32 55 | {52D1444F-0B18-4F98-BC62-3D11046190CC}.Debug|Mixed Platforms.Build.0 = Debug|Win32 56 | {52D1444F-0B18-4F98-BC62-3D11046190CC}.Debug|Win32.ActiveCfg = Debug|Win32 57 | {52D1444F-0B18-4F98-BC62-3D11046190CC}.Debug|Win32.Build.0 = Debug|Win32 58 | {52D1444F-0B18-4F98-BC62-3D11046190CC}.Debug|x64.ActiveCfg = Debug|x64 59 | {52D1444F-0B18-4F98-BC62-3D11046190CC}.Debug|x64.Build.0 = Debug|x64 60 | {52D1444F-0B18-4F98-BC62-3D11046190CC}.Release|Mixed Platforms.ActiveCfg = Release|Win32 61 | {52D1444F-0B18-4F98-BC62-3D11046190CC}.Release|Mixed Platforms.Build.0 = Release|Win32 62 | {52D1444F-0B18-4F98-BC62-3D11046190CC}.Release|Win32.ActiveCfg = Release|Win32 63 | {52D1444F-0B18-4F98-BC62-3D11046190CC}.Release|Win32.Build.0 = Release|Win32 64 | {52D1444F-0B18-4F98-BC62-3D11046190CC}.Release|x64.ActiveCfg = Release|x64 65 | {52D1444F-0B18-4F98-BC62-3D11046190CC}.Release|x64.Build.0 = Release|x64 66 | EndGlobalSection 67 | GlobalSection(SolutionProperties) = preSolution 68 | HideSolutionNode = FALSE 69 | EndGlobalSection 70 | EndGlobal 71 | -------------------------------------------------------------------------------- /distorm/COPYING: -------------------------------------------------------------------------------- 1 | :[diStorm3}: 2 | The ultimate disassembler library. 3 | Copyright (c) 2003-2016, Gil Dabah 4 | All rights reserved. 5 | 6 | Redistribution and use in source and binary forms, with or without 7 | modification, are permitted provided that the following conditions are met: 8 | * Redistributions of source code must retain the above copyright 9 | notice, this list of conditions and the following disclaimer. 10 | * Redistributions in binary form must reproduce the above copyright 11 | notice, this list of conditions and the following disclaimer in the 12 | documentation and/or other materials provided with the distribution. 13 | * Neither the name of the Gil Dabah nor the 14 | names of its contributors may be used to endorse or promote products 15 | derived from this software without specific prior written permission. 16 | 17 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 18 | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 19 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 20 | DISCLAIMED. IN NO EVENT SHALL GIL DABAH BE LIABLE FOR ANY 21 | DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 22 | (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 23 | LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 24 | ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 25 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 26 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 | -------------------------------------------------------------------------------- /distorm/src/config.h: -------------------------------------------------------------------------------- 1 | /* 2 | config.h 3 | 4 | diStorm3 - Powerful disassembler for X86/AMD64 5 | http://ragestorm.net/distorm/ 6 | distorm at gmail dot com 7 | Copyright (C) 2003-2016 Gil Dabah 8 | This library is licensed under the BSD license. See the file COPYING. 9 | */ 10 | 11 | 12 | #ifndef CONFIG_H 13 | #define CONFIG_H 14 | 15 | /* diStorm version number. */ 16 | #define __DISTORMV__ 0x030304 17 | 18 | #include /* memset, memcpy - can be easily self implemented for libc independency. */ 19 | 20 | #include "../include/distorm.h" 21 | 22 | 23 | /* 24 | * 64 bit offsets support: 25 | * This macro should be defined from compiler command line flags, e.g: -DSUPPORT_64BIT_OFFSET 26 | * Note: make sure that the caller (library user) defines it too! 27 | */ 28 | /* #define SUPPORT_64BIT_OFFSET */ 29 | 30 | /* 31 | * If you compile diStorm as a dynamic library (.dll or .so) file, make sure you uncomment the next line. 32 | * So the interface functions will be exported, otherwise they are useable only for static library. 33 | * For example, this macro is being set for compiling diStorm as a .dll for Python with CTypes. 34 | */ 35 | /* #define DISTORM_DYNAMIC */ 36 | 37 | /* 38 | * If DISTORM_LIGHT is defined, everything involved in formatting the instructions 39 | * as text will be excluded from compilation. 40 | * distorm_decode(..) and distorm_format(..) will not be available. 41 | * This will decrease the size of the executable and leave you with decomposition functionality only. 42 | * 43 | * Note: it should be either set in the preprocessor definitions manually or in command line -D switch. 44 | * #define DISTORM_LIGHT 45 | */ 46 | 47 | /* 48 | * diStorm now supports little/big endian CPU's. 49 | * It should detect the endianness according to predefined macro's of the compiler. 50 | * If you don't use GCC/MSVC you will have to define it on your own. 51 | */ 52 | 53 | /* These macros are used in order to make the code portable. */ 54 | #ifdef __GNUC__ 55 | 56 | #include 57 | 58 | #define _DLLEXPORT_ 59 | #define _FASTCALL_ 60 | #define _INLINE_ static 61 | /* GCC ignores this directive... */ 62 | /*#define _FASTCALL_ __attribute__((__fastcall__))*/ 63 | 64 | /* Set endianity (supposed to be LE though): */ 65 | #ifdef __BIG_ENDIAN__ 66 | #define BE_SYSTEM 67 | #endif 68 | 69 | /* End of __GCC__ */ 70 | 71 | #elif __WATCOMC__ 72 | 73 | #include 74 | 75 | #define _DLLEXPORT_ 76 | #define _FASTCALL_ 77 | #define _INLINE_ __inline 78 | 79 | /* End of __WATCOMC__ */ 80 | 81 | #elif __DMC__ 82 | 83 | #include 84 | 85 | #define _DLLEXPORT_ 86 | #define _FASTCALL_ 87 | #define _INLINE_ __inline 88 | 89 | /* End of __DMC__ */ 90 | 91 | #elif __TINYC__ 92 | 93 | #include 94 | 95 | #define _DLLEXPORT_ 96 | #define _FASTCALL_ 97 | #define _INLINE_ 98 | 99 | /* End of __TINYC__ */ 100 | 101 | #elif _MSC_VER 102 | 103 | /* stdint alternative is defined in distorm.h */ 104 | 105 | #define _DLLEXPORT_ __declspec(dllexport) 106 | #define _FASTCALL_ __fastcall 107 | #define _INLINE_ __inline 108 | 109 | /* Set endianity (supposed to be LE though): */ 110 | #if !defined(_M_IX86) && !defined(_M_X64) 111 | #define BE_SYSTEM 112 | #endif 113 | 114 | #endif /* #elif _MSC_VER */ 115 | 116 | /* If the library isn't compiled as a dynamic library don't export any functions. */ 117 | #ifndef DISTORM_DYNAMIC 118 | #undef _DLLEXPORT_ 119 | #define _DLLEXPORT_ 120 | #endif 121 | 122 | #ifndef FALSE 123 | #define FALSE 0 124 | #endif 125 | #ifndef TRUE 126 | #define TRUE 1 127 | #endif 128 | 129 | /* Define stream read functions for big endian systems. */ 130 | #ifdef BE_SYSTEM 131 | /* 132 | * These functions can read from the stream safely! 133 | * Swap endianity of input to little endian. 134 | */ 135 | static _INLINE_ int16_t RSHORT(const uint8_t *s) 136 | { 137 | return s[0] | (s[1] << 8); 138 | } 139 | static _INLINE_ uint16_t RUSHORT(const uint8_t *s) 140 | { 141 | return s[0] | (s[1] << 8); 142 | } 143 | static _INLINE_ int32_t RLONG(const uint8_t *s) 144 | { 145 | return s[0] | (s[1] << 8) | (s[2] << 16) | (s[3] << 24); 146 | } 147 | static _INLINE_ uint32_t RULONG(const uint8_t *s) 148 | { 149 | return s[0] | (s[1] << 8) | (s[2] << 16) | (s[3] << 24); 150 | } 151 | static _INLINE_ int64_t RLLONG(const uint8_t *s) 152 | { 153 | return s[0] | (s[1] << 8) | (s[2] << 16) | (s[3] << 24) | ((uint64_t)s[4] << 32) | ((uint64_t)s[5] << 40) | ((uint64_t)s[6] << 48) | ((uint64_t)s[7] << 56); 154 | } 155 | static _INLINE_ uint64_t RULLONG(const uint8_t *s) 156 | { 157 | return s[0] | (s[1] << 8) | (s[2] << 16) | (s[3] << 24) | ((uint64_t)s[4] << 32) | ((uint64_t)s[5] << 40) | ((uint64_t)s[6] << 48) | ((uint64_t)s[7] << 56); 158 | } 159 | #else 160 | /* Little endian macro's will just make the cast. */ 161 | #define RSHORT(x) *(int16_t *)x 162 | #define RUSHORT(x) *(uint16_t *)x 163 | #define RLONG(x) *(int32_t *)x 164 | #define RULONG(x) *(uint32_t *)x 165 | #define RLLONG(x) *(int64_t *)x 166 | #define RULLONG(x) *(uint64_t *)x 167 | #endif 168 | 169 | #endif /* CONFIG_H */ 170 | -------------------------------------------------------------------------------- /distorm/src/decoder.h: -------------------------------------------------------------------------------- 1 | /* 2 | decoder.h 3 | 4 | diStorm3 - Powerful disassembler for X86/AMD64 5 | http://ragestorm.net/distorm/ 6 | distorm at gmail dot com 7 | Copyright (C) 2011 Gil Dabah 8 | 9 | This program is free software: you can redistribute it and/or modify 10 | it under the terms of the GNU General Public License as published by 11 | the Free Software Foundation, either version 3 of the License, or 12 | (at your option) any later version. 13 | 14 | This program is distributed in the hope that it will be useful, 15 | but WITHOUT ANY WARRANTY; without even the implied warranty of 16 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17 | GNU General Public License for more details. 18 | 19 | You should have received a copy of the GNU General Public License 20 | along with this program. If not, see 21 | */ 22 | 23 | 24 | #ifndef DECODER_H 25 | #define DECODER_H 26 | 27 | #include "config.h" 28 | 29 | typedef unsigned int _iflags; 30 | 31 | _DecodeResult decode_internal(_CodeInfo* ci, int supportOldIntr, _DInst result[], unsigned int maxResultCount, unsigned int* usedInstructionsCount); 32 | 33 | #endif /* DECODER_H */ 34 | -------------------------------------------------------------------------------- /distorm/src/insts.h: -------------------------------------------------------------------------------- 1 | /* 2 | insts.h 3 | 4 | diStorm3 - Powerful disassembler for X86/AMD64 5 | http://ragestorm.net/distorm/ 6 | distorm at gmail dot com 7 | Copyright (C) 2003-2016 Gil Dabah 8 | This library is licensed under the BSD license. See the file COPYING. 9 | */ 10 | 11 | 12 | #ifndef INSTS_H 13 | #define INSTS_H 14 | 15 | #include "instructions.h" 16 | 17 | 18 | /* Flags Table */ 19 | extern _iflags FlagsTable[]; 20 | 21 | /* Root Trie DB */ 22 | extern _InstSharedInfo InstSharedInfoTable[]; 23 | extern _InstInfo InstInfos[]; 24 | extern _InstInfoEx InstInfosEx[]; 25 | extern _InstNode InstructionsTree[]; 26 | 27 | /* 3DNow! Trie DB */ 28 | extern _InstNode Table_0F_0F; 29 | /* AVX related: */ 30 | extern _InstNode Table_0F, Table_0F_38, Table_0F_3A; 31 | 32 | /* 33 | * The inst_lookup will return on of these two instructions according to the specified decoding mode. 34 | * ARPL or MOVSXD on 64 bits is one byte instruction at index 0x63. 35 | */ 36 | extern _InstInfo II_MOVSXD; 37 | 38 | /* 39 | * The NOP instruction can be prefixed by REX in 64bits, therefore we have to decide in runtime whether it's an XCHG or NOP instruction. 40 | * If 0x90 is prefixed by a usable REX it will become XCHG, otherwise it will become a NOP. 41 | * Also note that if it's prefixed by 0xf3, it becomes a Pause. 42 | */ 43 | extern _InstInfo II_NOP; 44 | extern _InstInfo II_PAUSE; 45 | 46 | /* 47 | * RDRAND and VMPTRLD share same 2.3 bytes opcode, and then alternates on the MOD bits, 48 | * RDRAND is OT_FULL_REG while VMPTRLD is OT_MEM, and there's no such mixed type. 49 | * So a hack into the inst_lookup was added for this decision, the DB isn't flexible enough. :( 50 | */ 51 | extern _InstInfo II_RDRAND; 52 | 53 | /* 54 | * Used for letting the extract operand know the type of operands without knowing the 55 | * instruction itself yet, because of the way those instructions work. 56 | * See function instructions.c!inst_lookup_3dnow. 57 | */ 58 | extern _InstInfo II_3DNOW; 59 | 60 | /* Helper tables for pseudo compare mnemonics. */ 61 | extern uint16_t CmpMnemonicOffsets[8]; /* SSE */ 62 | extern uint16_t VCmpMnemonicOffsets[32]; /* AVX */ 63 | 64 | #endif /* INSTS_H */ 65 | -------------------------------------------------------------------------------- /distorm/src/operands.h: -------------------------------------------------------------------------------- 1 | /* 2 | operands.h 3 | 4 | diStorm3 - Powerful disassembler for X86/AMD64 5 | http://ragestorm.net/distorm/ 6 | distorm at gmail dot com 7 | Copyright (C) 2003-2016 Gil Dabah 8 | This library is licensed under the BSD license. See the file COPYING. 9 | */ 10 | 11 | 12 | #ifndef OPERANDS_H 13 | #define OPERANDS_H 14 | 15 | #include "config.h" 16 | #include "decoder.h" 17 | #include "prefix.h" 18 | #include "instructions.h" 19 | 20 | 21 | extern uint32_t _REGISTERTORCLASS[]; 22 | 23 | int operands_extract(_CodeInfo* ci, _DInst* di, _InstInfo* ii, 24 | _iflags instFlags, _OpType type, _OperandNumberType opNum, 25 | unsigned int modrm, _PrefixState* ps, _DecodeType effOpSz, 26 | _DecodeType effAdrSz, int* lockableInstruction); 27 | 28 | #endif /* OPERANDS_H */ 29 | -------------------------------------------------------------------------------- /distorm/src/prefix.c: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ctxis/capemon/d7882e501202b34fb087e89b4e30a37e903ced74/distorm/src/prefix.c -------------------------------------------------------------------------------- /distorm/src/prefix.h: -------------------------------------------------------------------------------- 1 | /* 2 | prefix.h 3 | 4 | diStorm3 - Powerful disassembler for X86/AMD64 5 | http://ragestorm.net/distorm/ 6 | distorm at gmail dot com 7 | Copyright (C) 2003-2016 Gil Dabah 8 | This library is licensed under the BSD license. See the file COPYING. 9 | */ 10 | 11 | 12 | #ifndef PREFIX_H 13 | #define PREFIX_H 14 | 15 | #include "config.h" 16 | #include "decoder.h" 17 | 18 | 19 | /* Specifies the type of the extension prefix, such as: REX, 2 bytes VEX, 3 bytes VEX. */ 20 | typedef enum {PET_NONE = 0, PET_REX, PET_VEX2BYTES, PET_VEX3BYTES} _PrefixExtType; 21 | 22 | /* Specifies an index into a table of prefixes by their type. */ 23 | typedef enum {PFXIDX_NONE = -1, PFXIDX_REX, PFXIDX_LOREP, PFXIDX_SEG, PFXIDX_OP_SIZE, PFXIDX_ADRS, PFXIDX_MAX} _PrefixIndexer; 24 | 25 | /* 26 | * This holds the prefixes state for the current instruction we decode. 27 | * decodedPrefixes includes all specific prefixes that the instruction got. 28 | * start is a pointer to the first prefix to take into account. 29 | * last is a pointer to the last byte we scanned. 30 | * Other pointers are used to keep track of prefixes positions and help us know if they appeared already and where. 31 | */ 32 | typedef struct { 33 | _iflags decodedPrefixes, usedPrefixes; 34 | const uint8_t *start, *last, *vexPos, *rexPos; 35 | _PrefixExtType prefixExtType; 36 | uint16_t unusedPrefixesMask; 37 | /* Indicates whether the operand size prefix (0x66) was used as a mandatory prefix. */ 38 | int isOpSizeMandatory; 39 | /* If VEX prefix is used, store the VEX.vvvv field. */ 40 | unsigned int vexV; 41 | /* The fields B/X/R/W/L of REX and VEX are stored together in this byte. */ 42 | unsigned int vrex; 43 | 44 | /* !! Make sure pfxIndexer is LAST! Otherwise memset won't work well with it. !! */ 45 | 46 | /* Holds the offset to the prefix byte by its type. */ 47 | int pfxIndexer[PFXIDX_MAX]; 48 | } _PrefixState; 49 | 50 | /* 51 | * Intel supports 6 types of prefixes, whereas AMD supports 5 types (lock is seperated from rep/nz). 52 | * REX is the fifth prefix type, this time I'm based on AMD64. 53 | * VEX is the 6th, though it can't be repeated. 54 | */ 55 | #define MAX_PREFIXES (5) 56 | 57 | int prefixes_is_valid(unsigned int ch, _DecodeType dt); 58 | void prefixes_ignore(_PrefixState* ps, _PrefixIndexer pi); 59 | void prefixes_ignore_all(_PrefixState* ps); 60 | uint16_t prefixes_set_unused_mask(_PrefixState* ps); 61 | void prefixes_decode(const uint8_t* code, int codeLen, _PrefixState* ps, _DecodeType dt); 62 | void prefixes_use_segment(_iflags defaultSeg, _PrefixState* ps, _DecodeType dt, _DInst* di); 63 | 64 | #endif /* PREFIX_H */ 65 | -------------------------------------------------------------------------------- /distorm/src/textdefs.c: -------------------------------------------------------------------------------- 1 | /* 2 | textdefs.c 3 | 4 | diStorm3 - Powerful disassembler for X86/AMD64 5 | http://ragestorm.net/distorm/ 6 | distorm at gmail dot com 7 | Copyright (C) 2003-2016 Gil Dabah 8 | This library is licensed under the BSD license. See the file COPYING. 9 | */ 10 | 11 | 12 | #include "textdefs.h" 13 | 14 | #ifndef DISTORM_LIGHT 15 | 16 | static uint8_t Nibble2ChrTable[16] = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'}; 17 | #define NIBBLE_TO_CHR Nibble2ChrTable[t] 18 | 19 | void _FASTCALL_ str_hex_b(_WString* s, unsigned int x) 20 | { 21 | /* 22 | * def prebuilt(): 23 | * s = "" 24 | * for i in xrange(256): 25 | * if ((i % 0x10) == 0): 26 | * s += "\r\n" 27 | * s += "\"%02x\", " % (i) 28 | * return s 29 | */ 30 | static int8_t TextBTable[256][3] = { 31 | "00", "01", "02", "03", "04", "05", "06", "07", "08", "09", "0a", "0b", "0c", "0d", "0e", "0f", 32 | "10", "11", "12", "13", "14", "15", "16", "17", "18", "19", "1a", "1b", "1c", "1d", "1e", "1f", 33 | "20", "21", "22", "23", "24", "25", "26", "27", "28", "29", "2a", "2b", "2c", "2d", "2e", "2f", 34 | "30", "31", "32", "33", "34", "35", "36", "37", "38", "39", "3a", "3b", "3c", "3d", "3e", "3f", 35 | "40", "41", "42", "43", "44", "45", "46", "47", "48", "49", "4a", "4b", "4c", "4d", "4e", "4f", 36 | "50", "51", "52", "53", "54", "55", "56", "57", "58", "59", "5a", "5b", "5c", "5d", "5e", "5f", 37 | "60", "61", "62", "63", "64", "65", "66", "67", "68", "69", "6a", "6b", "6c", "6d", "6e", "6f", 38 | "70", "71", "72", "73", "74", "75", "76", "77", "78", "79", "7a", "7b", "7c", "7d", "7e", "7f", 39 | "80", "81", "82", "83", "84", "85", "86", "87", "88", "89", "8a", "8b", "8c", "8d", "8e", "8f", 40 | "90", "91", "92", "93", "94", "95", "96", "97", "98", "99", "9a", "9b", "9c", "9d", "9e", "9f", 41 | "a0", "a1", "a2", "a3", "a4", "a5", "a6", "a7", "a8", "a9", "aa", "ab", "ac", "ad", "ae", "af", 42 | "b0", "b1", "b2", "b3", "b4", "b5", "b6", "b7", "b8", "b9", "ba", "bb", "bc", "bd", "be", "bf", 43 | "c0", "c1", "c2", "c3", "c4", "c5", "c6", "c7", "c8", "c9", "ca", "cb", "cc", "cd", "ce", "cf", 44 | "d0", "d1", "d2", "d3", "d4", "d5", "d6", "d7", "d8", "d9", "da", "db", "dc", "dd", "de", "df", 45 | "e0", "e1", "e2", "e3", "e4", "e5", "e6", "e7", "e8", "e9", "ea", "eb", "ec", "ed", "ee", "ef", 46 | "f0", "f1", "f2", "f3", "f4", "f5", "f6", "f7", "f8", "f9", "fa", "fb", "fc", "fd", "fe", "ff" 47 | }; 48 | 49 | /* 50 | * Fixed length of 3 including null terminate character. 51 | */ 52 | memcpy(&s->p[s->length], TextBTable[x & 255], 3); 53 | s->length += 2; 54 | } 55 | 56 | void _FASTCALL_ str_code_hb(_WString* s, unsigned int x) 57 | { 58 | static int8_t TextHBTable[256][5] = { 59 | /* 60 | * def prebuilt(): 61 | * s = "" 62 | * for i in xrange(256): 63 | * if ((i % 0x10) == 0): 64 | * s += "\r\n" 65 | * s += "\"0x%x\", " % (i) 66 | * return s 67 | */ 68 | "0x0", "0x1", "0x2", "0x3", "0x4", "0x5", "0x6", "0x7", "0x8", "0x9", "0xa", "0xb", "0xc", "0xd", "0xe", "0xf", 69 | "0x10", "0x11", "0x12", "0x13", "0x14", "0x15", "0x16", "0x17", "0x18", "0x19", "0x1a", "0x1b", "0x1c", "0x1d", "0x1e", "0x1f", 70 | "0x20", "0x21", "0x22", "0x23", "0x24", "0x25", "0x26", "0x27", "0x28", "0x29", "0x2a", "0x2b", "0x2c", "0x2d", "0x2e", "0x2f", 71 | "0x30", "0x31", "0x32", "0x33", "0x34", "0x35", "0x36", "0x37", "0x38", "0x39", "0x3a", "0x3b", "0x3c", "0x3d", "0x3e", "0x3f", 72 | "0x40", "0x41", "0x42", "0x43", "0x44", "0x45", "0x46", "0x47", "0x48", "0x49", "0x4a", "0x4b", "0x4c", "0x4d", "0x4e", "0x4f", 73 | "0x50", "0x51", "0x52", "0x53", "0x54", "0x55", "0x56", "0x57", "0x58", "0x59", "0x5a", "0x5b", "0x5c", "0x5d", "0x5e", "0x5f", 74 | "0x60", "0x61", "0x62", "0x63", "0x64", "0x65", "0x66", "0x67", "0x68", "0x69", "0x6a", "0x6b", "0x6c", "0x6d", "0x6e", "0x6f", 75 | "0x70", "0x71", "0x72", "0x73", "0x74", "0x75", "0x76", "0x77", "0x78", "0x79", "0x7a", "0x7b", "0x7c", "0x7d", "0x7e", "0x7f", 76 | "0x80", "0x81", "0x82", "0x83", "0x84", "0x85", "0x86", "0x87", "0x88", "0x89", "0x8a", "0x8b", "0x8c", "0x8d", "0x8e", "0x8f", 77 | "0x90", "0x91", "0x92", "0x93", "0x94", "0x95", "0x96", "0x97", "0x98", "0x99", "0x9a", "0x9b", "0x9c", "0x9d", "0x9e", "0x9f", 78 | "0xa0", "0xa1", "0xa2", "0xa3", "0xa4", "0xa5", "0xa6", "0xa7", "0xa8", "0xa9", "0xaa", "0xab", "0xac", "0xad", "0xae", "0xaf", 79 | "0xb0", "0xb1", "0xb2", "0xb3", "0xb4", "0xb5", "0xb6", "0xb7", "0xb8", "0xb9", "0xba", "0xbb", "0xbc", "0xbd", "0xbe", "0xbf", 80 | "0xc0", "0xc1", "0xc2", "0xc3", "0xc4", "0xc5", "0xc6", "0xc7", "0xc8", "0xc9", "0xca", "0xcb", "0xcc", "0xcd", "0xce", "0xcf", 81 | "0xd0", "0xd1", "0xd2", "0xd3", "0xd4", "0xd5", "0xd6", "0xd7", "0xd8", "0xd9", "0xda", "0xdb", "0xdc", "0xdd", "0xde", "0xdf", 82 | "0xe0", "0xe1", "0xe2", "0xe3", "0xe4", "0xe5", "0xe6", "0xe7", "0xe8", "0xe9", "0xea", "0xeb", "0xec", "0xed", "0xee", "0xef", 83 | "0xf0", "0xf1", "0xf2", "0xf3", "0xf4", "0xf5", "0xf6", "0xf7", "0xf8", "0xf9", "0xfa", "0xfb", "0xfc", "0xfd", "0xfe", "0xff" 84 | }; 85 | 86 | if (x < 0x10) { /* < 0x10 has a fixed length of 4 including null terminate. */ 87 | memcpy(&s->p[s->length], TextHBTable[x & 255], 4); 88 | s->length += 3; 89 | } else { /* >= 0x10 has a fixed length of 5 including null terminate. */ 90 | memcpy(&s->p[s->length], TextHBTable[x & 255], 5); 91 | s->length += 4; 92 | } 93 | } 94 | 95 | void _FASTCALL_ str_code_hdw(_WString* s, uint32_t x) 96 | { 97 | int8_t* buf; 98 | int i = 0, shift = 0; 99 | unsigned int t = 0; 100 | 101 | buf = (int8_t*)&s->p[s->length]; 102 | 103 | buf[0] = '0'; 104 | buf[1] = 'x'; 105 | buf += 2; 106 | 107 | for (shift = 28; shift != 0; shift -= 4) { 108 | t = (x >> shift) & 0xf; 109 | if (i | t) buf[i++] = NIBBLE_TO_CHR; 110 | } 111 | t = x & 0xf; 112 | buf[i++] = NIBBLE_TO_CHR; 113 | 114 | s->length += i + 2; 115 | buf[i] = '\0'; 116 | } 117 | 118 | void _FASTCALL_ str_code_hqw(_WString* s, uint8_t src[8]) 119 | { 120 | int8_t* buf; 121 | int i = 0, shift = 0; 122 | uint32_t x = RULONG(&src[sizeof(int32_t)]); 123 | int t; 124 | 125 | buf = (int8_t*)&s->p[s->length]; 126 | buf[0] = '0'; 127 | buf[1] = 'x'; 128 | buf += 2; 129 | 130 | for (shift = 28; shift != -4; shift -= 4) { 131 | t = (x >> shift) & 0xf; 132 | if (i | t) buf[i++] = NIBBLE_TO_CHR; 133 | } 134 | 135 | x = RULONG(src); 136 | for (shift = 28; shift != 0; shift -= 4) { 137 | t = (x >> shift) & 0xf; 138 | if (i | t) buf[i++] = NIBBLE_TO_CHR; 139 | } 140 | t = x & 0xf; 141 | buf[i++] = NIBBLE_TO_CHR; 142 | 143 | s->length += i + 2; 144 | buf[i] = '\0'; 145 | } 146 | 147 | #ifdef SUPPORT_64BIT_OFFSET 148 | void _FASTCALL_ str_off64(_WString* s, OFFSET_INTEGER x) 149 | { 150 | int8_t* buf; 151 | int i = 0, shift = 0; 152 | OFFSET_INTEGER t = 0; 153 | 154 | buf = (int8_t*)&s->p[s->length]; 155 | 156 | buf[0] = '0'; 157 | buf[1] = 'x'; 158 | buf += 2; 159 | 160 | for (shift = 60; shift != 0; shift -= 4) { 161 | t = (x >> shift) & 0xf; 162 | if (i | t) buf[i++] = NIBBLE_TO_CHR; 163 | } 164 | t = x & 0xf; 165 | buf[i++] = NIBBLE_TO_CHR; 166 | 167 | s->length += i + 2; 168 | buf[i] = '\0'; 169 | } 170 | #endif /* SUPPORT_64BIT_OFFSET */ 171 | 172 | #endif /* DISTORM_LIGHT */ 173 | -------------------------------------------------------------------------------- /distorm/src/textdefs.h: -------------------------------------------------------------------------------- 1 | /* 2 | textdefs.h 3 | 4 | diStorm3 - Powerful disassembler for X86/AMD64 5 | http://ragestorm.net/distorm/ 6 | distorm at gmail dot com 7 | Copyright (C) 2003-2016 Gil Dabah 8 | This library is licensed under the BSD license. See the file COPYING. 9 | */ 10 | 11 | 12 | #ifndef TEXTDEFS_H 13 | #define TEXTDEFS_H 14 | 15 | #include "config.h" 16 | #include "wstring.h" 17 | 18 | #ifndef DISTORM_LIGHT 19 | 20 | #define PLUS_DISP_CHR '+' 21 | #define MINUS_DISP_CHR '-' 22 | #define OPEN_CHR '[' 23 | #define CLOSE_CHR ']' 24 | #define SP_CHR ' ' 25 | #define SEG_OFF_CHR ':' 26 | 27 | /* 28 | Naming Convention: 29 | 30 | * get - returns a pointer to a string. 31 | * str - concatenates to string. 32 | 33 | * hex - means the function is used for hex dump (number is padded to required size) - Little Endian output. 34 | * code - means the function is used for disassembled instruction - Big Endian output. 35 | * off - means the function is used for 64bit offset - Big Endian output. 36 | 37 | * h - '0x' in front of the string. 38 | 39 | * b - byte 40 | * dw - double word (can be used for word also) 41 | * qw - quad word 42 | 43 | * all numbers are in HEX. 44 | */ 45 | 46 | void _FASTCALL_ str_hex_b(_WString* s, unsigned int x); 47 | void _FASTCALL_ str_code_hb(_WString* s, unsigned int x); 48 | void _FASTCALL_ str_code_hdw(_WString* s, uint32_t x); 49 | void _FASTCALL_ str_code_hqw(_WString* s, uint8_t src[8]); 50 | 51 | #ifdef SUPPORT_64BIT_OFFSET 52 | void _FASTCALL_ str_off64(_WString* s, OFFSET_INTEGER x); 53 | #endif 54 | 55 | #endif /* DISTORM_LIGHT */ 56 | 57 | #endif /* TEXTDEFS_H */ 58 | -------------------------------------------------------------------------------- /distorm/src/wstring.c: -------------------------------------------------------------------------------- 1 | /* 2 | wstring.c 3 | 4 | diStorm3 - Powerful disassembler for X86/AMD64 5 | http://ragestorm.net/distorm/ 6 | distorm at gmail dot com 7 | Copyright (C) 2003-2016 Gil Dabah 8 | This library is licensed under the BSD license. See the file COPYING. 9 | */ 10 | 11 | 12 | #include "wstring.h" 13 | 14 | #ifndef DISTORM_LIGHT 15 | 16 | void strclear_WS(_WString* s) 17 | { 18 | s->p[0] = '\0'; 19 | s->length = 0; 20 | } 21 | 22 | void chrcat_WS(_WString* s, uint8_t ch) 23 | { 24 | s->p[s->length] = ch; 25 | s->p[s->length + 1] = '\0'; 26 | s->length += 1; 27 | } 28 | 29 | void strcpylen_WS(_WString* s, const int8_t* buf, unsigned int len) 30 | { 31 | s->length = len; 32 | memcpy((int8_t*)s->p, buf, len + 1); 33 | } 34 | 35 | void strcatlen_WS(_WString* s, const int8_t* buf, unsigned int len) 36 | { 37 | memcpy((int8_t*)&s->p[s->length], buf, len + 1); 38 | s->length += len; 39 | } 40 | 41 | void strcat_WS(_WString* s, const _WString* s2) 42 | { 43 | memcpy((int8_t*)&s->p[s->length], s2->p, s2->length + 1); 44 | s->length += s2->length; 45 | } 46 | 47 | #endif /* DISTORM_LIGHT */ 48 | -------------------------------------------------------------------------------- /distorm/src/wstring.h: -------------------------------------------------------------------------------- 1 | /* 2 | wstring.h 3 | 4 | diStorm3 - Powerful disassembler for X86/AMD64 5 | http://ragestorm.net/distorm/ 6 | distorm at gmail dot com 7 | Copyright (C) 2003-2016 Gil Dabah 8 | This library is licensed under the BSD license. See the file COPYING. 9 | */ 10 | 11 | 12 | #ifndef WSTRING_H 13 | #define WSTRING_H 14 | 15 | #include "config.h" 16 | 17 | #ifndef DISTORM_LIGHT 18 | 19 | void strclear_WS(_WString* s); 20 | void chrcat_WS(_WString* s, uint8_t ch); 21 | void strcpylen_WS(_WString* s, const int8_t* buf, unsigned int len); 22 | void strcatlen_WS(_WString* s, const int8_t* buf, unsigned int len); 23 | void strcat_WS(_WString* s, const _WString* s2); 24 | 25 | /* 26 | * Warning, this macro should be used only when the compiler knows the size of string in advance! 27 | * This macro is used in order to spare the call to strlen when the strings are known already. 28 | * Note: sizeof includes NULL terminated character. 29 | */ 30 | #define strcat_WSN(s, t) strcatlen_WS((s), ((const int8_t*)t), sizeof((t))-1) 31 | #define strcpy_WSN(s, t) strcpylen_WS((s), ((const int8_t*)t), sizeof((t))-1) 32 | 33 | #endif /* DISTORM_LIGHT */ 34 | 35 | #endif /* WSTRING_H */ 36 | -------------------------------------------------------------------------------- /distorm/src/x86defs.h: -------------------------------------------------------------------------------- 1 | /* 2 | x86defs.h 3 | 4 | diStorm3 - Powerful disassembler for X86/AMD64 5 | http://ragestorm.net/distorm/ 6 | distorm at gmail dot com 7 | Copyright (C) 2003-2016 Gil Dabah 8 | This library is licensed under the BSD license. See the file COPYING. 9 | */ 10 | 11 | 12 | #ifndef X86DEFS_H 13 | #define X86DEFS_H 14 | 15 | 16 | #define SEG_REGS_MAX (6) 17 | #define CREGS_MAX (9) 18 | #define DREGS_MAX (8) 19 | 20 | /* Maximum instruction size, including prefixes */ 21 | #define INST_MAXIMUM_SIZE (15) 22 | 23 | /* Maximum range of imm8 (comparison type) of special SSE CMP instructions. */ 24 | #define INST_CMP_MAX_RANGE (8) 25 | 26 | /* Maximum range of imm8 (comparison type) of special AVX VCMP instructions. */ 27 | #define INST_VCMP_MAX_RANGE (32) 28 | 29 | /* Wait instruction byte code. */ 30 | #define INST_WAIT_INDEX (0x9b) 31 | 32 | /* Lea instruction byte code. */ 33 | #define INST_LEA_INDEX (0x8d) 34 | 35 | /* NOP/XCHG instruction byte code. */ 36 | #define INST_NOP_INDEX (0x90) 37 | 38 | /* ARPL/MOVSXD instruction byte code. */ 39 | #define INST_ARPL_INDEX (0x63) 40 | 41 | /* 42 | * Minimal MODR/M value of divided instructions. 43 | * It's 0xc0, two MSBs set, which indicates a general purpose register is used too. 44 | */ 45 | #define INST_DIVIDED_MODRM (0xc0) 46 | 47 | /* This is the escape byte value used for 3DNow! instructions. */ 48 | #define _3DNOW_ESCAPE_BYTE (0x0f) 49 | 50 | #define PREFIX_LOCK (0xf0) 51 | #define PREFIX_REPNZ (0xf2) 52 | #define PREFIX_REP (0xf3) 53 | #define PREFIX_CS (0x2e) 54 | #define PREFIX_SS (0x36) 55 | #define PREFIX_DS (0x3e) 56 | #define PREFIX_ES (0x26) 57 | #define PREFIX_FS (0x64) 58 | #define PREFIX_GS (0x65) 59 | #define PREFIX_OP_SIZE (0x66) 60 | #define PREFIX_ADDR_SIZE (0x67) 61 | #define PREFIX_VEX2b (0xc5) 62 | #define PREFIX_VEX3b (0xc4) 63 | 64 | /* REX prefix value range, 64 bits mode decoding only. */ 65 | #define PREFIX_REX_LOW (0x40) 66 | #define PREFIX_REX_HI (0x4f) 67 | /* In order to use the extended GPR's we have to add 8 to the Modr/M info values. */ 68 | #define EX_GPR_BASE (8) 69 | 70 | /* Mask for REX and VEX features: */ 71 | /* Base */ 72 | #define PREFIX_EX_B (1) 73 | /* Index */ 74 | #define PREFIX_EX_X (2) 75 | /* Register */ 76 | #define PREFIX_EX_R (4) 77 | /* Operand Width */ 78 | #define PREFIX_EX_W (8) 79 | /* Vector Lengh */ 80 | #define PREFIX_EX_L (0x10) 81 | 82 | #endif /* X86DEFS_H */ 83 | -------------------------------------------------------------------------------- /hook_file.h: -------------------------------------------------------------------------------- 1 | /* 2 | Cuckoo Sandbox - Automated Malware Analysis 3 | Copyright (C) 2010-2014 Cuckoo Sandbox Developers 4 | 5 | This program is free software: you can redistribute it and/or modify 6 | it under the terms of the GNU General Public License as published by 7 | the Free Software Foundation, either version 3 of the License, or 8 | (at your option) any later version. 9 | 10 | This program is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | GNU General Public License for more details. 14 | 15 | You should have received a copy of the GNU General Public License 16 | along with this program. If not, see . 17 | */ 18 | #include "lookup.h" 19 | 20 | void file_init(); 21 | void file_close(HANDLE file_handle); 22 | void handle_duplicate(HANDLE old_handle, HANDLE new_handle); 23 | void remove_file_from_log_tracking(HANDLE fhandle); 24 | -------------------------------------------------------------------------------- /hook_sleep.h: -------------------------------------------------------------------------------- 1 | /* 2 | Cuckoo Sandbox - Automated Malware Analysis 3 | Copyright (C) 2010-2014 Cuckoo Sandbox Developers 4 | 5 | This program is free software: you can redistribute it and/or modify 6 | it under the terms of the GNU General Public License as published by 7 | the Free Software Foundation, either version 3 of the License, or 8 | (at your option) any later version. 9 | 10 | This program is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | GNU General Public License for more details. 14 | 15 | You should have received a copy of the GNU General Public License 16 | along with this program. If not, see . 17 | */ 18 | 19 | void disable_sleep_skip(); 20 | void init_sleep_skip(int first_process); 21 | void init_startup_time(unsigned int startup_time); 22 | -------------------------------------------------------------------------------- /hook_sync.c: -------------------------------------------------------------------------------- 1 | /* 2 | Cuckoo Sandbox - Automated Malware Analysis 3 | Copyright (C) 2010-2015 Cuckoo Sandbox Developers, Optiv, Inc. (brad.spengler@optiv.com) 4 | 5 | This program is free software: you can redistribute it and/or modify 6 | it under the terms of the GNU General Public License as published by 7 | the Free Software Foundation, either version 3 of the License, or 8 | (at your option) any later version. 9 | 10 | This program is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | GNU General Public License for more details. 14 | 15 | You should have received a copy of the GNU General Public License 16 | along with this program. If not, see . 17 | */ 18 | 19 | #include 20 | #include "ntapi.h" 21 | #include "hooking.h" 22 | #include "log.h" 23 | 24 | 25 | HOOKDEF(NTSTATUS, WINAPI, NtCreateMutant, 26 | __out PHANDLE MutantHandle, 27 | __in ACCESS_MASK DesiredAccess, 28 | __in_opt POBJECT_ATTRIBUTES ObjectAttributes, 29 | __in BOOLEAN InitialOwner 30 | ) { 31 | NTSTATUS ret = Old_NtCreateMutant(MutantHandle, DesiredAccess, 32 | ObjectAttributes, InitialOwner); 33 | LOQ_ntstatus("synchronization", "Poi", "Handle", MutantHandle, 34 | "MutexName", unistr_from_objattr(ObjectAttributes), 35 | "InitialOwner", InitialOwner); 36 | return ret; 37 | } 38 | 39 | HOOKDEF(NTSTATUS, WINAPI, NtOpenMutant, 40 | __out PHANDLE MutantHandle, 41 | __in ACCESS_MASK DesiredAccess, 42 | __in POBJECT_ATTRIBUTES ObjectAttributes 43 | ) { 44 | NTSTATUS ret = Old_NtOpenMutant(MutantHandle, DesiredAccess, 45 | ObjectAttributes); 46 | LOQ_ntstatus("synchronization", "Po", "Handle", MutantHandle, 47 | "MutexName", unistr_from_objattr(ObjectAttributes)); 48 | return ret; 49 | } 50 | 51 | HOOKDEF(NTSTATUS, WINAPI, NtCreateEvent, 52 | __out PHANDLE EventHandle, 53 | __in ACCESS_MASK DesiredAccess, 54 | __in_opt POBJECT_ATTRIBUTES ObjectAttributes, 55 | __in DWORD EventType, 56 | __in BOOLEAN InitialState 57 | ) { 58 | NTSTATUS ret = Old_NtCreateEvent(EventHandle, DesiredAccess, 59 | ObjectAttributes, EventType, InitialState); 60 | UNICODE_STRING *eventname = unistr_from_objattr(ObjectAttributes); 61 | if (eventname && eventname->Length) { 62 | LOQ_ntstatus("synchronization", "Poii", "Handle", EventHandle, 63 | "EventName", eventname, "EventType", EventType, "InitialState", InitialState); 64 | } 65 | return ret; 66 | } 67 | 68 | HOOKDEF(NTSTATUS, WINAPI, NtOpenEvent, 69 | __out PHANDLE EventHandle, 70 | __in ACCESS_MASK DesiredAccess, 71 | __in POBJECT_ATTRIBUTES ObjectAttributes 72 | ) { 73 | NTSTATUS ret = Old_NtOpenEvent(EventHandle, DesiredAccess, 74 | ObjectAttributes); 75 | LOQ_ntstatus("synchronization", "Po", "Handle", EventHandle, 76 | "EventName", unistr_from_objattr(ObjectAttributes)); 77 | return ret; 78 | 79 | } 80 | 81 | HOOKDEF(NTSTATUS, WINAPI, NtCreateNamedPipeFile, 82 | OUT PHANDLE NamedPipeFileHandle, 83 | IN ACCESS_MASK DesiredAccess, 84 | IN POBJECT_ATTRIBUTES ObjectAttributes, 85 | OUT PIO_STATUS_BLOCK IoStatusBlock, 86 | IN ULONG ShareAccess, 87 | IN ULONG CreateDisposition, 88 | IN ULONG CreateOptions, 89 | IN BOOLEAN WriteModeMessage, 90 | IN BOOLEAN ReadModeMessage, 91 | IN BOOLEAN NonBlocking, 92 | IN ULONG MaxInstances, 93 | IN ULONG InBufferSize, 94 | IN ULONG OutBufferSize, 95 | IN PLARGE_INTEGER DefaultTimeOut 96 | ) { 97 | NTSTATUS ret = Old_NtCreateNamedPipeFile(NamedPipeFileHandle, 98 | DesiredAccess, ObjectAttributes, IoStatusBlock, ShareAccess, 99 | CreateDisposition, CreateOptions, WriteModeMessage, ReadModeMessage, 100 | NonBlocking, MaxInstances, InBufferSize, OutBufferSize, 101 | DefaultTimeOut); 102 | LOQ_ntstatus("synchronization", "PhOi", "NamedPipeHandle", NamedPipeFileHandle, 103 | "DesiredAccess", DesiredAccess, "PipeName", ObjectAttributes, 104 | "ShareAccess", ShareAccess); 105 | return ret; 106 | } 107 | 108 | HOOKDEF(NTSTATUS, WINAPI, NtAddAtom, 109 | IN PWCHAR AtomName, 110 | IN ULONG AtomNameLength, 111 | OUT PRTL_ATOM Atom 112 | ) { 113 | NTSTATUS ret = Old_NtAddAtom(AtomName, AtomNameLength, Atom); 114 | LOQ_ntstatus("synchronization", "uh", "AtomName", AtomName, "Atom", *Atom); 115 | return ret; 116 | } 117 | 118 | HOOKDEF(NTSTATUS, WINAPI, NtDeleteAtom, 119 | IN RTL_ATOM Atom 120 | ) { 121 | NTSTATUS ret = Old_NtDeleteAtom(Atom); 122 | LOQ_ntstatus("synchronization", "h", "Atom", Atom); 123 | return ret; 124 | } 125 | 126 | HOOKDEF(NTSTATUS, WINAPI, NtFindAtom, 127 | IN PWCHAR AtomName, 128 | IN ULONG AtomNameLength, 129 | OUT PRTL_ATOM Atom OPTIONAL 130 | ) { 131 | ENSURE_RTL_ATOM(Atom); 132 | NTSTATUS ret = Old_NtFindAtom(AtomName, AtomNameLength, Atom); 133 | LOQ_ntstatus("synchronization", "uh", "AtomName", AtomName, "Atom", *Atom); 134 | return ret; 135 | } 136 | 137 | HOOKDEF(NTSTATUS, WINAPI, NtAddAtomEx, 138 | IN PWCHAR AtomName, 139 | IN ULONG AtomNameLength, 140 | OUT PRTL_ATOM Atom, 141 | IN PVOID Unknown 142 | ) { 143 | NTSTATUS ret = Old_NtAddAtomEx(AtomName, AtomNameLength, Atom, Unknown); 144 | LOQ_ntstatus("synchronization", "uh", "AtomName", AtomName, "Atom", *Atom); 145 | return ret; 146 | } 147 | 148 | HOOKDEF(NTSTATUS, WINAPI, NtQueryInformationAtom, 149 | IN RTL_ATOM Atom, 150 | IN ATOM_INFORMATION_CLASS AtomInformationClass, 151 | OUT PVOID AtomInformation, 152 | IN ULONG AtomInformationLength, 153 | OUT PULONG ReturnLength OPTIONAL 154 | ) { 155 | WCHAR* AtomName; 156 | ULONG AtomNameLength; 157 | 158 | NTSTATUS ret = Old_NtQueryInformationAtom(Atom, AtomInformationClass, AtomInformation, AtomInformationLength, ReturnLength); 159 | 160 | if (NT_SUCCESS(ret) && AtomInformationClass == AtomBasicInformation) 161 | { 162 | AtomNameLength = (ULONG)((PATOM_BASIC_INFORMATION)AtomInformation)->NameLength; 163 | AtomName = ((PATOM_BASIC_INFORMATION)AtomInformation)->Name; 164 | LOQ_ntstatus("synchronization", "bih", "AtomName", AtomNameLength, AtomName, "Size", AtomNameLength, "Atom", Atom); 165 | } 166 | else 167 | LOQ_ntstatus("synchronization", "h", "Atom", Atom); 168 | 169 | return ret; 170 | } 171 | -------------------------------------------------------------------------------- /ignore.c: -------------------------------------------------------------------------------- 1 | /* 2 | Cuckoo Sandbox - Automated Malware Analysis 3 | Copyright (C) 2010-2014 Cuckoo Sandbox Developers 4 | 5 | This program is free software: you can redistribute it and/or modify 6 | it under the terms of the GNU General Public License as published by 7 | the Free Software Foundation, either version 3 of the License, or 8 | (at your option) any later version. 9 | 10 | This program is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | GNU General Public License for more details. 14 | 15 | You should have received a copy of the GNU General Public License 16 | along with this program. If not, see . 17 | */ 18 | 19 | #include 20 | #include "ntapi.h" 21 | #include "ignore.h" 22 | #include "misc.h" 23 | #include "pipe.h" 24 | 25 | // 26 | // Protected Processes 27 | // 28 | 29 | static DWORD g_pids[MAX_PROTECTED_PIDS]; 30 | static DWORD g_pid_count; 31 | 32 | void add_protected_pid(DWORD pid) 33 | { 34 | g_pids[g_pid_count++] = pid; 35 | } 36 | 37 | int is_protected_pid(DWORD pid) 38 | { 39 | DWORD i; 40 | 41 | for (i = 0; i < g_pid_count; i++) { 42 | if(pid == g_pids[i]) { 43 | return 1; 44 | } 45 | } 46 | return 0; 47 | } 48 | 49 | // 50 | // Blacklist for Dumping Files 51 | // 52 | 53 | #define S(s, f) {L##s, sizeof(s)-1, f} 54 | 55 | #define FLAG_NONE 0 56 | #define FLAG_BEGINS_WITH 1 57 | 58 | static struct _ignored_file_t { 59 | const wchar_t *unicode; 60 | unsigned int length; 61 | unsigned int flags; 62 | } g_ignored_files[] = { 63 | S("\\??\\PIPE\\lsarpc", FLAG_NONE), 64 | S("\\??\\IDE#", FLAG_BEGINS_WITH), 65 | S("\\??\\STORAGE#", FLAG_BEGINS_WITH), 66 | S("\\??\\MountPointManager", FLAG_NONE), 67 | S("\\??\\root#", FLAG_BEGINS_WITH), 68 | S("\\Device\\", FLAG_BEGINS_WITH), 69 | }; 70 | 71 | int is_ignored_file_unicode(const wchar_t *fname, unsigned int length) 72 | { 73 | struct _ignored_file_t *f = g_ignored_files; 74 | unsigned int i; 75 | for (i = 0; i < ARRAYSIZE(g_ignored_files); i++, f++) { 76 | if(f->flags == FLAG_NONE && length == f->length && 77 | !wcsnicmp(fname, f->unicode, length)) { 78 | return 1; 79 | } 80 | else if(f->flags == FLAG_BEGINS_WITH && length >= f->length && 81 | !wcsnicmp(fname, f->unicode, f->length)) { 82 | return 1; 83 | } 84 | } 85 | return 0; 86 | } 87 | 88 | int is_ignored_file_objattr(const OBJECT_ATTRIBUTES *obj) 89 | { 90 | return is_ignored_file_unicode(obj->ObjectName->Buffer, 91 | obj->ObjectName->Length / sizeof(wchar_t)); 92 | } 93 | -------------------------------------------------------------------------------- /ignore.h: -------------------------------------------------------------------------------- 1 | /* 2 | Cuckoo Sandbox - Automated Malware Analysis 3 | Copyright (C) 2010-2014 Cuckoo Sandbox Developers 4 | 5 | This program is free software: you can redistribute it and/or modify 6 | it under the terms of the GNU General Public License as published by 7 | the Free Software Foundation, either version 3 of the License, or 8 | (at your option) any later version. 9 | 10 | This program is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | GNU General Public License for more details. 14 | 15 | You should have received a copy of the GNU General Public License 16 | along with this program. If not, see . 17 | */ 18 | 19 | #define MAX_PROTECTED_PIDS 32 20 | 21 | #include "ntapi.h" 22 | 23 | void add_protected_pid(DWORD pid); 24 | int is_protected_pid(DWORD pid); 25 | 26 | int is_ignored_file_ascii(const char *fname, unsigned int length); 27 | int is_ignored_file_unicode(const wchar_t *fname, unsigned int length); 28 | int is_ignored_file_objattr(const OBJECT_ATTRIBUTES *obj); 29 | 30 | void ignore_file_prepend_stuff(const OBJECT_ATTRIBUTES *obj, 31 | wchar_t **str, unsigned int *length); 32 | -------------------------------------------------------------------------------- /install.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | # directory in which the main repository of Cuckoo Sandbox can be found 4 | if [ -z "$CUCKOODIR" ]; then 5 | CUCKOODIR=../cuckoo 6 | fi 7 | 8 | # target filename - in case of testing with custom dll's one may wish to 9 | # use a different filename, such as "cuckoomon_bson.dll" 10 | if [ -z "$CUCKOOMON" ]; then 11 | CUCKOOMON=cuckoomon.dll 12 | fi 13 | 14 | make && cp cuckoomon.dll "$CUCKOODIR/analyzer/windows/dll/$CUCKOOMON" 15 | -------------------------------------------------------------------------------- /loader/loader/Loader.h: -------------------------------------------------------------------------------- 1 | /* 2 | CAPE - Config And Payload Extraction 3 | Copyright(C) 2015 - 2018 Context Information Security. (kevin.oreilly@contextis.com) 4 | 5 | This program is free software : you can redistribute it and / or modify 6 | it under the terms of the GNU General Public License as published by 7 | the Free Software Foundation, either version 3 of the License, or 8 | (at your option) any later version. 9 | 10 | This program is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | GNU General Public License for more details. 14 | 15 | You should have received a copy of the GNU General Public License 16 | along with this program.If not, see . 17 | */ 18 | #define _CRT_SECURE_NO_WARNINGS 1 19 | #include 20 | #include 21 | 22 | #define BOUND_DIRECTORY OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT] 23 | #define IAT_DIRECTORY OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IAT] 24 | #define IMPORT_DIRECTORY OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT] 25 | 26 | #define NT_SUCCESS(Status) ((NTSTATUS)(Status) >= 0) 27 | 28 | #define BUFSIZE 512 29 | #define PIPEBUFSIZE 16384 30 | 31 | #ifndef _WIN64 32 | #define DWORD_XX DWORD32 33 | #define IMAGE_ORDINAL_FLAG_XX IMAGE_ORDINAL_FLAG32 34 | #define IMAGE_THUNK_DATAXX IMAGE_THUNK_DATA32 35 | #define PIMAGE_THUNK_DATAXX PIMAGE_THUNK_DATA32 36 | #else 37 | #define DWORD_XX DWORD64 38 | #define IMAGE_ORDINAL_FLAG_XX IMAGE_ORDINAL_FLAG64 39 | #define IMAGE_THUNK_DATAXX IMAGE_THUNK_DATA64 40 | #define PIMAGE_THUNK_DATAXX PIMAGE_THUNK_DATA64 41 | #endif 42 | 43 | typedef struct _LSA_UNICODE_STRING 44 | { 45 | USHORT Length; 46 | USHORT MaximumLength; 47 | PWSTR Buffer; 48 | } LSA_UNICODE_STRING, *PLSA_UNICODE_STRING, UNICODE_STRING, *PUNICODE_STRING; 49 | 50 | typedef struct _CLIENT_ID { 51 | HANDLE UniqueProcess; 52 | HANDLE UniqueThread; 53 | } CLIENT_ID; 54 | typedef CLIENT_ID *PCLIENT_ID; 55 | 56 | typedef struct _PROCESS_BASIC_INFORMATION 57 | { 58 | PVOID Reserved1; 59 | PVOID PebBaseAddress; 60 | PVOID Reserved2[2]; 61 | ULONG_PTR UniqueProcessId; 62 | ULONG_PTR ParentProcessId; 63 | } PROCESS_BASIC_INFORMATION; 64 | 65 | typedef struct _PEB_LDR_DATA 66 | { 67 | ULONG Length; 68 | BOOLEAN Initialized; 69 | PVOID SsHandle; 70 | LIST_ENTRY InLoadOrderModuleList; 71 | LIST_ENTRY InMemoryOrderModuleList; 72 | LIST_ENTRY InInitializationOrderModuleList; 73 | } PEB_LDR_DATA, *PPEB_LDR_DATA; 74 | 75 | typedef struct _RTL_USER_PROCESS_PARAMETERS 76 | { 77 | BYTE Reserved1[16]; 78 | PVOID Reserved2[10]; 79 | UNICODE_STRING ImagePathName; 80 | UNICODE_STRING CommandLine; 81 | } RTL_USER_PROCESS_PARAMETERS, *PRTL_USER_PROCESS_PARAMETERS; 82 | 83 | typedef void (NTAPI *PPS_POST_PROCESS_INIT_ROUTINE) 84 | ( 85 | void 86 | ); 87 | 88 | typedef struct _PEB 89 | { 90 | BYTE Reserved1[2]; 91 | BYTE BeingDebugged; 92 | BOOLEAN Spare; 93 | HANDLE Mutant; 94 | PVOID ImageBaseAddress; 95 | PPEB_LDR_DATA Ldr; 96 | PRTL_USER_PROCESS_PARAMETERS ProcessParameters; 97 | BYTE Reserved4[104]; 98 | PVOID Reserved5[52]; 99 | PPS_POST_PROCESS_INIT_ROUTINE PostProcessInitRoutine; 100 | BYTE Reserved6[128]; 101 | PVOID Reserved7[1]; 102 | ULONG SessionId; 103 | } PEB, *PPEB; 104 | 105 | typedef struct _TEB 106 | { 107 | NT_TIB NtTib; 108 | PVOID EnvironmentPointer; 109 | CLIENT_ID ClientId; 110 | PVOID ActiveRpcHandle; 111 | PVOID ThreadLocalStoragePointer; 112 | PPEB ProcessEnvironmentBlock; 113 | ULONG LastErrorValue; 114 | // truncated 115 | } TEB, *PTEB; 116 | 117 | typedef NTSTATUS(WINAPI * _NtQuerySystemInformation) 118 | ( 119 | _In_ ULONG SystemInformationClass, 120 | _Inout_ PVOID SystemInformation, 121 | _In_ ULONG SystemInformationLength, 122 | _Out_opt_ PULONG ReturnLength 123 | ); 124 | 125 | typedef NTSTATUS(WINAPI * _NtContinue) 126 | ( 127 | void 128 | ); 129 | 130 | typedef LONG(WINAPI *_NtQueryInformationProcess)(HANDLE ProcessHandle, 131 | ULONG ProcessInformationClass, PVOID ProcessInformation, 132 | ULONG ProcessInformationLength, PULONG ReturnLength); 133 | 134 | typedef NTSTATUS (NTAPI *_RtlCreateUserThread) 135 | ( 136 | HANDLE, 137 | PSECURITY_DESCRIPTOR, 138 | BOOLEAN, 139 | ULONG, 140 | PULONG, 141 | PULONG, 142 | PVOID, 143 | PVOID, 144 | PHANDLE, 145 | PVOID 146 | ); 147 | 148 | typedef HRESULT (WINAPI *PDLLREGRSRV)(void); 149 | typedef void (cdecl *PSHELLCODE)(void); 150 | 151 | enum 152 | { 153 | ERROR_INVALID_PARAM = -1, 154 | ERROR_PROCESS_OPEN = -2, 155 | ERROR_THREAD_OPEN = -3, 156 | ERROR_ALLOCATE = -4, 157 | ERROR_WRITEMEMORY = -5, 158 | ERROR_QUEUEUSERAPC = -6, 159 | ERROR_CREATEREMOTETHREAD = -7, 160 | ERROR_RTLCREATEUSERTHREAD = -8, 161 | ERROR_INJECTMODE = -9, 162 | ERROR_MODE = -10, 163 | ERROR_DEBUGPRIV = -11, 164 | ERROR_ARGCOUNT = -12, 165 | ERROR_FILE_OPEN = -13, 166 | ERROR_DLL_PATH = -14, 167 | ERROR_READMEMORY = -15 168 | }; 169 | 170 | typedef struct _LoadLibraryThread { 171 | FARPROC LoadLibrary; 172 | FARPROC GetLastError; 173 | PCHAR DllPath; 174 | } LoadLibraryThread; 175 | 176 | SYSTEM_INFO SystemInfo; 177 | -------------------------------------------------------------------------------- /loader/loader/loader.vcxproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | Debug 6 | Win32 7 | 8 | 9 | Debug 10 | x64 11 | 12 | 13 | Release 14 | Win32 15 | 16 | 17 | Release 18 | x64 19 | 20 | 21 | 22 | {52D1444F-0B18-4F98-BC62-3D11046190CC} 23 | Win32Proj 24 | loader 25 | 10.0.17134.0 26 | 27 | 28 | 29 | Application 30 | true 31 | v141 32 | MultiByte 33 | 34 | 35 | Application 36 | true 37 | v141_xp 38 | MultiByte 39 | 40 | 41 | Application 42 | false 43 | v141 44 | true 45 | NotSet 46 | 47 | 48 | Application 49 | false 50 | v141_xp 51 | true 52 | NotSet 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | true 72 | $(ProjectName)_dbg 73 | 74 | 75 | true 76 | $(ProjectName)_dbg 77 | 78 | 79 | false 80 | 81 | 82 | false 83 | $(ProjectName)_x64 84 | 85 | 86 | 87 | 88 | 89 | Level3 90 | Disabled 91 | CUCKOODBG;WIN32;_DEBUG;_CONSOLE;_LIB;%(PreprocessorDefinitions) 92 | true 93 | MultiThreadedDebug 94 | 95 | 96 | Windows 97 | true 98 | 99 | 100 | 101 | 102 | 103 | 104 | Level3 105 | Disabled 106 | CUCKOODBG;WIN32;_DEBUG;_CONSOLE;_LIB;%(PreprocessorDefinitions) 107 | true 108 | MultiThreadedDebug 109 | 110 | 111 | Windows 112 | true 113 | 114 | 115 | 116 | 117 | Level3 118 | 119 | 120 | MaxSpeed 121 | true 122 | true 123 | WIN32;NDEBUG;_CONSOLE;_LIB;%(PreprocessorDefinitions) 124 | true 125 | MultiThreaded 126 | 127 | 128 | Windows 129 | true 130 | true 131 | true 132 | 133 | 134 | 135 | 136 | Level3 137 | 138 | 139 | MaxSpeed 140 | true 141 | true 142 | WIN32;NDEBUG;_CONSOLE;_LIB;%(PreprocessorDefinitions) 143 | true 144 | MultiThreaded 145 | 146 | 147 | Windows 148 | true 149 | true 150 | true 151 | 152 | 153 | 154 | 155 | 156 | 157 | 158 | 159 | 160 | 161 | 162 | -------------------------------------------------------------------------------- /loader/loader/loader.vcxproj.filters: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF} 6 | cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx 7 | 8 | 9 | {93995380-89BD-4b04-88EB-625FBE52EBFB} 10 | h;hh;hpp;hxx;hm;inl;inc;xsd 11 | 12 | 13 | {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} 14 | rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms 15 | 16 | 17 | 18 | 19 | Source Files 20 | 21 | 22 | 23 | 24 | Header Files 25 | 26 | 27 | -------------------------------------------------------------------------------- /log.h: -------------------------------------------------------------------------------- 1 | /* 2 | Cuckoo Sandbox - Automated Malware Analysis 3 | Copyright (C) 2010-2015 Cuckoo Sandbox Developers, Optiv, Inc. (brad.spengler@optiv.com) 4 | 5 | This program is free software: you can redistribute it and/or modify 6 | it under the terms of the GNU General Public License as published by 7 | the Free Software Foundation, either version 3 of the License, or 8 | (at your option) any later version. 9 | 10 | This program is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | GNU General Public License for more details. 14 | 15 | You should have received a copy of the GNU General Public License 16 | along with this program. If not, see . 17 | */ 18 | 19 | // 20 | // Log API 21 | // 22 | // The Log takes a format string and parses the extra arguments accordingly 23 | // 24 | // The following Format Specifiers are available: 25 | // s -> (char *) -> zero-terminated string 26 | // S -> (int, char *) -> string with length 27 | // f -> (char *) -> zero-terminated ascii filename string (to be normalized) 28 | // F -> (wchar_t *) zero-terminated unicode filename string (to be normalized) 29 | // u -> (wchar_t *) -> zero-terminated unicode string 30 | // U -> (int, wchar_t *) -> unicode string with length 31 | // b -> (int, void *) -> memory with a given size (alias for S) 32 | // B -> (int *, void *) -> memory with a given size (value at integer) 33 | // i -> (int) -> integer 34 | // l -> (long) -> long integer 35 | // L -> (long *) -> pointer to a long integer 36 | // p -> (void *) -> pointer (alias for l) 37 | // P -> (void **) -> pointer to a handle (alias for L) 38 | // o -> (UNICODE_STRING *) -> unicode string 39 | // O -> (OBJECT_ATTRIBUTES *) -> wrapper around a unicode string for filenames 40 | // K -> (OBJECT_ATTRIBUTES *) -> wrapper around a unicode string for registry keys 41 | // a -> (int, char **) -> array of string 42 | // A -> (int, wchar_t **) -> array of unicode strings 43 | // r -> (Type, int, char *) type as defined for Registry operations 44 | // R -> (Type, int, wchar_t *) type as defined for Registry operations 45 | // type r is for ascii functions, R for unicode (Nt* are unicode) 46 | // e -> (HKEY, char *) -> key/ascii key/value pair (to be normalized) 47 | // E -> (HKEY, wchar_t *) -> key/unicode key/value pair (to be normalized) 48 | // k -> (HKEY, UNICODE_STRING *) -> unicode string for registry values (to be normalized) 49 | // v -> (HKEY, char *) -> key/ascii value pair for registry values (to be normalized) 50 | // V -> (HKEY, wchar_t *) -> key/ascii value pair for registry values (to be normalized) 51 | 52 | // 53 | // Each of these format specifiers are prefixed with a zero-terminated key 54 | // value, e.g. 55 | // 56 | // log("s", "key", "value"); 57 | // 58 | // A format specifier can also be repeated for n times (with n in the range 59 | // 2..9), e.g. 60 | // 61 | // loq("sss", "key1", "value", "key2", "value2", "key3", "value3"); 62 | // loq("3s", "key1", "value", "key2", "value2", "key3", "value3"); 63 | // 64 | 65 | #include "hooking.h" 66 | 67 | void loq(int index, const char *category, const char *name, 68 | int is_success, ULONG_PTR return_value, const char *fmt, ...); 69 | void log_new_process(); 70 | void log_new_thread(); 71 | void log_anomaly(const char *subcategory, const char *msg); 72 | void log_hook_anomaly(const char *subcategory, int success, 73 | const hook_t *h, const char *msg); 74 | void log_hook_modification(const hook_t *h, const char *origbytes, const char *newbytes, unsigned int len); 75 | void log_hook_removal(const hook_t *h); 76 | void log_hook_restoration(const hook_t *h); 77 | void log_procname_anomaly(PUNICODE_STRING InitialName, PUNICODE_STRING InitialPath, PUNICODE_STRING CurrentName, PUNICODE_STRING CurrentPath); 78 | 79 | void log_init(int debug); 80 | void log_flush(); 81 | void log_free(); 82 | 83 | void debug_message(const char *msg); 84 | 85 | #define DEBUG_SOCKET 0xfffffffe 86 | 87 | int log_resolve_index(const char *funcname, int index); 88 | extern const char *logtbl[][2]; 89 | extern volatile LONG g_log_index; 90 | 91 | extern DWORD g_log_thread_id; 92 | extern DWORD g_logwatcher_thread_id; 93 | extern HANDLE g_log_handle; 94 | 95 | enum { 96 | API_OTHER = 0, 97 | API_NTREADFILE = 1, 98 | }; 99 | void set_special_api(DWORD API, BOOLEAN deletelast); 100 | DWORD get_last_api(void); 101 | 102 | extern size_t buffer_log_max; 103 | extern size_t large_buffer_log_max; 104 | 105 | #define _LOQ(eval, cat, fmt, ...) \ 106 | do { \ 107 | static volatile LONG _index; \ 108 | if (_index == 0) \ 109 | InterlockedExchange(&_index, InterlockedIncrement(&g_log_index)); \ 110 | loq(_index, cat, &__FUNCTION__[4], eval, (ULONG_PTR)ret, fmt, ##__VA_ARGS__); \ 111 | } while (0) 112 | 113 | #define LOQ_ntstatus(cat, fmt, ...) _LOQ(NT_SUCCESS(ret), cat, fmt, ##__VA_ARGS__) 114 | #define LOQ_nonnull(cat, fmt, ...) _LOQ(ret != NULL, cat, fmt, ##__VA_ARGS__) 115 | #define LOQ_handle(cat, fmt, ...) _LOQ(ret != NULL && ret != INVALID_HANDLE_VALUE, cat, fmt, ##__VA_ARGS__) 116 | #define LOQ_void(cat, fmt, ...) _LOQ(TRUE, cat, fmt, ##__VA_ARGS__) 117 | #define LOQ_bool(cat, fmt, ...) _LOQ(ret != FALSE, cat, fmt, ##__VA_ARGS__) 118 | #define LOQ_hresult(cat, fmt, ...) _LOQ(ret == S_OK, cat, fmt, ##__VA_ARGS__) 119 | #define LOQ_zero(cat, fmt, ...) _LOQ(ret == 0, cat, fmt, ##__VA_ARGS__) 120 | #define LOQ_nonzero(cat, fmt, ...) _LOQ(ret != 0, cat, fmt, ##__VA_ARGS__) 121 | #define LOQ_nonnegone(cat, fmt, ...) _LOQ(ret != -1, cat, fmt, ##__VA_ARGS__) 122 | #define LOQ_sockerr(cat, fmt, ...) _LOQ(ret != SOCKET_ERROR, cat, fmt, ##__VA_ARGS__) 123 | #define LOQ_sock(cat, fmt, ...) _LOQ(ret != INVALID_SOCKET, cat, fmt, ##__VA_ARGS__) 124 | #define LOQ_msgwait(cat, fmt, ...) _LOQ(ret != WAIT_FAILED, cat, fmt, ##__VA_ARGS__) 125 | 126 | #define ENSURE_LARGE_INTEGER(param) \ 127 | LARGE_INTEGER _##param; _##param.QuadPart = 0; if(param == NULL) param = &_##param 128 | 129 | #define ENSURE_RTL_ATOM(param) \ 130 | RTL_ATOM _##param = 0; if(param == NULL) param = &_##param 131 | 132 | #define ENSURE_DWORD(param) \ 133 | DWORD _##param = 0; if(param == NULL) param = &_##param 134 | 135 | #define ENSURE_ULONG(param) \ 136 | ULONG _##param = 0; if(param == NULL) param = &_##param 137 | #define ENSURE_ULONG_ZERO(param) \ 138 | ENSURE_ULONG(param); else *param = 0 139 | 140 | #define ENSURE_SIZET(param) \ 141 | ULONG_PTR _##param = 0; if(param == NULL) param = &_##param 142 | #define ENSURE_SIZET_ZERO(param) \ 143 | ENSURE_SIZET(param); else *param = 0 144 | 145 | #define ENSURE_CLIENT_ID(param) \ 146 | CLIENT_ID _##param; memset(&_##param, 0, sizeof(_##param)); if (param == NULL) param = &_##param 147 | 148 | #define ENSURE_HANDLE(param) \ 149 | HANDLE _##param; memset(&_##param, 0, sizeof(_##param)); if (param == NULL) param = &_##param 150 | 151 | #define ENSURE_STRUCT(param, type) \ 152 | type _##param; memset(&_##param, 0, sizeof(_##param)); if(param == NULL) param = &_##param 153 | 154 | typedef struct _lastlog_t { 155 | unsigned char *buf; 156 | unsigned int len; 157 | unsigned int compare_len; 158 | int *repeated_ptr; 159 | unsigned char *compare_ptr; 160 | } lastlog_t; -------------------------------------------------------------------------------- /lookup.c: -------------------------------------------------------------------------------- 1 | /* 2 | Cuckoo Sandbox - Automated Malware Analysis 3 | Copyright (C) 2010-2014 Cuckoo Sandbox Developers 4 | 5 | This program is free software: you can redistribute it and/or modify 6 | it under the terms of the GNU General Public License as published by 7 | the Free Software Foundation, either version 3 of the License, or 8 | (at your option) any later version. 9 | 10 | This program is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | GNU General Public License for more details. 14 | 15 | You should have received a copy of the GNU General Public License 16 | along with this program. If not, see . 17 | */ 18 | 19 | #include 20 | #include 21 | #include 22 | #include "ntapi.h" 23 | #include 24 | #include "lookup.h" 25 | #include "pipe.h" 26 | 27 | #define ENTER() EnterCriticalSection(&d->cs) 28 | #define LEAVE() LeaveCriticalSection(&d->cs) 29 | 30 | void lookup_init(lookup_t *d) 31 | { 32 | d->root = NULL; 33 | InitializeCriticalSection(&d->cs); 34 | } 35 | 36 | void lookup_init_no_cs(lookup_t *d) 37 | { 38 | d->root = NULL; 39 | } 40 | 41 | void lookup_free(lookup_t *d) 42 | { 43 | // TODO 44 | } 45 | 46 | void *lookup_add(lookup_t *d, ULONG_PTR id, unsigned int size) 47 | { 48 | entry_t *t = (entry_t *) malloc(sizeof(entry_t) + size); 49 | ENTER(); 50 | memset(t, 0, sizeof(*t)); 51 | t->next = d->root; 52 | t->id = id; 53 | t->size = size; 54 | d->root = t; 55 | LEAVE(); 56 | return t->data; 57 | } 58 | 59 | void *lookup_add_no_cs(lookup_t *d, ULONG_PTR id, unsigned int size) 60 | { 61 | entry_t *t = (entry_t *) malloc(sizeof(entry_t) + size); 62 | memset(t, 0, sizeof(*t)); 63 | t->next = d->root; 64 | t->id = id; 65 | t->size = size; 66 | d->root = t; 67 | return t->data; 68 | } 69 | 70 | void *lookup_get(lookup_t *d, ULONG_PTR id, unsigned int *size) 71 | { 72 | entry_t *p; 73 | ENTER(); 74 | for (p = d->root; p != NULL; p = p->next) { 75 | if(p->id == id) { 76 | void *data; 77 | if(size != NULL) { 78 | *size = p->size; 79 | } 80 | data = p->data; 81 | LEAVE(); 82 | return data; 83 | } 84 | } 85 | LEAVE(); 86 | return NULL; 87 | } 88 | 89 | void *lookup_get_no_cs(lookup_t *d, ULONG_PTR id, unsigned int *size) 90 | { 91 | entry_t *p; 92 | for (p = d->root; p != NULL; p = p->next) { 93 | if(p->id == id) { 94 | void *data; 95 | if(size != NULL) { 96 | *size = p->size; 97 | } 98 | data = p->data; 99 | return data; 100 | } 101 | } 102 | return NULL; 103 | } 104 | 105 | void lookup_del(lookup_t *d, ULONG_PTR id) 106 | { 107 | entry_t *p; 108 | entry_t *last; 109 | 110 | ENTER(); 111 | p = d->root; 112 | // edge case; we want to delete the first entry 113 | if(p != NULL && p->id == id) { 114 | entry_t *t = p->next; 115 | free(d->root); 116 | d->root = t; 117 | LEAVE(); 118 | return; 119 | } 120 | for (last = NULL; p != NULL; last = p, p = p->next) { 121 | if(p->id == id) { 122 | last->next = p->next; 123 | free(p); 124 | break; 125 | } 126 | } 127 | LEAVE(); 128 | } 129 | 130 | void lookup_del_no_cs(lookup_t *d, ULONG_PTR id) 131 | { 132 | entry_t *p; 133 | entry_t *last; 134 | 135 | p = d->root; 136 | // edge case; we want to delete the first entry 137 | if(p != NULL && p->id == id) { 138 | entry_t *t = p->next; 139 | free(d->root); 140 | d->root = t; 141 | return; 142 | } 143 | for (last = NULL; p != NULL; last = p, p = p->next) { 144 | if(p->id == id) { 145 | last->next = p->next; 146 | free(p); 147 | break; 148 | } 149 | } 150 | } 151 | -------------------------------------------------------------------------------- /lookup.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | /* 3 | Cuckoo Sandbox - Automated Malware Analysis 4 | Copyright (C) 2010-2014 Cuckoo Sandbox Developers 5 | 6 | This program is free software: you can redistribute it and/or modify 7 | it under the terms of the GNU General Public License as published by 8 | the Free Software Foundation, either version 3 of the License, or 9 | (at your option) any later version. 10 | 11 | This program is distributed in the hope that it will be useful, 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | GNU General Public License for more details. 15 | 16 | You should have received a copy of the GNU General Public License 17 | along with this program. If not, see . 18 | */ 19 | 20 | #include 21 | 22 | typedef struct _lookup_internal_t { 23 | CRITICAL_SECTION cs; 24 | void *root; 25 | } lookup_t; 26 | 27 | typedef struct _entry_t { 28 | struct _entry_t *next; 29 | ULONG_PTR id; 30 | unsigned int size; 31 | unsigned char data[0]; 32 | } entry_t; 33 | 34 | void lookup_init(lookup_t *d); 35 | void *lookup_add(lookup_t *d, ULONG_PTR id, unsigned int size); 36 | void *lookup_get(lookup_t *d, ULONG_PTR id, unsigned int *size); 37 | void lookup_del(lookup_t *d, ULONG_PTR id); 38 | 39 | void lookup_init_no_cs(lookup_t *d); 40 | void *lookup_add_no_cs(lookup_t *d, ULONG_PTR id, unsigned int size); 41 | void *lookup_get_no_cs(lookup_t *d, ULONG_PTR id, unsigned int *size); 42 | void lookup_del_no_cs(lookup_t *d, ULONG_PTR id); 43 | -------------------------------------------------------------------------------- /pipe.c: -------------------------------------------------------------------------------- 1 | /* 2 | Cuckoo Sandbox - Automated Malware Analysis 3 | Copyright (C) 2010-2015 Cuckoo Sandbox Developers, Optiv, Inc. (brad.spengler@optiv.com) 4 | 5 | This program is free software: you can redistribute it and/or modify 6 | it under the terms of the GNU General Public License as published by 7 | the Free Software Foundation, either version 3 of the License, or 8 | (at your option) any later version. 9 | 10 | This program is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | GNU General Public License for more details. 14 | 15 | You should have received a copy of the GNU General Public License 16 | along with this program. If not, see . 17 | */ 18 | 19 | #include 20 | #include "ntapi.h" 21 | #include "hooking.h" 22 | #include "pipe.h" 23 | #include "utf8.h" 24 | #include "misc.h" 25 | #include "config.h" 26 | #include "log.h" 27 | 28 | static int _pipe_utf8x(char **out, unsigned short x) 29 | { 30 | unsigned char buf[3]; 31 | int len = utf8_encode(x, buf); 32 | if(*out != NULL) { 33 | memcpy(*out, buf, len); 34 | *out += len; 35 | } 36 | return len; 37 | } 38 | 39 | static int _pipe_ascii(char **out, const char *s, int len) 40 | { 41 | int ret = 0; 42 | while (len-- != 0) { 43 | ret += _pipe_utf8x(out, *(unsigned char *) s++); 44 | } 45 | return ret; 46 | } 47 | 48 | static int _pipe_unicode(char **out, const wchar_t *s, int len) 49 | { 50 | int ret = 0; 51 | while (len-- != 0) { 52 | ret += _pipe_utf8x(out, *(unsigned short *) s++); 53 | } 54 | return ret; 55 | } 56 | 57 | static int _pipe_sprintf(char *out, const char *fmt, va_list args) 58 | { 59 | int ret = 0; 60 | while (*fmt != 0) { 61 | if(*fmt != '%') { 62 | ret += _pipe_utf8x(&out, *fmt++); 63 | continue; 64 | } 65 | if(*++fmt == 'z') { 66 | const char *s = va_arg(args, const char *); 67 | if(s == NULL) return -1; 68 | 69 | ret += _pipe_ascii(&out, s, (int)strlen(s)); 70 | } 71 | else if (*fmt == 'c') { 72 | char buf[2]; 73 | buf[0] = va_arg(args, char); 74 | buf[1] = '\0'; 75 | ret += _pipe_ascii(&out, buf, 1); 76 | } 77 | else if(*fmt == 'Z') { 78 | const wchar_t *s = va_arg(args, const wchar_t *); 79 | if(s == NULL) return -1; 80 | 81 | ret += _pipe_unicode(&out, s, lstrlenW(s)); 82 | } 83 | else if (*fmt == 'F') { 84 | const wchar_t *s = va_arg(args, const wchar_t *); 85 | wchar_t *absolutepath = malloc(32768 * sizeof(wchar_t)); 86 | if (s == NULL) return -1; 87 | if (absolutepath) { 88 | ensure_absolute_unicode_path(absolutepath, s); 89 | ret += _pipe_unicode(&out, absolutepath, lstrlenW(absolutepath)); 90 | free(absolutepath); 91 | } 92 | else { 93 | return -1; 94 | } 95 | } 96 | else if (*fmt == 's') { 97 | int len = va_arg(args, int); 98 | const char *s = va_arg(args, const char *); 99 | if(s == NULL || !is_valid_address_range((ULONG_PTR)s, len)) return -1; 100 | 101 | ret += _pipe_ascii(&out, s, len < 0 ? (int)strlen(s) : len); 102 | } 103 | else if(*fmt == 'S') { 104 | int len = va_arg(args, int); 105 | const wchar_t *s = va_arg(args, const wchar_t *); 106 | if(s == NULL || !is_valid_address_range((ULONG_PTR)s, len)) return -1; 107 | 108 | ret += _pipe_unicode(&out, s, len < 0 ? lstrlenW(s) : len); 109 | } 110 | else if(*fmt == 'o') { 111 | UNICODE_STRING *str = va_arg(args, UNICODE_STRING *); 112 | if(str == NULL) return -1; 113 | 114 | ret += _pipe_unicode(&out, str->Buffer, 115 | str->Length / sizeof(wchar_t)); 116 | } 117 | else if(*fmt == 'O') { 118 | OBJECT_ATTRIBUTES *obj = va_arg(args, OBJECT_ATTRIBUTES *); 119 | wchar_t path[MAX_PATH_PLUS_TOLERANCE]; 120 | wchar_t *absolutepath; 121 | 122 | if(obj == NULL || obj->ObjectName == NULL) return -1; 123 | 124 | absolutepath = malloc(32768 * sizeof(wchar_t)); 125 | if (absolutepath) { 126 | path_from_object_attributes(obj, path, (unsigned int)MAX_PATH_PLUS_TOLERANCE); 127 | 128 | ensure_absolute_unicode_path(absolutepath, path); 129 | 130 | ret += _pipe_unicode(&out, absolutepath, lstrlenW(absolutepath)); 131 | free(absolutepath); 132 | } 133 | else { 134 | ret += _pipe_unicode(&out, L"", 0); 135 | } 136 | } 137 | else if(*fmt == 'd') { 138 | char s[32]; 139 | num_to_string(s, sizeof(s), va_arg(args, int)); 140 | ret += _pipe_ascii(&out, s, (int)strlen(s)); 141 | } 142 | else if(*fmt == 'x') { 143 | char s[16]; 144 | sprintf(s, "%x", va_arg(args, int)); 145 | ret += _pipe_ascii(&out, s, (int)strlen(s)); 146 | } 147 | else if (*fmt == 'p') { 148 | char s[18]; 149 | sprintf(s, "%p", va_arg(args, void *)); 150 | ret += _pipe_ascii(&out, s, (int)strlen(s)); 151 | } 152 | else { 153 | const char *msg = "-- UNKNOWN FORMAT STRING -- "; 154 | ret += _pipe_ascii(&out, msg, (int)strlen(msg)); 155 | } 156 | fmt++; 157 | } 158 | return ret; 159 | } 160 | 161 | // reminder: %s doesn't follow sprintf semantics, use %z instead 162 | int pipe(const char *fmt, ...) 163 | { 164 | va_list args; 165 | int len; 166 | int ret = -1; 167 | lasterror_t lasterror; 168 | 169 | va_start(args, fmt); 170 | 171 | get_lasterrors(&lasterror); 172 | 173 | log_flush(); 174 | 175 | len = _pipe_sprintf(NULL, fmt, args); 176 | if (len > 0) { 177 | char *buf = calloc(1, len + 1); 178 | _pipe_sprintf(buf, fmt, args); 179 | 180 | #ifdef CUCKOODBG_PIPE 181 | char filename[64]; 182 | snprintf(filename, sizeof(filename), "c:\\pipe%u.log", GetCurrentProcessId()); 183 | FILE *f = fopen(filename, "ab"); 184 | if (f) { 185 | fwrite(buf, len, 1, f); 186 | fclose(f); 187 | ret = 0; 188 | } 189 | #else 190 | if (CallNamedPipeW(g_config.pipe_name, buf, len, buf, len, 191 | (unsigned long *)&len, NMPWAIT_WAIT_FOREVER) != 0) 192 | ret = 0; 193 | #endif 194 | free(buf); 195 | } 196 | 197 | va_end(args); 198 | 199 | set_lasterrors(&lasterror); 200 | 201 | return ret; 202 | } 203 | 204 | int pipe2(void *out, int *outlen, const char *fmt, ...) 205 | { 206 | va_list args; 207 | int len; 208 | int ret = -1; 209 | va_start(args, fmt); 210 | len = _pipe_sprintf(NULL, fmt, args); 211 | if(len > 0) { 212 | char *buf = calloc(1, len + 1); 213 | _pipe_sprintf(buf, fmt, args); 214 | va_end(args); 215 | 216 | if(CallNamedPipeW(g_config.pipe_name, buf, len, out, *outlen, 217 | (DWORD *) outlen, NMPWAIT_WAIT_FOREVER) != 0) 218 | ret = 0; 219 | free(buf); 220 | } 221 | return ret; 222 | } 223 | -------------------------------------------------------------------------------- /pipe.h: -------------------------------------------------------------------------------- 1 | /* 2 | Cuckoo Sandbox - Automated Malware Analysis 3 | Copyright (C) 2010-2014 Cuckoo Sandbox Developers 4 | 5 | This program is free software: you can redistribute it and/or modify 6 | it under the terms of the GNU General Public License as published by 7 | the Free Software Foundation, either version 3 of the License, or 8 | (at your option) any later version. 9 | 10 | This program is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | GNU General Public License for more details. 14 | 15 | You should have received a copy of the GNU General Public License 16 | along with this program. If not, see . 17 | */ 18 | 19 | // 20 | // Pipe API 21 | // 22 | // The following Format Specifiers are available: 23 | // z -> (char *) -> zero-terminated ascii string 24 | // Z -> (wchar_t *) -> zero-terminated unicode string 25 | // s -> (int, char *) -> ascii string with length 26 | // S -> (int, wchar_t *) -> unicode string with length 27 | // o -> (UNICODE_STRING *) -> unicode string 28 | // O -> (OBJECT_ATTRIBUTES *) -> wrapper around unicode string 29 | // d -> (int) -> integer 30 | // x -> (int) -> hexadecimal integer 31 | // p -> (void *) -> pointer as hex 32 | 33 | int pipe(const char *fmt, ...); 34 | int pipe2(void *out, int *outlen, const char *fmt, ...); 35 | 36 | #define PIPE_MAX_TIMEOUT 10000 37 | -------------------------------------------------------------------------------- /tests/Makefile: -------------------------------------------------------------------------------- 1 | MAKEFLAGS = -j8 2 | CFLAGS = -Wall -std=c99 -s -O2 3 | LIBS = -ldnsapi -lws2_32 -lwininet -lshlwapi 4 | 5 | ifneq ($(OS),Windows_NT) 6 | CC = i586-mingw32msvc-cc 7 | else 8 | CC = gcc 9 | endif 10 | 11 | TESTS = $(wildcard *.c) 12 | TESTSEXE = $(TESTS:.c=.exe) 13 | 14 | # please build all the object files using the main Makefile (in the parent 15 | # directory) 16 | CUCKOOOBJ := $(wildcard ../objects/*.o) 17 | CUCKOOOBJ += $(wildcard ../objects/bson/*.o) 18 | CUCKOOOBJ += $(wildcard ../objects/distorm3.2/*.o) 19 | 20 | all: $(TESTSEXE) 21 | 22 | %.exe: %.c $(CUCKOOOBJ) $(DISTORM3OBJ) 23 | $(CC) $(CFLAGS) -I../distorm3.2-package/include -I.. -o $@ $^ $(LIBS) 24 | 25 | clean: 26 | rm -f $(TESTSEXE) 27 | -------------------------------------------------------------------------------- /tests/apc-inject.c: -------------------------------------------------------------------------------- 1 | /* 2 | Cuckoo Sandbox - Automated Malware Analysis 3 | Copyright (C) 2010-2014 Cuckoo Sandbox Developers 4 | 5 | This program is free software: you can redistribute it and/or modify 6 | it under the terms of the GNU General Public License as published by 7 | the Free Software Foundation, either version 3 of the License, or 8 | (at your option) any later version. 9 | 10 | This program is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | GNU General Public License for more details. 14 | 15 | You should have received a copy of the GNU General Public License 16 | along with this program. If not, see . 17 | */ 18 | 19 | #define _WIN32_WINNT 0x0500 20 | #include 21 | #include 22 | #include 23 | 24 | int main() 25 | { 26 | LoadLibrary("../cuckoomon.dll"); 27 | 28 | FARPROC sleep = GetProcAddress(GetModuleHandle("kernel32"), "Sleep"); 29 | 30 | for (uint32_t tid = 2000; ; tid += 4) { 31 | HANDLE thread_handle = OpenThread(THREAD_ALL_ACCESS, FALSE, tid); 32 | if(thread_handle != NULL) { 33 | printf("tid %d .. :)\n", tid); 34 | QueueUserAPC((PAPCFUNC) sleep, thread_handle, 1337); 35 | CloseHandle(thread_handle); 36 | break; 37 | } 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /tests/apihooks.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | DWORD WINAPI dummy(LPVOID lpValue) 6 | { 7 | printf("dummy here!\n"); 8 | return 0; 9 | } 10 | 11 | int main() 12 | { 13 | // there we go 14 | LoadLibrary("../cuckoomon.dll"); 15 | 16 | FILE *fp = fopen("test-hello", "r"); 17 | if(fp != NULL) fclose(fp); 18 | 19 | fp = fopen("test-hello", "wb"); 20 | fwrite("whatsup", 1, 6, fp); 21 | fclose(fp); 22 | 23 | fp = fopen("test-hello", "rb"); 24 | char buf[6]; 25 | fread(buf, 1, 6, fp); 26 | fclose(fp); 27 | 28 | _mkdir("abc"); 29 | 30 | DeleteFile("test-hello"); 31 | 32 | HKEY hKey; 33 | if(RegCreateKeyEx(HKEY_CURRENT_USER, 34 | "Software\\Microsoft\\Windows\\CurrentVersion\\Run", 0, NULL, 0, 35 | KEY_ALL_ACCESS, NULL, &hKey, NULL) == ERROR_SUCCESS) { 36 | RegQueryInfoKey(hKey, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 37 | NULL, NULL, NULL); 38 | RegSetValueEx(hKey, "TestApiHooks", 0, REG_SZ, (BYTE *) "Hoi", 3); 39 | RegDeleteValue(hKey, "TestApiHooks"); 40 | RegCloseKey(hKey); 41 | } 42 | 43 | system("echo hai"); 44 | 45 | WinExec("echo hi there", SW_SHOW); 46 | 47 | CreateMutex(NULL, FALSE, "MutexNam3"); 48 | OpenMutex(MUTEX_ALL_ACCESS, FALSE, "OpenMutexName"); 49 | 50 | // just some random dll 51 | LoadLibrary("urlmon.dll"); 52 | 53 | FARPROC sleep = GetProcAddress(GetModuleHandle("kernel32"), "Sleep"); 54 | sleep(1000); 55 | 56 | printf("debugger: %d\n", IsDebuggerPresent()); 57 | 58 | CloseHandle(CreateThread(NULL, 0, &dummy, NULL, 0, NULL)); 59 | 60 | HANDLE thread_handle = CreateRemoteThread(GetCurrentProcess(), NULL, 0, 61 | &dummy, NULL, 0, NULL); 62 | WaitForSingleObject(thread_handle, INFINITE); 63 | CloseHandle(thread_handle); 64 | } 65 | -------------------------------------------------------------------------------- /tests/bind-port.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | int main() 5 | { 6 | WSADATA wsa; 7 | WSAStartup(MAKEWORD(2, 2), &wsa); 8 | 9 | SOCKET s = socket(AF_INET, SOCK_STREAM, 0); 10 | 11 | struct sockaddr_in addr = {}; 12 | addr.sin_family = AF_INET; 13 | addr.sin_addr.s_addr = 0; 14 | addr.sin_port = htons(0x29a); 15 | 16 | bind(s, (struct sockaddr *) &addr, sizeof(addr)); 17 | } 18 | -------------------------------------------------------------------------------- /tests/blacklist.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include "ignore.h" 5 | #include "ntapi.h" 6 | 7 | int main() 8 | { 9 | const wchar_t *unicode[] = { 10 | L"abcd", 11 | L"\\??\\IDE#what's up bro?", 12 | }; 13 | for (int i = 0; i < ARRAYSIZE(unicode); i++) { 14 | printf("%d <= %S\n", 15 | is_ignored_file_unicode(unicode[i], wcslen(unicode[i])), 16 | unicode[i]); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /tests/child-sleep.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | int main(int argc, char *argv[]) 5 | { 6 | if(argc == 4) { 7 | Sleep(5000); 8 | return 0; 9 | } 10 | 11 | Sleep(10000); 12 | 13 | char buf[256]; 14 | sprintf(buf, "%s a b c", argv[0]); 15 | system(buf); 16 | } 17 | -------------------------------------------------------------------------------- /tests/crash.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | int main() 4 | { 5 | char *p = NULL; 6 | *p = 0; 7 | } 8 | -------------------------------------------------------------------------------- /tests/create-file.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | int main() 5 | { 6 | const char *modes[] = {"r", "r+", "w", "w+", "a", "a+"}; 7 | const char *fname = "abc"; 8 | 9 | for (int i = 0; i < sizeof(modes)/sizeof(char *); i++) { 10 | DeleteFile(fname); 11 | FILE *fp = fopen(fname, modes[i]); 12 | if(fp != NULL) { 13 | fclose(fp); 14 | } 15 | } 16 | 17 | fclose(fopen(fname, "w")); 18 | for (int i = 0; i < sizeof(modes)/sizeof(char *); i++) { 19 | FILE *fp = fopen(fname, modes[i]); 20 | if(fp != NULL) { 21 | fclose(fp); 22 | } 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /tests/delete-file.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include "../ntapi.h" 4 | 5 | #define OBJ_CASE_INSENSITIVE 0x00000040 6 | #define OBJ_KERNEL_HANDLE 0x00000200 7 | 8 | #define InitializeObjectAttributes(p, n, a, r, s) { \ 9 | (p)->Length = sizeof(OBJECT_ATTRIBUTES); \ 10 | (p)->RootDirectory = r; \ 11 | (p)->Attributes = a; \ 12 | (p)->ObjectName = n; \ 13 | (p)->SecurityDescriptor = s; \ 14 | (p)->SecurityQualityOfService = NULL; \ 15 | } 16 | 17 | VOID (WINAPI *pRtlInitUnicodeString)(PUNICODE_STRING DestinationString, 18 | PCWSTR SourceString); 19 | 20 | NTSTATUS (WINAPI *pZwDeleteFile)(POBJECT_ATTRIBUTES ObjectAttributes); 21 | 22 | NTSTATUS (WINAPI *pZwCreateFile)(PHANDLE FileHandle, 23 | ACCESS_MASK DesiredAccess, POBJECT_ATTRIBUTES ObjectAttributes, 24 | PIO_STATUS_BLOCK IoStatusBlock, PVOID AllocationSize, 25 | ULONG FileAttributes, ULONG ShareAccess, ULONG CreateDisposition, 26 | ULONG CreateOptions, PVOID EaBuffer, ULONG EaLength); 27 | 28 | NTSTATUS (WINAPI *pZwSetInformationFile)(HANDLE FileHandle, 29 | PIO_STATUS_BLOCK IoStatusBlock, PVOID FileInformation, ULONG Length, 30 | FILE_INFORMATION_CLASS FileInformationClass); 31 | 32 | void write_file(const char *fname, const char *s) 33 | { 34 | FILE *fp = fopen(fname, "wb"); 35 | if(fp != NULL) { 36 | fputs(s, fp); 37 | fclose(fp); 38 | } 39 | } 40 | 41 | int main() 42 | { 43 | printf( 44 | "Going to try to delete files using various techiques.\n" 45 | "Note that the MoveFileEx method will fail (see source why)\n" 46 | ); 47 | 48 | write_file("abc.txt", "DeleteFile"); 49 | 50 | // 51 | // delete the file using the well-known DeleteFile function 52 | // 53 | 54 | printf("DeleteFile: %s (0x%08x)\n", DeleteFile("abc.txt") ? 55 | "SUCCESS" : "FAILURE", GetLastError()); 56 | 57 | write_file("abc.txt", "MoveFileEx"); 58 | 59 | // 60 | // delete the file using MoveFileEx, note that a NULL destination filename 61 | // is only supported when the MOVEFILE_DELAY_UNTIL_REBOOT flag is set. 62 | // (so this call will actually fail..) 63 | // 64 | 65 | printf("MoveFileEx: %s (0x%08x)\n", MoveFileEx("abc.txt", NULL, 0) ? 66 | "SUCCESS" : "FAILURE", GetLastError()); 67 | 68 | write_file("abc.txt", "ZwDeleteFile"); 69 | 70 | // 71 | // delete the file using ZwDeleteFile 72 | // 73 | 74 | UNICODE_STRING dir_fname, file_fname; 75 | OBJECT_ATTRIBUTES obj_dir, obj_file; 76 | IO_STATUS_BLOCK io_dir; 77 | HANDLE dir_handle; 78 | 79 | *(FARPROC *) &pRtlInitUnicodeString = GetProcAddress( 80 | GetModuleHandle("ntdll"), "RtlInitUnicodeString"); 81 | *(FARPROC *) &pZwDeleteFile = GetProcAddress( 82 | GetModuleHandle("ntdll"), "ZwDeleteFile"); 83 | *(FARPROC *) &pZwCreateFile = GetProcAddress( 84 | GetModuleHandle("ntdll"), "ZwCreateFile"); 85 | *(FARPROC *) &pZwSetInformationFile = GetProcAddress( 86 | GetModuleHandle("ntdll"), "ZwSetInformationFile"); 87 | 88 | // prepend the path with "\\??\\" 89 | wchar_t cur_dir[MAX_PATH] = L"\\??\\"; 90 | GetCurrentDirectoryW(MAX_PATH-4, cur_dir+4); 91 | 92 | pRtlInitUnicodeString(&dir_fname, cur_dir); 93 | pRtlInitUnicodeString(&file_fname, L"abc.txt"); 94 | 95 | InitializeObjectAttributes(&obj_dir, &dir_fname, 96 | OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE, NULL, NULL); 97 | 98 | // open the directory 99 | NTSTATUS ret = pZwCreateFile(&dir_handle, FILE_TRAVERSE, &obj_dir, 100 | &io_dir, NULL, FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ, FILE_OPEN, 101 | FILE_DIRECTORY_FILE, NULL, 0); 102 | 103 | if(NT_SUCCESS(ret)) { 104 | InitializeObjectAttributes(&obj_file, &file_fname, 105 | OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE, dir_handle, NULL); 106 | 107 | // delete the file 108 | ret = pZwDeleteFile(&obj_file); 109 | printf("ZwDeleteFile: %s (0x%08x)\n", NT_SUCCESS(ret) ? 110 | "SUCCESS" : "FAILURE", ret); 111 | CloseHandle(dir_handle); 112 | } 113 | else { 114 | printf("ZwDeleteFile: FAILURE (0x%08x)\n", ret); 115 | } 116 | 117 | write_file("abc.txt", "ZwSetInformationFile"); 118 | 119 | // 120 | // delete the file using ZwSetInformationFile 121 | // 122 | 123 | IO_STATUS_BLOCK io_file; 124 | HANDLE file_handle; 125 | 126 | // prepend the path with "\\??\\" and append "abc.txt" 127 | wchar_t file_name[MAX_PATH] = L"\\??\\"; 128 | GetCurrentDirectoryW(MAX_PATH-4, file_name+4); 129 | lstrcatW(file_name, L"\\abc.txt"); 130 | 131 | pRtlInitUnicodeString(&file_fname, file_name); 132 | InitializeObjectAttributes(&obj_file, &file_fname, 133 | OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE, NULL, NULL); 134 | 135 | // open the file with DELETE access rights 136 | ret = pZwCreateFile(&file_handle, DELETE, &obj_file, &io_file, NULL, 137 | FILE_ATTRIBUTE_NORMAL, 0, FILE_OPEN, 0, NULL, 0); 138 | if(NT_SUCCESS(ret)) { 139 | BOOLEAN disp_info = TRUE; 140 | ret = pZwSetInformationFile(file_handle, &io_file, &disp_info, 141 | sizeof(disp_info), FileDispositionInformation); 142 | CloseHandle(file_handle); 143 | 144 | printf("ZwSetInformationFile: %s (0x%08x)\n", NT_SUCCESS(ret) ? 145 | "SUCCESS" : "FAILURE", ret); 146 | } 147 | else { 148 | printf("ZwSetInformationFile: FAILURE (0x%08x)\n", ret); 149 | } 150 | } 151 | -------------------------------------------------------------------------------- /tests/getcursorpos.c: -------------------------------------------------------------------------------- 1 | /* 2 | Cuckoo Sandbox - Automated Malware Analysis 3 | Copyright (C) 2010-2014 Cuckoo Sandbox Developers 4 | 5 | This program is free software: you can redistribute it and/or modify 6 | it under the terms of the GNU General Public License as published by 7 | the Free Software Foundation, either version 3 of the License, or 8 | (at your option) any later version. 9 | 10 | This program is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | GNU General Public License for more details. 14 | 15 | You should have received a copy of the GNU General Public License 16 | along with this program. If not, see . 17 | */ 18 | 19 | #include 20 | #include 21 | 22 | int main() 23 | { 24 | for (int i = 0; i < 10; i++) { 25 | POINT p = {}; GetCursorPos(&p); 26 | printf("{x: %ld, y: %ld}\n", p.x, p.y); 27 | Sleep(100); 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /tests/logging.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include "../log.h" 4 | 5 | const char *module_name = "logging"; 6 | 7 | int main() 8 | { 9 | int ret = 0; 10 | 11 | log_init(0, 0, 1); 12 | 13 | LOQ_void("test", "2s", "a", "b", "c", "d"); 14 | LOQ_void("test", "S", "a", 4, "hello"); 15 | LOQ_void("test", "U", "b", 4, L"ab\u1337c"); 16 | LOQ_void("test", "s", "c", NULL); 17 | LOQ_void("test", "lUl", "a", 32, "b", 6, L"HelloWorld", "c", 32); 18 | 19 | // utf8 encoding examples from wikipedia, should result in the following: 20 | // "\x24\xc2\xa2\xe2\x82\xac" 21 | LOQ_void("test", "u", "a", L"\u0024\u00a2\u20ac"); 22 | 23 | int argc = 4; 24 | char *argv[] = {"a", "b", "c", "d"}; 25 | LOQ_void("test", "a", "a", argc, argv); 26 | 27 | // registry stuff 28 | LOQ_void("test", "r", "a", REG_SZ, 0, "lolz"); 29 | LOQ_void("test", "r", "a", REG_DWORD, 4, "\x10\x00\x00\x00"); 30 | LOQ_void("test", "R", "a", REG_SZ, 1337, L"omgz0r"); 31 | LOQ_void("test", "R", "a", REG_BINARY, 8, "Hello World"); 32 | } 33 | -------------------------------------------------------------------------------- /tests/lookup.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include "lookup.h" 4 | 5 | typedef struct _entry_t { 6 | struct _entry_t *next; 7 | unsigned int id; 8 | unsigned int size; 9 | unsigned char data[0]; 10 | } entry_t; 11 | 12 | int main() 13 | { 14 | lookup_t a; 15 | 16 | lookup_init(&a); 17 | strcpy((char *) lookup_add(&a, 1, 10), "abc"); 18 | strcpy((char *) lookup_add(&a, 2, 20), "def"); 19 | lookup_del(&a, 1); 20 | strcpy((char *) lookup_add(&a, 3, 30), "ghi"); 21 | strcpy((char *) lookup_add(&a, 4, 40), "jkl"); 22 | lookup_del(&a, 4); 23 | 24 | for (int i = 0; i < 5; i++) { 25 | printf("%d -> %p\n", i, lookup_get(&a, i, NULL)); 26 | } 27 | 28 | for (entry_t *p = a.root; p != NULL; p = p->next) { 29 | printf("%p %d %d\n", p, p->id, p->size); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /tests/migrate-process.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | int main() 5 | { 6 | // process identifier of explorer.exe on my VM 7 | CloseHandle(OpenProcess(PROCESS_ALL_ACCESS, FALSE, 468)); 8 | } 9 | -------------------------------------------------------------------------------- /tests/mitigate-process.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | /* multiple ways to inject into another process */ 5 | 6 | int main(int argc, char *argv[]) 7 | { 8 | if(argc == 2) { 9 | printf("Child process %s.. exiting..\n", argv[1]); 10 | ExitProcess(0); 11 | } 12 | 13 | char buf[256]; 14 | 15 | // WinExec 16 | sprintf(buf, "\"%s\" a", argv[0]); 17 | WinExec(buf, SW_SHOW); 18 | 19 | // ShellExecute 20 | ShellExecute(NULL, NULL, argv[0], "b", NULL, SW_SHOW); 21 | 22 | // CreateProcess 23 | sprintf(buf, "\"%s\" c", argv[0]); 24 | STARTUPINFO si = {sizeof(si)}; PROCESS_INFORMATION pi = {}; 25 | CreateProcess(NULL, buf, NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi); 26 | 27 | // system 28 | sprintf(buf, "\"%s\" d", argv[0]); 29 | system(buf); 30 | 31 | return 0; 32 | } 33 | -------------------------------------------------------------------------------- /tests/mousebutton-count.c: -------------------------------------------------------------------------------- 1 | /* 2 | Cuckoo Sandbox - Automated Malware Analysis 3 | Copyright (C) 2010-2014 Cuckoo Sandbox Developers 4 | 5 | This program is free software: you can redistribute it and/or modify 6 | it under the terms of the GNU General Public License as published by 7 | the Free Software Foundation, either version 3 of the License, or 8 | (at your option) any later version. 9 | 10 | This program is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | GNU General Public License for more details. 14 | 15 | You should have received a copy of the GNU General Public License 16 | along with this program. If not, see . 17 | */ 18 | 19 | #include 20 | #include 21 | 22 | int main() 23 | { 24 | printf("count: %d\n", GetSystemMetrics(SM_CMOUSEBUTTONS)); 25 | } 26 | -------------------------------------------------------------------------------- /tests/open-protected-pid.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | int main() 5 | { 6 | // this is the process identifier of agent.py on my VM 7 | HANDLE process_handle = OpenProcess(PROCESS_ALL_ACCESS, FALSE, 1576); 8 | printf("process-handle: %p -> %d\n", process_handle, GetLastError()); 9 | return 0; 10 | } 11 | -------------------------------------------------------------------------------- /tests/peb-check.c: -------------------------------------------------------------------------------- 1 | /* 2 | Cuckoo Sandbox - Automated Malware Analysis 3 | Copyright (C) 2010-2014 Cuckoo Sandbox Developers 4 | 5 | This program is free software: you can redistribute it and/or modify 6 | it under the terms of the GNU General Public License as published by 7 | the Free Software Foundation, either version 3 of the License, or 8 | (at your option) any later version. 9 | 10 | This program is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | GNU General Public License for more details. 14 | 15 | You should have received a copy of the GNU General Public License 16 | along with this program. If not, see . 17 | */ 18 | 19 | #include 20 | #include 21 | 22 | int main() 23 | { 24 | LoadLibrary("../cuckoomon.dll"); 25 | 26 | HMODULE cuckoomon_handle = GetModuleHandle("cuckoomon.dll"); 27 | printf("cuckoomon -> 0x%08x\n", cuckoomon_handle); 28 | return 0; 29 | } 30 | -------------------------------------------------------------------------------- /tests/sleep.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | DWORD WINAPI thread(LPVOID lpNothing) 5 | { 6 | return 0; 7 | } 8 | 9 | int main() 10 | { 11 | LoadLibrary("../cuckoomon.dll"); 12 | 13 | // sleep for five seconds (skipped) 14 | for (int i = 0; i < 100; i++) { 15 | Sleep(50); 16 | 17 | printf("tick: %ld\n", GetTickCount()); 18 | } 19 | 20 | // sleep for 10 seconds (skipped) 21 | Sleep(10000); 22 | 23 | printf("tick: %ld\n", GetTickCount()); 24 | 25 | printf("starting second thread\n"); 26 | CloseHandle(CreateThread(NULL, 0, &thread, NULL, 0, NULL)); 27 | 28 | // sleep for 5 seconds (not skipped) 29 | Sleep(5000); 30 | } 31 | -------------------------------------------------------------------------------- /tests/sleep2.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | int main() 5 | { 6 | LoadLibrary("../cuckoomon.dll"); 7 | 8 | unsigned int start = GetTickCount(); 9 | printf("%d\n", start); 10 | 11 | Sleep(1000); 12 | 13 | printf("%d -> %d\n", GetTickCount(), GetTickCount() - start); 14 | 15 | for (int i = 0; i < 10; i++) { 16 | for (int j = 0; j < 0xfffffff; j++); 17 | } 18 | 19 | printf("%d -> %d\n", GetTickCount(), GetTickCount() - start); 20 | 21 | Sleep(1000); 22 | 23 | printf("%d -> %d\n", GetTickCount(), GetTickCount() - start); 24 | } 25 | -------------------------------------------------------------------------------- /tests/startup-time.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | // Idea originally taken from the following article 6 | // http://spth.virii.lu/v4/articles/m0sa/evade.html 7 | 8 | int main() 9 | { 10 | if(GetTickCount() < 10 * 60 * 1000) { 11 | printf("Running under a VM!\n"); 12 | } 13 | else { 14 | printf("This computer is ok! Uptime: %d\n", GetTickCount()); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /tests/suspended-process.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | int main(int argc, char *argv[]) 5 | { 6 | if(argc != 1) { 7 | printf("arg: %s\n", argv[1]); 8 | fflush(stdout); 9 | return 1337; 10 | } 11 | 12 | STARTUPINFO si = {sizeof(si)}; PROCESS_INFORMATION pi; char buf[256]; 13 | 14 | sprintf(buf, "\"%s\" a", argv[0]); 15 | 16 | BOOL ret = CreateProcess(argv[0], buf, NULL, NULL, FALSE, 17 | CREATE_SUSPENDED, NULL, NULL, &si, &pi); 18 | 19 | printf("ret: %d\n", ret); 20 | fflush(stdout); 21 | 22 | ResumeThread(pi.hThread); 23 | WaitForSingleObject(pi.hThread, INFINITE); 24 | WaitForSingleObject(pi.hProcess, INFINITE); 25 | 26 | DWORD exit_code; 27 | GetExitCodeProcess(pi.hProcess, &exit_code); 28 | printf("ret: %d\n", exit_code); 29 | fflush(stdout); 30 | } 31 | -------------------------------------------------------------------------------- /tests/test-dns.c: -------------------------------------------------------------------------------- 1 | #define _WIN32_WINNT 0x0501 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | int main() 8 | { 9 | LoadLibrary("../cuckoomon.dll"); 10 | 11 | printf("DnsQuery -> %d\n", DnsQuery("jbremer.org", DNS_TYPE_A, 12 | DNS_QUERY_STANDARD, NULL, NULL, NULL)); 13 | 14 | struct addrinfo *info = NULL; 15 | printf("getaddrinfo -> %d\n", getaddrinfo("jbremer.org", NULL, NULL, 16 | &info)); 17 | 18 | printf("gethostbyname -> %p\n", gethostbyname("jbremer.org")); 19 | } 20 | -------------------------------------------------------------------------------- /tests/test-lasterr.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include "hooking.h" 4 | #include "ntapi.h" 5 | 6 | #define HOOK(library, funcname) {L###library, #funcname, NULL, \ 7 | &New_##funcname##0, (void **) &Old_##funcname##0} 8 | 9 | HOOKDEF(BOOL, WINAPI, DeleteFileW0, 10 | __in LPWSTR lpFileName 11 | ) { 12 | BOOL ret = Old_DeleteFileW0(lpFileName); 13 | 14 | printf("ret: %d, lasterr: %d, %d\n", ret, GetLastError(), 15 | hook_get_last_error()); 16 | 17 | SetLastError(0x1337); 18 | 19 | printf("ret: %d, lasterr: %d, %d\n", ret, GetLastError(), 20 | hook_get_last_error()); 21 | 22 | hook_set_last_error(0xb00b); 23 | 24 | printf("ret: %d, lasterr: %d, %d\n", ret, GetLastError(), 25 | hook_get_last_error()); 26 | 27 | return ret; 28 | } 29 | 30 | HOOKDEF(NTSTATUS, WINAPI, NtOpenFile0, 31 | __out PHANDLE FileHandle, 32 | __in ACCESS_MASK DesiredAccess, 33 | __in POBJECT_ATTRIBUTES ObjectAttributes, 34 | __out PIO_STATUS_BLOCK IoStatusBlock, 35 | __in ULONG ShareAccess, 36 | __in ULONG OpenOptions 37 | ) { 38 | NTSTATUS ret = Old_NtOpenFile0(FileHandle, DesiredAccess, ObjectAttributes, 39 | IoStatusBlock, ShareAccess, OpenOptions); 40 | SetLastError(0x1338); 41 | printf("OMG!!! %d\n", GetLastError()); 42 | return ret; 43 | } 44 | 45 | int main() 46 | { 47 | static hook_t hook[] = { 48 | HOOK(kernel32, DeleteFileW), 49 | HOOK(ntdll, NtOpenFile), 50 | }; 51 | 52 | DWORD old_protect; 53 | VirtualProtect(hook, sizeof(hook), PAGE_EXECUTE_READWRITE, &old_protect); 54 | 55 | hook_api(&hook[0], HOOK_JMP_DIRECT); 56 | hook_api(&hook[1], HOOK_JMP_DIRECT); 57 | 58 | DeleteFile("hoi"); 59 | printf("lasterr: %d\n", GetLastError()); 60 | } 61 | -------------------------------------------------------------------------------- /tests/test-lde.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include "../hooking.h" 3 | 4 | int main() 5 | { 6 | unsigned char b[][8] = { 7 | {0x55}, 8 | {0x89, 0xe5}, 9 | {0x83, 0xec, 0x18}, 10 | }; 11 | 12 | for (int i = 0; i < sizeof(b)/sizeof(b[0]); i++) { 13 | printf("%d\n", lde(b[i])); 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /tests/unhook.c: -------------------------------------------------------------------------------- 1 | /* 2 | Cuckoo Sandbox - Automated Malware Analysis 3 | Copyright (C) 2010-2014 Cuckoo Sandbox Developers 4 | 5 | This program is free software: you can redistribute it and/or modify 6 | it under the terms of the GNU General Public License as published by 7 | the Free Software Foundation, either version 3 of the License, or 8 | (at your option) any later version. 9 | 10 | This program is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | GNU General Public License for more details. 14 | 15 | You should have received a copy of the GNU General Public License 16 | along with this program. If not, see . 17 | */ 18 | 19 | #include 20 | #include 21 | 22 | int main(int argc, char *argv[]) 23 | { 24 | FARPROC fp = GetProcAddress( 25 | GetModuleHandle("kernel32"), "IsDebuggerPresent"); 26 | 27 | unsigned long old_protect; 28 | VirtualProtect(fp, 0x1000, PAGE_EXECUTE_READWRITE, &old_protect); 29 | 30 | // Corrupt the hook. 31 | memset(fp, 0xcc, 32); 32 | 33 | fp = GetProcAddress(GetModuleHandle("kernel32"), "CopyFileA"); 34 | 35 | VirtualProtect(fp, 0x1000, PAGE_EXECUTE_READWRITE, &old_protect); 36 | 37 | // Restore the hook. 38 | memcpy(fp, "\x8b\xff\x55\x8b\xec", 5); 39 | 40 | Sleep(10000); 41 | } 42 | -------------------------------------------------------------------------------- /tests/wininet.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | int print_url_contents(const char *url) 6 | { 7 | HINTERNET internet_handle, request_handle; 8 | char buffer[1024]; unsigned long bytes_read; 9 | 10 | internet_handle = InternetOpen(NULL, INTERNET_OPEN_TYPE_DIRECT, NULL, 11 | NULL, 0); 12 | if(internet_handle == NULL) return FALSE; 13 | 14 | request_handle = InternetOpenUrl(internet_handle, url, NULL, 0, 0, 0); 15 | if(request_handle == NULL) { 16 | InternetCloseHandle(internet_handle); 17 | return FALSE; 18 | } 19 | 20 | while (InternetReadFile(request_handle, buffer, sizeof(buffer), 21 | &bytes_read) != FALSE && bytes_read != 0) { 22 | fwrite(buffer, bytes_read, 1, stderr); 23 | } 24 | 25 | InternetCloseHandle(internet_handle); 26 | InternetCloseHandle(request_handle); 27 | return TRUE; 28 | } 29 | 30 | int main() 31 | { 32 | print_url_contents("http://jbremer.org/"); 33 | } 34 | -------------------------------------------------------------------------------- /tests/write-file.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | int main() 5 | { 6 | const char *fnames[] = { 7 | "C:\\a.txt", 8 | "C:\\b.txt", 9 | "C:\\c.txt", 10 | "C:\\d.txt", 11 | "C:\\e.txt", 12 | }; 13 | 14 | FILE *fp[3]; 15 | for (int i = 0; i < 5; i++) { 16 | fp[i] = fopen(fnames[i], "w"); 17 | } 18 | 19 | for (int i = 0; i < 20; i++) { 20 | fprintf(fp[rand() % 5], "Hello %d\n", i); 21 | } 22 | 23 | for (int i = 0; i < 20; i++) { 24 | int idx = rand() % 5; 25 | if(fp[idx] != NULL) { 26 | fclose(fp[idx]); 27 | fp[idx] = NULL; 28 | } 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /unhook.h: -------------------------------------------------------------------------------- 1 | /* 2 | Cuckoo Sandbox - Automated Malware Analysis 3 | Copyright (C) 2010-2014 Cuckoo Sandbox Developers 4 | 5 | This program is free software: you can redistribute it and/or modify 6 | it under the terms of the GNU General Public License as published by 7 | the Free Software Foundation, either version 3 of the License, or 8 | (at your option) any later version. 9 | 10 | This program is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | GNU General Public License for more details. 14 | 15 | You should have received a copy of the GNU General Public License 16 | along with this program. If not, see . 17 | */ 18 | 19 | void unhook_detect_add_region(const hook_t *hook, const uint8_t *addr, 20 | const uint8_t *orig, const uint8_t *our, uint32_t length); 21 | int address_already_hooked(uint8_t *addr); 22 | 23 | int unhook_init_detection(); 24 | int terminate_event_init(); 25 | int procname_watch_init(); 26 | int init_watchdog(); 27 | void restore_hooks_on_range(ULONG_PTR start, ULONG_PTR end); 28 | 29 | extern DWORD g_unhook_detect_thread_id; 30 | extern DWORD g_unhook_watcher_thread_id; 31 | extern DWORD g_watchdog_thread_id; 32 | extern DWORD g_procname_watcher_thread_id; 33 | extern DWORD g_terminate_event_thread_id; -------------------------------------------------------------------------------- /utf8.c: -------------------------------------------------------------------------------- 1 | /* 2 | Cuckoo Sandbox - Automated Malware Analysis 3 | Copyright (C) 2010-2014 Cuckoo Sandbox Developers 4 | 5 | This program is free software: you can redistribute it and/or modify 6 | it under the terms of the GNU General Public License as published by 7 | the Free Software Foundation, either version 3 of the License, or 8 | (at your option) any later version. 9 | 10 | This program is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | GNU General Public License for more details. 14 | 15 | You should have received a copy of the GNU General Public License 16 | along with this program. If not, see . 17 | */ 18 | 19 | #include 20 | #include 21 | #include "alloc.h" 22 | #include "utf8.h" 23 | 24 | int utf8_encode(unsigned short c, unsigned char *out) 25 | { 26 | if(c < 0x80) { 27 | *out = c & 0x7F; 28 | return 1; 29 | } 30 | else if(c < 0x800) { 31 | *out = 0xc0 | ((c >> 6) & 0x1F); 32 | out[1] = 0x80 | (c & 0x3f); 33 | return 2; 34 | } 35 | else { 36 | *out = 0xe0 | ((c >> 12) & 0x0F); 37 | out[1] = 0x80 | ((c >> 6) & 0x3F); 38 | out[2] = 0x80 | (c & 0x3f); 39 | return 3; 40 | } 41 | } 42 | 43 | int utf8_length(unsigned short x) 44 | { 45 | unsigned char buf[3]; 46 | return utf8_encode(x, buf); 47 | } 48 | 49 | int utf8_strlen_ascii(const char *s, int len) 50 | { 51 | int ret = 0; 52 | 53 | if(len < 0) 54 | len = (int)strlen(s); 55 | 56 | while (len-- != 0) { 57 | ret += utf8_length(*s++); 58 | } 59 | return ret; 60 | } 61 | 62 | int utf8_strlen_unicode(const wchar_t *s, int len) 63 | { 64 | int ret = 0; 65 | 66 | if(len < 0) 67 | len = lstrlenW(s); 68 | 69 | while (len-- != 0) { 70 | ret += utf8_length(*s++); 71 | } 72 | return ret; 73 | } 74 | 75 | char * utf8_string(const char *str, int length) 76 | { 77 | int encoded_length; 78 | char *utf8string; 79 | int pos = 4; 80 | 81 | if (length == -1) 82 | length = (int)strlen(str); 83 | 84 | encoded_length = utf8_strlen_ascii(str, length); 85 | utf8string = (char *) malloc(encoded_length+4); 86 | *((int *) utf8string) = encoded_length; 87 | 88 | while (length-- != 0) { 89 | pos += utf8_encode(*str++, (unsigned char *) &utf8string[pos]); 90 | } 91 | return utf8string; 92 | } 93 | 94 | char * utf8_wstring(const wchar_t *str, int length) 95 | { 96 | int encoded_length; 97 | char *utf8string; 98 | int pos = 4; 99 | if (length == -1) length = lstrlenW(str); 100 | 101 | encoded_length = utf8_strlen_unicode(str, length); 102 | utf8string = (char *) malloc(encoded_length+4); 103 | *((int *) utf8string) = encoded_length; 104 | 105 | while (length-- != 0) { 106 | pos += utf8_encode(*str++, (unsigned char *) &utf8string[pos]); 107 | } 108 | return utf8string; 109 | } 110 | -------------------------------------------------------------------------------- /utf8.h: -------------------------------------------------------------------------------- 1 | /* 2 | Cuckoo Sandbox - Automated Malware Analysis 3 | Copyright (C) 2010-2014 Cuckoo Sandbox Developers 4 | 5 | This program is free software: you can redistribute it and/or modify 6 | it under the terms of the GNU General Public License as published by 7 | the Free Software Foundation, either version 3 of the License, or 8 | (at your option) any later version. 9 | 10 | This program is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | GNU General Public License for more details. 14 | 15 | You should have received a copy of the GNU General Public License 16 | along with this program. If not, see . 17 | */ 18 | 19 | int utf8_encode(unsigned short x, unsigned char *out); 20 | int utf8_length(unsigned short x); 21 | 22 | // name is a bit weird.. but it calculates the length of the utf8 encoded 23 | // ascii/unicode string "s" in bytes 24 | int utf8_strlen_ascii(const char *s, int len); 25 | int utf8_strlen_unicode(const wchar_t *s, int len); 26 | 27 | char * utf8_string(const char *str, int length); 28 | char * utf8_wstring(const wchar_t *str, int length); 29 | --------------------------------------------------------------------------------