├── .editorconfig ├── .gitattributes ├── .github └── workflows │ ├── build.yml │ └── release.yml ├── .gitignore ├── CHANGELOG.md ├── LICENSE ├── README.md ├── Tools ├── ATAIdentifyDump │ ├── ATAIdentifyDump.cpp │ ├── ATAIdentifyDump.vcxproj │ ├── ATAIdentifyDump.vcxproj.filters │ ├── IdentifyDeviceData.h │ ├── README.md │ ├── pch.cpp │ └── pch.h └── StructDumpCodegen │ ├── README.md │ └── struct_dump_codegen.linq ├── al-khaser.sln └── al-khaser ├── Al-khaser.cpp ├── AntiAnalysis ├── pch.h ├── process.cpp └── process.h ├── AntiDebug ├── BeingDebugged.cpp ├── BeingDebugged.h ├── CheckRemoteDebuggerPresent.cpp ├── CheckRemoteDebuggerPresent.h ├── CloseHandle_InvalidHandle.cpp ├── CloseHandle_InvalidHandle.h ├── HardwareBreakpoints.cpp ├── HardwareBreakpoints.h ├── Interrupt_0x2d.cpp ├── Interrupt_0x2d.h ├── Interrupt_3.cpp ├── Interrupt_3.h ├── IsDebuggerPresent.cpp ├── IsDebuggerPresent.h ├── LowFragmentationHeap.cpp ├── LowFragmentationHeap.h ├── MemoryBreakpoints_PageGuard.cpp ├── MemoryBreakpoints_PageGuard.h ├── ModuleBoundsHookCheck.cpp ├── ModuleBoundsHookCheck.h ├── NtGlobalFlag.cpp ├── NtGlobalFlag.h ├── NtQueryInformationProcess_ProcessDebugFlags.cpp ├── NtQueryInformationProcess_ProcessDebugFlags.h ├── NtQueryInformationProcess_ProcessDebugObject.cpp ├── NtQueryInformationProcess_ProcessDebugObject.h ├── NtQueryInformationProcess_ProcessDebugPort.cpp ├── NtQueryInformationProcess_ProcessDebugPort.h ├── NtQueryObject_AllTypesInformation.cpp ├── NtQueryObject_ObjectInformation.h ├── NtQueryObject_ObjectTypeInformation.cpp ├── NtQuerySystemInformation_SystemKernelDebuggerInformation.cpp ├── NtQuerySystemInformation_SystemKernelDebuggerInformation.h ├── NtSetInformationThread_ThreadHideFromDebugger.cpp ├── NtSetInformationThread_ThreadHideFromDebugger.h ├── NtSystemDebugControl.cpp ├── NtSystemDebugControl.h ├── NtYieldExecution.cpp ├── NtYieldExecution.h ├── OutputDebugStringAPI.cpp ├── OutputDebugStringAPI.h ├── PageExceptionBreakpointCheck.cpp ├── PageExceptionBreakpointCheck.h ├── ParentProcess.cpp ├── ParentProcess.h ├── ProcessHeap_Flags.cpp ├── ProcessHeap_Flags.h ├── ProcessHeap_ForceFlags.cpp ├── ProcessHeap_ForceFlags.h ├── ProcessJob.cpp ├── ProcessJob.h ├── ScanForModules.cpp ├── ScanForModules.h ├── SeDebugPrivilege.cpp ├── SeDebugPrivilege.h ├── SetHandleInformation_API.cpp ├── SetHandleInformation_API.h ├── SharedUserData_KernelDebugger.cpp ├── SharedUserData_KernelDebugger.h ├── SoftwareBreakpoints.cpp ├── SoftwareBreakpoints.h ├── TLS_callbacks.cpp ├── TLS_callbacks.h ├── TrapFlag.cpp ├── TrapFlag.h ├── UnhandledExceptionFilter_Handler.cpp ├── UnhandledExceptionFilter_Handler.h ├── WUDF_IsDebuggerPresent.cpp ├── WUDF_IsDebuggerPresent.h ├── WriteWatch.cpp ├── WriteWatch.h ├── int2d_x64.asm ├── int2d_x86.asm └── pch.h ├── AntiDisassm ├── AntiDisassm.cpp ├── AntiDisassm.h ├── AntiDisassm_x64.asm ├── AntiDisassm_x86.asm └── pch.h ├── AntiDump ├── ErasePEHeaderFromMemory.cpp ├── ErasePEHeaderFromMemory.h ├── SizeOfImage.cpp ├── SizeOfImage.h └── pch.h ├── AntiVM ├── Generic.cpp ├── Generic.h ├── HyperV.cpp ├── HyperV.h ├── KVM.cpp ├── KVM.h ├── Parallels.cpp ├── Parallels.h ├── Qemu.cpp ├── Qemu.h ├── Services.cpp ├── Services.h ├── VMWare.cpp ├── VMWare.h ├── VirtualBox.cpp ├── VirtualBox.h ├── VirtualPC.cpp ├── VirtualPC.h ├── Wine.cpp ├── Wine.h ├── Xen.cpp ├── Xen.h └── pch.h ├── CodeInjection ├── CreateRemoteThread.cpp ├── CreateRemoteThread.h ├── GetSetThreadContext.cpp ├── GetSetThreadContext.h ├── InjectedDLL │ ├── InjectedDLL.cpp │ ├── InjectedDLL.h │ ├── InjectedDLL.vcxproj │ ├── InjectedDLL.vcxproj.filters │ └── definitions.def ├── NtCreateThreadEx.cpp ├── NtCreateThreadEx.h ├── QueueUserAPC.cpp ├── QueueUserAPC.h ├── RtlCreateUserThread.cpp ├── RtlCreateUserThread.h ├── SetWindowsHooksEx.cpp ├── SetWindowsHooksEx.h └── pch.h ├── OfficeMacro ├── al-khaser.docm └── macros.vba ├── Shared ├── APIs.cpp ├── APIs.h ├── ApiTypeDefs.cpp ├── ApiTypeDefs.h ├── Common.cpp ├── Common.h ├── Utils.cpp ├── Utils.h ├── VersionHelpers.h ├── WinStructs.h ├── log.cpp ├── log.h ├── pch.h └── winapifamily.h ├── TimingAttacks ├── pch.h ├── timing.cpp └── timing.h ├── al-khaser.manifest ├── al-khaser.vcxproj ├── al-khaser.vcxproj.filters ├── packages.config ├── pch.cpp └── pch.h /.editorconfig: -------------------------------------------------------------------------------- 1 | ; Top-most EditorConfig file 2 | root = true 3 | 4 | ; Windows-style newlines 5 | [*] 6 | end_of_line = CRLF 7 | 8 | ; Tab indentation 9 | [*.{cpp,h}] 10 | indent_style = tab 11 | tab_width = 4 -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | ############################################################################### 2 | # Set default behavior to automatically normalize line endings. 3 | ############################################################################### 4 | * text=auto 5 | 6 | ############################################################################### 7 | # Set the merge driver for project and solution files 8 | # 9 | # Merging from the command prompt will add diff markers to the files if there 10 | # are conflicts (Merging from VS is not affected by the settings below, in VS 11 | # the diff markers are never inserted). Diff markers may cause the following 12 | # file extensions to fail to load in VS. An alternative would be to treat 13 | # these files as binary and thus will always conflict and require user 14 | # intervention with every merge. To do so, just comment the entries below and 15 | # uncomment the group further below 16 | ############################################################################### 17 | 18 | *.sln text eol=crlf 19 | *.csproj text eol=crlf 20 | *.vbproj text eol=crlf 21 | *.vcxproj text eol=crlf 22 | *.vcproj text eol=crlf 23 | *.dbproj text eol=crlf 24 | *.fsproj text eol=crlf 25 | *.lsproj text eol=crlf 26 | *.wixproj text eol=crlf 27 | *.modelproj text eol=crlf 28 | *.sqlproj text eol=crlf 29 | *.wmaproj text eol=crlf 30 | 31 | *.xproj text eol=crlf 32 | *.props text eol=crlf 33 | *.filters text eol=crlf 34 | *.vcxitems text eol=crlf 35 | 36 | 37 | #*.sln merge=binary 38 | #*.csproj merge=binary 39 | #*.vbproj merge=binary 40 | #*.vcxproj merge=binary 41 | #*.vcproj merge=binary 42 | #*.dbproj merge=binary 43 | #*.fsproj merge=binary 44 | #*.lsproj merge=binary 45 | #*.wixproj merge=binary 46 | #*.modelproj merge=binary 47 | #*.sqlproj merge=binary 48 | #*.wwaproj merge=binary 49 | 50 | #*.xproj merge=binary 51 | #*.props merge=binary 52 | #*.filters merge=binary 53 | #*.vcxitems merge=binary 54 | -------------------------------------------------------------------------------- /.github/workflows/build.yml: -------------------------------------------------------------------------------- 1 | name: Build Pull Request Artifacts 2 | on: [pull_request] 3 | jobs: 4 | build: 5 | runs-on: windows-2022 6 | 7 | steps: 8 | - uses: actions/checkout@v2 9 | 10 | - name: Add MSBuild to PATH 11 | uses: microsoft/setup-msbuild@v1.1.3 12 | 13 | - name: Restore NuGet packages 14 | run: nuget restore ${{env.SOLUTION_FILE_PATH}} 15 | 16 | - name: Build x86 17 | run: msbuild /m /p:Platform=x86 /p:Configuration=Release al-khaser.sln 18 | 19 | - name: Build x64 20 | run: msbuild /m /p:Platform=x64 /p:Configuration=Release al-khaser.sln 21 | 22 | - name: Zip x86 Binaries 23 | run: 7z a -t7z -m0=lzma2 -mx=9 -mfb=64 -md=32m -mhe=on -p"yug69gG89T98HGUY8y" al-khaser_x86.7z al-khaser_x86.exe 24 | 25 | - name: Zip x64 Binaries 26 | run: 7z a -t7z -m0=lzma2 -mx=9 -mfb=64 -md=32m -mhe=on -p"yug69gG89T98HGUY8y" al-khaser_x64.7z al-khaser_x64.exe 27 | 28 | - name: Upload x86 Binaries 29 | uses: actions/upload-artifact@v4 30 | with: 31 | name: x86 32 | path: "al-khaser_x86.7z" 33 | 34 | - name: Upload x64 Binaries 35 | uses: actions/upload-artifact@v4 36 | with: 37 | name: x64 38 | path: "al-khaser_x64.7z" 39 | -------------------------------------------------------------------------------- /.github/workflows/release.yml: -------------------------------------------------------------------------------- 1 | name: Build Release Artifacts 2 | on: 3 | release: 4 | types: [published] 5 | jobs: 6 | build: 7 | runs-on: windows-2022 8 | 9 | steps: 10 | - uses: actions/checkout@v2 11 | 12 | - name: Add MSBuild to PATH 13 | uses: microsoft/setup-msbuild@v1.1.3 14 | 15 | - name: Restore NuGet packages 16 | run: nuget restore ${{env.SOLUTION_FILE_PATH}} 17 | 18 | - name: Build x86 19 | run: msbuild /m /p:Platform=x86 /p:Configuration=Release al-khaser.sln 20 | 21 | - name: Build x64 22 | run: msbuild /m /p:Platform=x64 /p:Configuration=Release al-khaser.sln 23 | 24 | - name: Zip x86 Binaries 25 | run: 7z a -t7z -m0=lzma2 -mx=9 -mfb=64 -md=32m -mhe=on -p"yug69gG89T98HGUY8y" al-khaser_x86.7z al-khaser_x86.exe 26 | 27 | - name: Zip x64 Binaries 28 | run: 7z a -t7z -m0=lzma2 -mx=9 -mfb=64 -md=32m -mhe=on -p"yug69gG89T98HGUY8y" al-khaser_x64.7z al-khaser_x64.exe 29 | 30 | - name: Attach Binaries to release 31 | uses: AButler/upload-release-assets@v3.0 32 | with: 33 | files: "al-khaser_x*.7z" 34 | repo-token: ${{ secrets.GITHUB_TOKEN }} 35 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Compiled Object files 2 | *.slo 3 | *.lo 4 | *.o 5 | *.obj 6 | 7 | # User-specific files 8 | *.suo 9 | *.user 10 | *.userosscache 11 | *.sln.docstates 12 | 13 | # Precompiled Headers 14 | *.gch 15 | *.pch 16 | 17 | # Compiled Dynamic libraries 18 | *.so 19 | *.dylib 20 | *.dll 21 | 22 | # Fortran module files 23 | *.mod 24 | 25 | # Compiled Static libraries 26 | *.lai 27 | *.la 28 | *.a 29 | *.lib 30 | 31 | # Executables 32 | *.out 33 | *.app 34 | 35 | # User-specific files 36 | *.suo 37 | *.user 38 | *.userosscache 39 | *.sln.docstates 40 | 41 | # Visual C++ cache files 42 | ipch/ 43 | *.aps 44 | *.ncb 45 | *.opensdf 46 | *.sdf 47 | *.cachefile 48 | 49 | # Build results 50 | [Dd]ebug/ 51 | [Dd]ebugPublic/ 52 | [Rr]elease/ 53 | [Rr]eleases/ 54 | x64/ 55 | x86/ 56 | build/ 57 | bld/ 58 | [Bb]in/ 59 | [Oo]bj/ 60 | *.VC.opendb 61 | 62 | # Visual C++ Solution 63 | *.VC.db 64 | 65 | # NuGet packages 66 | packages/ 67 | 68 | # Alkhaser log file 69 | log.txt 70 | 71 | # Packages 72 | packages/ 73 | -------------------------------------------------------------------------------- /Tools/ATAIdentifyDump/ATAIdentifyDump.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;ipp;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 | Header Files 20 | 21 | 22 | Header Files 23 | 24 | 25 | 26 | 27 | Source Files 28 | 29 | 30 | Source Files 31 | 32 | 33 | -------------------------------------------------------------------------------- /Tools/ATAIdentifyDump/IdentifyDeviceData.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | typedef struct _IDENTIFY_DEVICE_DATA { 4 | struct { 5 | USHORT Reserved1 : 1; 6 | USHORT Retired3 : 1; 7 | USHORT ResponseIncomplete : 1; 8 | USHORT Retired2 : 3; 9 | USHORT FixedDevice : 1; 10 | USHORT RemovableMedia : 1; 11 | USHORT Retired1 : 7; 12 | USHORT DeviceType : 1; 13 | } GeneralConfiguration; 14 | USHORT NumCylinders; 15 | USHORT ReservedWord2; 16 | USHORT NumHeads; 17 | USHORT Retired1[2]; 18 | USHORT NumSectorsPerTrack; 19 | USHORT VendorUnique1[3]; 20 | UCHAR SerialNumber[20]; 21 | USHORT Retired2[2]; 22 | USHORT Obsolete1; 23 | UCHAR FirmwareRevision[8]; 24 | UCHAR ModelNumber[40]; 25 | UCHAR MaximumBlockTransfer; 26 | UCHAR VendorUnique2; 27 | USHORT ReservedWord48; 28 | struct { 29 | UCHAR ReservedByte49; 30 | UCHAR DmaSupported : 1; 31 | UCHAR LbaSupported : 1; 32 | UCHAR IordyDisable : 1; 33 | UCHAR IordySupported : 1; 34 | UCHAR Reserved1 : 1; 35 | UCHAR StandybyTimerSupport : 1; 36 | UCHAR Reserved2 : 2; 37 | USHORT ReservedWord50; 38 | } Capabilities; 39 | USHORT ObsoleteWords51[2]; 40 | USHORT TranslationFieldsValid : 3; 41 | USHORT Reserved3 : 13; 42 | USHORT NumberOfCurrentCylinders; 43 | USHORT NumberOfCurrentHeads; 44 | USHORT CurrentSectorsPerTrack; 45 | ULONG CurrentSectorCapacity; 46 | UCHAR CurrentMultiSectorSetting; 47 | UCHAR MultiSectorSettingValid : 1; 48 | UCHAR ReservedByte59 : 7; 49 | ULONG UserAddressableSectors; 50 | USHORT ObsoleteWord62; 51 | USHORT MultiWordDMASupport : 8; 52 | USHORT MultiWordDMAActive : 8; 53 | USHORT AdvancedPIOModes : 8; 54 | USHORT ReservedByte64 : 8; 55 | USHORT MinimumMWXferCycleTime; 56 | USHORT RecommendedMWXferCycleTime; 57 | USHORT MinimumPIOCycleTime; 58 | USHORT MinimumPIOCycleTimeIORDY; 59 | USHORT ReservedWords69[6]; 60 | USHORT QueueDepth : 5; 61 | USHORT ReservedWord75 : 11; 62 | USHORT ReservedWords76[4]; 63 | USHORT MajorRevision; 64 | USHORT MinorRevision; 65 | struct { 66 | USHORT SmartCommands : 1; 67 | USHORT SecurityMode : 1; 68 | USHORT RemovableMediaFeature : 1; 69 | USHORT PowerManagement : 1; 70 | USHORT Reserved1 : 1; 71 | USHORT WriteCache : 1; 72 | USHORT LookAhead : 1; 73 | USHORT ReleaseInterrupt : 1; 74 | USHORT ServiceInterrupt : 1; 75 | USHORT DeviceReset : 1; 76 | USHORT HostProtectedArea : 1; 77 | USHORT Obsolete1 : 1; 78 | USHORT WriteBuffer : 1; 79 | USHORT ReadBuffer : 1; 80 | USHORT Nop : 1; 81 | USHORT Obsolete2 : 1; 82 | USHORT DownloadMicrocode : 1; 83 | USHORT DmaQueued : 1; 84 | USHORT Cfa : 1; 85 | USHORT AdvancedPm : 1; 86 | USHORT Msn : 1; 87 | USHORT PowerUpInStandby : 1; 88 | USHORT ManualPowerUp : 1; 89 | USHORT Reserved2 : 1; 90 | USHORT SetMax : 1; 91 | USHORT Acoustics : 1; 92 | USHORT BigLba : 1; 93 | USHORT DeviceConfigOverlay : 1; 94 | USHORT FlushCache : 1; 95 | USHORT FlushCacheExt : 1; 96 | USHORT Resrved3 : 2; 97 | USHORT SmartErrorLog : 1; 98 | USHORT SmartSelfTest : 1; 99 | USHORT MediaSerialNumber : 1; 100 | USHORT MediaCardPassThrough : 1; 101 | USHORT StreamingFeature : 1; 102 | USHORT GpLogging : 1; 103 | USHORT WriteFua : 1; 104 | USHORT WriteQueuedFua : 1; 105 | USHORT WWN64Bit : 1; 106 | USHORT URGReadStream : 1; 107 | USHORT URGWriteStream : 1; 108 | USHORT ReservedForTechReport : 2; 109 | USHORT IdleWithUnloadFeature : 1; 110 | USHORT Reserved4 : 2; 111 | } CommandSetSupport; 112 | struct { 113 | USHORT SmartCommands : 1; 114 | USHORT SecurityMode : 1; 115 | USHORT RemovableMediaFeature : 1; 116 | USHORT PowerManagement : 1; 117 | USHORT Reserved1 : 1; 118 | USHORT WriteCache : 1; 119 | USHORT LookAhead : 1; 120 | USHORT ReleaseInterrupt : 1; 121 | USHORT ServiceInterrupt : 1; 122 | USHORT DeviceReset : 1; 123 | USHORT HostProtectedArea : 1; 124 | USHORT Obsolete1 : 1; 125 | USHORT WriteBuffer : 1; 126 | USHORT ReadBuffer : 1; 127 | USHORT Nop : 1; 128 | USHORT Obsolete2 : 1; 129 | USHORT DownloadMicrocode : 1; 130 | USHORT DmaQueued : 1; 131 | USHORT Cfa : 1; 132 | USHORT AdvancedPm : 1; 133 | USHORT Msn : 1; 134 | USHORT PowerUpInStandby : 1; 135 | USHORT ManualPowerUp : 1; 136 | USHORT Reserved2 : 1; 137 | USHORT SetMax : 1; 138 | USHORT Acoustics : 1; 139 | USHORT BigLba : 1; 140 | USHORT DeviceConfigOverlay : 1; 141 | USHORT FlushCache : 1; 142 | USHORT FlushCacheExt : 1; 143 | USHORT Resrved3 : 2; 144 | USHORT SmartErrorLog : 1; 145 | USHORT SmartSelfTest : 1; 146 | USHORT MediaSerialNumber : 1; 147 | USHORT MediaCardPassThrough : 1; 148 | USHORT StreamingFeature : 1; 149 | USHORT GpLogging : 1; 150 | USHORT WriteFua : 1; 151 | USHORT WriteQueuedFua : 1; 152 | USHORT WWN64Bit : 1; 153 | USHORT URGReadStream : 1; 154 | USHORT URGWriteStream : 1; 155 | USHORT ReservedForTechReport : 2; 156 | USHORT IdleWithUnloadFeature : 1; 157 | USHORT Reserved4 : 2; 158 | } CommandSetActive; 159 | USHORT UltraDMASupport : 8; 160 | USHORT UltraDMAActive : 8; 161 | USHORT ReservedWord89[4]; 162 | USHORT HardwareResetResult; 163 | USHORT CurrentAcousticValue : 8; 164 | USHORT RecommendedAcousticValue : 8; 165 | USHORT ReservedWord95[5]; 166 | ULONG Max48BitLBA[2]; 167 | USHORT StreamingTransferTime; 168 | USHORT ReservedWord105; 169 | struct { 170 | USHORT LogicalSectorsPerPhysicalSector : 4; 171 | USHORT Reserved0 : 8; 172 | USHORT LogicalSectorLongerThan256Words : 1; 173 | USHORT MultipleLogicalSectorsPerPhysicalSector : 1; 174 | USHORT Reserved1 : 2; 175 | } PhysicalLogicalSectorSize; 176 | USHORT InterSeekDelay; 177 | USHORT WorldWideName[4]; 178 | USHORT ReservedForWorldWideName128[4]; 179 | USHORT ReservedForTlcTechnicalReport; 180 | USHORT WordsPerLogicalSector[2]; 181 | struct { 182 | USHORT ReservedForDrqTechnicalReport : 1; 183 | USHORT WriteReadVerifySupported : 1; 184 | USHORT Reserved01 : 11; 185 | USHORT Reserved1 : 2; 186 | } CommandSetSupportExt; 187 | struct { 188 | USHORT ReservedForDrqTechnicalReport : 1; 189 | USHORT WriteReadVerifyEnabled : 1; 190 | USHORT Reserved01 : 11; 191 | USHORT Reserved1 : 2; 192 | } CommandSetActiveExt; 193 | USHORT ReservedForExpandedSupportandActive[6]; 194 | USHORT MsnSupport : 2; 195 | USHORT ReservedWord1274 : 14; 196 | struct { 197 | USHORT SecuritySupported : 1; 198 | USHORT SecurityEnabled : 1; 199 | USHORT SecurityLocked : 1; 200 | USHORT SecurityFrozen : 1; 201 | USHORT SecurityCountExpired : 1; 202 | USHORT EnhancedSecurityEraseSupported : 1; 203 | USHORT Reserved0 : 2; 204 | USHORT SecurityLevel : 1; 205 | USHORT Reserved1 : 7; 206 | } SecurityStatus; 207 | USHORT ReservedWord129[31]; 208 | struct { 209 | USHORT MaximumCurrentInMA2 : 12; 210 | USHORT CfaPowerMode1Disabled : 1; 211 | USHORT CfaPowerMode1Required : 1; 212 | USHORT Reserved0 : 1; 213 | USHORT Word160Supported : 1; 214 | } CfaPowerModel; 215 | USHORT ReservedForCfaWord161[8]; 216 | struct { 217 | USHORT SupportsTrim : 1; 218 | USHORT Reserved0 : 15; 219 | } DataSetManagementFeature; 220 | USHORT ReservedForCfaWord170[6]; 221 | USHORT CurrentMediaSerialNumber[30]; 222 | USHORT ReservedWord206; 223 | USHORT ReservedWord207[2]; 224 | struct { 225 | USHORT AlignmentOfLogicalWithinPhysical : 14; 226 | USHORT Word209Supported : 1; 227 | USHORT Reserved0 : 1; 228 | } BlockAlignment; 229 | USHORT WriteReadVerifySectorCountMode3Only[2]; 230 | USHORT WriteReadVerifySectorCountMode2Only[2]; 231 | struct { 232 | USHORT NVCachePowerModeEnabled : 1; 233 | USHORT Reserved0 : 3; 234 | USHORT NVCacheFeatureSetEnabled : 1; 235 | USHORT Reserved1 : 3; 236 | USHORT NVCachePowerModeVersion : 4; 237 | USHORT NVCacheFeatureSetVersion : 4; 238 | } NVCacheCapabilities; 239 | USHORT NVCacheSizeLSW; 240 | USHORT NVCacheSizeMSW; 241 | USHORT NominalMediaRotationRate; 242 | USHORT ReservedWord218; 243 | struct { 244 | UCHAR NVCacheEstimatedTimeToSpinUpInSeconds; 245 | UCHAR Reserved; 246 | } NVCacheOptions; 247 | USHORT ReservedWord220[35]; 248 | USHORT Signature : 8; 249 | USHORT CheckSum : 8; 250 | } IDENTIFY_DEVICE_DATA, *PIDENTIFY_DEVICE_DATA; -------------------------------------------------------------------------------- /Tools/ATAIdentifyDump/README.md: -------------------------------------------------------------------------------- 1 | # ATAIdentifyDump 2 | 3 | ATAIdentifyDump dumps ATA IDENTIFY data from physical disks. This data is useful for identifying VMs. 4 | 5 | You must run this tool as an administrator. -------------------------------------------------------------------------------- /Tools/ATAIdentifyDump/pch.cpp: -------------------------------------------------------------------------------- 1 | #include "pch.h" 2 | -------------------------------------------------------------------------------- /Tools/ATAIdentifyDump/pch.h: -------------------------------------------------------------------------------- 1 | #ifndef PCH_H 2 | #define PCH_H 3 | 4 | #include 5 | #include 6 | #include 7 | #include "IdentifyDeviceData.h" 8 | 9 | #endif // PCH_H -------------------------------------------------------------------------------- /Tools/StructDumpCodegen/README.md: -------------------------------------------------------------------------------- 1 | # Struct Dump Codegen 2 | 3 | This is a LINQpad script to turn a struct definition into C++ code that prints out its contents. So far it supports USHORT, ULONG, and UCHAR. 4 | 5 | This was written specifically for IDENTIFY_DEVICE_DATA in order to speed up writing ATAIdentifyDump. 6 | 7 | This can probably be used for similar structs too, so it might be useful elsewhere. -------------------------------------------------------------------------------- /Tools/StructDumpCodegen/struct_dump_codegen.linq: -------------------------------------------------------------------------------- 1 | 2 | <RuntimeDirectory>\System.Drawing.dll 3 | <RuntimeDirectory>\System.IO.dll 4 | <RuntimeDirectory>\System.Net.dll 5 | <RuntimeDirectory>\System.Numerics.dll 6 | <RuntimeDirectory>\System.Numerics.Vectors.dll 7 | <RuntimeDirectory>\System.Security.dll 8 | System.Collections 9 | System.Collections.Concurrent 10 | System.Collections.Generic 11 | System.Collections.Specialized 12 | System.Drawing 13 | System.Drawing.Imaging 14 | System.IO 15 | System.IO.MemoryMappedFiles 16 | System.IO.Pipes 17 | System.IO.Ports 18 | System.Net 19 | System.Net.Sockets 20 | System.Numerics 21 | System.Runtime.InteropServices 22 | System.Runtime.InteropServices 23 | System.Runtime.Serialization 24 | System.Runtime.Serialization.Formatters.Binary 25 | System.Security 26 | System.Security.AccessControl 27 | System.Security.Cryptography 28 | System.Security.Principal 29 | System.Text 30 | System.Threading 31 | System.Threading.Tasks 32 | 33 | 34 | /* 35 | Script to turn a struct definition into C++ code that prints out its contents. So far it supports USHORT, ULONG, and UCHAR. 36 | 37 | This was written specifically for IDENTIFY_DEVICE_DATA in order to speed up writing ATAIdentifyDump. 38 | 39 | This can probably be used for similar structs too, so it might be useful elsewhere. 40 | */ 41 | 42 | const string SourceFile = @"C:\Users\Graham\Source\Repos\al-khaser\Tools\ATAIdentifyDump\IdentifyDeviceData.h"; 43 | const string StructVar = "idd"; 44 | const bool SwapStringEndian = true; // for IDENTIFY_DEVICE_DATA 45 | 46 | void Main() 47 | { 48 | 49 | string[] lines = File.ReadAllLines(SourceFile); 50 | 51 | bool foundStart = false; 52 | bool inStruct = false; 53 | var structLines = new List(); 54 | 55 | var output = new StringBuilder(); 56 | 57 | foreach (string rawLine in lines) 58 | { 59 | var line = rawLine.Trim().TrimEnd(';'); 60 | if (!foundStart) 61 | { 62 | if (line.StartsWith("typedef struct")) 63 | { 64 | foundStart = true; 65 | } 66 | continue; 67 | } 68 | 69 | if (line.StartsWith("struct {")) 70 | { 71 | if (inStruct) 72 | { 73 | throw new InvalidDataException(); 74 | } 75 | 76 | // we're starting a nested structure 77 | inStruct = true; 78 | structLines.Clear(); 79 | continue; 80 | } 81 | 82 | if (line.StartsWith("}")) 83 | { 84 | if (!inStruct) 85 | { 86 | Console.WriteLine("// end"); 87 | break; 88 | } 89 | 90 | // we're ending a nested structure 91 | var structNameMatch = Regex.Match(line, "^}\\s+([a-zA-Z0-9]+)$"); 92 | if (!structNameMatch.Success) 93 | { 94 | throw new InvalidDataException(); 95 | } 96 | 97 | string structName = structNameMatch.Groups[1].Value; 98 | 99 | inStruct = false; 100 | foreach (string structLine in structLines) 101 | { 102 | ProcessLine(StructVar, structLine, structName); 103 | } 104 | continue; 105 | } 106 | 107 | if (inStruct) 108 | { 109 | structLines.Add(line); 110 | continue; 111 | } 112 | 113 | ProcessLine(StructVar, line); 114 | } 115 | } 116 | 117 | void ProcessLine(string structvar, string line, string structname = null) 118 | { 119 | string[] parts = line.Split(" ".ToCharArray(), StringSplitOptions.RemoveEmptyEntries); 120 | 121 | string fieldType = null; 122 | string fieldName = null; 123 | int arraySize = 0; 124 | 125 | if (parts.Length == 2) 126 | { 127 | fieldType = parts[0]; 128 | if (parts[1].Contains("[")) 129 | { 130 | var arrayMatch = Regex.Match(parts[1], "^([a-zA-Z0-9]+)\\[(\\d+)\\]$"); 131 | if (!arrayMatch.Success) 132 | { 133 | throw new InvalidDataException(); 134 | } 135 | fieldName = arrayMatch.Groups[1].Value; 136 | arraySize = int.Parse(arrayMatch.Groups[2].Value); 137 | } 138 | else 139 | { 140 | fieldName = parts[1]; 141 | } 142 | } 143 | else 144 | { 145 | if (!parts.Contains(":")) 146 | { 147 | throw new InvalidDataException(); 148 | } 149 | 150 | fieldType = parts[0]; 151 | fieldName = parts[1]; 152 | } 153 | 154 | if (structname != null) 155 | { 156 | structname += "."; 157 | } 158 | 159 | if (fieldType == "USHORT") 160 | { 161 | if (arraySize == 0) 162 | { 163 | Console.WriteLine($"printf(\"{structname ?? ""}{fieldName} = %hu\\r\\n\", {structvar}->{structname ?? ""}{fieldName});"); 164 | } 165 | else 166 | { 167 | for (int i = 0; i < arraySize; i++) 168 | { 169 | Console.WriteLine($"printf(\"{structname ?? ""}{fieldName}[{i}] = %hu\\r\\n\", {structvar}->{structname ?? ""}{fieldName}[{i}]);"); 170 | } 171 | } 172 | } 173 | else if (fieldType == "ULONG") 174 | { 175 | if (arraySize == 0) 176 | { 177 | Console.WriteLine($"printf(\"{structname ?? ""}{fieldName} = %lu\\r\\n\", {structvar}->{structname ?? ""}{fieldName});"); 178 | } 179 | else 180 | { 181 | for (int i = 0; i < arraySize; i++) 182 | { 183 | Console.WriteLine($"printf(\"{structname ?? ""}{fieldName}[{i}] = %lu\\r\\n\", {structvar}->{structname ?? ""}{fieldName}[{i}]);"); 184 | } 185 | } 186 | } 187 | else if (fieldType == "UCHAR") 188 | { 189 | if (arraySize == 0) 190 | { 191 | Console.WriteLine($"printf(\"{structname ?? ""}{fieldName} = %d\\r\\n\", {structvar}->{structname ?? ""}{fieldName});"); 192 | } 193 | else 194 | { 195 | string format = string.Concat(Enumerable.Repeat("%c", arraySize)); 196 | Console.Write($"printf(\"{structname ?? ""}{fieldName} = \\\"{format}\\\"\\r\\n\""); 197 | for (int i = 0; i < arraySize; i++) 198 | { 199 | int ni = i; 200 | if (SwapStringEndian) 201 | { 202 | ni = (i - (i % 2)) + (1 - (i % 2)); 203 | } 204 | Console.Write($", {structvar}->{structname ?? ""}{fieldName}[{ni}]"); 205 | } 206 | Console.WriteLine(");"); 207 | } 208 | } 209 | else 210 | { 211 | throw new InvalidDataException(); 212 | } 213 | } -------------------------------------------------------------------------------- /al-khaser.sln: -------------------------------------------------------------------------------- 1 | Microsoft Visual Studio Solution File, Format Version 12.00 2 | # Visual Studio 15 3 | VisualStudioVersion = 15.0.28010.2026 4 | MinimumVisualStudioVersion = 10.0.40219.1 5 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "al-khaser", "al-khaser\al-khaser.vcxproj", "{77AEFBC3-0ECE-46AD-A113-966AAAA838E1}" 6 | EndProject 7 | Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Tools", "Tools", "{71BFEE2B-52EC-4526-90F5-D91D98B9C786}" 8 | EndProject 9 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ATAIdentifyDump", "Tools\ATAIdentifyDump\ATAIdentifyDump.vcxproj", "{245D8670-A888-4ECC-9B51-80584E55B701}" 10 | EndProject 11 | Global 12 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 13 | Debug|x64 = Debug|x64 14 | Debug|x86 = Debug|x86 15 | Release|x64 = Release|x64 16 | Release|x86 = Release|x86 17 | EndGlobalSection 18 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 19 | {77AEFBC3-0ECE-46AD-A113-966AAAA838E1}.Debug|x64.ActiveCfg = Debug|x64 20 | {77AEFBC3-0ECE-46AD-A113-966AAAA838E1}.Debug|x64.Build.0 = Debug|x64 21 | {77AEFBC3-0ECE-46AD-A113-966AAAA838E1}.Debug|x86.ActiveCfg = Debug|Win32 22 | {77AEFBC3-0ECE-46AD-A113-966AAAA838E1}.Debug|x86.Build.0 = Debug|Win32 23 | {77AEFBC3-0ECE-46AD-A113-966AAAA838E1}.Release|x64.ActiveCfg = Release|x64 24 | {77AEFBC3-0ECE-46AD-A113-966AAAA838E1}.Release|x64.Build.0 = Release|x64 25 | {77AEFBC3-0ECE-46AD-A113-966AAAA838E1}.Release|x86.ActiveCfg = Release|Win32 26 | {77AEFBC3-0ECE-46AD-A113-966AAAA838E1}.Release|x86.Build.0 = Release|Win32 27 | {245D8670-A888-4ECC-9B51-80584E55B701}.Debug|x64.ActiveCfg = Debug|x64 28 | {245D8670-A888-4ECC-9B51-80584E55B701}.Debug|x64.Build.0 = Debug|x64 29 | {245D8670-A888-4ECC-9B51-80584E55B701}.Debug|x86.ActiveCfg = Debug|Win32 30 | {245D8670-A888-4ECC-9B51-80584E55B701}.Debug|x86.Build.0 = Debug|Win32 31 | {245D8670-A888-4ECC-9B51-80584E55B701}.Release|x64.ActiveCfg = Release|x64 32 | {245D8670-A888-4ECC-9B51-80584E55B701}.Release|x64.Build.0 = Release|x64 33 | {245D8670-A888-4ECC-9B51-80584E55B701}.Release|x86.ActiveCfg = Release|Win32 34 | {245D8670-A888-4ECC-9B51-80584E55B701}.Release|x86.Build.0 = Release|Win32 35 | EndGlobalSection 36 | GlobalSection(SolutionProperties) = preSolution 37 | HideSolutionNode = FALSE 38 | EndGlobalSection 39 | GlobalSection(NestedProjects) = preSolution 40 | {245D8670-A888-4ECC-9B51-80584E55B701} = {71BFEE2B-52EC-4526-90F5-D91D98B9C786} 41 | EndGlobalSection 42 | GlobalSection(ExtensibilityGlobals) = postSolution 43 | SolutionGuid = {0772817E-132F-4922-8377-5DA07255372F} 44 | EndGlobalSection 45 | EndGlobal 46 | -------------------------------------------------------------------------------- /al-khaser/AntiAnalysis/pch.h: -------------------------------------------------------------------------------- 1 | #include "../pch.h" -------------------------------------------------------------------------------- /al-khaser/AntiAnalysis/process.cpp: -------------------------------------------------------------------------------- 1 | #include "pch.h" 2 | #pragma once 3 | #include "process.h" 4 | 5 | /* 6 | Check for process list 7 | */ 8 | 9 | VOID analysis_tools_process() 10 | { 11 | const TCHAR *szProcesses[] = { 12 | _T("ollydbg.exe"), // OllyDebug debugger 13 | _T("ollyice.exe"), // OllyICE debugger 14 | _T("ProcessHacker.exe"), // Process Hacker 15 | _T("tcpview.exe"), // Part of Sysinternals Suite 16 | _T("autoruns.exe"), // Part of Sysinternals Suite 17 | _T("autorunsc.exe"), // Part of Sysinternals Suite 18 | _T("filemon.exe"), // Part of Sysinternals Suite 19 | _T("procmon.exe"), // Part of Sysinternals Suite 20 | _T("regmon.exe"), // Part of Sysinternals Suite 21 | _T("procexp.exe"), // Part of Sysinternals Suite 22 | _T("idaq.exe"), // IDA Pro Interactive Disassembler 23 | _T("idaq64.exe"), // IDA Pro Interactive Disassembler 24 | _T("ImmunityDebugger.exe"), // ImmunityDebugger 25 | _T("Wireshark.exe"), // Wireshark packet sniffer 26 | _T("dumpcap.exe"), // Network traffic dump tool 27 | _T("HookExplorer.exe"), // Find various types of runtime hooks 28 | _T("ImportREC.exe"), // Import Reconstructor 29 | _T("PETools.exe"), // PE Tool 30 | _T("LordPE.exe"), // LordPE 31 | _T("SysInspector.exe"), // ESET SysInspector 32 | _T("proc_analyzer.exe"), // Part of SysAnalyzer iDefense 33 | _T("sysAnalyzer.exe"), // Part of SysAnalyzer iDefense 34 | _T("sniff_hit.exe"), // Part of SysAnalyzer iDefense 35 | _T("windbg.exe"), // Microsoft WinDbg 36 | _T("joeboxcontrol.exe"), // Part of Joe Sandbox 37 | _T("joeboxserver.exe"), // Part of Joe Sandbox 38 | _T("ResourceHacker.exe"), // Resource Hacker 39 | _T("x32dbg.exe"), // x32dbg 40 | _T("x64dbg.exe"), // x64dbg 41 | _T("Fiddler.exe"), // Fiddler 42 | _T("httpdebugger.exe"), // Http Debugger 43 | _T("cheatengine-i386.exe"), // Cheat Engine 44 | _T("cheatengine-x86_64.exe"), // Cheat Engine 45 | _T("cheatengine-x86_64-SSE4-AVX2.exe"), // Cheat Engine 46 | _T("frida-helper-32.exe"), // Frida 47 | _T("frida-helper-64.exe"), // Frida 48 | _T("ghidra.exe"), // Ghidra 49 | _T("radare2.exe"), // radare2 50 | _T("r2.exe"), // 51 | _T("cutter.exe"), // Cutter 52 | _T("dnSpy.exe"), // DnSpy 53 | _T("dnSpyEx.exe"), // 54 | _T("ILSpy.exe"), // ILSpy 55 | _T("HxD.exe"), // HxD 56 | _T("SystemInformer.exe"), // System Informer 57 | _T("DetectItEasy.exe"), // DIE 58 | _T("FakeNet.exe"), // FakeNet-NG 59 | _T("ResourceHacker.exe"), // Resource editor 60 | }; 61 | 62 | WORD iLength = sizeof(szProcesses) / sizeof(szProcesses[0]); 63 | for (int i = 0; i < iLength; i++) 64 | { 65 | TCHAR msg[256] = _T(""); 66 | _stprintf_s(msg, sizeof(msg) / sizeof(TCHAR), _T("Checking process of malware analysis tool: %s "), szProcesses[i]); 67 | if (GetProcessIdFromName(szProcesses[i])) 68 | print_results(TRUE, msg); 69 | else 70 | print_results(FALSE, msg); 71 | } 72 | } 73 | -------------------------------------------------------------------------------- /al-khaser/AntiAnalysis/process.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | VOID analysis_tools_process(); 4 | 5 | /* 6 | 7 | avpui.exe 8 | avgui.exe 9 | bdagent.exe 10 | 11 | */ -------------------------------------------------------------------------------- /al-khaser/AntiDebug/BeingDebugged.cpp: -------------------------------------------------------------------------------- 1 | #include "pch.h" 2 | #include "BeingDebugged.h" 3 | 4 | 5 | BOOL 6 | IsDebuggerPresentPEB( 7 | VOID 8 | ) 9 | /*++ 10 | 11 | Routine Description: 12 | 13 | Checks if the BeingDebugged flag is set in the Process Environment Block (PEB). 14 | This is effectively the same code that IsDebuggerPresent() executes internally. 15 | The PEB pointer is fetched from DWORD FS:[0x30] on x86_32 and QWORD GS:[0x60] on x86_64. 16 | 17 | Arguments: 18 | 19 | None 20 | 21 | Return Value: 22 | 23 | TRUE - if debugger was detected 24 | FALSE - otherwise 25 | --*/ 26 | { 27 | #if defined (ENV64BIT) 28 | PPEB pPeb = (PPEB)__readgsqword(0x60); 29 | 30 | #elif defined(ENV32BIT) 31 | PPEB pPeb = (PPEB)__readfsdword(0x30); 32 | 33 | #endif 34 | 35 | return pPeb->BeingDebugged == 1; 36 | } 37 | -------------------------------------------------------------------------------- /al-khaser/AntiDebug/BeingDebugged.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | BOOL IsDebuggerPresentPEB(); 4 | -------------------------------------------------------------------------------- /al-khaser/AntiDebug/CheckRemoteDebuggerPresent.cpp: -------------------------------------------------------------------------------- 1 | #include "pch.h" 2 | #include "CheckRemoteDebuggerPresent.h" 3 | 4 | BOOL 5 | CheckRemoteDebuggerPresentAPI ( 6 | VOID 7 | ) 8 | /*++ 9 | 10 | Routine Description: 11 | 12 | CheckRemoteDebuggerPresent() is another Win32 Debugging API function; 13 | it can be used to check if a remote process is being debugged. However, 14 | we can also use this as another method for checking if our own process 15 | is being debugged. This API internally calls the NTDLL export 16 | NtQueryInformationProcess function with the PROCESSINFOCLASS set to 17 | 7 (ProcessDebugPort). 18 | 19 | Arguments: 20 | 21 | None 22 | 23 | Return Value: 24 | 25 | TRUE - if debugger was detected 26 | FALSE - otherwise 27 | --*/ 28 | { 29 | BOOL bIsDbgPresent = FALSE; 30 | CheckRemoteDebuggerPresent(GetCurrentProcess(), &bIsDbgPresent); 31 | return bIsDbgPresent; 32 | } 33 | -------------------------------------------------------------------------------- /al-khaser/AntiDebug/CheckRemoteDebuggerPresent.h: -------------------------------------------------------------------------------- 1 | BOOL CheckRemoteDebuggerPresentAPI(); -------------------------------------------------------------------------------- /al-khaser/AntiDebug/CloseHandle_InvalidHandle.cpp: -------------------------------------------------------------------------------- 1 | #include "pch.h" 2 | 3 | 4 | /* 5 | APIs making use of the ZwClose syscall (such as CloseHandle, indirectly) 6 | can be used to detect a debugger. When a process is debugged, calling ZwClose 7 | with an invalid handle will generate a STATUS_INVALID_HANDLE (0xC0000008) exception. 8 | As with all anti-debugs that rely on information made directly available. 9 | */ 10 | 11 | 12 | BOOL NtClose_InvalideHandle() 13 | { 14 | auto NtClose_ = static_cast(API::GetAPI(API_IDENTIFIER::API_NtClose)); 15 | 16 | __try { 17 | NtClose_(reinterpret_cast(0x99999999ULL)); 18 | } 19 | __except (EXCEPTION_EXECUTE_HANDLER) { 20 | return TRUE; 21 | } 22 | 23 | return FALSE; 24 | 25 | } 26 | 27 | BOOL CloseHandle_InvalideHandle() 28 | { 29 | // Let's try first with user mode API: CloseHandle 30 | __try { 31 | CloseHandle(reinterpret_cast(0x99999999ULL)); 32 | } 33 | __except (EXCEPTION_EXECUTE_HANDLER) { 34 | return TRUE; 35 | } 36 | 37 | // Direct call to NtClose to bypass user mode hooks 38 | if (NtClose_InvalideHandle()) 39 | return TRUE; 40 | else 41 | return FALSE; 42 | } 43 | 44 | -------------------------------------------------------------------------------- /al-khaser/AntiDebug/CloseHandle_InvalidHandle.h: -------------------------------------------------------------------------------- 1 | BOOL CloseHandle_InvalideHandle(); -------------------------------------------------------------------------------- /al-khaser/AntiDebug/HardwareBreakpoints.cpp: -------------------------------------------------------------------------------- 1 | #include "pch.h" 2 | 3 | #include "HardwareBreakpoints.h" 4 | 5 | /* 6 | Hardware breakpoints are a technology implemented by Intel in their processor architecture, 7 | and are controlled by the use of special registers known as Dr0-Dr7. 8 | Dr0 through Dr3 are 32 bit registers that hold the address of the breakpoint . 9 | */ 10 | 11 | 12 | BOOL HardwareBreakpoints() 13 | { 14 | BOOL bResult = FALSE; 15 | 16 | // This structure is key to the function and is the 17 | // medium for detection and removal 18 | PCONTEXT ctx = PCONTEXT(VirtualAlloc(NULL, sizeof(CONTEXT), MEM_COMMIT, PAGE_READWRITE)); 19 | 20 | if (ctx) { 21 | 22 | SecureZeroMemory(ctx, sizeof(CONTEXT)); 23 | 24 | // The CONTEXT structure is an in/out parameter therefore we have 25 | // to set the flags so Get/SetThreadContext knows what to set or get. 26 | ctx->ContextFlags = CONTEXT_DEBUG_REGISTERS; 27 | 28 | // Get the registers 29 | if (GetThreadContext(GetCurrentThread(), ctx)) { 30 | 31 | // Now we can check for hardware breakpoints, its not 32 | // necessary to check Dr6 and Dr7, however feel free to 33 | if (ctx->Dr0 != 0 || ctx->Dr1 != 0 || ctx->Dr2 != 0 || ctx->Dr3 != 0) 34 | bResult = TRUE; 35 | } 36 | 37 | VirtualFree(ctx, 0, MEM_RELEASE); 38 | } 39 | 40 | return bResult; 41 | } 42 | -------------------------------------------------------------------------------- /al-khaser/AntiDebug/HardwareBreakpoints.h: -------------------------------------------------------------------------------- 1 | BOOL HardwareBreakpoints(); -------------------------------------------------------------------------------- /al-khaser/AntiDebug/Interrupt_0x2d.cpp: -------------------------------------------------------------------------------- 1 | #include "pch.h" 2 | 3 | #include "Interrupt_0x2d.h" 4 | 5 | /* 6 | The Interrupt_0x2d function will check to see if a debugger is attached to the current process. It does this by setting up 7 | SEH and using the Int 2D instruction which will only cause an exception if there is no debugger. Also when used in OllyDBG 8 | it will skip a byte in the disassembly which could be used to detect the debugger. 9 | 10 | Vectored Exception Handling is used here because SEH is an anti-debug trick in itself. 11 | */ 12 | 13 | extern "C" void __int2d(); 14 | 15 | static BOOL SwallowedException = TRUE; 16 | 17 | static LONG CALLBACK VectoredHandler( 18 | _In_ PEXCEPTION_POINTERS ExceptionInfo 19 | ) 20 | { 21 | SwallowedException = FALSE; 22 | if (ExceptionInfo->ExceptionRecord->ExceptionCode == EXCEPTION_BREAKPOINT) 23 | { 24 | //The Int 2D instruction already increased EIP/RIP so we don't do that (although it wouldnt hurt). 25 | return EXCEPTION_CONTINUE_EXECUTION; 26 | } 27 | return EXCEPTION_CONTINUE_SEARCH; 28 | } 29 | 30 | BOOL Interrupt_0x2d() 31 | { 32 | PVOID Handle = AddVectoredExceptionHandler(1, VectoredHandler); 33 | SwallowedException = TRUE; 34 | __int2d(); 35 | RemoveVectoredExceptionHandler(Handle); 36 | return SwallowedException; 37 | } 38 | -------------------------------------------------------------------------------- /al-khaser/AntiDebug/Interrupt_0x2d.h: -------------------------------------------------------------------------------- 1 | BOOL Interrupt_0x2d(); -------------------------------------------------------------------------------- /al-khaser/AntiDebug/Interrupt_3.cpp: -------------------------------------------------------------------------------- 1 | #include "pch.h" 2 | 3 | #include "Interrupt_3.h" 4 | 5 | /* 6 | INT 3 generates a call to trap in the debugger and is triggered by opcode 0xCC within the executing process. 7 | When a debugger is attached, the 0xCC execution will cause the debugger to catch the breakpoint and handle 8 | the resulting exception. If a debugger is not attached, the exception is passed through to a structured 9 | exception handler thus informing the process that no debugger is present. 10 | 11 | Vectored Exception Handling is used here because SEH is an anti-debug trick in itself. 12 | */ 13 | 14 | static BOOL SwallowedException = TRUE; 15 | 16 | static LONG CALLBACK VectoredHandler( 17 | _In_ PEXCEPTION_POINTERS ExceptionInfo 18 | ) 19 | { 20 | SwallowedException = FALSE; 21 | if (ExceptionInfo->ExceptionRecord->ExceptionCode == EXCEPTION_BREAKPOINT) 22 | { 23 | //Increase EIP/RIP to continue execution. 24 | #ifdef _WIN64 25 | ExceptionInfo->ContextRecord->Rip++; 26 | #else 27 | ExceptionInfo->ContextRecord->Eip++; 28 | #endif 29 | return EXCEPTION_CONTINUE_EXECUTION; 30 | } 31 | return EXCEPTION_CONTINUE_SEARCH; 32 | } 33 | 34 | 35 | 36 | BOOL Interrupt_3() 37 | { 38 | PVOID Handle = AddVectoredExceptionHandler(1, VectoredHandler); 39 | SwallowedException = TRUE; 40 | __debugbreak(); 41 | RemoveVectoredExceptionHandler(Handle); 42 | return SwallowedException; 43 | } 44 | -------------------------------------------------------------------------------- /al-khaser/AntiDebug/Interrupt_3.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | BOOL Interrupt_3(); -------------------------------------------------------------------------------- /al-khaser/AntiDebug/IsDebuggerPresent.cpp: -------------------------------------------------------------------------------- 1 | #include "pch.h" 2 | #include "IsDebuggerPresent.h" 3 | 4 | BOOL 5 | IsDebuggerPresentAPI ( 6 | VOID 7 | ) 8 | /*++ 9 | 10 | Routine Description: 11 | 12 | Calls the IsDebuggerPresent() API. This function is part of the 13 | Win32 Debugging API and it returns TRUE if a user mode debugger 14 | is present. Internally, it simply returns the value of the 15 | PEB->BeingDebugged flag. 16 | 17 | Arguments: 18 | 19 | None 20 | 21 | Return Value: 22 | 23 | TRUE - if debugger was detected 24 | FALSE - otherwise 25 | --*/ 26 | { 27 | return IsDebuggerPresent(); 28 | } 29 | -------------------------------------------------------------------------------- /al-khaser/AntiDebug/IsDebuggerPresent.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | BOOL IsDebuggerPresentAPI(); -------------------------------------------------------------------------------- /al-khaser/AntiDebug/LowFragmentationHeap.cpp: -------------------------------------------------------------------------------- 1 | #include "pch.h" 2 | #include "LowFragmentationHeap.h" 3 | 4 | 5 | BOOL 6 | LowFragmentationHeap( 7 | VOID 8 | ) 9 | /*++ 10 | 11 | Routine Description: 12 | Originally found by Souhail Hammou: 13 | http://rce4fun.blogspot.com/2014/02/anti-debugging-trick-checking-for-low.html 14 | Under a debugger, the process does not have a Low Fragmentation Heap (LFH) 15 | The routine simply checks whether the nt!_HEAP.FrontEndHeap is NULL. 16 | 17 | Arguments: 18 | 19 | None 20 | 21 | Return Value: 22 | 23 | TRUE - if debugger was detected 24 | FALSE - otherwise 25 | --*/ 26 | { 27 | 28 | PINT_PTR FrontEndHeap = NULL; 29 | 30 | // Get the default process heap. 31 | HANDLE hHeap = GetProcessHeap(); 32 | 33 | // The FrontEndHeap offset of the _HEAP structure 34 | // is found on different locations depending of the OS. 35 | 36 | if (IsWindowsVista() || IsWindows7()) { 37 | #if defined (ENV64BIT) 38 | FrontEndHeap = (PINT_PTR)((CHAR*)hHeap + 0x178); 39 | 40 | #elif defined(ENV32BIT) 41 | FrontEndHeap = (PINT_PTR)((CHAR*)hHeap + 0xd4); 42 | #endif 43 | } 44 | 45 | if (IsWindows8or8PointOne()) { 46 | #if defined (ENV64BIT) 47 | FrontEndHeap = (PINT_PTR)((CHAR*)hHeap + 0x170); 48 | 49 | #elif defined(ENV32BIT) 50 | FrontEndHeap = (PINT_PTR)((CHAR*)hHeap + 0xd0); 51 | #endif 52 | } 53 | 54 | // In Windows 10. the offset changes very often. 55 | // Ignoring it from now. 56 | if (FrontEndHeap && *FrontEndHeap == NULL) { 57 | return TRUE; 58 | } 59 | 60 | return FALSE; 61 | } 62 | -------------------------------------------------------------------------------- /al-khaser/AntiDebug/LowFragmentationHeap.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | BOOL 4 | LowFragmentationHeap( 5 | VOID 6 | ); -------------------------------------------------------------------------------- /al-khaser/AntiDebug/MemoryBreakpoints_PageGuard.cpp: -------------------------------------------------------------------------------- 1 | #include "pch.h" 2 | 3 | #include "MemoryBreakpoints_PageGuard.h" 4 | 5 | /* 6 | In essence, what occurs is that we allocate a dynamic buffer and write a RET to the buffer. 7 | We then mark the page as a guard page and push a potential return address onto the stack. Next, we jump to our page, 8 | and if we're under a debugger, specifically OllyDBG, then we will hit the RET instruction and return to the address we pushed onto 9 | the stack before we jumped to our page. Otherwise, a STATUS_GUARD_PAGE_VIOLATION exception will occur, and we know we're not being 10 | debugged by OllyDBG. 11 | */ 12 | 13 | BOOL MemoryBreakpoints_PageGuard() 14 | { 15 | UCHAR *pMem = NULL; 16 | SYSTEM_INFO SystemInfo = { 0 }; 17 | DWORD OldProtect = 0; 18 | PVOID pAllocation = NULL; // Get the page size for the system 19 | 20 | // Retrieves information about the current system. 21 | GetSystemInfo(&SystemInfo); 22 | 23 | // Allocate memory 24 | pAllocation = VirtualAlloc(NULL, SystemInfo.dwPageSize, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE); 25 | if (pAllocation == NULL) 26 | return FALSE; 27 | 28 | // Write a ret to the buffer (opcode 0xc3) 29 | RtlFillMemory(pAllocation, 1, 0xC3); 30 | 31 | // Make the page a guard page 32 | if (VirtualProtect(pAllocation, SystemInfo.dwPageSize, PAGE_EXECUTE_READWRITE | PAGE_GUARD, &OldProtect) == 0) 33 | return FALSE; 34 | 35 | __try 36 | { 37 | ((void(*)())pAllocation)(); // Exception or execution, which shall it be :D? 38 | } 39 | __except (GetExceptionCode() == STATUS_GUARD_PAGE_VIOLATION ? EXCEPTION_EXECUTE_HANDLER : EXCEPTION_CONTINUE_SEARCH) 40 | { 41 | VirtualFree(pAllocation, 0, MEM_RELEASE); 42 | return FALSE; 43 | } 44 | 45 | VirtualFree(pAllocation, 0, MEM_RELEASE); 46 | return TRUE; 47 | } 48 | -------------------------------------------------------------------------------- /al-khaser/AntiDebug/MemoryBreakpoints_PageGuard.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | BOOL MemoryBreakpoints_PageGuard(); -------------------------------------------------------------------------------- /al-khaser/AntiDebug/ModuleBoundsHookCheck.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | BOOL ModuleBoundsHookCheck(); -------------------------------------------------------------------------------- /al-khaser/AntiDebug/NtGlobalFlag.cpp: -------------------------------------------------------------------------------- 1 | #include "pch.h" 2 | #include "NtGlobalFlag.h" 3 | 4 | 5 | BOOL 6 | NtGlobalFlag ( 7 | VOID 8 | ) 9 | /*++ 10 | 11 | Routine Description: 12 | 13 | NtGlobalFlag is a DWORD value inside the process PEB. This value 14 | contains many flags set by the OS that affects the way the process 15 | runs. When a process is being debugged, the flags: 16 | - FLG_HEAP_ENABLE_TAIL_CHECK (0x10) 17 | - FLG_HEAP_ENABLE_FREE_CHECK (0x20) 18 | - FLG_HEAP_VALIDATE_PARAMETERS(0x40) are set for the process 19 | 20 | If the 32-bit executable is being run on a 64-bit system, both the 21 | 32-bit and 64-bit PEBs are checked. The WoW64 PEB address is 22 | fetched via the WoW64 Thread Environment Block (TEB) at FS:[0x18]-0x2000. 23 | 24 | Arguments: 25 | 26 | None 27 | 28 | Return Value: 29 | 30 | TRUE - if debugger was detected 31 | FALSE - otherwise 32 | --*/ 33 | { 34 | PDWORD pNtGlobalFlag = NULL, pNtGlobalFlagWoW64 = NULL; 35 | 36 | #if defined (ENV64BIT) 37 | pNtGlobalFlag = (PDWORD)(__readgsqword(0x60) + 0xBC); 38 | 39 | #elif defined(ENV32BIT) 40 | /* NtGlobalFlags for real 32-bits OS */ 41 | BYTE* _teb32 = (BYTE*)__readfsdword(0x18); 42 | DWORD _peb32 = *(DWORD*)(_teb32 + 0x30); 43 | pNtGlobalFlag = (PDWORD)(_peb32 + 0x68); 44 | 45 | if (IsWoW64()) 46 | { 47 | /* In Wow64, there is a separate PEB for the 32-bit portion and the 64-bit portion 48 | which we can double-check */ 49 | 50 | BYTE* _teb64 = (BYTE*)__readfsdword(0x18) - 0x2000; 51 | DWORD64 _peb64 = *(DWORD64*)(_teb64 + 0x60); 52 | pNtGlobalFlagWoW64 = (PDWORD)(_peb64 + 0xBC); 53 | } 54 | #endif 55 | 56 | BOOL normalDetected = pNtGlobalFlag && *pNtGlobalFlag & 0x00000070; 57 | BOOL wow64Detected = pNtGlobalFlagWoW64 && *pNtGlobalFlagWoW64 & 0x00000070; 58 | 59 | if(normalDetected || wow64Detected) 60 | return TRUE; 61 | else 62 | return FALSE; 63 | } 64 | -------------------------------------------------------------------------------- /al-khaser/AntiDebug/NtGlobalFlag.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | BOOL NtGlobalFlag(); -------------------------------------------------------------------------------- /al-khaser/AntiDebug/NtQueryInformationProcess_ProcessDebugFlags.cpp: -------------------------------------------------------------------------------- 1 | #include "pch.h" 2 | 3 | #include "NtQueryInformationProcess_ProcessDebugFlags.h" 4 | 5 | /* 6 | When NtQueryProcessInformation is called with the ProcessDebugFlags class, the function will return the inverse of EPROCESS->NoDebugInherit, 7 | which means that if a debugger is present, then this function will return FALSE if the process is being debugged. 8 | */ 9 | 10 | BOOL NtQueryInformationProcess_ProcessDebugFlags() 11 | { 12 | // ProcessDebugFlags 13 | const int ProcessDebugFlags = 0x1f; 14 | 15 | auto NtQueryInfoProcess = static_cast(API::GetAPI(API_IDENTIFIER::API_NtQueryInformationProcess)); 16 | 17 | // Other Vars 18 | NTSTATUS Status; 19 | DWORD NoDebugInherit = 0; 20 | 21 | Status = NtQueryInfoProcess(GetCurrentProcess(), ProcessDebugFlags, &NoDebugInherit, sizeof(DWORD), NULL); 22 | if (Status == 0x00000000 && NoDebugInherit == 0) 23 | return TRUE; 24 | else 25 | return FALSE; 26 | } 27 | -------------------------------------------------------------------------------- /al-khaser/AntiDebug/NtQueryInformationProcess_ProcessDebugFlags.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | BOOL NtQueryInformationProcess_ProcessDebugFlags(); -------------------------------------------------------------------------------- /al-khaser/AntiDebug/NtQueryInformationProcess_ProcessDebugObject.cpp: -------------------------------------------------------------------------------- 1 | #include "pch.h" 2 | 3 | #include "NtQueryInformationProcess_ProcessDebugObject.h" 4 | 5 | /* 6 | This function uses NtQuerySystemInformation to try to retrieve a handle to the current process's debug object handle. 7 | If the function is successful it'll return true which means we're being debugged or it'll return false if it fails 8 | the process isn't being debugged 9 | */ 10 | 11 | BOOL NtQueryInformationProcess_ProcessDebugObject() 12 | { 13 | // ProcessDebugObjectHandle 14 | const int ProcessDebugObjectHandle = 0x1e; 15 | 16 | auto NtQueryInfoProcess = static_cast(API::GetAPI(API_IDENTIFIER::API_NtQueryInformationProcess)); 17 | 18 | // Other Vars 19 | NTSTATUS Status; 20 | HANDLE hDebugObject = NULL; 21 | 22 | #if defined (ENV64BIT) 23 | DWORD dProcessInformationLength = sizeof(ULONG) * 2; 24 | DWORD64 IsRemotePresent = 0; 25 | 26 | #elif defined(ENV32BIT) 27 | DWORD dProcessInformationLength = sizeof(ULONG); 28 | DWORD32 IsRemotePresent = 0; 29 | #endif 30 | 31 | // Regular check 32 | Status = NtQueryInfoProcess(GetCurrentProcess(), ProcessDebugObjectHandle, &hDebugObject, dProcessInformationLength, NULL); 33 | 34 | if (Status != STATUS_PORT_NOT_SET) 35 | return TRUE; 36 | if (hDebugObject != NULL) 37 | return TRUE; 38 | 39 | // Check with overlapping return length and debug object handle buffers to find anti-anti-debuggers 40 | Status = NtQueryInfoProcess(GetCurrentProcess(), ProcessDebugObjectHandle, &hDebugObject, dProcessInformationLength, (PULONG)&hDebugObject); 41 | if (Status != STATUS_PORT_NOT_SET) 42 | return TRUE; 43 | if (hDebugObject == NULL) 44 | return TRUE; // Handle incorrectly zeroed 45 | if ((ULONG)(ULONG_PTR)hDebugObject != dProcessInformationLength) 46 | return TRUE; // Return length incorrectly overwritten 47 | 48 | return FALSE; 49 | } 50 | -------------------------------------------------------------------------------- /al-khaser/AntiDebug/NtQueryInformationProcess_ProcessDebugObject.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | BOOL NtQueryInformationProcess_ProcessDebugObject(); 4 | 5 | #define STATUS_PORT_NOT_SET ((NTSTATUS)0xC0000353L) 6 | -------------------------------------------------------------------------------- /al-khaser/AntiDebug/NtQueryInformationProcess_ProcessDebugPort.cpp: -------------------------------------------------------------------------------- 1 | #include "pch.h" 2 | 3 | #include "NtQueryInformationProcess_ProcessDebugPort.h" 4 | 5 | /* 6 | Instead of calling CheckRemoteDebuggerPresent an individual could also make directly the call to 7 | NtQueryInformationProcess process theirself. 8 | */ 9 | 10 | BOOL NtQueryInformationProcess_ProcessDebugPort () 11 | { 12 | auto NtQueryInfoProcess = static_cast(API::GetAPI(API_IDENTIFIER::API_NtQueryInformationProcess)); 13 | 14 | // ProcessDebugPort 15 | const int ProcessDbgPort = 7; 16 | 17 | // Other Vars 18 | NTSTATUS Status; 19 | 20 | #if defined (ENV64BIT) 21 | DWORD dProcessInformationLength = sizeof(ULONG) * 2; 22 | DWORD64 IsRemotePresent = 0; 23 | 24 | #elif defined(ENV32BIT) 25 | DWORD dProcessInformationLength = sizeof(ULONG); 26 | DWORD32 IsRemotePresent = 0; 27 | #endif 28 | 29 | Status = NtQueryInfoProcess(GetCurrentProcess(), ProcessDbgPort, &IsRemotePresent, dProcessInformationLength, NULL); 30 | if(Status == 0x00000000 && IsRemotePresent != 0) 31 | return TRUE; 32 | else 33 | return FALSE; 34 | } 35 | 36 | -------------------------------------------------------------------------------- /al-khaser/AntiDebug/NtQueryInformationProcess_ProcessDebugPort.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | BOOL NtQueryInformationProcess_ProcessDebugPort(); -------------------------------------------------------------------------------- /al-khaser/AntiDebug/NtQueryObject_AllTypesInformation.cpp: -------------------------------------------------------------------------------- 1 | #include "pch.h" 2 | 3 | #include "NtQueryObject_ObjectInformation.h" 4 | 5 | /* 6 | Windows XP introduced a "debug object". When a debugging session begins, a debug object is created, 7 | and a handle is associated with it. Using the ntdll NtQueryObject() function with class: ObjectAllTypesInformation. 8 | ObjectAllTypesInformation (3) will return a list with all existing object type, we should iterate over objects to 9 | locate "DebugObject". Todo: Support for Win10 10 | */ 11 | 12 | 13 | BOOL NtQueryObject_ObjectAllTypesInformation() 14 | { 15 | //NOTE this check is unreliable, a debugger present on the system doesn't mean it's attached to you 16 | 17 | auto NtQueryObject = static_cast(API::GetAPI(API_IDENTIFIER::API_NtQueryObject)); 18 | 19 | // Some vars 20 | ULONG size; 21 | PVOID pMemory = NULL; 22 | POBJECT_ALL_INFORMATION pObjectAllInfo = NULL; 23 | NTSTATUS Status; 24 | 25 | // Get the size of the information needed 26 | Status = NtQueryObject(NULL, 3, &size, sizeof(ULONG), &size); 27 | 28 | // Alocate memory for the list 29 | pMemory = VirtualAlloc(NULL, size, MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE); 30 | if (pMemory == NULL) 31 | return FALSE; 32 | 33 | // Now we can actually retrieve the list 34 | Status = NtQueryObject((HANDLE)-1, 3, pMemory, size, NULL); 35 | 36 | // Status != STATUS_SUCCESS 37 | if (Status != 0x00000000) 38 | { 39 | VirtualFree(pMemory, 0, MEM_RELEASE); 40 | return FALSE; 41 | } 42 | 43 | // We have the information we need 44 | pObjectAllInfo = (POBJECT_ALL_INFORMATION)pMemory; 45 | UCHAR *pObjInfoLocation = (UCHAR*)pObjectAllInfo->ObjectTypeInformation; 46 | ULONG NumObjects = pObjectAllInfo->NumberOfObjects; 47 | 48 | for (UINT i = 0; i < NumObjects; i++) 49 | { 50 | 51 | POBJECT_TYPE_INFORMATION pObjectTypeInfo = (POBJECT_TYPE_INFORMATION)pObjInfoLocation; 52 | 53 | // The debug object will always be present 54 | if (StrCmp(_T("DebugObject"), pObjectTypeInfo->TypeName.Buffer) == 0) 55 | { 56 | // Are there any objects? 57 | if (pObjectTypeInfo->TotalNumberOfObjects > 0) 58 | { 59 | VirtualFree(pMemory, 0, MEM_RELEASE); 60 | return TRUE; 61 | } 62 | else 63 | { 64 | VirtualFree(pMemory, 0, MEM_RELEASE); 65 | return FALSE; 66 | } 67 | } 68 | 69 | // Get the address of the current entries 70 | // string so we can find the end 71 | pObjInfoLocation = (unsigned char*)pObjectTypeInfo->TypeName.Buffer; 72 | 73 | // Add the size 74 | pObjInfoLocation += pObjectTypeInfo->TypeName.MaximumLength; 75 | 76 | // Skip the trailing null and alignment bytes 77 | ULONG_PTR tmp = ((ULONG_PTR)pObjInfoLocation) & -(int)sizeof(void*); 78 | 79 | // Not pretty but it works 80 | if ((ULONG_PTR)tmp != (ULONG_PTR)pObjInfoLocation) 81 | tmp += sizeof(void*); 82 | pObjInfoLocation = ((unsigned char*)tmp); 83 | } 84 | 85 | VirtualFree(pMemory, 0, MEM_RELEASE); 86 | return FALSE; 87 | } 88 | -------------------------------------------------------------------------------- /al-khaser/AntiDebug/NtQueryObject_ObjectInformation.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | BOOL NtQueryObject_ObjectAllTypesInformation(); 4 | BOOL NtQueryObject_ObjectTypeInformation(); 5 | 6 | 7 | #define DEBUG_READ_EVENT 0x0001 8 | #define DEBUG_PROCESS_ASSIGN 0x0002 9 | #define DEBUG_SET_INFORMATION 0x0004 10 | #define DEBUG_QUERY_INFORMATION 0x0008 11 | #define DEBUG_ALL_ACCESS (STANDARD_RIGHTS_REQUIRED | SYNCHRONIZE | \ 12 | DEBUG_READ_EVENT | DEBUG_PROCESS_ASSIGN | DEBUG_SET_INFORMATION | \ 13 | DEBUG_QUERY_INFORMATION) 14 | 15 | typedef struct _OBJECT_TYPE_INFORMATION { 16 | UNICODE_STRING TypeName; 17 | ULONG TotalNumberOfHandles; 18 | ULONG TotalNumberOfObjects; 19 | }OBJECT_TYPE_INFORMATION, *POBJECT_TYPE_INFORMATION; 20 | 21 | typedef struct _OBJECT_ALL_INFORMATION { 22 | ULONG NumberOfObjects; 23 | OBJECT_TYPE_INFORMATION ObjectTypeInformation[1]; 24 | }OBJECT_ALL_INFORMATION, *POBJECT_ALL_INFORMATION; -------------------------------------------------------------------------------- /al-khaser/AntiDebug/NtQueryObject_ObjectTypeInformation.cpp: -------------------------------------------------------------------------------- 1 | #include "pch.h" 2 | 3 | #include "NtQueryObject_ObjectInformation.h" 4 | 5 | /* 6 | Windows XP introduced a "debug object". When a debugging session begins, a debug object is created, 7 | and a handle is associated with it. Using the ntdll NtQueryObject() function with class: ObjectTypeInformation. 8 | ObjectTypeInformation will return the type information of the supplied handle. 9 | */ 10 | 11 | 12 | BOOL NtQueryObject_ObjectTypeInformation() 13 | { 14 | //NOTE this check now only detects if NtQueryObject is hooked to set ObjectInformation->TotalNumberOfObjects = 0 15 | 16 | // We have to import the function 17 | auto NtQueryObject = static_cast(API::GetAPI(API_IDENTIFIER::API_NtQueryObject)); 18 | auto NtCreateDebugObject = static_cast(API::GetAPI(API_IDENTIFIER::API_NtCreateDebugObject)); 19 | 20 | // Some vars 21 | HANDLE DebugObjectHandle; 22 | OBJECT_ATTRIBUTES ObjectAttributes; 23 | InitializeObjectAttributes(&ObjectAttributes, 0, 0, 0, 0); 24 | BYTE memory[0x1000] = { 0 }; 25 | POBJECT_TYPE_INFORMATION ObjectInformation = (POBJECT_TYPE_INFORMATION)memory; 26 | NTSTATUS Status; 27 | 28 | NtCreateDebugObject(&DebugObjectHandle, DEBUG_ALL_ACCESS, &ObjectAttributes, FALSE); 29 | 30 | if (API::IsAvailable(API_IDENTIFIER::API_NtQueryObject)) 31 | { 32 | Status = NtQueryObject(DebugObjectHandle, ObjectTypeInformation, ObjectInformation, sizeof(memory), 0); 33 | 34 | // Make sure to not screw up later checks 35 | CloseHandle(DebugObjectHandle); 36 | 37 | 38 | if (Status >= 0) 39 | { 40 | if (ObjectInformation->TotalNumberOfObjects == 0) 41 | return TRUE; //There should be at least one object (we just created it). 42 | else 43 | return FALSE; 44 | } 45 | else 46 | { 47 | //NOTE: this should actually never happen on a valid handle (so this check can be bypassed by failing NtQueryObject) 48 | return FALSE; 49 | } 50 | } 51 | else 52 | return FALSE; 53 | 54 | } 55 | -------------------------------------------------------------------------------- /al-khaser/AntiDebug/NtQuerySystemInformation_SystemKernelDebuggerInformation.cpp: -------------------------------------------------------------------------------- 1 | #include "pch.h" 2 | 3 | #include "NtQuerySystemInformation_SystemKernelDebuggerInformation.h" 4 | 5 | /* 6 | When NtQuerySystemInformation is called with the SystemKernelDebuggerInformation class, the function will return 7 | a SYSTEM_KERNEL_DEBUGGER_INFORMATION struct which will reveal the presence of a kernel debugger. 8 | */ 9 | 10 | BOOL NtQuerySystemInformation_SystemKernelDebuggerInformation() 11 | { 12 | // SystemKernelDebuggerInformation 13 | const int SystemKernelDebuggerInformation = 0x23; 14 | 15 | // The debugger information struct 16 | SYSTEM_KERNEL_DEBUGGER_INFORMATION KdDebuggerInfo; 17 | 18 | auto NtQuerySystemInformation = static_cast(API::GetAPI(API_IDENTIFIER::API_NtQuerySystemInformation)); 19 | 20 | // Call NtQuerySystemInformation 21 | NTSTATUS Status = NtQuerySystemInformation(SystemKernelDebuggerInformation, &KdDebuggerInfo, sizeof(SYSTEM_KERNEL_DEBUGGER_INFORMATION), NULL); 22 | if (Status >= 0) 23 | { 24 | // KernelDebuggerEnabled almost always implies !KernelDebuggerNotPresent. KernelDebuggerNotPresent can sometimes 25 | // change if the debugger is temporarily disconnected, but either of these means a debugger is enabled. 26 | if (KdDebuggerInfo.KernelDebuggerEnabled || !KdDebuggerInfo.KernelDebuggerNotPresent) 27 | return TRUE; 28 | } 29 | return FALSE; 30 | } 31 | -------------------------------------------------------------------------------- /al-khaser/AntiDebug/NtQuerySystemInformation_SystemKernelDebuggerInformation.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | BOOL NtQuerySystemInformation_SystemKernelDebuggerInformation(); 4 | 5 | typedef struct _SYSTEM_KERNEL_DEBUGGER_INFORMATION 6 | { 7 | BOOLEAN KernelDebuggerEnabled; 8 | BOOLEAN KernelDebuggerNotPresent; 9 | } SYSTEM_KERNEL_DEBUGGER_INFORMATION, *PSYSTEM_KERNEL_DEBUGGER_INFORMATION; -------------------------------------------------------------------------------- /al-khaser/AntiDebug/NtSetInformationThread_ThreadHideFromDebugger.cpp: -------------------------------------------------------------------------------- 1 | #include "pch.h" 2 | 3 | #include "NtSetInformationThread_ThreadHideFromDebugger.h" 4 | 5 | /* 6 | Calling NtSetInformationThread will attempt with ThreadInformationClass set to x11 (ThreadHideFromDebugger) 7 | to hide a thread from the debugger, Passing NULL for hThread will cause the function to hide the thread the 8 | function is running in. Also, the function returns false on failure and true on success. When the function 9 | is called, the thread will continue to run but a debugger will no longer receive any events related to that thread. 10 | 11 | These checks also look for hooks on the NtSetInformationThread API that try to block ThreadHideFromDebugger. 12 | */ 13 | 14 | #ifndef STATUS_INFO_LENGTH_MISMATCH 15 | #define STATUS_INFO_LENGTH_MISMATCH ((DWORD)0xC0000004L) 16 | #endif 17 | #ifndef STATUS_DATATYPE_MISALIGNMENT 18 | #define STATUS_DATATYPE_MISALIGNMENT ((DWORD)0x80000002L) 19 | #endif 20 | 21 | 22 | BOOL NtSetInformationThread_ThreadHideFromDebugger() 23 | { 24 | // this is needed because the bool data type can be at unaligned memory locations, whereas the NtQueryInformationThread API expects 32-bit aligned pointers. 25 | struct AlignedBool 26 | { 27 | alignas(4) bool Value; 28 | }; 29 | 30 | // ThreadHideFromDebugger 31 | const int ThreadHideFromDebugger = 0x11; 32 | 33 | auto NtSetInformationThread = static_cast(API::GetAPI(API_IDENTIFIER::API_NtSetInformationThread)); 34 | auto NtQueryInformationThread = static_cast(API::GetAPI(API_IDENTIFIER::API_NtQueryInformationThread)); 35 | 36 | NTSTATUS Status; 37 | bool doQITcheck = false; 38 | 39 | // only do the QueryInformationThread check if we're on Vista and the API is available. 40 | // this is because the ThreadHideFromDebugger class can only be queried from Vista onwards. 41 | if (API::IsAvailable(API_IDENTIFIER::API_NtQueryInformationThread)) 42 | { 43 | doQITcheck = IsWindowsVistaOrGreater(); 44 | } 45 | 46 | AlignedBool isThreadHidden; 47 | isThreadHidden.Value = false; 48 | 49 | // First issue a bogus call with an incorrect length parameter. If it succeeds, we know NtSetInformationThread was hooked. 50 | Status = NtSetInformationThread(GetCurrentThread(), ThreadHideFromDebugger, &isThreadHidden, 12345); 51 | if (Status == 0) 52 | return TRUE; 53 | 54 | // Next try again but give it a bogus thread handle. If it succeeds, again we know NtSetInformationThread was hooked. 55 | Status = NtSetInformationThread((HANDLE)0xFFFF, ThreadHideFromDebugger, NULL, 0); 56 | if (Status == 0) 57 | return TRUE; 58 | 59 | // Now try a legitimate call. 60 | Status = NtSetInformationThread(GetCurrentThread(), ThreadHideFromDebugger, NULL, 0); 61 | 62 | if (Status == 0) 63 | { 64 | if (doQITcheck) 65 | { 66 | // note: the ThreadHideFromDebugger query expects a bool (1 byte), not a BOOL (4 bytes) 67 | // if a BOOL is used, the kernel returns 0xC0000004 (STATUS_INFO_LENGTH_MISMATCH) because BOOL is typedef int. 68 | 69 | // first do a legitimate call. this should succeed or return an error such as access denied. 70 | Status = NtQueryInformationThread(GetCurrentThread(), ThreadHideFromDebugger, &isThreadHidden.Value, sizeof(bool), NULL); 71 | 72 | // this shouldn't happen, because we used the correct length. this will only happen if a buggy hook mistakenly expects a BOOL rather than a bool. 73 | if (Status == STATUS_INFO_LENGTH_MISMATCH) 74 | { 75 | // we found a buggy hook that expects some size other than 1 76 | return TRUE; 77 | } 78 | 79 | // if the legitimate call succeeded, continue with additional bogus API call checks 80 | if (Status == 0) 81 | { 82 | AlignedBool bogusIsThreadHidden; 83 | bogusIsThreadHidden.Value = false; 84 | 85 | // now do a bogus call with the wrong size. this will catch buggy hooks that accept BOOL (4 bytes) or just don't have any size checks 86 | Status = NtQueryInformationThread(GetCurrentThread(), ThreadHideFromDebugger, &bogusIsThreadHidden.Value, sizeof(BOOL), NULL); 87 | if (Status != STATUS_INFO_LENGTH_MISMATCH) 88 | { 89 | // we found a buggy hook that allows for incorrect size values 90 | return TRUE; 91 | } 92 | 93 | // NtQueryInformationThread explicitly requires the ThreadInformation pointer to be aligned. as such, it should reject unaligned pointers. 94 | // hooks are almost certainly guaranteed to not retain this behaviour, so it's a very nice way to catch them out. 95 | const size_t UnalignedCheckCount = 8; 96 | bool bogusUnalignedValues[UnalignedCheckCount]; 97 | int alignmentErrorCount = 0; 98 | #if _WIN64 99 | // on 64-bit, up to two elements in the array should be aligned. 100 | const size_t MaxAlignmentCheckSuccessCount = 2; 101 | #else 102 | // on 32-bit, there should be either two or four aligned elements (unsure how WoW64 affects this, so I'm just gonna assume 2 or 4 are ok) 103 | const size_t MaxAlignmentCheckSuccessCount = 4; 104 | #endif 105 | for (size_t i = 0; i < UnalignedCheckCount; i++) 106 | { 107 | Status = NtQueryInformationThread(GetCurrentThread(), ThreadHideFromDebugger, &(bogusUnalignedValues[i]), sizeof(BOOL), NULL); 108 | if (Status == STATUS_DATATYPE_MISALIGNMENT) 109 | { 110 | alignmentErrorCount++; 111 | } 112 | } 113 | // if there weren't enough alignment errors, we know that the API must be hooked and not checking alignment properly! 114 | if (UnalignedCheckCount - MaxAlignmentCheckSuccessCount > alignmentErrorCount) 115 | { 116 | return TRUE; 117 | } 118 | 119 | // the legitimate call was successful, and the bogus call was unsuccessful, so return false (no detection) if the HideFromDebugger flag was properly set. 120 | // if the HideFromDebugger flag was not set, i.e. the NtSetInformationThread call lied to us about being successful, then return true (debugger/hook detected) 121 | return isThreadHidden.Value ? FALSE : TRUE; 122 | } 123 | } 124 | } 125 | else 126 | { 127 | // call failed, should've succeeded 128 | return TRUE; 129 | } 130 | 131 | // we didn't find any hooks. 132 | return FALSE; 133 | } 134 | -------------------------------------------------------------------------------- /al-khaser/AntiDebug/NtSetInformationThread_ThreadHideFromDebugger.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | BOOL NtSetInformationThread_ThreadHideFromDebugger(); -------------------------------------------------------------------------------- /al-khaser/AntiDebug/NtSystemDebugControl.cpp: -------------------------------------------------------------------------------- 1 | #include "pch.h" 2 | 3 | BOOL NtSystemDebugControl_Command() { 4 | auto NtSystemDebugControl_ = static_cast(API::GetAPI(API_IDENTIFIER::API_NtSystemDebugControl)); 5 | 6 | auto status = NtSystemDebugControl_(SYSDBG_COMMAND::SysDbgCheckLowMemory, 0, 0, 0, 0, 0); 7 | 8 | const auto STATUS_DEBUGGER_INACTIVE = 0xC0000354L; 9 | const auto STATUS_ACCESS_DENIED = 0xC0000022L; 10 | const auto STATUS_NOT_IMPLEMENTED = 0xC0000002L; 11 | 12 | // some windows build not supports SysDbgCheckLowMemory which returns 0xC0000002L 13 | if (status == STATUS_DEBUGGER_INACTIVE || status == STATUS_NOT_IMPLEMENTED) { 14 | return FALSE; 15 | } else { 16 | // kernel debugger found 17 | if (status != STATUS_ACCESS_DENIED) { 18 | // usermode debugger too 19 | } 20 | return TRUE; 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /al-khaser/AntiDebug/NtSystemDebugControl.h: -------------------------------------------------------------------------------- 1 | BOOL NtSystemDebugControl_Command(); -------------------------------------------------------------------------------- /al-khaser/AntiDebug/NtYieldExecution.cpp: -------------------------------------------------------------------------------- 1 | #include "pch.h" 2 | #include "NtYieldExecution.h" 3 | 4 | /* 5 | The ntdll function NtYieldExecution or its kernel32 equivalent SwitchToThread function allows the current 6 | thread to offer to give up the rest of its time slice, and allow the next scheduled thread to 7 | execute. If no threads are scheduled to execute (or when the system is busy in particular ways and will 8 | not allow a switch to occur), then the ntdll NtYieldExecution() function returns the 9 | STATUS_NO_YIELD_PERFORMED (0x40000024) status, which causes the kernel32 SwitchToThread() function to 10 | return a zero. When an application is being debugged, the act of single-stepping through the 11 | code causes debug events and often results in no yield being allowed. However, this is a hopelessly 12 | unreliable method for detecting a debugger because it will also detect the presence of a thread that is running with high priority. 13 | */ 14 | 15 | 16 | BOOL NtYieldExecutionAPI() 17 | { 18 | //NOTE: this check is unreliable, don't actually use this in a real environment 19 | 20 | auto NtYieldExecution = static_cast(API::GetAPI(API_IDENTIFIER::API_NtYieldExecution)); 21 | 22 | INT iDebugged = 0; 23 | 24 | for (int i = 0; i < 0x20; i++) 25 | { 26 | Sleep(0xf); 27 | 28 | if (NtYieldExecution() != STATUS_NO_YIELD_PERFORMED) 29 | iDebugged++; 30 | } 31 | 32 | if (iDebugged <= 3) 33 | return FALSE; 34 | else 35 | return TRUE; 36 | 37 | 38 | } 39 | -------------------------------------------------------------------------------- /al-khaser/AntiDebug/NtYieldExecution.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #define STATUS_NO_YIELD_PERFORMED 0x40000024 4 | 5 | BOOL NtYieldExecutionAPI(); -------------------------------------------------------------------------------- /al-khaser/AntiDebug/OutputDebugStringAPI.cpp: -------------------------------------------------------------------------------- 1 | #include "pch.h" 2 | 3 | #include "OutputDebugStringAPI.h" 4 | 5 | /* 6 | OutputDebugString() is typically used to output a string value to the debugging data stream. 7 | This string is then displayed in the debugger. Due to this fact, the function OutputDebugString() 8 | acts differently based on the existence of a debugger on the running process. If a debugger is 9 | attached to the process, the function will execute normally and no error state will be registered; 10 | however if there is no debugger attached, LastError will be set by the process letting us know that 11 | we are debugger free. To execute this method we set LastError to an arbitrary value of our choosing 12 | and then call OutputDebugString(). We then check GetLastError() and if our error code remains, 13 | we know we are debugger free. This Works only in Windows XP/2000 14 | */ 15 | 16 | BOOL OutputDebugStringAPI() 17 | { 18 | 19 | BOOL IsDbgPresent = FALSE; 20 | DWORD Val = 0x29A; 21 | 22 | // This is working only in Windows XP/2000 23 | if (IsWindowsXPOr2k()) 24 | { 25 | SetLastError(Val); 26 | OutputDebugString(_T("random")); 27 | 28 | if (GetLastError() == Val) 29 | IsDbgPresent = TRUE; 30 | } 31 | 32 | return IsDbgPresent; 33 | } 34 | 35 | -------------------------------------------------------------------------------- /al-khaser/AntiDebug/OutputDebugStringAPI.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | BOOL OutputDebugStringAPI(); 4 | -------------------------------------------------------------------------------- /al-khaser/AntiDebug/PageExceptionBreakpointCheck.cpp: -------------------------------------------------------------------------------- 1 | #include "pch.h" 2 | 3 | #ifdef _DEBUG 4 | #define OutputDebugStringDbgOnly(S) OutputDebugString(S) 5 | #else 6 | #define OutputDebugStringDbgOnly(S) do {} while(0); 7 | #endif 8 | 9 | std::vector executablePages = {}; 10 | 11 | void PageExceptionInitialEnum() 12 | { 13 | SYSTEM_INFO sysInfo; 14 | GetSystemInfo(&sysInfo); 15 | size_t pageSize = sysInfo.dwPageSize; 16 | 17 | HMODULE hMainModule; 18 | MODULEINFO moduleInfo; 19 | 20 | MEMORY_BASIC_INFORMATION memInfo = { 0 }; 21 | 22 | // Get the main module handle from an address stored within it (pointer to this method) 23 | if (GetModuleHandleEx(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS, (LPCWSTR)PageExceptionBreakpointCheck, &hMainModule)) 24 | { 25 | // Get information about the main module (we want to know the size of it) 26 | if (GetModuleInformation(GetCurrentProcess(), hMainModule, &moduleInfo, sizeof(MODULEINFO))) 27 | { 28 | // cast the module to a pointer 29 | unsigned char* module = static_cast(moduleInfo.lpBaseOfDll); 30 | for (size_t ofs = 0; ofs < moduleInfo.SizeOfImage; ofs += pageSize) 31 | { 32 | if (VirtualQuery(module + ofs, &memInfo, sizeof(MEMORY_BASIC_INFORMATION)) >= sizeof(MEMORY_BASIC_INFORMATION)) 33 | { 34 | if ((memInfo.Protect & PAGE_EXECUTE) == PAGE_EXECUTE || 35 | (memInfo.Protect & PAGE_EXECUTE_READ) == PAGE_EXECUTE_READ || 36 | (memInfo.Protect & PAGE_EXECUTE_WRITECOPY) == PAGE_EXECUTE_WRITECOPY || 37 | (memInfo.Protect & PAGE_EXECUTE_READWRITE) == PAGE_EXECUTE_READWRITE) 38 | { 39 | executablePages.push_back(module + ofs); 40 | } 41 | } 42 | } 43 | } 44 | } 45 | } 46 | 47 | BOOL PageExceptionBreakpointCheck() 48 | { 49 | SYSTEM_INFO sysInfo; 50 | GetSystemInfo(&sysInfo); 51 | size_t pageSize = sysInfo.dwPageSize; 52 | 53 | HMODULE hMainModule; 54 | MODULEINFO moduleInfo; 55 | 56 | MEMORY_BASIC_INFORMATION memInfo = { 0 }; 57 | 58 | wchar_t buffer[512]; 59 | 60 | // first we check if any of the pages are executable+guard or noaccess 61 | 62 | // Get the main module handle from an address stored within it (pointer to this method) 63 | if (GetModuleHandleEx(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS, (LPCWSTR)PageExceptionBreakpointCheck, &hMainModule)) 64 | { 65 | // Get information about the main module (we want to know the size of it) 66 | if (GetModuleInformation(GetCurrentProcess(), hMainModule, &moduleInfo, sizeof(MODULEINFO))) 67 | { 68 | // cast the module to a pointer 69 | unsigned char* module = static_cast(moduleInfo.lpBaseOfDll); 70 | for (size_t ofs = 0; ofs < moduleInfo.SizeOfImage; ofs += pageSize) 71 | { 72 | SecureZeroMemory(buffer, 512); 73 | wsprintf(buffer, L"Scanning %p... ", module + ofs); 74 | OutputDebugStringDbgOnly(buffer); 75 | if (VirtualQuery(module + ofs, &memInfo, sizeof(MEMORY_BASIC_INFORMATION)) >= sizeof(MEMORY_BASIC_INFORMATION)) 76 | { 77 | if (memInfo.AllocationProtect == 0) 78 | OutputDebugStringDbgOnly(L"^ AllocationProtect is zero. Potential shenanigans."); 79 | if (memInfo.Protect == 0) 80 | OutputDebugStringDbgOnly(L"^ Protect is zero. Potential shenanigans."); 81 | 82 | if ((memInfo.Protect & PAGE_EXECUTE) == PAGE_EXECUTE || 83 | (memInfo.Protect & PAGE_EXECUTE_READ) == PAGE_EXECUTE_READ || 84 | (memInfo.Protect & PAGE_EXECUTE_WRITECOPY) == PAGE_EXECUTE_WRITECOPY || 85 | (memInfo.Protect & PAGE_EXECUTE_READWRITE) == PAGE_EXECUTE_READWRITE) 86 | { 87 | // this is an executable page 88 | OutputDebugStringDbgOnly(L"^ is executable."); 89 | 90 | if ((memInfo.Protect & PAGE_GUARD) == PAGE_GUARD || 91 | (memInfo.AllocationProtect & PAGE_GUARD) == PAGE_GUARD) 92 | { 93 | // this is an executable guard page, page exception debugging detected 94 | OutputDebugStringDbgOnly(L"^ is guard page !!!!!!"); 95 | return TRUE; 96 | } 97 | } 98 | 99 | if ((memInfo.Protect & PAGE_NOACCESS) == PAGE_NOACCESS) 100 | { 101 | // this is a NOACCESS page, which shouldn't exist here (alternative way to set page exception BPs) 102 | OutputDebugStringDbgOnly(L"^ is NOACCESS !!!!!!!"); 103 | return TRUE; 104 | } 105 | } 106 | else OutputDebugStringDbgOnly(L"^ FAILED!"); 107 | } 108 | } 109 | 110 | OutputDebugStringDbgOnly(L"Moving on to delta check..."); 111 | 112 | for (PVOID page : executablePages) 113 | { 114 | SecureZeroMemory(buffer, 512); 115 | wsprintf(buffer, L"Scanning delta for %p... ", page); 116 | OutputDebugStringDbgOnly(buffer); 117 | 118 | if (VirtualQuery(page, &memInfo, sizeof(MEMORY_BASIC_INFORMATION)) >= sizeof(MEMORY_BASIC_INFORMATION)) 119 | { 120 | if (memInfo.AllocationProtect == 0) 121 | OutputDebugStringDbgOnly(L"^ AllocationProtect is zero. Potential shenanigans."); 122 | if (memInfo.Protect == 0) 123 | OutputDebugStringDbgOnly(L"^ Protect is zero. Potential shenanigans."); 124 | 125 | if (!((memInfo.Protect & PAGE_EXECUTE) == PAGE_EXECUTE || 126 | (memInfo.Protect & PAGE_EXECUTE_READ) == PAGE_EXECUTE_READ || 127 | (memInfo.Protect & PAGE_EXECUTE_WRITECOPY) == PAGE_EXECUTE_WRITECOPY || 128 | (memInfo.Protect & PAGE_EXECUTE_READWRITE) == PAGE_EXECUTE_READWRITE)) 129 | { 130 | // page was executable, now isn't! 131 | OutputDebugStringDbgOnly(L"^ was executable, now isn't !!!!!!"); 132 | return TRUE; 133 | } 134 | } 135 | } 136 | } 137 | 138 | return FALSE; 139 | } -------------------------------------------------------------------------------- /al-khaser/AntiDebug/PageExceptionBreakpointCheck.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | void PageExceptionInitialEnum(); 4 | BOOL PageExceptionBreakpointCheck(); 5 | -------------------------------------------------------------------------------- /al-khaser/AntiDebug/ParentProcess.cpp: -------------------------------------------------------------------------------- 1 | #include "pch.h" 2 | #include "ParentProcess.h" 3 | 4 | #define _SILENCE_EXPERIMENTAL_FILESYSTEM_DEPRECATION_WARNING 5 | #include 6 | 7 | DWORD GetExplorerPIDbyShellWindow() 8 | { 9 | DWORD dwProcessId = 0; 10 | 11 | // Get the PID of explorer by its windows handle 12 | GetWindowThreadProcessId(GetShellWindow(), &dwProcessId); 13 | 14 | return dwProcessId; 15 | } 16 | 17 | DWORD GetParentProcessId() 18 | { 19 | auto NtQueryInfoProcess = static_cast(API::GetAPI(API_IDENTIFIER::API_NtQueryInformationProcess)); 20 | 21 | NTSTATUS Status = 0; 22 | ALK_PROCESS_BASIC_INFORMATION pbi; 23 | SecureZeroMemory(&pbi, sizeof(ALK_PROCESS_BASIC_INFORMATION)); 24 | 25 | const UINT ProcessBasicInformation = 0; 26 | 27 | Status = NtQueryInfoProcess(GetCurrentProcess(), ProcessBasicInformation, (PVOID)&pbi, sizeof(ALK_PROCESS_BASIC_INFORMATION), 0); 28 | 29 | if (Status != 0) 30 | { 31 | return 0; 32 | } 33 | else 34 | { 35 | return (DWORD)pbi.ParentProcessId; 36 | } 37 | } 38 | 39 | BOOL IsParentExplorerExe() 40 | { 41 | // this check will throw a false positive if you're running an alternative shell. 42 | 43 | DWORD parentPid = GetParentProcessId(); 44 | 45 | bool parentPidEqualsExplorerPid = false; 46 | 47 | if (parentPid > 0) 48 | { 49 | // first check 50 | HANDLE hParent = OpenProcess(PROCESS_QUERY_LIMITED_INFORMATION, FALSE, parentPid); 51 | if (hParent != INVALID_HANDLE_VALUE) 52 | { 53 | WCHAR winDir[MAX_PATH]; 54 | WCHAR parentProcessPath[MAX_PATH]; 55 | if (GetModuleFileNameExW(hParent, NULL, parentProcessPath, MAX_PATH) && GetWindowsDirectory(winDir, MAX_PATH)) 56 | { 57 | CloseHandle(hParent); 58 | 59 | // get path to X:\Windows\explorer.exe 60 | auto expectedPath = std::experimental::filesystem::path(winDir); 61 | expectedPath = expectedPath.append("explorer.exe"); 62 | 63 | // get path to parent process 64 | auto actualPath = std::experimental::filesystem::path(parentProcessPath); 65 | 66 | // if the paths are equivalent, no detection. 67 | return std::experimental::filesystem::equivalent(expectedPath, actualPath) ? FALSE : TRUE; 68 | } 69 | CloseHandle(hParent); 70 | } 71 | 72 | // if the first check couldn't be completed, fall back to the shell window approach. 73 | // this check is less ideal because it throws false positives if you have explorer process isolation enabled (i.e. one process per explorer window) 74 | DWORD explorerPid = GetExplorerPIDbyShellWindow(); 75 | if (explorerPid > 0) 76 | { 77 | if (parentPid != explorerPid) 78 | { 79 | return TRUE; 80 | } 81 | } 82 | } 83 | 84 | return FALSE; 85 | } 86 | -------------------------------------------------------------------------------- /al-khaser/AntiDebug/ParentProcess.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | typedef struct _ALK_PROCESS_BASIC_INFORMATION { 4 | PVOID Reserved1; 5 | void* PebBaseAddress; 6 | PVOID Reserved2[2]; 7 | ULONG_PTR UniqueProcessId; 8 | ULONG_PTR ParentProcessId; 9 | } ALK_PROCESS_BASIC_INFORMATION; 10 | 11 | BOOL IsParentExplorerExe(); -------------------------------------------------------------------------------- /al-khaser/AntiDebug/ProcessHeap_Flags.cpp: -------------------------------------------------------------------------------- 1 | #include "pch.h" 2 | 3 | #include "ProcessHeap_Flags.h" 4 | 5 | /* 6 | When a program is run under a debugger, and is created using the debug process creation flags, the heap flags are changed. 7 | These Flags exit at a different location depending upon the version of the operating system. 8 | On Windows XP, these flags exist at 0x0C offset from heap base in 32bit system and offset 0x14 in 64bits 9 | On Windows 7, these flags exist at 0x40 offset from heap base in 32bit system and offset 0x70 in 64bits. 10 | */ 11 | 12 | #if defined (ENV64BIT) 13 | PUINT32 GetHeapFlags_x64() 14 | { 15 | PINT64 pProcessHeap = NULL; 16 | PUINT32 pHeapFlags = NULL; 17 | if (IsWindowsVistaOrGreater()){ 18 | pProcessHeap = (PINT64)(__readgsqword(0x60) + 0x30); 19 | pHeapFlags = (PUINT32)(*pProcessHeap + 0x70); 20 | } 21 | 22 | else { 23 | pProcessHeap = (PINT64)(__readgsqword(0x60) + 0x30); 24 | pHeapFlags = (PUINT32)(*pProcessHeap + 0x14); 25 | } 26 | 27 | return pHeapFlags; 28 | } 29 | 30 | #elif defined(ENV32BIT) 31 | PUINT32 GetHeapFlags_x86() 32 | { 33 | PUINT32 pProcessHeap, pHeapFlags = NULL; 34 | 35 | if (IsWindowsVistaOrGreater()){ 36 | pProcessHeap = (PUINT32)(__readfsdword(0x30) + 0x18); 37 | pHeapFlags = (PUINT32)(*pProcessHeap + 0x40); 38 | } 39 | 40 | else { 41 | pProcessHeap = (PUINT32)(__readfsdword(0x30) + 0x18); 42 | pHeapFlags = (PUINT32)(*pProcessHeap + 0x0C); 43 | } 44 | 45 | return pHeapFlags; 46 | } 47 | #endif 48 | 49 | 50 | BOOL HeapFlags() 51 | { 52 | PUINT32 pHeapFlags = NULL; 53 | 54 | #if defined (ENV64BIT) 55 | pHeapFlags = GetHeapFlags_x64(); 56 | 57 | #elif defined(ENV32BIT) 58 | pHeapFlags = GetHeapFlags_x86(); 59 | 60 | #endif 61 | 62 | if (*pHeapFlags > 2) 63 | return TRUE; 64 | else 65 | return FALSE; 66 | } 67 | -------------------------------------------------------------------------------- /al-khaser/AntiDebug/ProcessHeap_Flags.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | BOOL HeapFlags(); -------------------------------------------------------------------------------- /al-khaser/AntiDebug/ProcessHeap_ForceFlags.cpp: -------------------------------------------------------------------------------- 1 | #include "pch.h" 2 | 3 | #include "ProcessHeap_ForceFlags.h" 4 | 5 | /* 6 | When a program is run under a debugger, and is created using the debug process creation flags. The heap flags are changed. 7 | These Flags exit at a different location depending upon the version of the operating system. 8 | On Windows XP, these flags exist at 0x10 offset from heap base in 32bit system and offset 0x18 in bits. 9 | On Windows 7, these flags exist at 0x44 offset from heap base in 32bit system and offset 0x74 in 64bits. 10 | */ 11 | 12 | 13 | #if defined (ENV64BIT) 14 | PUINT32 GetForceFlags_x64() 15 | { 16 | PINT64 pProcessHeap = NULL; 17 | PUINT32 pHeapForceFlags = NULL; 18 | if (IsWindowsVistaOrGreater()){ 19 | pProcessHeap = (PINT64)(__readgsqword(0x60) + 0x30); 20 | pHeapForceFlags = (PUINT32)(*pProcessHeap + 0x74); 21 | } 22 | 23 | else { 24 | pProcessHeap = (PINT64)(__readgsqword(0x60) + 0x30); 25 | pHeapForceFlags = (PUINT32)(*pProcessHeap + 0x18); 26 | } 27 | 28 | return pHeapForceFlags; 29 | } 30 | 31 | #elif defined(ENV32BIT) 32 | PUINT32 GetForceFlags_x86() 33 | { 34 | PUINT32 pProcessHeap, pHeapForceFlags = NULL; 35 | if (IsWindowsVistaOrGreater()) 36 | { 37 | pProcessHeap = (PUINT32)(__readfsdword(0x30) + 0x18); 38 | pHeapForceFlags = (PUINT32)(*pProcessHeap + 0x44); 39 | 40 | } 41 | 42 | else { 43 | pProcessHeap = (PUINT32)(__readfsdword(0x30) + 0x18); 44 | pHeapForceFlags = (PUINT32)(*pProcessHeap + 0x10); 45 | } 46 | 47 | return pHeapForceFlags; 48 | } 49 | #endif 50 | 51 | BOOL HeapForceFlags() 52 | { 53 | PUINT32 pHeapForceFlags = NULL; 54 | 55 | #if defined (ENV64BIT) 56 | pHeapForceFlags = GetForceFlags_x64(); 57 | 58 | #elif defined(ENV32BIT) 59 | pHeapForceFlags = GetForceFlags_x86(); 60 | 61 | #endif 62 | 63 | if (*pHeapForceFlags > 0) 64 | return TRUE; 65 | else 66 | return FALSE; 67 | 68 | } 69 | -------------------------------------------------------------------------------- /al-khaser/AntiDebug/ProcessHeap_ForceFlags.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | BOOL HeapForceFlags(); -------------------------------------------------------------------------------- /al-khaser/AntiDebug/ProcessJob.cpp: -------------------------------------------------------------------------------- 1 | #include "pch.h" 2 | 3 | #include "ProcessJob.h" 4 | 5 | /* 6 | * ProcessJob - Contributed by Graham Sutherland (https://github.com/gsuberland) 7 | * 8 | * Checks whether the process is part of a job object and, if so, any non-whitelisted processes are part of that job. 9 | * 10 | * Debuggers and other analysis applications usually place processes inside a job so that child processes will exit 11 | * when the parent process exits. 12 | * You can observe this with Visual Studio by running al-khaser with Debug -> Start Without Debugging. 13 | * 14 | */ 15 | 16 | BOOL ProcessJob() 17 | { 18 | BOOL foundProblem = FALSE; 19 | 20 | DWORD jobProcessStructSize = sizeof(JOBOBJECT_BASIC_PROCESS_ID_LIST) + sizeof(ULONG_PTR) * 1024; 21 | JOBOBJECT_BASIC_PROCESS_ID_LIST* jobProcessIdList = static_cast(malloc(jobProcessStructSize)); 22 | 23 | if (jobProcessIdList) { 24 | 25 | SecureZeroMemory(jobProcessIdList, jobProcessStructSize); 26 | 27 | jobProcessIdList->NumberOfProcessIdsInList = 1024; 28 | 29 | if (QueryInformationJobObject(NULL, JobObjectBasicProcessIdList, jobProcessIdList, jobProcessStructSize, NULL)) 30 | { 31 | int ok_processes = 0; 32 | for (DWORD i = 0; i < jobProcessIdList->NumberOfAssignedProcesses; i++) 33 | { 34 | ULONG_PTR processId = jobProcessIdList->ProcessIdList[i]; 35 | 36 | // is this the current process? if so that's ok 37 | if (processId == (ULONG_PTR)GetCurrentProcessId()) 38 | { 39 | ok_processes++; 40 | } 41 | else 42 | { 43 | 44 | // find the process name for this job process 45 | HANDLE hJobProcess = OpenProcess(PROCESS_QUERY_INFORMATION, FALSE, (DWORD)processId); 46 | if (hJobProcess != NULL) 47 | { 48 | const int processNameBufferSize = 4096; 49 | LPTSTR processName = static_cast(malloc(sizeof(TCHAR) * processNameBufferSize)); 50 | if (processName) { 51 | SecureZeroMemory(processName, sizeof(TCHAR) * processNameBufferSize); 52 | 53 | if (GetProcessImageFileName(hJobProcess, processName, processNameBufferSize) > 0) 54 | { 55 | String pnStr(processName); 56 | 57 | // ignore conhost.exe (this hosts the al-khaser executable in a console) 58 | if (pnStr.find(String(L"\\Windows\\System32\\conhost.exe")) != std::string::npos) 59 | { 60 | ok_processes++; 61 | } 62 | } 63 | 64 | free(processName); 65 | } 66 | CloseHandle(hJobProcess); 67 | } 68 | } 69 | } 70 | 71 | // if we found other processes in the job other than the current process and conhost, report a problem 72 | foundProblem = ok_processes != jobProcessIdList->NumberOfAssignedProcesses; 73 | } 74 | 75 | free(jobProcessIdList); 76 | } 77 | return foundProblem; 78 | } 79 | -------------------------------------------------------------------------------- /al-khaser/AntiDebug/ProcessJob.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #ifndef UNICODE 4 | typedef std::string String; 5 | #else 6 | typedef std::wstring String; 7 | #endif 8 | 9 | BOOL ProcessJob(); -------------------------------------------------------------------------------- /al-khaser/AntiDebug/ScanForModules.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | BOOL ScanForModules_EnumProcessModulesEx_32bit(); 4 | BOOL ScanForModules_EnumProcessModulesEx_64bit(); 5 | BOOL ScanForModules_EnumProcessModulesEx_All(); 6 | BOOL ScanForModules_ToolHelp32(); 7 | BOOL ScanForModules_LDR_Direct(); 8 | BOOL ScanForModules_LdrEnumerateLoadedModules(); 9 | BOOL ScanForModules_MemoryWalk_GMI(); 10 | BOOL ScanForModules_MemoryWalk_Hidden(); 11 | BOOL ScanForModules_DotNetModuleStructures(); 12 | -------------------------------------------------------------------------------- /al-khaser/AntiDebug/SeDebugPrivilege.cpp: -------------------------------------------------------------------------------- 1 | #include "pch.h" 2 | 3 | #include "SeDebugPrivilege.h" 4 | 5 | /* 6 | If we're being debugged and the process has SeDebugPrivileges privileges then OpenProcess call will be successful. 7 | This requires administrator privilege ! 8 | In Windows XP, Vista and 7, calling OpenProcess with PROCESS_ALL_ACCESS will fait even with SeDebugPrivilege enabled, 9 | That's why I used PROCESS_QUERY_LIMITED_INFORMATION 10 | */ 11 | 12 | 13 | DWORD GetCsrssProcessId() 14 | { 15 | if (API::IsAvailable(API_IDENTIFIER::API_CsrGetProcessId)) 16 | { 17 | auto CsrGetProcessId = static_cast(API::GetAPI(API_IDENTIFIER::API_CsrGetProcessId)); 18 | 19 | return CsrGetProcessId(); 20 | } 21 | else 22 | return GetProcessIdFromName(_T("csrss.exe")); 23 | } 24 | 25 | 26 | BOOL CanOpenCsrss() 27 | { 28 | HANDLE hCsrss = OpenProcess(PROCESS_QUERY_LIMITED_INFORMATION, FALSE, GetCsrssProcessId()); 29 | if (hCsrss != NULL) 30 | { 31 | CloseHandle(hCsrss); 32 | return TRUE; 33 | } 34 | else 35 | return FALSE; 36 | } 37 | -------------------------------------------------------------------------------- /al-khaser/AntiDebug/SeDebugPrivilege.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | BOOL CanOpenCsrss(); 4 | -------------------------------------------------------------------------------- /al-khaser/AntiDebug/SetHandleInformation_API.cpp: -------------------------------------------------------------------------------- 1 | #include "pch.h" 2 | 3 | #include "SetHandleInformation_API.h" 4 | 5 | 6 | BOOL SetHandleInformatiom_ProtectedHandle() 7 | { 8 | /* some vars */ 9 | HANDLE hMutex; 10 | 11 | /* Create a mutex so we can get a handle */ 12 | hMutex = CreateMutex(NULL, FALSE, _T("Random name")); 13 | 14 | if (hMutex) { 15 | 16 | /* Protect our handle */ 17 | SetHandleInformation(hMutex, HANDLE_FLAG_PROTECT_FROM_CLOSE, HANDLE_FLAG_PROTECT_FROM_CLOSE); 18 | 19 | 20 | __try { 21 | /* Then, let's try close it */ 22 | CloseHandle(hMutex); 23 | } 24 | 25 | __except (EXCEPTION_EXECUTE_HANDLER) { 26 | return TRUE; 27 | } 28 | 29 | } 30 | 31 | return FALSE; 32 | 33 | } 34 | -------------------------------------------------------------------------------- /al-khaser/AntiDebug/SetHandleInformation_API.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | BOOL SetHandleInformatiom_ProtectedHandle(); -------------------------------------------------------------------------------- /al-khaser/AntiDebug/SharedUserData_KernelDebugger.cpp: -------------------------------------------------------------------------------- 1 | #include "pch.h" 2 | 3 | #include "SharedUserData_KernelDebugger.h" 4 | 5 | /* 6 | NtQuerySystemInformation can be used to detect the presence of a kernel debugger. However, the 7 | same information can be obtained from user mode with no system calls at all. This is done by 8 | reading from the KUSER_SHARED_DATA struct, which is has a fixed user mode address of 0x7FFE0000 in all versions 9 | of Windows in both 32 and 64 bit. In kernel mode it is located at 0xFFDF0000 (32 bit) or 0xFFFFF78000000000 (64 bit). 10 | Detailed information about KUSER_SHARED_DATA can be found here: http://www.geoffchappell.com/studies/windows/km/ntoskrnl/structs/kuser_shared_data.htm 11 | */ 12 | 13 | BOOL SharedUserData_KernelDebugger() 14 | { 15 | // The fixed user mode address of KUSER_SHARED_DATA 16 | const ULONG_PTR UserSharedData = 0x7FFE0000; 17 | 18 | // UserSharedData->KdDebuggerEnabled is a BOOLEAN according to ntddk.h, which gives the false impression that it is 19 | // either true or false. However, this field is actually a set of bit flags, and is only zero if no debugger is present. 20 | const UCHAR KdDebuggerEnabledByte = *(UCHAR*)(UserSharedData + 0x2D4); // 0x2D4 = the offset of the field 21 | 22 | // Extract the flags. 23 | // The meaning of these is the same as in NtQuerySystemInformation(SystemKernelDebuggerInformation). 24 | // Normally if a debugger is attached, KdDebuggerEnabled is true, KdDebuggerNotPresent is false and the byte is 0x3. 25 | const BOOLEAN KdDebuggerEnabled = (KdDebuggerEnabledByte & 0x1) == 0x1; 26 | const BOOLEAN KdDebuggerNotPresent = (KdDebuggerEnabledByte & 0x2) == 0; 27 | 28 | if (KdDebuggerEnabled || !KdDebuggerNotPresent) 29 | return TRUE; 30 | 31 | return FALSE; 32 | } 33 | -------------------------------------------------------------------------------- /al-khaser/AntiDebug/SharedUserData_KernelDebugger.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | BOOL SharedUserData_KernelDebugger(); -------------------------------------------------------------------------------- /al-khaser/AntiDebug/SoftwareBreakpoints.cpp: -------------------------------------------------------------------------------- 1 | #include "pch.h" 2 | 3 | #include "SoftwareBreakpoints.h" 4 | 5 | 6 | /* 7 | Software breakpoints aka INT 3 represented in the IA-32 instruction set with the opcode CC (0xCC). 8 | Given a memory addresse and size, it is relatively simple to scan for the byte 0xCC -> if(pTmp[i] == 0xCC) 9 | An obfuscated method would be to check if our memory byte xored with 0x55 is equal 0x99 for example ... 10 | */ 11 | 12 | VOID My_Critical_Function() 13 | { 14 | int a = 1; 15 | int b = 2; 16 | int c = a + b; 17 | _tprintf(_T("I am critical function, you should protect against int3 bps %d"), c); 18 | } 19 | 20 | 21 | VOID Myfunction_Adresss_Next() 22 | { 23 | My_Critical_Function(); 24 | /* 25 | There is no guaranteed way of determining the size of a function at run time(and little reason to do so) 26 | however if you assume that the linker located functions that are adjacent in the source code sequentially in memory, 27 | then the following may give an indication of the size of a function Critical_Function by using : 28 | int Critical_Function_length = (int)Myfunction_Adresss_Next - (int)Critical_Function 29 | Works only if you compile the file in Release mode. 30 | */ 31 | }; 32 | 33 | BOOL SoftwareBreakpoints() 34 | { 35 | //NOTE this check might not work on x64 because of alignment 0xCC bytes 36 | size_t sSizeToCheck = (size_t)(Myfunction_Adresss_Next)-(size_t)(My_Critical_Function); 37 | PUCHAR Critical_Function = (PUCHAR)My_Critical_Function; 38 | 39 | for (size_t i = 0; i < sSizeToCheck; i++) { 40 | if (Critical_Function[i] == 0xCC) // Adding another level of indirection : 0xCC xor 0x55 = 0x99 41 | return TRUE; 42 | } 43 | return FALSE; 44 | } 45 | -------------------------------------------------------------------------------- /al-khaser/AntiDebug/SoftwareBreakpoints.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | BOOL SoftwareBreakpoints(); 4 | -------------------------------------------------------------------------------- /al-khaser/AntiDebug/TLS_callbacks.cpp: -------------------------------------------------------------------------------- 1 | #include "pch.h" 2 | 3 | #include "TLS_callbacks.h" 4 | 5 | // The Thread Local Storage (TLS) callback is called before the execution of the EntryPoint of the application 6 | // Malware takes advantages to perform anti-debug and anti-vm checks. 7 | // There could be more than one callback, and sometimes, inside one call back, one can create one in the fly. 8 | 9 | 10 | volatile bool has_run = false; 11 | 12 | VOID WINAPI tls_callback(PVOID hModule, DWORD dwReason, PVOID pContext) 13 | { 14 | if (!has_run) 15 | { 16 | has_run = true; 17 | tls_callback_thread_event = CreateEvent(NULL, FALSE, FALSE, NULL); 18 | tls_callback_process_event = CreateEvent(NULL, FALSE, FALSE, NULL); 19 | } 20 | 21 | if (dwReason == DLL_THREAD_ATTACH) 22 | { 23 | OutputDebugString(L"TLS callback: thread attach"); 24 | tls_callback_thread_data = 0xDEADBEEF; 25 | SetEvent(tls_callback_thread_event); 26 | } 27 | 28 | if (dwReason == DLL_PROCESS_ATTACH) 29 | { 30 | OutputDebugString(L"TLS callback: process attach"); 31 | tls_callback_process_data = 0xDEADBEEF; 32 | SetEvent(tls_callback_process_event); 33 | } 34 | } 35 | 36 | DWORD WINAPI TLSCallbackDummyThread( 37 | _In_ LPVOID lpParameter 38 | ) 39 | { 40 | OutputDebugString(L"TLS callback: dummy thread launched"); 41 | return 0; 42 | } 43 | 44 | BOOL TLSCallbackThread() 45 | { 46 | const int BLOWN = 1000; 47 | 48 | if (CreateThread(NULL, 0, &TLSCallbackDummyThread, NULL, 0, NULL) == NULL) 49 | { 50 | OutputDebugString(L"TLS callback: couldn't start dummy thread"); 51 | } 52 | 53 | int fuse = 0; 54 | while (tls_callback_thread_event == NULL && ++fuse != BLOWN) { SwitchToThread(); } 55 | if (fuse >= BLOWN) 56 | { 57 | OutputDebugString(L"TLSCallbackThread timeout on event creation."); 58 | return TRUE; 59 | } 60 | 61 | DWORD waitStatus = WaitForSingleObject(tls_callback_thread_event, 5000); 62 | if (waitStatus != WAIT_OBJECT_0) 63 | { 64 | if (waitStatus == WAIT_FAILED) 65 | OutputDebugString(L"TLSCallbackThread wait failed."); 66 | else if (waitStatus == WAIT_ABANDONED) 67 | OutputDebugString(L"TLSCallbackThread wait abandoned."); 68 | else 69 | OutputDebugString(L"TLSCallbackThread timeout on event wait."); 70 | return TRUE; 71 | } 72 | 73 | if (tls_callback_thread_data != 0xDEADBEEF) 74 | OutputDebugString(L"TLSCallbackThread data did not match."); 75 | else 76 | OutputDebugString(L"All seems fine for TLSCallbackThread."); 77 | 78 | return tls_callback_thread_data == 0xDEADBEEF ? FALSE : TRUE; 79 | } 80 | 81 | BOOL TLSCallbackProcess() 82 | { 83 | const int BLOWN = 1000; 84 | 85 | int fuse = 0; 86 | while (tls_callback_process_event == NULL && ++fuse != BLOWN) { SwitchToThread(); } 87 | if (fuse >= BLOWN) 88 | { 89 | OutputDebugString(L"TLSCallbackProcess timeout on event creation."); 90 | return TRUE; 91 | } 92 | 93 | DWORD waitStatus = WaitForSingleObject(tls_callback_process_event, 5000); 94 | if (waitStatus != WAIT_OBJECT_0) 95 | { 96 | if (waitStatus == WAIT_FAILED) 97 | OutputDebugString(L"TLSCallbackProcess wait failed."); 98 | else if (waitStatus == WAIT_ABANDONED) 99 | OutputDebugString(L"TLSCallbackProcess wait abandoned."); 100 | else 101 | OutputDebugString(L"TLSCallbackProcess timeout on event wait."); 102 | return TRUE; 103 | } 104 | 105 | if (tls_callback_process_data != 0xDEADBEEF) 106 | OutputDebugString(L"TLSCallbackProcess data did not match."); 107 | else 108 | OutputDebugString(L"All seems fine for TLSCallbackProcess."); 109 | 110 | return tls_callback_process_data == 0xDEADBEEF ? FALSE : TRUE; 111 | } 112 | 113 | #ifdef _WIN64 114 | #pragma comment (linker, "/INCLUDE:_tls_used") 115 | #pragma comment (linker, "/INCLUDE:tls_callback_func") 116 | #else 117 | #pragma comment (linker, "/INCLUDE:__tls_used") 118 | #pragma comment (linker, "/INCLUDE:_tls_callback_func") 119 | #endif 120 | 121 | 122 | #ifdef _WIN64 123 | #pragma const_seg(".CRT$XLF") 124 | EXTERN_C const 125 | #else 126 | #pragma data_seg(".CRT$XLF") 127 | EXTERN_C 128 | #endif 129 | 130 | PIMAGE_TLS_CALLBACK tls_callback_func = tls_callback; 131 | 132 | #ifdef _WIN64 133 | #pragma const_seg() 134 | #else 135 | #pragma data_seg() 136 | #endif //_WIN64 137 | -------------------------------------------------------------------------------- /al-khaser/AntiDebug/TLS_callbacks.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | static volatile HANDLE tls_callback_thread_event = 0; 4 | static volatile HANDLE tls_callback_process_event = 0; 5 | static volatile UINT32 tls_callback_thread_data = 0; 6 | static volatile UINT32 tls_callback_process_data = 0; 7 | 8 | VOID WINAPI tls_callback(PVOID hModule, DWORD dwReason, PVOID pContext); 9 | BOOL TLSCallbackThread(); 10 | BOOL TLSCallbackProcess(); 11 | -------------------------------------------------------------------------------- /al-khaser/AntiDebug/TrapFlag.cpp: -------------------------------------------------------------------------------- 1 | #include "pch.h" 2 | 3 | #include "TrapFlag.h" 4 | 5 | /* 6 | This technique is similar to exceptions based debugger detections. 7 | You enable the trap flag in the current process and check whether 8 | an exception is raised or not. If an exception is not raised, you 9 | can assume that a debugger has “swallowed” the exception for us, 10 | and that the program is being traced. The beauty of this approach 11 | is that it detects every debugger, user mode or kernel mode, 12 | because they all use the trap flag for tracing a program. 13 | 14 | Vectored Exception Handling is used here because SEH is an 15 | anti-debug trick in itself. 16 | */ 17 | 18 | static BOOL SwallowedException = TRUE; 19 | 20 | static LONG CALLBACK VectoredHandler( 21 | _In_ PEXCEPTION_POINTERS ExceptionInfo 22 | ) 23 | { 24 | SwallowedException = FALSE; 25 | 26 | if (ExceptionInfo->ExceptionRecord->ExceptionCode == EXCEPTION_SINGLE_STEP) 27 | return EXCEPTION_CONTINUE_EXECUTION; 28 | 29 | return EXCEPTION_CONTINUE_SEARCH; 30 | } 31 | 32 | 33 | 34 | BOOL TrapFlag() 35 | { 36 | PVOID Handle = AddVectoredExceptionHandler(1, VectoredHandler); 37 | SwallowedException = TRUE; 38 | 39 | #ifdef _WIN64 40 | UINT64 eflags = __readeflags(); 41 | #else 42 | UINT eflags = __readeflags(); 43 | #endif 44 | 45 | // Set the trap flag 46 | eflags |= 0x100; 47 | __writeeflags(eflags); 48 | 49 | RemoveVectoredExceptionHandler(Handle); 50 | return SwallowedException; 51 | } 52 | -------------------------------------------------------------------------------- /al-khaser/AntiDebug/TrapFlag.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | BOOL TrapFlag(); -------------------------------------------------------------------------------- /al-khaser/AntiDebug/UnhandledExceptionFilter_Handler.cpp: -------------------------------------------------------------------------------- 1 | #include "pch.h" 2 | #include "UnhandledExceptionFilter_Handler.h" 3 | 4 | 5 | /* 6 | When an exception occurs, and no registered Exception Handlers exist (neither Structured nor 7 | Vectored), or if none of the registered handlers handles the exception, then the kernel32 8 | UnhandledExceptionFilter() function will be called as a last resort. 9 | */ 10 | 11 | BOOL bIsBeinDbg = TRUE; 12 | 13 | LONG WINAPI UnhandledExcepFilter(PEXCEPTION_POINTERS pExcepPointers) 14 | { 15 | // If a debugger is present, then this function will not be reached. 16 | bIsBeinDbg = FALSE; 17 | return EXCEPTION_CONTINUE_EXECUTION; 18 | } 19 | 20 | 21 | BOOL UnhandledExcepFilterTest () 22 | { 23 | LPTOP_LEVEL_EXCEPTION_FILTER Top = SetUnhandledExceptionFilter(UnhandledExcepFilter); 24 | RaiseException(EXCEPTION_FLT_DIVIDE_BY_ZERO, 0, 0, NULL); 25 | SetUnhandledExceptionFilter(Top); 26 | return bIsBeinDbg; 27 | } 28 | -------------------------------------------------------------------------------- /al-khaser/AntiDebug/UnhandledExceptionFilter_Handler.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | BOOL UnhandledExcepFilterTest(); -------------------------------------------------------------------------------- /al-khaser/AntiDebug/WUDF_IsDebuggerPresent.cpp: -------------------------------------------------------------------------------- 1 | #include "pch.h" 2 | #include "WUDF_IsDebuggerPresent.h" 3 | 4 | BOOL WUDF_IsAnyDebuggerPresent() 5 | { 6 | if (API::IsAvailable(API_IDENTIFIER::API_WudfIsAnyDebuggerPresent)) 7 | { 8 | auto WudfIsAnyDebuggerPresent = static_cast(API::GetAPI(API_IDENTIFIER::API_WudfIsAnyDebuggerPresent)); 9 | return WudfIsAnyDebuggerPresent() == 0 ? FALSE : TRUE; 10 | } 11 | else 12 | return FALSE; 13 | } 14 | 15 | BOOL WUDF_IsKernelDebuggerPresent() 16 | { 17 | if (API::IsAvailable(API_IDENTIFIER::API_WudfIsKernelDebuggerPresent)) 18 | { 19 | auto WudfIsKernelDebuggerPresent = static_cast(API::GetAPI(API_IDENTIFIER::API_WudfIsKernelDebuggerPresent)); 20 | return WudfIsKernelDebuggerPresent() == 0 ? FALSE : TRUE; 21 | } 22 | else 23 | return FALSE; 24 | } 25 | 26 | BOOL WUDF_IsUserDebuggerPresent() 27 | { 28 | if (API::IsAvailable(API_IDENTIFIER::API_WudfIsUserDebuggerPresent)) 29 | { 30 | auto WudfIsUserDebuggerPresent = static_cast(API::GetAPI(API_IDENTIFIER::API_WudfIsUserDebuggerPresent)); 31 | return WudfIsUserDebuggerPresent() == 0 ? FALSE : TRUE; 32 | } 33 | else 34 | return FALSE; 35 | } 36 | -------------------------------------------------------------------------------- /al-khaser/AntiDebug/WUDF_IsDebuggerPresent.h: -------------------------------------------------------------------------------- 1 | BOOL WUDF_IsAnyDebuggerPresent(); 2 | BOOL WUDF_IsKernelDebuggerPresent(); 3 | BOOL WUDF_IsUserDebuggerPresent(); 4 | -------------------------------------------------------------------------------- /al-khaser/AntiDebug/WriteWatch.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | BOOL VirtualAlloc_WriteWatch_BufferOnly(); 4 | BOOL VirtualAlloc_WriteWatch_APICalls(); 5 | BOOL VirtualAlloc_WriteWatch_IsDebuggerPresent(); 6 | BOOL VirtualAlloc_WriteWatch_CodeWrite(); -------------------------------------------------------------------------------- /al-khaser/AntiDebug/int2d_x64.asm: -------------------------------------------------------------------------------- 1 | .code 2 | 3 | __int2d proc 4 | mov rax, 0 5 | int 2dh 6 | nop 7 | ret 8 | __int2d endp 9 | 10 | end 11 | -------------------------------------------------------------------------------- /al-khaser/AntiDebug/int2d_x86.asm: -------------------------------------------------------------------------------- 1 | .model flat 2 | .code 3 | 4 | ___int2d proc 5 | mov eax, 0 6 | int 2dh 7 | nop 8 | ret 9 | ___int2d endp 10 | 11 | end 12 | -------------------------------------------------------------------------------- /al-khaser/AntiDebug/pch.h: -------------------------------------------------------------------------------- 1 | #include "../pch.h" -------------------------------------------------------------------------------- /al-khaser/AntiDisassm/AntiDisassm.cpp: -------------------------------------------------------------------------------- 1 | #include "pch.h" 2 | 3 | #include "AntiDisassm.h" 4 | 5 | 6 | extern "C" void __AsmConstantCondition(); 7 | extern "C" void __AsmJmpSameTarget(); 8 | extern "C" void __AsmImpossibleDisassm(); 9 | extern "C" void __AsmFunctionPointer(DWORD); 10 | extern "C" void __AsmReturnPointerAbuse(DWORD64); 11 | #ifndef _WIN64 12 | extern "C" void __AsmSEHMisuse(); 13 | #endif 14 | 15 | /* 16 | This technique is composed of a single conditional jump instruction placed where the condition 17 | will always be the same. 18 | */ 19 | VOID AntiDisassmConstantCondition() 20 | { 21 | __AsmConstantCondition(); 22 | } 23 | 24 | /* 25 | The most common anti-disassembly technique seen in the wild is two back-to back 26 | conditional jump instructions that both point to the same target. For example, 27 | if a jz XYZ is followed by jnz XYZ, the location XYZ will always be jumped to 28 | */ 29 | VOID AntiDisassmAsmJmpSameTarget() 30 | { 31 | __AsmJmpSameTarget(); 32 | } 33 | 34 | 35 | /* 36 | By using a data byte placed strategically after a conditional jump instruction 37 | with the idea that disassembly starting at this byte will prevent the real instruction 38 | that follows from being disassembled because the byte that inserted is the opcode for 39 | a multibyte instruction. 40 | 41 | */ 42 | VOID AntiDisassmImpossibleDiasassm() 43 | { 44 | __AsmImpossibleDisassm(); 45 | } 46 | 47 | 48 | /* 49 | If function pointers are used in handwritten assembly or crafted in a nonstandard way 50 | in source code, the results can be difficult to reverse engineer without dynamic analysis. 51 | */ 52 | VOID AntiDisassmFunctionPointer() 53 | { 54 | 55 | DWORD Number = 2; 56 | __AsmFunctionPointer(Number); 57 | } 58 | 59 | 60 | /* 61 | The most obvious result of this technique is that the disassembler doesn�t show any 62 | code cross - reference to the target being jumped to. 63 | */ 64 | VOID AntiDisassmReturnPointerAbuse() 65 | { 66 | __AsmReturnPointerAbuse(666); 67 | } 68 | 69 | #ifndef _WIN64 70 | VOID AntiDisassmSEHMisuse() 71 | { 72 | __AsmSEHMisuse(); 73 | } 74 | #endif -------------------------------------------------------------------------------- /al-khaser/AntiDisassm/AntiDisassm.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | VOID AntiDisassmConstantCondition(); 4 | VOID AntiDisassmAsmJmpSameTarget(); 5 | VOID AntiDisassmImpossibleDiasassm(); 6 | VOID AntiDisassmFunctionPointer(); 7 | VOID AntiDisassmReturnPointerAbuse(); 8 | VOID AntiDisassmSEHMisuse(); -------------------------------------------------------------------------------- /al-khaser/AntiDisassm/AntiDisassm_x64.asm: -------------------------------------------------------------------------------- 1 | 2 | .code 3 | 4 | __AsmConstantCondition proc 5 | xor rax, rax 6 | jz L_END 7 | db 0e8h 8 | L_END: 9 | nop 10 | ret 11 | __AsmConstantCondition endp 12 | 13 | 14 | __AsmJmpSameTarget proc 15 | jz L_END 16 | jnz L_END 17 | db 0e8h 18 | L_END: 19 | nop 20 | ret 21 | __AsmJmpSameTarget endp 22 | 23 | 24 | __AsmImpossibleDisassm proc 25 | push rax 26 | 27 | mov ax, 05EBh ; db 066h, 0B8h, 0EBh, 005h 28 | xor eax, eax ; db 033h, 0C0h 29 | db 074h, 0fah 30 | db 0e8h ; call 31 | 32 | pop rax 33 | ret 34 | __AsmImpossibleDisassm endp 35 | 36 | ; a dummy function 37 | func2 proc 38 | mov rax, r8 39 | shl rax, 2 40 | ret 41 | func2 endp 42 | 43 | 44 | __AsmFunctionPointer proc 45 | push rax 46 | push rcx 47 | push rsi 48 | mov rcx, offset func2 49 | mov r8, 02h 50 | call rcx 51 | mov rsi, rax 52 | mov r8, 03h 53 | call rcx 54 | lea rax, [rsi+rax+1] 55 | pop rsi 56 | pop rcx 57 | pop rax 58 | ret 59 | __AsmFunctionPointer endp 60 | 61 | 62 | __AsmReturnPointerAbuse proc 63 | call $+5 64 | add qword ptr[rsp], 6 65 | ret 66 | 67 | push rax 68 | mov rax, rcx 69 | imul rax, 40h 70 | pop rax 71 | ret 72 | __AsmReturnPointerAbuse endp 73 | 74 | 75 | end 76 | -------------------------------------------------------------------------------- /al-khaser/AntiDisassm/AntiDisassm_x86.asm: -------------------------------------------------------------------------------- 1 | .model flat, c 2 | 3 | .code 4 | 5 | __AsmConstantCondition proc 6 | xor eax, eax 7 | jz L_END 8 | db 0e8h 9 | L_END: 10 | nop 11 | ret 12 | __AsmConstantCondition endp 13 | 14 | 15 | __AsmJmpSameTarget proc 16 | jz L_END 17 | jnz L_END 18 | db 0e8h 19 | L_END: 20 | nop 21 | ret 22 | __AsmJmpSameTarget endp 23 | 24 | 25 | __AsmImpossibleDisassm proc 26 | push eax 27 | 28 | mov ax, 05EBh ; db 066h, 0B8h, 0EBh, 005h 29 | xor eax, eax ; db 033h, 0C0h 30 | db 074h, 0fah 31 | db 0e8h ; call 32 | 33 | pop eax 34 | ret 35 | __AsmImpossibleDisassm endp 36 | 37 | ; a dummy function 38 | func2 proc arg_0:DWORD 39 | mov eax, [arg_0] 40 | shl eax, 2 41 | pop ebp 42 | retn 43 | func2 endp 44 | 45 | 46 | __AsmFunctionPointer proc arg_0:DWORD 47 | 48 | LOCAL var_4:DWORD 49 | 50 | push ecx 51 | push esi 52 | mov [var_4], offset func2 53 | push 03h 54 | call [var_4] 55 | add esp, 4 56 | mov esi, eax 57 | mov eax, [arg_0] 58 | push eax 59 | call [var_4] 60 | add esp, 4 61 | lea eax, [esi+eax+1] 62 | pop esi 63 | mov esp, ebp 64 | pop ebp 65 | retn 66 | __AsmFunctionPointer endp 67 | 68 | __AsmReturnPointerAbuse proc 69 | 70 | call $+5 71 | add dword ptr[esp], 5 72 | retn 73 | 74 | push eax 75 | mov eax, [ebp+8] 76 | imul eax, 40h 77 | pop eax 78 | retn 79 | __AsmReturnPointerAbuse endp 80 | 81 | ; another dummy function 82 | func3 proc 83 | mov esp, [esp+8] 84 | ASSUME FS:NOTHING 85 | mov eax, dword ptr fs:[0] 86 | ASSUME FS:ERROR 87 | mov eax, [eax] 88 | mov eax, [eax] 89 | ASSUME FS:NOTHING 90 | mov dword ptr fs:[0], eax 91 | ASSUME FS:ERROR 92 | add esp, 8 93 | pop ebp 94 | retn 95 | func3 endp 96 | 97 | __AsmSEHMisuse proc 98 | push ebp 99 | mov eax, offset func3 100 | push eax 101 | ASSUME FS:NOTHING 102 | push dword ptr fs:[0] 103 | mov dword ptr fs:[0], esp 104 | ASSUME FS:ERROR 105 | xor ecx, ecx 106 | div ecx 107 | call func2 108 | retn 109 | __AsmSEHMisuse endp 110 | 111 | end 112 | -------------------------------------------------------------------------------- /al-khaser/AntiDisassm/pch.h: -------------------------------------------------------------------------------- 1 | #include "../pch.h" -------------------------------------------------------------------------------- /al-khaser/AntiDump/ErasePEHeaderFromMemory.cpp: -------------------------------------------------------------------------------- 1 | #include "pch.h" 2 | 3 | #include "ErasePEHeaderFromMemory.h" 4 | 5 | /* This function will erase the current images PE header from memory preventing a successful image if dumped */ 6 | 7 | 8 | VOID ErasePEHeaderFromMemory() 9 | { 10 | _tprintf(_T("[*] Erasing PE header from memory\n")); 11 | DWORD OldProtect = 0; 12 | 13 | // Get base address of module 14 | char *pBaseAddr = (char*)GetModuleHandle(NULL); 15 | 16 | // Change memory protection 17 | VirtualProtect(pBaseAddr, 4096, // Assume x86 page size 18 | PAGE_READWRITE, &OldProtect); 19 | 20 | // Erase the header 21 | SecureZeroMemory(pBaseAddr, 4096); 22 | } 23 | 24 | 25 | 26 | -------------------------------------------------------------------------------- /al-khaser/AntiDump/ErasePEHeaderFromMemory.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | VOID ErasePEHeaderFromMemory(); -------------------------------------------------------------------------------- /al-khaser/AntiDump/SizeOfImage.cpp: -------------------------------------------------------------------------------- 1 | #include "pch.h" 2 | 3 | #include "SizeOfImage.h" 4 | 5 | // Any unreasonably large value will work say for example 0x100000 or 100,000h 6 | 7 | VOID SizeOfImage() 8 | { 9 | 10 | #if defined (ENV64BIT) 11 | PPEB pPeb = (PPEB)__readgsqword(0x60); 12 | #elif defined(ENV32BIT) 13 | PPEB pPeb = (PPEB)__readfsdword(0x30); 14 | #endif 15 | 16 | _tprintf(_T("[*] Increasing SizeOfImage in PE Header to: 0x100000\n")); 17 | 18 | // The following pointer hackery is because winternl.h defines incomplete PEB types 19 | PLIST_ENTRY InLoadOrderModuleList = (PLIST_ENTRY)pPeb->Ldr->Reserved2[1]; // pPeb->Ldr->InLoadOrderModuleList 20 | PLDR_DATA_TABLE_ENTRY tableEntry = CONTAINING_RECORD(InLoadOrderModuleList, LDR_DATA_TABLE_ENTRY, Reserved1[0] /*InLoadOrderLinks*/); 21 | PULONG pEntrySizeOfImage = (PULONG)&tableEntry->Reserved3[1]; // &tableEntry->SizeOfImage 22 | *pEntrySizeOfImage = (ULONG)((INT_PTR)tableEntry->DllBase + 0x100000); 23 | } 24 | -------------------------------------------------------------------------------- /al-khaser/AntiDump/SizeOfImage.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | VOID SizeOfImage(); -------------------------------------------------------------------------------- /al-khaser/AntiDump/pch.h: -------------------------------------------------------------------------------- 1 | #include "../pch.h" -------------------------------------------------------------------------------- /al-khaser/AntiVM/Generic.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | VOID loaded_dlls(); 4 | VOID known_file_names(); 5 | VOID known_usernames(); 6 | VOID known_hostnames(); 7 | VOID other_known_sandbox_environment_checks(); 8 | BOOL NumberOfProcessors(); 9 | BOOL idt_trick(); 10 | BOOL ldt_trick(); 11 | BOOL gdt_trick(); 12 | BOOL str_trick(); 13 | BOOL number_cores_wmi(); 14 | BOOL disk_size_wmi(); 15 | BOOL setupdi_diskdrive(); 16 | BOOL mouse_movement(); 17 | BOOL lack_user_input(); 18 | BOOL memory_space(); 19 | BOOL dizk_size_deviceiocontrol(); 20 | BOOL disk_size_getdiskfreespace(); 21 | BOOL accelerated_sleep(); 22 | BOOL cpuid_is_hypervisor(); 23 | BOOL cpuid_hypervisor_vendor(); 24 | BOOL serial_number_bios_wmi(); 25 | BOOL model_computer_system_wmi(); 26 | BOOL manufacturer_computer_system_wmi(); 27 | BOOL current_temperature_acpi_wmi(); 28 | BOOL process_id_processor_wmi(); 29 | BOOL power_capabilities(); 30 | BOOL hybridanalysismacdetect(); 31 | BOOL cpu_fan_wmi(); 32 | BOOL caption_video_controller_wmi(); 33 | BOOL query_license_value(); 34 | BOOL cachememory_wmi(); 35 | BOOL physicalmemory_wmi(); 36 | BOOL memorydevice_wmi(); 37 | BOOL memoryarray_wmi(); 38 | BOOL voltageprobe_wmi(); 39 | BOOL portconnector_wmi(); 40 | BOOL smbiosmemory_wmi(); 41 | BOOL perfctrs_thermalzoneinfo_wmi(); 42 | BOOL cim_memory_wmi(); 43 | BOOL cim_numericsensor_wmi(); 44 | BOOL cim_physicalconnector_wmi(); 45 | BOOL cim_sensor_wmi(); 46 | BOOL cim_slot_wmi(); 47 | BOOL cim_temperaturesensor_wmi(); 48 | BOOL cim_voltagesensor_wmi(); 49 | BOOL pirated_windows(); 50 | BOOL registry_services_disk_enum(); 51 | BOOL registry_disk_enum(); 52 | BOOL number_SMBIOS_tables(); 53 | BOOL firmware_ACPI(); 54 | BOOL hosting_check(); 55 | VOID looking_glass_vdd_processes(); 56 | -------------------------------------------------------------------------------- /al-khaser/AntiVM/HyperV.cpp: -------------------------------------------------------------------------------- 1 | #include "pch.h" 2 | #include "HyperV.h" 3 | 4 | 5 | BOOL check_hyperv_driver_objects() 6 | { 7 | auto driverList = enumerate_object_directory(L"\\Driver"); 8 | if (driverList == nullptr) 9 | { 10 | return FALSE; 11 | } 12 | for (wchar_t* driver : *driverList) 13 | { 14 | if (StrCmpCW(driver, L"VMBusHID") == 0) 15 | { 16 | return TRUE; 17 | } 18 | if (StrCmpCW(driver, L"vmbus") == 0) 19 | { 20 | return TRUE; 21 | } 22 | if (StrCmpCW(driver, L"vmgid") == 0) 23 | { 24 | return TRUE; 25 | } 26 | if (StrCmpCW(driver, L"IndirectKmd") == 0) 27 | { 28 | return TRUE; 29 | } 30 | if (StrCmpCW(driver, L"HyperVideo") == 0) 31 | { 32 | return TRUE; 33 | } 34 | if (StrCmpCW(driver, L"hyperkbd") == 0) 35 | { 36 | return TRUE; 37 | } 38 | } 39 | return FALSE; 40 | } 41 | 42 | 43 | BOOL check_hyperv_global_objects() 44 | { 45 | auto globalObjs = enumerate_object_directory(L"\\GLOBAL??"); 46 | if (globalObjs == nullptr) 47 | { 48 | return FALSE; 49 | } 50 | for (wchar_t* globalObj : *globalObjs) 51 | { 52 | if (StrStrW(globalObj, L"VMBUS#") != NULL) 53 | { 54 | return TRUE; 55 | } 56 | if (StrCmpCW(globalObj, L"VDRVROOT") == 0) 57 | { 58 | return TRUE; 59 | } 60 | if (StrCmpCW(globalObj, L"VmGenerationCounter") == 0) 61 | { 62 | return TRUE; 63 | } 64 | if (StrCmpCW(globalObj, L"VmGid") == 0) 65 | { 66 | return TRUE; 67 | } 68 | } 69 | return FALSE; 70 | } 71 | -------------------------------------------------------------------------------- /al-khaser/AntiVM/HyperV.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | BOOL check_hyperv_driver_objects(); 4 | BOOL check_hyperv_global_objects(); 5 | -------------------------------------------------------------------------------- /al-khaser/AntiVM/KVM.cpp: -------------------------------------------------------------------------------- 1 | #include "pch.h" 2 | 3 | 4 | /* 5 | Check against kvm registry keys 6 | */ 7 | VOID kvm_reg_keys() 8 | { 9 | /* Array of strings of blacklisted registry keys */ 10 | const TCHAR* szKeys[] = { 11 | _T("SYSTEM\\ControlSet001\\Services\\vioscsi"), 12 | _T("SYSTEM\\ControlSet001\\Services\\viostor"), 13 | _T("SYSTEM\\ControlSet001\\Services\\VirtIO-FS Service"), 14 | _T("SYSTEM\\ControlSet001\\Services\\VirtioSerial"), 15 | _T("SYSTEM\\ControlSet001\\Services\\BALLOON"), 16 | _T("SYSTEM\\ControlSet001\\Services\\BalloonService"), 17 | _T("SYSTEM\\ControlSet001\\Services\\netkvm"), 18 | _T("SYSTEM\\CurrentControlSet\\Enum\\PCI\\VEN_1AF4*"), 19 | }; 20 | 21 | WORD dwlength = sizeof(szKeys) / sizeof(szKeys[0]); 22 | 23 | /* Check one by one */ 24 | for (int i = 0; i < dwlength; i++) 25 | { 26 | TCHAR msg[256] = _T(""); 27 | _stprintf_s(msg, sizeof(msg) / sizeof(TCHAR), _T("Checking reg key %s "), szKeys[i]); 28 | if (Is_RegKeyExists(HKEY_LOCAL_MACHINE, szKeys[i])) 29 | print_results(TRUE, msg); 30 | else 31 | print_results(FALSE, msg); 32 | } 33 | } 34 | 35 | /* 36 | Check against kvm blacklisted files 37 | */ 38 | VOID kvm_files() 39 | { 40 | /* Array of strings of blacklisted paths */ 41 | const TCHAR* szPaths[] = { 42 | _T("System32\\drivers\\balloon.sys"), 43 | _T("System32\\drivers\\netkvm.sys"), 44 | _T("System32\\drivers\\pvpanic.sys"), 45 | _T("System32\\drivers\\viofs.sys"), 46 | _T("System32\\drivers\\viogpudo.sys"), 47 | _T("System32\\drivers\\vioinput.sys"), 48 | _T("System32\\drivers\\viorng.sys"), 49 | _T("System32\\drivers\\vioscsi.sys"), 50 | _T("System32\\drivers\\vioser.sys"), 51 | _T("System32\\drivers\\viostor.sys"), 52 | 53 | }; 54 | 55 | /* Getting Windows Directory */ 56 | WORD dwlength = sizeof(szPaths) / sizeof(szPaths[0]); 57 | TCHAR szWinDir[MAX_PATH] = _T(""); 58 | TCHAR szPath[MAX_PATH] = _T(""); 59 | PVOID OldValue = NULL; 60 | 61 | GetWindowsDirectory(szWinDir, MAX_PATH); 62 | 63 | if (IsWoW64()) { 64 | Wow64DisableWow64FsRedirection(&OldValue); 65 | } 66 | 67 | /* Check one by one */ 68 | for (int i = 0; i < dwlength; i++) 69 | { 70 | PathCombine(szPath, szWinDir, szPaths[i]); 71 | TCHAR msg[256] = _T(""); 72 | _stprintf_s(msg, sizeof(msg) / sizeof(TCHAR), _T("Checking file %s "), szPath); 73 | if (is_FileExists(szPath)) 74 | print_results(TRUE, msg); 75 | else 76 | print_results(FALSE, msg); 77 | } 78 | 79 | if (IsWoW64()) { 80 | Wow64RevertWow64FsRedirection(&OldValue); 81 | } 82 | } 83 | 84 | /* 85 | Check against kvm blacklisted directories 86 | */ 87 | BOOL kvm_dir() 88 | { 89 | TCHAR szProgramFile[MAX_PATH]; 90 | TCHAR szPath[MAX_PATH] = _T(""); 91 | TCHAR szTarget[MAX_PATH] = _T("Virtio-Win\\"); 92 | 93 | if (IsWoW64()) 94 | ExpandEnvironmentStrings(_T("%ProgramW6432%"), szProgramFile, ARRAYSIZE(szProgramFile)); 95 | else 96 | SHGetSpecialFolderPath(NULL, szProgramFile, CSIDL_PROGRAM_FILES, FALSE); 97 | 98 | PathCombine(szPath, szProgramFile, szTarget); 99 | return is_DirectoryExists(szPath); 100 | } -------------------------------------------------------------------------------- /al-khaser/AntiVM/KVM.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | VOID kvm_reg_keys(); 4 | VOID kvm_files(); 5 | BOOL kvm_dir(); 6 | -------------------------------------------------------------------------------- /al-khaser/AntiVM/Parallels.cpp: -------------------------------------------------------------------------------- 1 | #include "pch.h" 2 | 3 | #include "Parallels.h" 4 | 5 | /* 6 | Check against Parallels registry keys 7 | */ 8 | VOID parallels_reg_keys() 9 | { 10 | /* Array of strings of blacklisted registry keys */ 11 | const TCHAR* szKeys[] = { 12 | _T("SYSTEM\\CurrentControlSet\\Enum\\PCI\\VEN_1AB8*"), 13 | }; 14 | 15 | WORD dwlength = sizeof(szKeys) / sizeof(szKeys[0]); 16 | 17 | /* Check one by one */ 18 | for (int i = 0; i < dwlength; i++) 19 | { 20 | TCHAR msg[256] = _T(""); 21 | _stprintf_s(msg, sizeof(msg) / sizeof(TCHAR), _T("Checking reg key %s "), szKeys[i]); 22 | 23 | if (Is_RegKeyExists(HKEY_LOCAL_MACHINE, szKeys[i])) 24 | print_results(TRUE, msg); 25 | else 26 | print_results(FALSE, msg); 27 | } 28 | } 29 | 30 | /* 31 | Check for process list 32 | */ 33 | 34 | VOID parallels_process() 35 | { 36 | const TCHAR *szProcesses[] = { 37 | _T("prl_cc.exe"), 38 | _T("prl_tools.exe"), 39 | }; 40 | 41 | WORD iLength = sizeof(szProcesses) / sizeof(szProcesses[0]); 42 | for (int i = 0; i < iLength; i++) 43 | { 44 | TCHAR msg[256] = _T(""); 45 | _stprintf_s(msg, sizeof(msg) / sizeof(TCHAR), _T("Checking Parallels processes: %s"), szProcesses[i]); 46 | if (GetProcessIdFromName(szProcesses[i])) 47 | print_results(TRUE, msg); 48 | else 49 | print_results(FALSE, msg); 50 | } 51 | } 52 | 53 | 54 | /* 55 | Check Parallels NIC MAC address 56 | */ 57 | BOOL parallels_check_mac() 58 | { 59 | // Parallels, Inc. 60 | return check_mac_addr(_T("\x00\x1C\x42")); 61 | } 62 | -------------------------------------------------------------------------------- /al-khaser/AntiVM/Parallels.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | VOID parallels_reg_keys(); 4 | VOID parallels_process(); 5 | BOOL parallels_check_mac(); -------------------------------------------------------------------------------- /al-khaser/AntiVM/Qemu.cpp: -------------------------------------------------------------------------------- 1 | #include "pch.h" 2 | 3 | #include "Qemu.h" 4 | 5 | /* 6 | Registry key values 7 | */ 8 | 9 | VOID qemu_reg_key_value() 10 | { 11 | /* Array of strings of blacklisted registry key values */ 12 | const TCHAR *szEntries[][3] = { 13 | { _T("HARDWARE\\DEVICEMAP\\Scsi\\Scsi Port 0\\Scsi Bus 0\\Target Id 0\\Logical Unit Id 0"), _T("Identifier"), _T("QEMU") }, 14 | { _T("HARDWARE\\Description\\System"), _T("SystemBiosVersion"), _T("QEMU") }, 15 | }; 16 | 17 | WORD dwLength = sizeof(szEntries) / sizeof(szEntries[0]); 18 | 19 | for (int i = 0; i < dwLength; i++) 20 | { 21 | TCHAR msg[256] = _T(""); 22 | _stprintf_s(msg, sizeof(msg) / sizeof(TCHAR), _T("Checking reg key %s "), szEntries[i][0]); 23 | if (Is_RegKeyValueExists(HKEY_LOCAL_MACHINE, szEntries[i][0], szEntries[i][1], szEntries[i][2])) 24 | print_results(TRUE, msg); 25 | else 26 | print_results(FALSE, msg); 27 | } 28 | } 29 | 30 | 31 | /* 32 | Check against QEMU registry keys 33 | */ 34 | VOID qemu_reg_keys() 35 | { 36 | /* Array of strings of blacklisted registry keys */ 37 | const TCHAR* szKeys[] = { 38 | _T("SYSTEM\\CurrentControlSet\\Enum\\PCI\\VEN_1B36*"), 39 | }; 40 | 41 | WORD dwlength = sizeof(szKeys) / sizeof(szKeys[0]); 42 | 43 | /* Check one by one */ 44 | for (int i = 0; i < dwlength; i++) 45 | { 46 | TCHAR msg[256] = _T(""); 47 | _stprintf_s(msg, sizeof(msg) / sizeof(TCHAR), _T("Checking reg key %s "), szKeys[i]); 48 | 49 | if (Is_RegKeyExists(HKEY_LOCAL_MACHINE, szKeys[i])) 50 | print_results(TRUE, msg); 51 | else 52 | print_results(FALSE, msg); 53 | } 54 | } 55 | 56 | /* 57 | Check for process list 58 | */ 59 | 60 | VOID qemu_processes() 61 | { 62 | const TCHAR *szProcesses[] = { 63 | _T("qemu-ga.exe"), // QEMU guest agent. 64 | _T("vdagent.exe"), // SPICE guest tools. 65 | _T("vdservice.exe"), // SPICE guest tools. 66 | }; 67 | 68 | WORD iLength = sizeof(szProcesses) / sizeof(szProcesses[0]); 69 | for (int i = 0; i < iLength; i++) 70 | { 71 | TCHAR msg[256] = _T(""); 72 | _stprintf_s(msg, sizeof(msg) / sizeof(TCHAR), _T("Checking qemu processes %s "), szProcesses[i]); 73 | if (GetProcessIdFromName(szProcesses[i])) 74 | print_results(TRUE, msg); 75 | else 76 | print_results(FALSE, msg); 77 | } 78 | } 79 | 80 | /* 81 | Check against blacklisted directories. 82 | */ 83 | VOID qemu_dir() 84 | { 85 | TCHAR szProgramFile[MAX_PATH]; 86 | TCHAR szPath[MAX_PATH] = _T(""); 87 | 88 | const TCHAR* szDirectories[] = { 89 | _T("qemu-ga"), // QEMU guest agent. 90 | _T("SPICE Guest Tools"), // SPICE guest tools. 91 | }; 92 | 93 | WORD iLength = sizeof(szDirectories) / sizeof(szDirectories[0]); 94 | for (int i = 0; i < iLength; i++) 95 | { 96 | TCHAR msg[256] = _T(""); 97 | 98 | if (IsWoW64()) 99 | ExpandEnvironmentStrings(_T("%ProgramW6432%"), szProgramFile, ARRAYSIZE(szProgramFile)); 100 | else 101 | SHGetSpecialFolderPath(NULL, szProgramFile, CSIDL_PROGRAM_FILES, FALSE); 102 | 103 | PathCombine(szPath, szProgramFile, szDirectories[i]); 104 | 105 | _stprintf_s(msg, sizeof(msg) / sizeof(TCHAR), _T("Checking QEMU directory %s "), szPath); 106 | if (is_DirectoryExists(szPath)) 107 | print_results(TRUE, msg); 108 | else 109 | print_results(FALSE, msg); 110 | } 111 | } 112 | 113 | 114 | /* 115 | Check for SMBIOS firmware 116 | */ 117 | BOOL qemu_firmware_SMBIOS() 118 | { 119 | BOOL result = FALSE; 120 | 121 | DWORD smbiosSize = 0; 122 | PBYTE smbios = get_system_firmware(static_cast('RSMB'), 0x0000, &smbiosSize); 123 | if (smbios != NULL) 124 | { 125 | PBYTE qemuString1 = (PBYTE)"qemu"; 126 | size_t StringLen = 4; 127 | PBYTE qemuString2 = (PBYTE)"QEMU"; 128 | 129 | if (find_str_in_data(qemuString1, StringLen, smbios, smbiosSize) || 130 | find_str_in_data(qemuString2, StringLen, smbios, smbiosSize)) 131 | { 132 | result = TRUE; 133 | } 134 | 135 | free(smbios); 136 | } 137 | 138 | return result; 139 | } 140 | 141 | 142 | /* 143 | Check for ACPI firmware 144 | */ 145 | BOOL qemu_firmware_ACPI() 146 | { 147 | BOOL result = FALSE; 148 | 149 | PDWORD tableNames = static_cast(malloc(4096)); 150 | 151 | if (tableNames) { 152 | SecureZeroMemory(tableNames, 4096); 153 | DWORD tableSize = enum_system_firmware_tables(static_cast('ACPI'), tableNames, 4096); 154 | 155 | // API not available 156 | if (tableSize == -1) 157 | return FALSE; 158 | 159 | DWORD tableCount = tableSize / 4; 160 | if (tableSize < 4 || tableCount == 0) 161 | { 162 | result = TRUE; 163 | } 164 | else 165 | { 166 | const char* strings[] = { 167 | "FWCF", // fw_cfg name 168 | "QEMU0002", // fw_cfg HID/CID 169 | "BOCHS", // OEM ID 170 | "BXPC" // OEM Table ID 171 | }; 172 | 173 | for (DWORD i = 0; i < tableCount; i++) 174 | { 175 | DWORD tableSize = 0; 176 | PBYTE table = get_system_firmware(static_cast('ACPI'), tableNames[i], &tableSize); 177 | 178 | if (table) { 179 | 180 | for (DWORD j = 0; j < sizeof(strings) / sizeof(char*); j++) 181 | { 182 | if (!find_str_in_data((PBYTE)strings[j], strlen(strings[j]), table, tableSize)) 183 | { 184 | free(table); 185 | result = TRUE; 186 | goto out; 187 | } 188 | } 189 | 190 | free(table); 191 | } 192 | } 193 | 194 | DWORD tableSize = 0; 195 | PBYTE table = get_system_firmware(static_cast('ACPI'), static_cast('PCAF'), &tableSize); 196 | 197 | if (table) { 198 | if (tableSize < 45) 199 | { 200 | return FALSE; // Corrupted table 201 | } 202 | 203 | // Format: [HexOffset DecimalOffset ByteLength] FieldName : FieldValue (in hex) 204 | // [02Dh 0045 001h ] PM Profile : 00 [Unspecified] - hardcoded in QEMU src 205 | if ((BYTE) table[45] == (BYTE)0) 206 | { 207 | result = TRUE; 208 | } 209 | 210 | free(table); 211 | } 212 | } 213 | out: 214 | free(tableNames); 215 | } 216 | return result; 217 | } 218 | -------------------------------------------------------------------------------- /al-khaser/AntiVM/Qemu.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | VOID qemu_reg_key_value(); 4 | VOID qemu_reg_keys(); 5 | VOID qemu_processes(); 6 | VOID qemu_dir(); 7 | BOOL qemu_firmware_ACPI(); 8 | BOOL qemu_firmware_SMBIOS(); 9 | -------------------------------------------------------------------------------- /al-khaser/AntiVM/Services.cpp: -------------------------------------------------------------------------------- 1 | #include "pch.h" 2 | 3 | #include "Services.h" 4 | 5 | BOOL VMDriverServices() 6 | { 7 | const int KnownServiceCount = 13; 8 | const TCHAR* KnownVMServices[KnownServiceCount] = { 9 | L"VBoxWddm", 10 | L"VBoxSF", //VirtualBox Shared Folders 11 | L"VBoxMouse", //VirtualBox Guest Mouse 12 | L"VBoxGuest", //VirtualBox Guest Driver 13 | L"vmci", //VMWare VMCI Bus Driver 14 | L"vmhgfs", //VMWare Host Guest Control Redirector 15 | L"vmmouse", 16 | L"vmmemctl", //VMWare Guest Memory Controller Driver 17 | L"vmusb", 18 | L"vmusbmouse", 19 | L"vmx_svga", 20 | L"vmxnet", 21 | L"vmx86" 22 | }; 23 | 24 | SC_HANDLE hSCM = OpenSCManager(NULL, SERVICES_ACTIVE_DATABASE, SC_MANAGER_CONNECT | SC_MANAGER_ENUMERATE_SERVICE); 25 | if (hSCM != NULL) 26 | { 27 | ENUM_SERVICE_STATUS_PROCESS* services = NULL; 28 | DWORD serviceCount = 0; 29 | if (get_services(hSCM, SERVICE_DRIVER, &services, &serviceCount)) 30 | { 31 | bool ok = true; 32 | 33 | for (DWORD i = 0; i < serviceCount; i++) 34 | { 35 | for (int s = 0; s < KnownServiceCount; s++) 36 | { 37 | if (StrCmpIW(services[i].lpServiceName, KnownVMServices[s]) == 0) 38 | { 39 | ok = false; 40 | break; 41 | } 42 | } 43 | } 44 | 45 | free(services); 46 | 47 | if (ok) 48 | { 49 | CloseServiceHandle(hSCM); 50 | return FALSE; 51 | } 52 | 53 | } 54 | else 55 | { 56 | printf("Failed to get services list.\n"); 57 | } 58 | CloseServiceHandle(hSCM); 59 | } 60 | else 61 | { 62 | printf("Failed to get SCM handle.\n"); 63 | } 64 | 65 | return TRUE; 66 | } 67 | 68 | BOOL get_services(_In_ SC_HANDLE hServiceManager, _In_ DWORD serviceType, _Out_ ENUM_SERVICE_STATUS_PROCESS** servicesBuffer, _Out_ DWORD* serviceCount) 69 | { 70 | DWORD serviceBufferSize = 1024 * sizeof(ENUM_SERVICE_STATUS_PROCESS); 71 | ENUM_SERVICE_STATUS_PROCESS* services = static_cast(malloc(serviceBufferSize)); 72 | 73 | if (serviceCount) //assume failure 74 | *serviceCount = 0; 75 | 76 | if (services) { 77 | 78 | SecureZeroMemory(services, serviceBufferSize); 79 | 80 | DWORD remainderBufferSize = 0; 81 | DWORD resumeHandle = 0; 82 | if (EnumServicesStatusEx(hServiceManager, SC_ENUM_PROCESS_INFO, serviceType, SERVICE_STATE_ALL, (LPBYTE)services, serviceBufferSize, &remainderBufferSize, serviceCount, &resumeHandle, NULL) != 0) 83 | { 84 | // success and we enumerated all the services 85 | *servicesBuffer = services; 86 | return TRUE; 87 | } 88 | 89 | DWORD lastError = GetLastError(); 90 | if (lastError == ERROR_MORE_DATA) 91 | { 92 | // we didn't get all the services, so we'll just re-enumerate all to make things easy 93 | serviceBufferSize += remainderBufferSize; 94 | 95 | ENUM_SERVICE_STATUS_PROCESS* tmp; 96 | 97 | tmp = static_cast(realloc(services, serviceBufferSize)); 98 | if (tmp) { 99 | services = tmp; 100 | SecureZeroMemory(services, serviceBufferSize); 101 | if (EnumServicesStatusEx(hServiceManager, SC_ENUM_PROCESS_INFO, serviceType, SERVICE_STATE_ALL, (LPBYTE)services, serviceBufferSize, &remainderBufferSize, serviceCount, NULL, NULL) != 0) 102 | { 103 | *servicesBuffer = services; 104 | return TRUE; 105 | } 106 | } 107 | } 108 | else 109 | { 110 | printf("ERROR: %u\n", lastError); 111 | } 112 | 113 | free(services); 114 | 115 | } 116 | return FALSE; 117 | } 118 | -------------------------------------------------------------------------------- /al-khaser/AntiVM/Services.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | BOOL VMDriverServices(); 4 | BOOL get_services(_In_ SC_HANDLE hServiceManager, _In_ DWORD serviceType, _Out_ ENUM_SERVICE_STATUS_PROCESS** servicesBuffer, _Out_ DWORD* serviceCount); 5 | -------------------------------------------------------------------------------- /al-khaser/AntiVM/VMWare.cpp: -------------------------------------------------------------------------------- 1 | #include "pch.h" 2 | 3 | #include "VMWare.h" 4 | 5 | /* 6 | Check against VMWare registry key values 7 | */ 8 | VOID vmware_reg_key_value() 9 | { 10 | /* Array of strings of blacklisted registry key values */ 11 | const TCHAR *szEntries[][3] = { 12 | { _T("HARDWARE\\DEVICEMAP\\Scsi\\Scsi Port 0\\Scsi Bus 0\\Target Id 0\\Logical Unit Id 0"), _T("Identifier"), _T("VMWARE") }, 13 | { _T("HARDWARE\\DEVICEMAP\\Scsi\\Scsi Port 1\\Scsi Bus 0\\Target Id 0\\Logical Unit Id 0"), _T("Identifier"), _T("VMWARE") }, 14 | { _T("HARDWARE\\DEVICEMAP\\Scsi\\Scsi Port 2\\Scsi Bus 0\\Target Id 0\\Logical Unit Id 0"), _T("Identifier"), _T("VMWARE") }, 15 | { _T("SYSTEM\\ControlSet001\\Control\\SystemInformation"), _T("SystemManufacturer"), _T("VMWARE") }, 16 | { _T("SYSTEM\\ControlSet001\\Control\\SystemInformation"), _T("SystemProductName"), _T("VMWARE") }, 17 | }; 18 | 19 | WORD dwLength = sizeof(szEntries) / sizeof(szEntries[0]); 20 | 21 | for (int i = 0; i < dwLength; i++) 22 | { 23 | TCHAR msg[256] = _T(""); 24 | _stprintf_s(msg, sizeof(msg) / sizeof(TCHAR), _T("Checking reg key %s"), szEntries[i][0]); 25 | if (Is_RegKeyValueExists(HKEY_LOCAL_MACHINE, szEntries[i][0], szEntries[i][1], szEntries[i][2])) 26 | print_results(TRUE, msg); 27 | else 28 | print_results(FALSE, msg); 29 | } 30 | } 31 | 32 | 33 | 34 | /* 35 | Check against VMWare registry keys 36 | */ 37 | VOID vmware_reg_keys() 38 | { 39 | /* Array of strings of blacklisted registry keys */ 40 | const TCHAR* szKeys[] = { 41 | _T("SOFTWARE\\VMware, Inc.\\VMware Tools"), 42 | _T("SYSTEM\\CurrentControlSet\\Enum\\PCI\\VEN_15AD*"), 43 | }; 44 | 45 | WORD dwlength = sizeof(szKeys) / sizeof(szKeys[0]); 46 | 47 | /* Check one by one */ 48 | for (int i = 0; i < dwlength; i++) 49 | { 50 | TCHAR msg[256] = _T(""); 51 | _stprintf_s(msg, sizeof(msg) / sizeof(TCHAR), _T("Checking reg key %s "), szKeys[i]); 52 | if (Is_RegKeyExists(HKEY_LOCAL_MACHINE, szKeys[i])) 53 | print_results(TRUE, msg); 54 | else 55 | print_results(FALSE, msg); 56 | } 57 | } 58 | 59 | 60 | /* 61 | Check against VMWare blacklisted files 62 | */ 63 | VOID vmware_files() 64 | { 65 | /* Array of strings of blacklisted paths */ 66 | const TCHAR* szPaths[] = { 67 | _T("System32\\drivers\\vmnet.sys"), 68 | _T("System32\\drivers\\vmmouse.sys"), 69 | _T("System32\\drivers\\vmusb.sys"), 70 | _T("System32\\drivers\\vm3dmp.sys"), 71 | _T("System32\\drivers\\vmci.sys"), 72 | _T("System32\\drivers\\vmhgfs.sys"), 73 | _T("System32\\drivers\\vmmemctl.sys"), 74 | _T("System32\\drivers\\vmx86.sys"), 75 | _T("System32\\drivers\\vmrawdsk.sys"), 76 | _T("System32\\drivers\\vmusbmouse.sys"), 77 | _T("System32\\drivers\\vmkdb.sys"), 78 | _T("System32\\drivers\\vmnetuserif.sys"), 79 | _T("System32\\drivers\\vmnetadapter.sys"), 80 | }; 81 | 82 | /* Getting Windows Directory */ 83 | WORD dwlength = sizeof(szPaths) / sizeof(szPaths[0]); 84 | TCHAR szWinDir[MAX_PATH] = _T(""); 85 | TCHAR szPath[MAX_PATH] = _T(""); 86 | PVOID OldValue = NULL; 87 | 88 | GetWindowsDirectory(szWinDir, MAX_PATH); 89 | 90 | if (IsWoW64()) { 91 | Wow64DisableWow64FsRedirection(&OldValue); 92 | } 93 | 94 | /* Check one by one */ 95 | for (int i = 0; i < dwlength; i++) 96 | { 97 | PathCombine(szPath, szWinDir, szPaths[i]); 98 | TCHAR msg[256] = _T(""); 99 | _stprintf_s(msg, sizeof(msg) / sizeof(TCHAR), _T("Checking file %s "), szPath); 100 | if (is_FileExists(szPath)) 101 | print_results(TRUE, msg); 102 | else 103 | print_results(FALSE, msg); 104 | } 105 | 106 | if (IsWoW64()) { 107 | Wow64RevertWow64FsRedirection(&OldValue); 108 | } 109 | 110 | } 111 | 112 | /* 113 | Check against VMWare blacklisted directories 114 | */ 115 | BOOL vmware_dir() 116 | { 117 | TCHAR szProgramFile[MAX_PATH]; 118 | TCHAR szPath[MAX_PATH] = _T(""); 119 | TCHAR szTarget[MAX_PATH] = _T("VMWare\\"); 120 | 121 | if (IsWoW64()) 122 | ExpandEnvironmentStrings(_T("%ProgramW6432%"), szProgramFile, ARRAYSIZE(szProgramFile)); 123 | else 124 | SHGetSpecialFolderPath(NULL, szProgramFile, CSIDL_PROGRAM_FILES, FALSE); 125 | 126 | PathCombine(szPath, szProgramFile, szTarget); 127 | return is_DirectoryExists(szPath); 128 | } 129 | 130 | 131 | /* 132 | Check VMWare NIC MAC addresses 133 | */ 134 | VOID vmware_mac() 135 | { 136 | /* VMWre blacklisted mac adr */ 137 | const TCHAR *szMac[][2] = { 138 | { _T("\x00\x05\x69"), _T("00:05:69") }, // VMWare, Inc. 139 | { _T("\x00\x0C\x29"), _T("00:0c:29") }, // VMWare, Inc. 140 | { _T("\x00\x1C\x14"), _T("00:1C:14") }, // VMWare, Inc. 141 | { _T("\x00\x50\x56"), _T("00:50:56") }, // VMWare, Inc. 142 | }; 143 | 144 | WORD dwLength = sizeof(szMac) / sizeof(szMac[0]); 145 | 146 | /* Check one by one */ 147 | for (int i = 0; i < dwLength; i++) 148 | { 149 | TCHAR msg[256] = _T(""); 150 | _stprintf_s(msg, sizeof(msg) / sizeof(TCHAR), _T("Checking MAC starting with %s"), szMac[i][1]); 151 | if (check_mac_addr(szMac[i][0])) 152 | print_results(TRUE, msg); 153 | else 154 | print_results(FALSE, msg); 155 | } 156 | } 157 | 158 | 159 | /* 160 | Check against VMWare adapter name 161 | */ 162 | BOOL vmware_adapter_name() 163 | { 164 | const TCHAR* szAdapterName = _T("VMWare"); 165 | if (check_adapter_name(szAdapterName)) 166 | return TRUE; 167 | else 168 | return FALSE; 169 | } 170 | 171 | 172 | /* 173 | Check against VMWare pseaudo-devices 174 | */ 175 | VOID vmware_devices() 176 | { 177 | const TCHAR *devices[] = { 178 | _T("\\\\.\\HGFS"), 179 | _T("\\\\.\\vmci"), 180 | }; 181 | 182 | WORD iLength = sizeof(devices) / sizeof(devices[0]); 183 | for (int i = 0; i < iLength; i++) 184 | { 185 | HANDLE hFile = CreateFile(devices[i], GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); 186 | TCHAR msg[256] = _T(""); 187 | _stprintf_s(msg, sizeof(msg) / sizeof(TCHAR), _T("Checking device %s "), devices[i]); 188 | 189 | if (hFile != INVALID_HANDLE_VALUE) { 190 | CloseHandle(hFile); 191 | print_results(TRUE, msg); 192 | } 193 | else 194 | print_results(FALSE, msg); 195 | } 196 | } 197 | 198 | 199 | /* 200 | Check for process list 201 | */ 202 | 203 | VOID vmware_processes() 204 | { 205 | const TCHAR *szProcesses[] = { 206 | _T("vmtoolsd.exe"), 207 | _T("vmwaretray.exe"), 208 | _T("vmwareuser.exe"), 209 | _T("VGAuthService.exe"), 210 | _T("vmacthlp.exe"), 211 | }; 212 | 213 | WORD iLength = sizeof(szProcesses) / sizeof(szProcesses[0]); 214 | for (int i = 0; i < iLength; i++) 215 | { 216 | TCHAR msg[256] = _T(""); 217 | _stprintf_s(msg, sizeof(msg) / sizeof(TCHAR), _T("Checking VWware process %s "), szProcesses[i]); 218 | if (GetProcessIdFromName(szProcesses[i])) 219 | print_results(TRUE, msg); 220 | else 221 | print_results(FALSE, msg); 222 | } 223 | } 224 | 225 | /* 226 | Check for SMBIOS firmware 227 | */ 228 | BOOL vmware_firmware_SMBIOS() 229 | { 230 | BOOL result = FALSE; 231 | const DWORD Signature = static_cast('RSMB'); 232 | 233 | DWORD smbiosSize = 0; 234 | PBYTE smbios = get_system_firmware(static_cast('RSMB'), 0x0000, &smbiosSize); 235 | if (smbios != NULL) 236 | { 237 | PBYTE vmwareString = (PBYTE)"VMware"; 238 | size_t vmwwareStringLen = 6; 239 | 240 | if (find_str_in_data(vmwareString, vmwwareStringLen, smbios, smbiosSize)) 241 | { 242 | result = TRUE; 243 | } 244 | 245 | free(smbios); 246 | } 247 | 248 | return result; 249 | } 250 | 251 | /* 252 | Check for ACPI firmware 253 | */ 254 | BOOL vmware_firmware_ACPI() 255 | { 256 | BOOL result = FALSE; 257 | 258 | PDWORD tableNames = static_cast(malloc(4096)); 259 | 260 | if (tableNames == NULL) 261 | return FALSE; 262 | 263 | SecureZeroMemory(tableNames, 4096); 264 | DWORD tableSize = enum_system_firmware_tables(static_cast('ACPI'), tableNames, 4096); 265 | 266 | // API not available 267 | if (tableSize == -1) 268 | return FALSE; 269 | 270 | DWORD tableCount = tableSize / 4; 271 | if (tableSize < 4 || tableCount == 0) 272 | { 273 | result = TRUE; 274 | } 275 | else 276 | { 277 | for (DWORD i = 0; i < tableCount; i++) { 278 | DWORD tableSize = 0; 279 | PBYTE table = get_system_firmware(static_cast('ACPI'), tableNames[i], &tableSize); 280 | 281 | if (table) { 282 | 283 | PBYTE vmwareString = (PBYTE)"VMWARE"; 284 | size_t vmwwareStringLen = 6; 285 | 286 | if (find_str_in_data(vmwareString, vmwwareStringLen, table, tableSize)) { 287 | result = TRUE; 288 | } 289 | 290 | free(table); 291 | } 292 | } 293 | } 294 | 295 | free(tableNames); 296 | return result; 297 | } 298 | 299 | -------------------------------------------------------------------------------- /al-khaser/AntiVM/VMWare.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | VOID vmware_reg_key_value(); 4 | VOID vmware_reg_keys(); 5 | VOID vmware_files(); 6 | BOOL vmware_dir(); 7 | VOID vmware_mac(); 8 | BOOL vmware_adapter_name(); 9 | VOID vmware_devices(); 10 | VOID vmware_processes(); 11 | BOOL vmware_firmware_SMBIOS(); 12 | BOOL vmware_firmware_ACPI(); -------------------------------------------------------------------------------- /al-khaser/AntiVM/VirtualBox.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | VOID vbox_reg_key_value(); 4 | VOID vbox_reg_keys(); 5 | VOID vbox_files(); 6 | BOOL vbox_dir(); 7 | 8 | BOOL vbox_check_mac(); 9 | VOID vbox_devices(); 10 | BOOL vbox_window_class(); 11 | BOOL vbox_network_share(); 12 | VOID vbox_processes(); 13 | BOOL vbox_mac_wmi(); 14 | BOOL vbox_eventlogfile_wmi(); 15 | BOOL vbox_firmware_SMBIOS(); 16 | BOOL vbox_firmware_ACPI(); 17 | BOOL vbox_bus_wmi(); 18 | BOOL vbox_baseboard_wmi(); 19 | BOOL vbox_pnpentity_pcideviceid_wmi(); 20 | BOOL vbox_pnpentity_controllers_wmi(); 21 | BOOL vbox_pnpentity_vboxname_wmi(); 22 | -------------------------------------------------------------------------------- /al-khaser/AntiVM/VirtualPC.cpp: -------------------------------------------------------------------------------- 1 | #include "pch.h" 2 | 3 | #include "VirtualPC.h" 4 | 5 | /* 6 | Check for process list 7 | */ 8 | 9 | VOID virtual_pc_process() 10 | { 11 | const TCHAR *szProcesses[] = { 12 | _T("VMSrvc.exe"), 13 | _T("VMUSrvc.exe"), 14 | }; 15 | 16 | WORD iLength = sizeof(szProcesses) / sizeof(szProcesses[0]); 17 | for (int i = 0; i < iLength; i++) 18 | { 19 | TCHAR msg[256] = _T(""); 20 | _stprintf_s(msg, sizeof(msg) / sizeof(TCHAR), _T("Checking Virtual PC processes %s "), szProcesses[i]); 21 | if (GetProcessIdFromName(szProcesses[i])) 22 | print_results(TRUE, msg); 23 | else 24 | print_results(FALSE, msg); 25 | } 26 | } 27 | 28 | 29 | 30 | VOID virtual_pc_reg_keys() 31 | { 32 | /* Array of strings of blacklisted registry keys */ 33 | const TCHAR* szKeys[] = { 34 | _T("SOFTWARE\\Microsoft\\Virtual Machine\\Guest\\Parameters"), 35 | _T("SYSTEM\\CurrentControlSet\\Enum\\PCI\\VEN_5333*"), 36 | }; 37 | 38 | WORD dwlength = sizeof(szKeys) / sizeof(szKeys[0]); 39 | 40 | /* Check one by one */ 41 | for (int i = 0; i < dwlength; i++) 42 | { 43 | TCHAR msg[256] = _T(""); 44 | _stprintf_s(msg, sizeof(msg) / sizeof(TCHAR), _T("Checking reg key %s "), szKeys[i]); 45 | if (Is_RegKeyExists(HKEY_LOCAL_MACHINE, szKeys[i])) 46 | print_results(TRUE, msg); 47 | else 48 | print_results(FALSE, msg); 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /al-khaser/AntiVM/VirtualPC.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | 4 | VOID virtual_pc_process(); 5 | VOID virtual_pc_reg_keys(); 6 | -------------------------------------------------------------------------------- /al-khaser/AntiVM/Wine.cpp: -------------------------------------------------------------------------------- 1 | #include "pch.h" 2 | 3 | #include "Wine.h" 4 | 5 | /* 6 | Check against Wine export dlls 7 | */ 8 | BOOL wine_exports() 9 | { 10 | /* Some vars */ 11 | HMODULE hKernel32; 12 | 13 | /* Get kernel32 module handle */ 14 | hKernel32 = GetModuleHandle(_T("kernel32.dll")); 15 | if (hKernel32 == NULL) { 16 | print_last_error(_T("GetModuleHandle")); 17 | return FALSE; 18 | } 19 | 20 | /* Check if wine_get_unix_file_name is exported by this dll */ 21 | if (GetProcAddress(hKernel32, "wine_get_unix_file_name") == NULL) 22 | return FALSE; 23 | else 24 | return TRUE; 25 | } 26 | 27 | /* 28 | Check against Wine registry keys 29 | */ 30 | VOID wine_reg_keys() 31 | { 32 | /* Array of strings of blacklisted registry keys */ 33 | const TCHAR* szKeys[] = { 34 | _T("SOFTWARE\\Wine") 35 | }; 36 | 37 | WORD dwlength = sizeof(szKeys) / sizeof(szKeys[0]); 38 | 39 | /* Check one by one */ 40 | for (int i = 0; i < dwlength; i++) 41 | { 42 | TCHAR msg[256] = _T(""); 43 | _stprintf_s(msg, sizeof(msg) / sizeof(TCHAR), _T("Checking reg key %s "), szKeys[i]); 44 | if (Is_RegKeyExists(HKEY_CURRENT_USER, szKeys[i])) 45 | print_results(TRUE, msg); 46 | else 47 | print_results(FALSE, msg); 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /al-khaser/AntiVM/Wine.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | BOOL wine_exports(); 4 | VOID wine_reg_keys(); -------------------------------------------------------------------------------- /al-khaser/AntiVM/Xen.cpp: -------------------------------------------------------------------------------- 1 | #include "pch.h" 2 | 3 | #include "Xen.h" 4 | 5 | /* 6 | Check against Xen registry keys 7 | */ 8 | VOID xen_reg_keys() 9 | { 10 | /* Array of strings of blacklisted registry keys */ 11 | const TCHAR* szKeys[] = { 12 | _T("SYSTEM\\CurrentControlSet\\Enum\\PCI\\VEN_5853*"), 13 | }; 14 | 15 | WORD dwlength = sizeof(szKeys) / sizeof(szKeys[0]); 16 | 17 | /* Check one by one */ 18 | for (int i = 0; i < dwlength; i++) 19 | { 20 | TCHAR msg[256] = _T(""); 21 | _stprintf_s(msg, sizeof(msg) / sizeof(TCHAR), _T("Checking reg key %s "), szKeys[i]); 22 | if (Is_RegKeyExists(HKEY_LOCAL_MACHINE, szKeys[i])) 23 | print_results(TRUE, msg); 24 | else 25 | print_results(FALSE, msg); 26 | } 27 | } 28 | 29 | /* 30 | Check for process list 31 | */ 32 | 33 | VOID xen_process() 34 | { 35 | const TCHAR *szProcesses[] = { 36 | _T("xenservice.exe"), 37 | }; 38 | 39 | WORD iLength = sizeof(szProcesses) / sizeof(szProcesses[0]); 40 | for (int i = 0; i < iLength; i++) 41 | { 42 | TCHAR msg[256] = _T(""); 43 | _stprintf_s(msg, sizeof(msg) / sizeof(TCHAR), _T("Checking Citrix Xen process %s"), szProcesses[i]); 44 | if (GetProcessIdFromName(szProcesses[i])) 45 | print_results(TRUE, msg); 46 | else 47 | print_results(FALSE, msg); 48 | } 49 | } 50 | 51 | 52 | 53 | /* 54 | Check Xen NIC MAC address 55 | */ 56 | BOOL xen_check_mac() 57 | { 58 | // Xensource, Inc. 59 | return check_mac_addr(_T("\x00\x16\x3E")); 60 | } 61 | -------------------------------------------------------------------------------- /al-khaser/AntiVM/Xen.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | VOID xen_reg_keys(); 4 | VOID xen_process(); 5 | BOOL xen_check_mac(); -------------------------------------------------------------------------------- /al-khaser/AntiVM/pch.h: -------------------------------------------------------------------------------- 1 | #include "../pch.h" -------------------------------------------------------------------------------- /al-khaser/CodeInjection/CreateRemoteThread.cpp: -------------------------------------------------------------------------------- 1 | #include "pch.h" 2 | 3 | #include "CreateRemoteThread.h" 4 | 5 | BOOL CreateRemoteThread_Injection() 6 | { 7 | /* Some vars */ 8 | DWORD dwProcessId; 9 | HANDLE hProcess = NULL, hRemoteThread = NULL; 10 | HMODULE hKernel32; 11 | FARPROC LoadLibraryAddress; 12 | LPVOID lpBaseAddress = NULL; 13 | TCHAR lpDllName[] = _T("InjectedDLL.dll"); 14 | TCHAR lpDllPath[MAX_PATH]; 15 | SIZE_T dwSize; 16 | BOOL bStatus = FALSE, bDebugPrivilegeEnabled; 17 | 18 | /* Get Process ID from Process name */ 19 | dwProcessId = GetProcessIdFromName(_T("notepad.exe")); 20 | if (dwProcessId == NULL) 21 | return FALSE; 22 | _tprintf(_T("\t[+] Getting proc id: %u\n"), dwProcessId); 23 | 24 | /* Set Debug privilege */ 25 | bDebugPrivilegeEnabled = SetDebugPrivileges(); 26 | _tprintf(_T("\t[+] Setting Debug Privileges [%d]\n"), bDebugPrivilegeEnabled); 27 | if (!bDebugPrivilegeEnabled) 28 | return FALSE; 29 | 30 | /* Obtain a handle the process */ 31 | hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, dwProcessId); 32 | if (hProcess == NULL) { 33 | print_last_error(_T("OpenProcess")); 34 | goto Cleanup; 35 | } 36 | 37 | /* Obtain a handle to kernel32 */ 38 | hKernel32 = GetModuleHandle(_T("kernel32.dll")); 39 | if (hKernel32 == NULL) { 40 | print_last_error(_T("GetModuleHandle")); 41 | goto Cleanup; 42 | } 43 | 44 | /* Get LoadLibrary address */ 45 | _tprintf(_T("\t[+] Looking for LoadLibrary in kernel32\n")); 46 | LoadLibraryAddress = GetProcAddress(hKernel32, "LoadLibraryW"); 47 | if (LoadLibraryAddress == NULL) { 48 | print_last_error(_T("GetProcAddress")); 49 | goto Cleanup; 50 | } 51 | _tprintf(_T("\t[+] Found at 0x%p\n"), LoadLibraryAddress); 52 | 53 | /* Get the full path of the dll */ 54 | GetFullPathName(lpDllName, MAX_PATH, lpDllPath, NULL); 55 | _tprintf(_T("\t[+] Full DLL Path: %s\n"), lpDllPath); 56 | 57 | /* Calculate the number of bytes needed for the DLL's pathname */ 58 | dwSize = _tcslen(lpDllPath) * sizeof(TCHAR); 59 | 60 | /* Allocate memory into the remote process */ 61 | _tprintf(_T("\t[+] Allocating space for the path of the DLL\n")); 62 | lpBaseAddress = VirtualAllocEx(hProcess, NULL, dwSize, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE); 63 | if (lpBaseAddress == NULL) { 64 | print_last_error(_T("VirtualAllocEx")); 65 | goto Cleanup; 66 | } 67 | 68 | /* Write to the remote process */ 69 | printf("\t[+] Writing into the current process space at 0x%p\n", lpBaseAddress); 70 | if (!WriteProcessMemory(hProcess, lpBaseAddress, lpDllPath, dwSize, NULL)) { 71 | print_last_error(_T("WriteProcessMemory")); 72 | goto Cleanup; 73 | } 74 | 75 | /* Create the more thread */ 76 | hRemoteThread = CreateRemoteThread(hProcess, NULL, 0, (LPTHREAD_START_ROUTINE)LoadLibraryAddress, lpBaseAddress, NULL, 0); 77 | if (hRemoteThread == NULL) { 78 | print_last_error(_T("CreateRemoteThread")); 79 | } 80 | else { 81 | _tprintf(_T("Remote thread has been created successfully ...\n")); 82 | WaitForSingleObject(hRemoteThread, INFINITE); 83 | CloseHandle(hRemoteThread); 84 | 85 | /* assign function success return result */ 86 | bStatus = TRUE; 87 | } 88 | 89 | Cleanup: 90 | /* If lpBaseAddress initialized then hProcess is initialized too because of upper check. */ 91 | if (lpBaseAddress) { 92 | VirtualFreeEx(hProcess, lpBaseAddress, 0, MEM_RELEASE); 93 | } 94 | if (hProcess) CloseHandle(hProcess); 95 | 96 | return bStatus; 97 | } 98 | -------------------------------------------------------------------------------- /al-khaser/CodeInjection/CreateRemoteThread.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | BOOL CreateRemoteThread_Injection(); -------------------------------------------------------------------------------- /al-khaser/CodeInjection/GetSetThreadContext.cpp: -------------------------------------------------------------------------------- 1 | #include "pch.h" 2 | 3 | #include "GetSetThreadContext.h" 4 | 5 | BOOL GetSetThreadContext_Injection() 6 | { 7 | #ifdef _WIN64 8 | return TRUE; //TODO implement this on x64 9 | #else 10 | TCHAR lpApplicationName[] = _T("C:\\Windows\\System32\\svchost.exe"); 11 | TCHAR lpApplicationName2[] = _T("C:\\masm32\\examples\\dialogs_later\\basic\\basicdlg.exe"); 12 | BOOL bResult = FALSE; 13 | 14 | STARTUPINFO StartupInfo; 15 | PROCESS_INFORMATION ProcessInfo; 16 | 17 | PCONTEXT pContext = NULL; 18 | HANDLE hFile = INVALID_HANDLE_VALUE; 19 | 20 | SecureZeroMemory(&StartupInfo, sizeof(STARTUPINFO)); 21 | SecureZeroMemory(&ProcessInfo, sizeof(PPROCESS_INFORMATION)); 22 | 23 | do { /* not a loop */ 24 | 25 | // Create the hollowed process in suspended mode 26 | if (!CreateProcess(lpApplicationName, NULL, NULL, NULL, FALSE, CREATE_SUSPENDED, NULL, NULL, &StartupInfo, &ProcessInfo)) { 27 | print_last_error(_T("CreateProcess")); 28 | break; 29 | } 30 | 31 | // Allocate space for context structure 32 | LPVOID pTargetImageBase = NULL; 33 | 34 | pContext = PCONTEXT(VirtualAlloc(NULL, sizeof(CONTEXT), MEM_COMMIT, PAGE_READWRITE)); 35 | if (pContext == NULL) { 36 | print_last_error(_T("VirtualAlloc")); 37 | break; 38 | } 39 | 40 | // Get the thread context of target 41 | pContext->ContextFlags = CONTEXT_FULL; 42 | if (!GetThreadContext(ProcessInfo.hThread, pContext)) { 43 | print_last_error(_T("GetThreadContext")); 44 | break; 45 | } 46 | 47 | // Read the image base address of target 48 | ReadProcessMemory(ProcessInfo.hProcess, LPCVOID(pContext->Ebx + 8), pTargetImageBase, 4, NULL); 49 | 50 | // Opening source image 51 | hFile = CreateFile(lpApplicationName2, GENERIC_READ, NULL, NULL, OPEN_ALWAYS, NULL, NULL); 52 | if (hFile == INVALID_HANDLE_VALUE) 53 | { 54 | print_last_error(_T("CreateFile")); 55 | break; 56 | } 57 | 58 | // Reading the file 59 | DWORD dwSize = GetFileSize(hFile, 0); 60 | DWORD dwBytesRead; 61 | PBYTE pBuffer = static_cast(MALLOC(dwSize)); 62 | 63 | if (pBuffer == NULL) { 64 | print_last_error(_T("HeapAlloc")); 65 | break; 66 | } 67 | else { 68 | 69 | SecureZeroMemory(pBuffer, dwSize); 70 | 71 | ReadFile(hFile, pBuffer, dwSize, &dwBytesRead, 0); 72 | PIMAGE_SECTION_HEADER pImageSectionHeader; 73 | 74 | PIMAGE_DOS_HEADER pDosHeader = (PIMAGE_DOS_HEADER)pBuffer; 75 | if (pDosHeader->e_magic == IMAGE_DOS_SIGNATURE) 76 | { 77 | PIMAGE_NT_HEADERS32 pNTHeaders = PIMAGE_NT_HEADERS(DWORD(pBuffer) + pDosHeader->e_lfanew); 78 | if (pNTHeaders->Signature == IMAGE_NT_SIGNATURE) 79 | { 80 | 81 | if (DWORD(pTargetImageBase) == pNTHeaders->OptionalHeader.ImageBase) 82 | { 83 | pNtUnmapViewOfSection NtUnmapViewOfSection; 84 | NtUnmapViewOfSection = (pNtUnmapViewOfSection)(GetProcAddress(GetModuleHandleA("ntdll.dll"), "NtUnmapViewOfSection")); 85 | NtUnmapViewOfSection(ProcessInfo.hProcess, pTargetImageBase); 86 | } 87 | 88 | LPVOID pImageBase; 89 | 90 | pImageBase = VirtualAllocEx(ProcessInfo.hProcess, LPVOID(pNTHeaders->OptionalHeader.ImageBase), 91 | pNTHeaders->OptionalHeader.SizeOfImage, 92 | MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE); 93 | 94 | if (pImageBase == NULL) { 95 | print_last_error(_T("VirtualAllocEx")); 96 | break; 97 | } 98 | else { 99 | 100 | WriteProcessMemory(ProcessInfo.hProcess, pImageBase, pBuffer, pNTHeaders->OptionalHeader.SizeOfHeaders, NULL); 101 | for (int Count = 0; Count < pNTHeaders->FileHeader.NumberOfSections; Count++) 102 | { 103 | pImageSectionHeader = PIMAGE_SECTION_HEADER(DWORD(pBuffer) + pDosHeader->e_lfanew + 248 + (Count * 40)); 104 | WriteProcessMemory(ProcessInfo.hProcess, LPVOID(DWORD(pImageBase) + pImageSectionHeader->VirtualAddress), 105 | LPVOID(DWORD(pBuffer) + pImageSectionHeader->PointerToRawData), pImageSectionHeader->SizeOfRawData, NULL); 106 | } 107 | WriteProcessMemory(ProcessInfo.hProcess, LPVOID(pContext->Ebx + 8), LPVOID(&pNTHeaders->OptionalHeader.ImageBase), 4, NULL); 108 | pContext->Eax = DWORD(pImageBase) + pNTHeaders->OptionalHeader.AddressOfEntryPoint; 109 | SetThreadContext(ProcessInfo.hThread, LPCONTEXT(pContext)); 110 | 111 | LONG dwRet; 112 | 113 | dwRet = ResumeThread(ProcessInfo.hThread); 114 | bResult = (dwRet != -1); 115 | } 116 | } 117 | } 118 | 119 | FREE(pBuffer); 120 | } 121 | 122 | } while (FALSE); /* not a loop */ 123 | 124 | /* Cleanup */ 125 | if (ProcessInfo.hThread) CloseHandle(ProcessInfo.hThread); 126 | if (ProcessInfo.hProcess) CloseHandle(ProcessInfo.hProcess); 127 | if (pContext) VirtualFree(pContext, 0, MEM_RELEASE); 128 | if (hFile != INVALID_HANDLE_VALUE) CloseHandle(hFile); 129 | 130 | return bResult; 131 | #endif 132 | } 133 | -------------------------------------------------------------------------------- /al-khaser/CodeInjection/GetSetThreadContext.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | BOOL GetSetThreadContext_Injection(); 4 | -------------------------------------------------------------------------------- /al-khaser/CodeInjection/InjectedDLL/InjectedDLL.cpp: -------------------------------------------------------------------------------- 1 | #include "stdafx.h" 2 | #include "InjectedDLL.h" 3 | 4 | LRESULT CALLBACK MyProc(INT code, WPARAM wParam, LPARAM lParam); 5 | 6 | LRESULT CALLBACK MyProc(INT code, WPARAM wParam, LPARAM lParam) 7 | { 8 | //here goes our code 9 | TCHAR str[MAX_PATH] = _T(""); 10 | _stprintf(str, _T("[Al-khaser] - Injected from process: %d"), GetCurrentProcessId()); 11 | OutputDebugString(str); 12 | return CallNextHookEx(NULL, code, wParam, lParam); //this is needed to let other applications set other hooks on this target 13 | } 14 | 15 | 16 | BOOL APIENTRY DllMain(HMODULE hModule, DWORD dwReason, LPVOID lpReserved) 17 | { 18 | switch (dwReason) 19 | { 20 | case DLL_PROCESS_ATTACH: 21 | OutputDebugString(_T("[Al-khaser] - DLL is attached")); 22 | break; 23 | 24 | case DLL_PROCESS_DETACH: 25 | OutputDebugString(_T("[Al-khaser] - DLL is detached")); 26 | break; 27 | 28 | case DLL_THREAD_ATTACH: 29 | OutputDebugString(_T("[Al-khaser] - Thread is atached")); 30 | break; 31 | 32 | case DLL_THREAD_DETACH: 33 | OutputDebugString(_T("[Al-khaser] - Thread is detached")); 34 | break; 35 | } 36 | 37 | /* Returns TRUE on success, FALSE on failure */ 38 | return TRUE; 39 | } 40 | -------------------------------------------------------------------------------- /al-khaser/CodeInjection/InjectedDLL/InjectedDLL.h: -------------------------------------------------------------------------------- 1 | #include 2 | #include -------------------------------------------------------------------------------- /al-khaser/CodeInjection/InjectedDLL/InjectedDLL.vcxproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Debug 6 | Win32 7 | 8 | 9 | Release 10 | Win32 11 | 12 | 13 | Debug 14 | x64 15 | 16 | 17 | Release 18 | x64 19 | 20 | 21 | 22 | {BFB018FC-33D1-4351-B6EA-1CA77336A0E4} 23 | Win32Proj 24 | InjectedDLL 25 | 8.1 26 | 27 | 28 | 29 | DynamicLibrary 30 | true 31 | v140_xp 32 | Unicode 33 | 34 | 35 | DynamicLibrary 36 | false 37 | v140_xp 38 | true 39 | Unicode 40 | 41 | 42 | DynamicLibrary 43 | true 44 | v140 45 | Unicode 46 | 47 | 48 | DynamicLibrary 49 | false 50 | v140 51 | true 52 | Unicode 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | true 74 | 75 | 76 | true 77 | 78 | 79 | false 80 | 81 | 82 | false 83 | 84 | 85 | 86 | 87 | 88 | Level3 89 | Disabled 90 | WIN32;_DEBUG;_WINDOWS;_USRDLL;INJECTEDDLL_EXPORTS;%(PreprocessorDefinitions) 91 | MultiThreaded 92 | false 93 | 94 | 95 | Windows 96 | true 97 | definitions.def 98 | 99 | 100 | 101 | 102 | 103 | 104 | Level3 105 | Disabled 106 | _DEBUG;_WINDOWS;_USRDLL;INJECTEDDLL_EXPORTS;%(PreprocessorDefinitions) 107 | 108 | 109 | Windows 110 | true 111 | definitions.def 112 | 113 | 114 | 115 | 116 | Level3 117 | 118 | 119 | MaxSpeed 120 | true 121 | true 122 | WIN32;NDEBUG;_WINDOWS;_USRDLL;INJECTEDDLL_EXPORTS;%(PreprocessorDefinitions) 123 | MultiThreaded 124 | 125 | 126 | Windows 127 | true 128 | true 129 | true 130 | definitions.def 131 | 132 | 133 | 134 | 135 | Level3 136 | 137 | 138 | MaxSpeed 139 | true 140 | true 141 | NDEBUG;_WINDOWS;_USRDLL;INJECTEDDLL_EXPORTS;%(PreprocessorDefinitions) 142 | 143 | 144 | Windows 145 | true 146 | true 147 | true 148 | definitions.def 149 | 150 | 151 | 152 | 153 | 154 | 155 | 156 | 157 | 158 | 159 | 160 | 161 | 162 | 163 | -------------------------------------------------------------------------------- /al-khaser/CodeInjection/InjectedDLL/InjectedDLL.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 | 28 | 29 | Source Files 30 | 31 | 32 | -------------------------------------------------------------------------------- /al-khaser/CodeInjection/InjectedDLL/definitions.def: -------------------------------------------------------------------------------- 1 | LIBRARY 2 | EXPORTS 3 | MyProc -------------------------------------------------------------------------------- /al-khaser/CodeInjection/NtCreateThreadEx.cpp: -------------------------------------------------------------------------------- 1 | #include "pch.h" 2 | 3 | #include "NtCreateThreadEx.h" 4 | 5 | BOOL NtCreateThreadEx_Injection() 6 | { 7 | // some vars 8 | HMODULE hNtdll; 9 | DWORD dwProcessId; 10 | HANDLE hProcess = NULL; 11 | TCHAR lpDllName[] = _T("InjectedDLL.dll"); 12 | TCHAR lpDllPath[MAX_PATH]; 13 | LPVOID lpBaseAddress = NULL; 14 | BOOL bStatus = FALSE; 15 | HMODULE hKernel32; 16 | FARPROC LoadLibraryAddress; 17 | HANDLE hRemoteThread = NULL; 18 | NTSTATUS Status; 19 | SIZE_T dwSize; 20 | CLIENT_ID ClientId; 21 | PS_ATTRIBUTE_LIST PsAttrList; 22 | 23 | // we have to import our function 24 | pNtCreateThreadEx NtCreateThreadEx = NULL; 25 | 26 | /* 27 | GetLastError cannot be used with NtCreateThreadEx because this service does not set Win32 LastError value. 28 | Native status code must be translated to Win32 error code and set manually. 29 | */ 30 | pRtlNtStatusToDosError RtlNtStatusToDosErrorPtr = NULL; 31 | 32 | /* Get Process ID from Process name */ 33 | dwProcessId = GetProcessIdFromName(_T("notepad.exe")); 34 | if (dwProcessId == 0) 35 | return FALSE; 36 | _tprintf(_T("\t[+] Getting proc id: %u\n"), dwProcessId); 37 | 38 | /* Obtain a handle the process */ 39 | hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, dwProcessId); 40 | if (hProcess == NULL) { 41 | print_last_error(_T("OpenProcess")); 42 | goto Cleanup; 43 | } 44 | 45 | /* Get module handle of ntdll */ 46 | hNtdll = GetModuleHandle(_T("ntdll.dll")); 47 | if (hNtdll == NULL) { 48 | print_last_error(_T("GetModuleHandle")); 49 | goto Cleanup; 50 | } 51 | 52 | /* Obtain a handle to kernel32 */ 53 | hKernel32 = GetModuleHandle(_T("kernel32.dll")); 54 | if (hKernel32 == NULL) { 55 | print_last_error(_T("GetModuleHandle")); 56 | goto Cleanup; 57 | } 58 | 59 | /* Get routine pointer, failure is not critical */ 60 | RtlNtStatusToDosErrorPtr = (pRtlNtStatusToDosError)GetProcAddress(hNtdll, "RtlNtStatusToDosError"); 61 | 62 | // Get the address NtCreateThreadEx 63 | _tprintf(_T("\t[+] Looking for NtCreateThreadEx in ntdll\n")); 64 | NtCreateThreadEx = (pNtCreateThreadEx)GetProcAddress(hNtdll, "NtCreateThreadEx"); 65 | if (NtCreateThreadEx == NULL) { 66 | print_last_error(_T("GetProcAddress")); 67 | goto Cleanup; 68 | } 69 | _tprintf(_T("\t[+] Found at 0x%p\n"), NtCreateThreadEx); 70 | 71 | /* Get LoadLibrary address */ 72 | _tprintf(_T("\t[+] Looking for LoadLibrary in kernel32\n")); 73 | LoadLibraryAddress = GetProcAddress(hKernel32, "LoadLibraryW"); 74 | if (LoadLibraryAddress == NULL) { 75 | print_last_error(_T("GetProcAddress")); 76 | goto Cleanup; 77 | } 78 | _tprintf(_T("\t[+] Found at 0x%p\n"), LoadLibraryAddress); 79 | 80 | /* Get the full path of the dll */ 81 | GetFullPathName(lpDllName, MAX_PATH, lpDllPath, NULL); 82 | _tprintf(_T("\t[+] Full DLL Path: %s\n"), lpDllPath); 83 | 84 | /* Calculate the number of bytes needed for the DLL's pathname */ 85 | dwSize = _tcslen(lpDllPath) * sizeof(TCHAR); 86 | 87 | /* Allocate memory into the remote process */ 88 | _tprintf(_T("\t[+] Allocating space for the path of the DLL\n")); 89 | lpBaseAddress = VirtualAllocEx(hProcess, NULL, dwSize, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE); 90 | if (lpBaseAddress == NULL) { 91 | print_last_error(_T("VirtualAllocEx")); 92 | goto Cleanup; 93 | } 94 | 95 | /* Write to the remote process */ 96 | printf("\t[+] Writing into the current process space at 0x%p\n", lpBaseAddress); 97 | if (!WriteProcessMemory(hProcess, lpBaseAddress, lpDllPath, dwSize, NULL)) { 98 | print_last_error(_T("WriteProcessMemory")); 99 | goto Cleanup; 100 | } 101 | 102 | /* Create the more thread */ 103 | SecureZeroMemory(&PsAttrList, sizeof(PsAttrList)); 104 | 105 | /* Setup attributes entry */ 106 | PsAttrList.TotalLength = sizeof(PS_ATTRIBUTE_LIST); 107 | PsAttrList.Attributes[0].Attribute = PS_ATTRIBUTE_CLIENT_ID; 108 | PsAttrList.Attributes[0].Size = sizeof(CLIENT_ID); 109 | PsAttrList.Attributes[0].u1.ValuePtr = &ClientId; 110 | 111 | Status = NtCreateThreadEx(&hRemoteThread, THREAD_ALL_ACCESS, NULL, hProcess, 112 | (LPTHREAD_START_ROUTINE)LoadLibraryAddress, lpBaseAddress, 0, 0, 0, 0, &PsAttrList); 113 | 114 | if (!NT_SUCCESS(Status)) { 115 | if (RtlNtStatusToDosErrorPtr) { 116 | SetLastError(RtlNtStatusToDosErrorPtr(Status)); 117 | } 118 | else { 119 | SetLastError(ERROR_INTERNAL_ERROR); 120 | } 121 | print_last_error(_T("NtCreateThreadEx")); 122 | } 123 | 124 | else { 125 | _tprintf(_T("Remote thread has been created successfully ...\n")); 126 | WaitForSingleObject(hRemoteThread, INFINITE); 127 | CloseHandle(hRemoteThread); 128 | 129 | /* assign function success return result */ 130 | bStatus = TRUE; 131 | } 132 | 133 | Cleanup: 134 | /* If lpBaseAddress initialized then hProcess is initialized too because of upper check. */ 135 | if (lpBaseAddress) { 136 | VirtualFreeEx(hProcess, lpBaseAddress, 0, MEM_RELEASE); 137 | } 138 | if (hProcess) CloseHandle(hProcess); 139 | 140 | return bStatus; 141 | } 142 | -------------------------------------------------------------------------------- /al-khaser/CodeInjection/NtCreateThreadEx.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | BOOL NtCreateThreadEx_Injection(); 4 | -------------------------------------------------------------------------------- /al-khaser/CodeInjection/QueueUserAPC.cpp: -------------------------------------------------------------------------------- 1 | #include "pch.h" 2 | 3 | #include "QueueUserAPC.h" 4 | 5 | // 6 | // Check whatever InjectedDLL.dll was loaded, because this dll 7 | // does not provide any other way of caller notification. 8 | // 9 | BOOL IsDllInjected(DWORD dwProcessId, LPTSTR DllName) 10 | { 11 | BOOL bFound = FALSE; 12 | HANDLE hSnapshot; 13 | 14 | hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, dwProcessId); 15 | if (hSnapshot != INVALID_HANDLE_VALUE) { 16 | 17 | MODULEENTRY32 me32; 18 | me32.dwSize = sizeof(MODULEENTRY32); 19 | 20 | if (Module32First(hSnapshot, &me32)) { 21 | 22 | do { 23 | 24 | if (StrCmpI(me32.szModule, DllName) == 0) { 25 | bFound = TRUE; 26 | break; 27 | } 28 | 29 | } while (Module32Next(hSnapshot, &me32)); 30 | 31 | } 32 | 33 | CloseHandle(hSnapshot); 34 | } 35 | 36 | return bFound; 37 | } 38 | 39 | BOOL QueueUserAPC_Injection() 40 | { 41 | TCHAR lpDllName[] = _T("InjectedDLL.dll"); 42 | TCHAR lpDllPath[MAX_PATH]; 43 | 44 | HANDLE hThreadSnapshot = INVALID_HANDLE_VALUE; 45 | 46 | DWORD dwTargetProcessId, dwCurrentProcessId = GetCurrentProcessId(); 47 | 48 | HANDLE hProcess = NULL; 49 | HANDLE hThread = NULL; 50 | 51 | HMODULE hKernel32; 52 | 53 | FARPROC LoadLibraryAddress; 54 | LPVOID lpBaseAddress = NULL; 55 | BOOL bStatus = FALSE; 56 | 57 | 58 | /* Get Process ID from Process name */ 59 | 60 | // 61 | // calc used because it has multiple threads and some of them maybe alertable. 62 | // 63 | dwTargetProcessId = GetProcessIdFromName(_T("calc.exe")); 64 | if (dwTargetProcessId == 0) 65 | dwTargetProcessId = GetProcessIdFromName(_T("win32calc.exe"));//w10 classic calc 66 | 67 | if (dwTargetProcessId == 0) { 68 | print_last_error(_T("GetProcessIdFromName")); 69 | return FALSE; 70 | } 71 | 72 | /* Obtain a hmodule of kernel32 */ 73 | hKernel32 = GetModuleHandle(_T("kernel32.dll")); 74 | if (hKernel32 == NULL) { 75 | print_last_error(_T("GetModuleHandle")); 76 | return FALSE; 77 | } 78 | 79 | /* Get LoadLibrary address */ 80 | _tprintf(_T("\t[+] Looking for LoadLibrary in kernel32\n")); 81 | LoadLibraryAddress = GetProcAddress(hKernel32, "LoadLibraryW"); 82 | if (LoadLibraryAddress == NULL) { 83 | print_last_error(_T("GetProcAddress")); 84 | return FALSE; 85 | } 86 | _tprintf(_T("\t[+] Found at 0x%p\n"), LoadLibraryAddress); 87 | 88 | _tprintf(_T("\t[+] Getting proc id: %u\n"), dwTargetProcessId); 89 | 90 | /* Obtain a handle the process */ 91 | hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, dwTargetProcessId); 92 | if (hProcess == NULL) { 93 | print_last_error(_T("OpenProcess")); 94 | return FALSE; 95 | } 96 | 97 | do { // not a loop 98 | 99 | /* Get the full path of the dll */ 100 | GetFullPathName(lpDllName, MAX_PATH, lpDllPath, NULL); 101 | _tprintf(_T("\t[+] Full DLL Path: %s\n"), lpDllPath); 102 | 103 | // The maximum size of the string buffer. 104 | SIZE_T WriteBufferSize = _tcslen(lpDllPath) * sizeof(TCHAR); 105 | 106 | /* Allocate memory into the remote process */ 107 | _tprintf(_T("\t[+] Allocating space for the path of the DLL\n")); 108 | lpBaseAddress = VirtualAllocEx(hProcess, NULL, WriteBufferSize, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE); 109 | if (lpBaseAddress == NULL) { 110 | print_last_error(_T("VirtualAllocEx")); 111 | break; 112 | } 113 | 114 | /* Write to the remote process */ 115 | printf("\t[+] Writing into the current process space at 0x%p\n", lpBaseAddress); 116 | if (!WriteProcessMemory(hProcess, lpBaseAddress, lpDllPath, WriteBufferSize, NULL)) { 117 | print_last_error(_T("WriteProcessMemory")); 118 | break; 119 | } 120 | 121 | hThreadSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPTHREAD, 0); 122 | if (hThreadSnapshot == INVALID_HANDLE_VALUE) 123 | break; 124 | 125 | THREADENTRY32 te32; 126 | te32.dwSize = sizeof(THREADENTRY32); 127 | 128 | // 129 | // Brute force threads to find suitable alertable thread for APC injection (if any). 130 | // 131 | if (Thread32First(hThreadSnapshot, &te32)) { 132 | do { 133 | if (te32.th32OwnerProcessID == dwTargetProcessId) { 134 | 135 | hThread = OpenThread(THREAD_ALL_ACCESS, FALSE, te32.th32ThreadID); 136 | if (hThread) { 137 | 138 | if (QueueUserAPC((PAPCFUNC)LoadLibraryAddress, hThread, (ULONG_PTR)lpBaseAddress)) { 139 | 140 | if (IsDllInjected(dwTargetProcessId, lpDllName)) { 141 | bStatus = TRUE; 142 | } 143 | } 144 | CloseHandle(hThread); 145 | } 146 | } 147 | 148 | // dll injected - leave 149 | if (bStatus) { 150 | _tprintf(_T("\t[+] Dll has been injected successfully ...\n")); 151 | break; 152 | } 153 | 154 | } while (Thread32Next(hThreadSnapshot, &te32)); 155 | } 156 | 157 | } while (FALSE); // not a loop 158 | 159 | // 160 | // Cleanup. 161 | // 162 | if (hThreadSnapshot != INVALID_HANDLE_VALUE) CloseHandle(hThreadSnapshot); 163 | 164 | if (lpBaseAddress) { 165 | VirtualFreeEx(hProcess, lpBaseAddress, 0, MEM_RELEASE); 166 | } 167 | 168 | CloseHandle(hProcess); 169 | 170 | return bStatus; 171 | } 172 | -------------------------------------------------------------------------------- /al-khaser/CodeInjection/QueueUserAPC.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | BOOL QueueUserAPC_Injection(); 4 | 5 | -------------------------------------------------------------------------------- /al-khaser/CodeInjection/RtlCreateUserThread.cpp: -------------------------------------------------------------------------------- 1 | #include "pch.h" 2 | 3 | #include "RtlCreateUserThread.h" 4 | 5 | BOOL RtlCreateUserThread_Injection() 6 | { 7 | // some vars 8 | HMODULE hNtdll; 9 | DWORD dwProcessId; 10 | HANDLE hProcess; 11 | TCHAR lpDllName[] = _T("InjectedDLL.dll"); 12 | TCHAR lpDllPath[MAX_PATH]; 13 | LPVOID lpBaseAddress = NULL; 14 | BOOL bStatus = FALSE; 15 | HMODULE hKernel32; 16 | FARPROC LoadLibraryAddress; 17 | HANDLE hRemoteThread = NULL; 18 | SIZE_T dwSize; 19 | NTSTATUS Status; 20 | 21 | // we have to import our function 22 | pRtlCreateUserThread RtlCreateUserThread = NULL; 23 | 24 | /* 25 | GetLastError cannot be used with RtlCreateUserThread because this routine does not set Win32 LastError value. 26 | Native status code must be translated to Win32 error code and set manually. 27 | */ 28 | pRtlNtStatusToDosError RtlNtStatusToDosErrorPtr = NULL; 29 | 30 | /* Get Process ID from Process name */ 31 | dwProcessId = GetProcessIdFromName(_T("notepad.exe")); 32 | if (dwProcessId == NULL) 33 | return FALSE; 34 | _tprintf(_T("\t[+] Getting proc id: %u\n"), dwProcessId); 35 | 36 | /* Obtain a handle the process */ 37 | hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, dwProcessId); 38 | if (hProcess == NULL) { 39 | print_last_error(_T("OpenProcess")); 40 | return FALSE; 41 | } 42 | 43 | /* Get module handle of ntdll */ 44 | hNtdll = GetModuleHandle(_T("ntdll.dll")); 45 | if (hNtdll == NULL) { 46 | print_last_error(_T("GetModuleHandle")); 47 | goto Cleanup; 48 | } 49 | 50 | /* Get routine pointer, failure is not critical */ 51 | RtlNtStatusToDosErrorPtr = (pRtlNtStatusToDosError)GetProcAddress(hNtdll, "RtlNtStatusToDosError"); 52 | 53 | /* Obtain a handle to kernel32 */ 54 | hKernel32 = GetModuleHandle(_T("kernel32.dll")); 55 | if (hKernel32 == NULL) { 56 | print_last_error(_T("GetModuleHandle")); 57 | goto Cleanup; 58 | } 59 | 60 | // Get the address RtlCreateUserThread 61 | _tprintf(_T("\t[+] Looking for RtlCreateUserThread in ntdll\n")); 62 | RtlCreateUserThread = (pRtlCreateUserThread)GetProcAddress(hNtdll, "RtlCreateUserThread"); 63 | if (RtlCreateUserThread == NULL) { 64 | print_last_error(_T("GetProcAddress")); 65 | goto Cleanup; 66 | } 67 | _tprintf(_T("\t[+] Found at 0x%p\n"), RtlCreateUserThread); 68 | 69 | /* Get LoadLibrary address */ 70 | _tprintf(_T("\t[+] Looking for LoadLibrary in kernel32\n")); 71 | LoadLibraryAddress = GetProcAddress(hKernel32, "LoadLibraryW"); 72 | if (LoadLibraryAddress == NULL) { 73 | print_last_error(_T("GetProcAddress")); 74 | goto Cleanup; 75 | } 76 | _tprintf(_T("\t[+] Found at 0x%p\n"), LoadLibraryAddress); 77 | 78 | /* Get the full path of the dll */ 79 | GetFullPathName(lpDllName, MAX_PATH, lpDllPath, NULL); 80 | _tprintf(_T("\t[+] Full DLL Path: %s\n"), lpDllPath); 81 | 82 | /* Calculate the number of bytes needed for the DLL's pathname */ 83 | dwSize = _tcslen(lpDllPath) * sizeof(TCHAR); 84 | 85 | /* Allocate memory into the remote process */ 86 | _tprintf(_T("\t[+] Allocating space for the path of the DLL\n")); 87 | lpBaseAddress = VirtualAllocEx(hProcess, NULL, dwSize, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE); 88 | if (lpBaseAddress == NULL) { 89 | print_last_error(_T("VirtualAllocEx")); 90 | goto Cleanup; 91 | } 92 | 93 | /* Write to the remote process */ 94 | printf("\t[+] Writing into the current process space at 0x%p\n", lpBaseAddress); 95 | if (!WriteProcessMemory(hProcess, lpBaseAddress, lpDllPath, dwSize, NULL)) { 96 | print_last_error(_T("WriteProcessMemory")); 97 | goto Cleanup; 98 | } 99 | 100 | /* Create the more thread */ 101 | Status = RtlCreateUserThread(hProcess, NULL, 0, 0, 0, 0, LoadLibraryAddress, lpBaseAddress, &hRemoteThread, NULL); 102 | if (!NT_SUCCESS(Status)) { 103 | if (RtlNtStatusToDosErrorPtr) { 104 | SetLastError(RtlNtStatusToDosErrorPtr(Status)); 105 | } 106 | else { 107 | SetLastError(ERROR_INTERNAL_ERROR); 108 | } 109 | print_last_error(_T("RtlCreateUserThread")); 110 | } 111 | else { 112 | _tprintf(_T("Remote thread has been created successfully ...\n")); 113 | WaitForSingleObject(hRemoteThread, INFINITE); 114 | CloseHandle(hRemoteThread); 115 | 116 | /* assign function success return result */ 117 | bStatus = TRUE; 118 | } 119 | Cleanup: 120 | /* hProcess is always initialized here. */ 121 | if (lpBaseAddress) { 122 | VirtualFreeEx(hProcess, lpBaseAddress, 0, MEM_RELEASE); 123 | } 124 | CloseHandle(hProcess); 125 | 126 | return bStatus; 127 | } 128 | -------------------------------------------------------------------------------- /al-khaser/CodeInjection/RtlCreateUserThread.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | BOOL RtlCreateUserThread_Injection(); 4 | -------------------------------------------------------------------------------- /al-khaser/CodeInjection/SetWindowsHooksEx.cpp: -------------------------------------------------------------------------------- 1 | #include "pch.h" 2 | 3 | #include "SetWindowsHooksEx.h" 4 | 5 | BOOL SetWindowsHooksEx_Injection() 6 | { 7 | TCHAR lpDllName[] = _T("InjectedDLL.dll"); 8 | TCHAR lpDllPath[MAX_PATH]; 9 | HOOKPROC myFunctionAddress; 10 | HMODULE hOurDll; 11 | DWORD dwProcessId, dwThreadId; 12 | HHOOK hHook; 13 | 14 | /* Get Process ID from Process name */ 15 | dwProcessId = GetProcessIdFromName(_T("notepad.exe")); 16 | if (dwProcessId == NULL) 17 | return FALSE; 18 | _tprintf(_T("\t[+] Getting proc id: %u\n"), dwProcessId); 19 | 20 | /* Get thread id from process id */ 21 | dwThreadId = GetMainThreadId(dwProcessId); 22 | if (dwThreadId == NULL) 23 | return FALSE; 24 | _tprintf(_T("\t[+] Getting main thread id of proc id: %u\n"), dwThreadId); 25 | 26 | /* Get the full path of the dll to be injected */ 27 | GetFullPathName(lpDllName, MAX_PATH, lpDllPath, NULL); 28 | _tprintf(_T("\t[+] Full DLL Path: %s\n"), lpDllPath); 29 | 30 | /* Obtain a handle to our injected dll */ 31 | hOurDll = LoadLibrary(lpDllPath); 32 | if (hOurDll == NULL) { 33 | print_last_error(_T("LoadLibrary")); 34 | return FALSE; 35 | } 36 | 37 | /* Get 'MyProc' address */ 38 | _tprintf(_T("\t[+] Looking for 'MyProc' in our dll\n")); 39 | myFunctionAddress = (HOOKPROC)GetProcAddress(hOurDll, "MyProc"); 40 | if (myFunctionAddress == NULL) { 41 | print_last_error(_T("GetProcAddress")); 42 | return FALSE; 43 | } 44 | _tprintf(_T("\t[+] Found at 0x%p\n"), myFunctionAddress); 45 | 46 | /* Injection happens here */ 47 | hHook = SetWindowsHookEx(WH_KEYBOARD, myFunctionAddress, hOurDll, dwThreadId); 48 | if (hHook == NULL) { 49 | print_last_error(_T("SetWindowsHookEx")); 50 | return FALSE; 51 | } 52 | 53 | /* Unhook */ 54 | _tprintf(_T("SetWindowsHookEx created successfully ...\n")); 55 | 56 | /* When we want to remove the hook */ 57 | // UnhookWindowsHookEx(hHook); 58 | 59 | return TRUE; 60 | 61 | } 62 | -------------------------------------------------------------------------------- /al-khaser/CodeInjection/SetWindowsHooksEx.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | BOOL SetWindowsHooksEx_Injection(); -------------------------------------------------------------------------------- /al-khaser/CodeInjection/pch.h: -------------------------------------------------------------------------------- 1 | #include "../pch.h" -------------------------------------------------------------------------------- /al-khaser/OfficeMacro/al-khaser.docm: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ayoubfaouzi/al-khaser/c0602534742d4eb02d02482b9dabffa02d250d28/al-khaser/OfficeMacro/al-khaser.docm -------------------------------------------------------------------------------- /al-khaser/OfficeMacro/macros.vba: -------------------------------------------------------------------------------- 1 | Sub Document_Close() 2 | 3 | On Error Resume Next 4 | 5 | ActiveDocument.Range.Text = "Al-khaser 0.69 by Lord Noteworthy" & vbCrLf & vbCrLf & "Public malware techniques used in the wild: Virtual Machine, Emulation, Debuggers, Sandbox detection." & vbCrLf 6 | 7 | checkFileMRU 8 | End Sub 9 | 10 | 11 | Public Sub checkFileMRU() 12 | 13 | printMsg "[*] Checking Application.RecentFiles.Count ..." 14 | 15 | ActiveDocument.Range.Text = ActiveDocument.Range.Text & msg 16 | If Application.RecentFiles.Count < 3 Then 17 | printMsg "BAD" 18 | Else 19 | printMsg "GOOD" 20 | End If 21 | 22 | End Sub 23 | 24 | 25 | Public Function printMsg(msg) 26 | 27 | ActiveDocument.Range.Text = ActiveDocument.Range.Text & msg 28 | 29 | End Function -------------------------------------------------------------------------------- /al-khaser/Shared/APIs.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | enum API_IDENTIFIER 4 | { 5 | API_CsrGetProcessId, 6 | API_EnumSystemFirmwareTables, 7 | API_GetActiveProcessorCount, 8 | API_GetSystemFirmwareTable, 9 | API_GetNativeSystemInfo, 10 | API_GetProductInfo, 11 | API_EnumProcessModulesEx_Kernel, 12 | API_EnumProcessModulesEx_PSAPI, 13 | API_IsWow64Process, 14 | API_LdrEnumerateLoadedModules, 15 | API_NtClose, 16 | API_NtSystemDebugControl, 17 | API_NtCreateDebugObject, 18 | API_NtDelayExecution, 19 | API_NtOpenDirectoryObject, 20 | API_NtQueryInformationThread, 21 | API_NtQueryInformationProcess, 22 | API_NtQueryLicenseValue, 23 | API_NtQueryDirectoryObject, 24 | API_NtQueryObject, 25 | API_NtQuerySystemInformation, 26 | API_NtSetInformationThread, 27 | API_NtWow64QueryInformationProcess64, 28 | API_NtWow64QueryVirtualMemory64, 29 | API_NtWow64ReadVirtualMemory64, 30 | API_NtYieldExecution, 31 | API_RtlGetVersion, 32 | API_RtlInitUnicodeString, 33 | API_WudfIsAnyDebuggerPresent, 34 | API_WudfIsKernelDebuggerPresent, 35 | API_WudfIsUserDebuggerPresent, 36 | }; 37 | 38 | enum API_OS_VERSION 39 | { 40 | NONE, 41 | WIN_XP, 42 | WIN_XP_SP1, 43 | WIN_XP_SP2, 44 | WIN_XP_SP3, 45 | WIN_VISTA, 46 | WIN_VISTA_SP1, 47 | WIN_VISTA_SP2, 48 | WIN_7, 49 | WIN_7_SP1, 50 | WIN_80, 51 | WIN_81, 52 | WIN_10, 53 | VERSION_MAX 54 | }; 55 | 56 | enum API_OS_BITS 57 | { 58 | ANY, 59 | X86_ONLY, 60 | X64_ONLY, 61 | }; 62 | 63 | struct VERSION_FUNCTION_MAP 64 | { 65 | API_OS_VERSION Version; 66 | bool(*Function)(); 67 | 68 | VERSION_FUNCTION_MAP(API_OS_VERSION version, bool(*function)()) 69 | { 70 | Version = version; 71 | Function = function; 72 | } 73 | 74 | VERSION_FUNCTION_MAP() 75 | { 76 | } 77 | }; 78 | 79 | struct API_DATA 80 | { 81 | API_IDENTIFIER Identifier; 82 | const char* Library; 83 | const char* EntryName; 84 | API_OS_BITS PlatformBits; 85 | API_OS_VERSION MinVersion; 86 | API_OS_VERSION RemovedInVersion; 87 | bool Available; 88 | bool ExpectedAvailable; 89 | void* Pointer; 90 | 91 | API_DATA(API_IDENTIFIER identifier, const char* lib, const char* name, API_OS_BITS bits, API_OS_VERSION minVersion, API_OS_VERSION removedInVersion) 92 | { 93 | Identifier = identifier; 94 | Library = lib; 95 | EntryName = name; 96 | PlatformBits = bits; 97 | MinVersion = minVersion; 98 | RemovedInVersion = removedInVersion; 99 | Available = false; 100 | ExpectedAvailable = false; 101 | Pointer = nullptr; 102 | } 103 | }; 104 | 105 | const VERSION_FUNCTION_MAP VersionFunctionMap[] = { 106 | { API_OS_VERSION::NONE, nullptr }, 107 | { API_OS_VERSION::WIN_XP, IsWindowsXPOrGreater }, 108 | { API_OS_VERSION::WIN_XP_SP1, IsWindowsXPSP1OrGreater }, 109 | { API_OS_VERSION::WIN_XP_SP2, IsWindowsXPSP2OrGreater }, 110 | { API_OS_VERSION::WIN_XP_SP3, IsWindowsXPSP3OrGreater }, 111 | { API_OS_VERSION::WIN_VISTA, IsWindowsVistaOrGreater }, 112 | { API_OS_VERSION::WIN_VISTA_SP1, IsWindowsVistaSP1OrGreater }, 113 | { API_OS_VERSION::WIN_VISTA_SP2, IsWindowsVistaSP2OrGreater }, 114 | { API_OS_VERSION::WIN_7, IsWindows7OrGreater }, 115 | { API_OS_VERSION::WIN_7_SP1, IsWindows7SP1OrGreater }, 116 | { API_OS_VERSION::WIN_80, IsWindows8OrGreater }, 117 | { API_OS_VERSION::WIN_81, IsWindows8Point1OrGreater }, 118 | { API_OS_VERSION::WIN_10, IsWindows10OrGreater }, 119 | }; 120 | 121 | class API 122 | { 123 | private: 124 | static bool ShouldFunctionExistOnCurrentPlatform(API_OS_BITS bits, API_OS_VERSION minVersion, API_OS_VERSION removedInVersion); 125 | public: 126 | static void Init(); 127 | static void PrintAvailabilityReport(); 128 | static bool IsAvailable(API_IDENTIFIER api); 129 | static void* GetAPI(API_IDENTIFIER api); 130 | }; -------------------------------------------------------------------------------- /al-khaser/Shared/ApiTypeDefs.cpp: -------------------------------------------------------------------------------- 1 | #include "pch.h" 2 | -------------------------------------------------------------------------------- /al-khaser/Shared/ApiTypeDefs.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | typedef DWORD(NTAPI* pCsrGetId)(VOID); 4 | typedef BOOL(WINAPI* pEnumProcessModulesEx)( 5 | HANDLE hProcess, 6 | HMODULE *lphModule, 7 | DWORD cb, 8 | LPDWORD lpcbNeeded, 9 | DWORD dwFilterFlag); 10 | typedef UINT(WINAPI* pEnumSystemFirmwareTables)(DWORD, PVOID, DWORD); 11 | typedef DWORD(WINAPI* pGetActiveProcessorCount)(WORD); 12 | typedef UINT(WINAPI* pGetSystemFirmwareTable)(DWORD, DWORD, PVOID, DWORD); 13 | typedef void (WINAPI *pGetNativeSystemInfo)(LPSYSTEM_INFO); 14 | typedef BOOL(WINAPI *pGetProductInfo)(DWORD, DWORD, DWORD, DWORD, PDWORD); 15 | typedef BOOL(WINAPI *pIsWow64Process) (HANDLE, PBOOL); 16 | typedef DWORD(WINAPI * pRtlCreateUserThread)( 17 | IN HANDLE ProcessHandle, 18 | IN PSECURITY_DESCRIPTOR SecurityDescriptor, 19 | IN BOOL CreateSuspended, 20 | IN ULONG StackZeroBits, 21 | IN OUT PULONG StackReserved, 22 | IN OUT PULONG StackCommit, 23 | IN LPVOID StartAddress, 24 | IN LPVOID StartParameter, 25 | OUT HANDLE ThreadHandle, 26 | OUT LPVOID ClientID 27 | ); 28 | typedef NTSTATUS(WINAPI* pNtClose)(HANDLE); 29 | typedef enum _SYSDBG_COMMAND { 30 | SysDbgQueryModuleInformation, 31 | SysDbgQueryTraceInformation, 32 | SysDbgSetTracepoint, 33 | SysDbgSetSpecialCall, 34 | SysDbgClearSpecialCalls, 35 | SysDbgQuerySpecialCalls, 36 | SysDbgBreakPoint, 37 | SysDbgQueryVersion, 38 | SysDbgReadVirtual, 39 | SysDbgWriteVirtual, 40 | SysDbgReadPhysical, 41 | SysDbgWritePhysical, 42 | SysDbgReadControlSpace, 43 | SysDbgWriteControlSpace, 44 | SysDbgReadIoSpace, 45 | SysDbgWriteIoSpace, 46 | SysDbgReadMsr, 47 | SysDbgWriteMsr, 48 | SysDbgReadBusData, 49 | SysDbgWriteBusData, 50 | SysDbgCheckLowMemory, 51 | SysDbgEnableKernelDebugger, 52 | SysDbgDisableKernelDebugger, 53 | SysDbgGetAutoKdEnable, 54 | SysDbgSetAutoKdEnable, 55 | SysDbgGetPrintBufferSize, 56 | SysDbgSetPrintBufferSize, 57 | SysDbgGetKdUmExceptionEnable, 58 | SysDbgSetKdUmExceptionEnable, 59 | SysDbgGetTriageDump, 60 | SysDbgGetKdBlockEnable, 61 | SysDbgSetKdBlockEnable, 62 | } SYSDBG_COMMAND, * PSYSDBG_COMMAND; 63 | typedef NTSTATUS(NTAPI* pNtSystemDebugControl)( 64 | IN SYSDBG_COMMAND Command, 65 | IN PVOID InputBuffer, 66 | IN ULONG InputBufferLength, 67 | OUT PVOID OutputBuffer, 68 | IN ULONG OutputBufferLength, 69 | OUT PULONG ReturnLength); 70 | typedef NTSTATUS(WINAPI *pNtCreateDebugObject)(OUT PHANDLE, IN ACCESS_MASK, IN POBJECT_ATTRIBUTES, IN ULONG); 71 | typedef NTSTATUS(WINAPI *pNtCreateThreadEx)( 72 | OUT PHANDLE ThreadHandle, 73 | IN ACCESS_MASK DesiredAccess, 74 | IN OPTIONAL POBJECT_ATTRIBUTES ObjectAttributes, 75 | IN HANDLE ProcessHandle, 76 | IN PVOID StartRoutine, 77 | IN OPTIONAL PVOID Argument, 78 | IN ULONG CreateFlags, //THREAD_CREATE_FLAGS_* 79 | IN OPTIONAL ULONG_PTR ZeroBits, 80 | IN OPTIONAL SIZE_T StackSize, 81 | IN OPTIONAL SIZE_T MaximumStackSize, 82 | IN OPTIONAL PPS_ATTRIBUTE_LIST AttributeList 83 | ); 84 | typedef NTSTATUS(WINAPI *pNtDelayExecution)(IN BOOLEAN, IN PLARGE_INTEGER); 85 | typedef NTSTATUS(WINAPI *pNtQueryInformationProcess)(IN HANDLE, IN UINT, OUT PVOID, IN ULONG, OUT PULONG); 86 | typedef NTSTATUS(WINAPI *pNtQueryInformationThread)(HANDLE, UINT, PVOID, ULONG, PULONG); 87 | 88 | typedef NTSTATUS(NTAPI *pNtQueryLicenseValue)( 89 | IN PUNICODE_STRING ValueName, 90 | OUT OPTIONAL PULONG Type, 91 | OUT PVOID Data, 92 | IN ULONG DataSize, 93 | OUT PULONG ResultDataSize); 94 | 95 | typedef VOID (NTAPI *pRtlInitUnicodeString)( 96 | _Out_ PUNICODE_STRING DestinationString, 97 | _In_opt_ PCWSTR SourceString); 98 | 99 | 100 | typedef NTSTATUS(WINAPI *pNtQueryDirectoryObject)(_In_ HANDLE, _Out_opt_ PVOID, _In_ ULONG, _In_ BOOLEAN, _In_ BOOLEAN, _Inout_ PULONG, _Out_opt_ PULONG); 101 | typedef NTSTATUS(WINAPI *pNtOpenDirectoryObject)(OUT PHANDLE, IN ACCESS_MASK, IN POBJECT_ATTRIBUTES); 102 | 103 | typedef NTSTATUS(WINAPI *pNtQueryObject)(IN HANDLE, IN UINT, OUT PVOID, IN ULONG, OUT PULONG); 104 | typedef NTSTATUS(WINAPI *pNtQuerySystemInformation)(IN UINT, OUT PVOID, IN ULONG, OUT PULONG); 105 | typedef NTSTATUS(WINAPI *pNtSetInformationThread)(HANDLE, UINT, PVOID, ULONG); 106 | typedef NTSTATUS(WINAPI* pNtUnmapViewOfSection)(HANDLE ProcessHandle, PVOID BaseAddress); 107 | typedef NTSTATUS(WINAPI* pNtYieldExecution)(); 108 | typedef NTSTATUS(WINAPI* pRtlGetVersion)(RTL_OSVERSIONINFOEXW*); 109 | typedef ULONG (NTAPI* pRtlNtStatusToDosError)(IN NTSTATUS Status); 110 | typedef NTSTATUS(NTAPI * pNtWow64QueryInformationProcess64)( 111 | IN HANDLE ProcessHandle, 112 | ULONG ProcessInformationClass, 113 | OUT PVOID ProcessInformation, 114 | IN ULONG ProcessInformationLength, 115 | OUT PULONG ReturnLength OPTIONAL); 116 | typedef NTSTATUS(WINAPI *pNtWow64ReadVirtualMemory64)( 117 | HANDLE ProcessHandle, 118 | PVOID64 BaseAddress, 119 | PVOID Buffer, 120 | ULONGLONG BufferSize, 121 | PULONGLONG NumberOfBytesRead 122 | ); 123 | typedef NTSTATUS(NTAPI *pNtWow64QueryVirtualMemory64)( 124 | IN HANDLE ProcessHandle, 125 | IN PVOID64 BaseAddress, 126 | IN DWORD MemoryInformationClass, 127 | OUT PMEMORY_BASIC_INFORMATION64 MemoryInformation, 128 | IN ULONG64 Size, 129 | OUT PULONG64 ReturnLength OPTIONAL); 130 | typedef NTSTATUS(NTAPI *pLdrEnumerateLoadedModules)( 131 | IN BOOLEAN ReservedFlag, 132 | IN PLDR_ENUM_CALLBACK EnumProc, 133 | IN PVOID Context); 134 | typedef INT(NTAPI *pWudfIsAnyDebuggerPresent)(); 135 | typedef INT(NTAPI *pWudfIsKernelDebuggerPresent)(); 136 | typedef INT(NTAPI *pWudfIsUserDebuggerPresent)(); 137 | -------------------------------------------------------------------------------- /al-khaser/Shared/Common.cpp: -------------------------------------------------------------------------------- 1 | #include "pch.h" 2 | #include "Common.h" 3 | 4 | VOID print_detected() 5 | { 6 | /* Get handle to standard output */ 7 | HANDLE nStdHandle = GetStdHandle(STD_OUTPUT_HANDLE); 8 | CONSOLE_SCREEN_BUFFER_INFO ConsoleScreenBufferInfo; 9 | SecureZeroMemory(&ConsoleScreenBufferInfo, sizeof(CONSOLE_SCREEN_BUFFER_INFO)); 10 | 11 | /* Save the original console color */ 12 | GetConsoleScreenBufferInfo(nStdHandle, &ConsoleScreenBufferInfo); 13 | WORD OriginalColors = *(&ConsoleScreenBufferInfo.wAttributes); 14 | 15 | SetConsoleTextAttribute(nStdHandle, 12); 16 | _tprintf(TEXT("[ BAD ]\n")); 17 | SetConsoleTextAttribute(nStdHandle, OriginalColors); 18 | } 19 | 20 | VOID print_not_detected() 21 | { 22 | /* Get handle to standard output */ 23 | HANDLE nStdHandle = GetStdHandle(STD_OUTPUT_HANDLE); 24 | CONSOLE_SCREEN_BUFFER_INFO ConsoleScreenBufferInfo; 25 | SecureZeroMemory(&ConsoleScreenBufferInfo, sizeof(CONSOLE_SCREEN_BUFFER_INFO)); 26 | 27 | /* Save the original console color */ 28 | GetConsoleScreenBufferInfo(nStdHandle, &ConsoleScreenBufferInfo); 29 | WORD OriginalColors = *(&ConsoleScreenBufferInfo.wAttributes); 30 | 31 | SetConsoleTextAttribute(nStdHandle, 10); 32 | _tprintf(TEXT("[ GOOD ]\n")); 33 | SetConsoleTextAttribute(nStdHandle, OriginalColors); 34 | } 35 | 36 | VOID print_category(const TCHAR* text) 37 | { 38 | /* Get handle to standard output */ 39 | HANDLE nStdHandle = GetStdHandle(STD_OUTPUT_HANDLE); 40 | CONSOLE_SCREEN_BUFFER_INFO ConsoleScreenBufferInfo; 41 | SecureZeroMemory(&ConsoleScreenBufferInfo, sizeof(CONSOLE_SCREEN_BUFFER_INFO)); 42 | 43 | /* Save the original console color */ 44 | GetConsoleScreenBufferInfo(nStdHandle, &ConsoleScreenBufferInfo); 45 | WORD OriginalColors = *(&ConsoleScreenBufferInfo.wAttributes); 46 | 47 | SetConsoleTextAttribute(nStdHandle, 13); 48 | _tprintf(TEXT("\n-------------------------[%s]-------------------------\n"), text); 49 | SetConsoleTextAttribute(nStdHandle, OriginalColors); 50 | } 51 | 52 | VOID _print_check_text(const TCHAR* szMsg) 53 | { 54 | _tprintf(TEXT("[*] %s"), szMsg); 55 | 56 | /* align the result according to the length of the text */ 57 | size_t spaces_to_padd = 95 - _tcslen(szMsg); 58 | while (spaces_to_padd > 0) { 59 | _tprintf(TEXT(" ")); 60 | spaces_to_padd--; 61 | } 62 | } 63 | 64 | VOID _print_check_result(int result, const TCHAR* szMsg) 65 | { 66 | if (result == TRUE) 67 | print_detected(); 68 | else 69 | print_not_detected(); 70 | 71 | /* log to file*/ 72 | TCHAR buffer[256] = _T(""); 73 | _stprintf_s(buffer, sizeof(buffer) / sizeof(TCHAR), _T("[*] %s -> %d"), szMsg, result); 74 | LOG_PRINT(buffer); 75 | } 76 | 77 | VOID print_results(int result, TCHAR* szMsg) 78 | { 79 | _print_check_text(szMsg); 80 | _print_check_result(result, szMsg); 81 | } 82 | 83 | // note: templated version of this function is in Common.h 84 | VOID exec_check(int(*callback)(), const TCHAR* szMsg) 85 | { 86 | /* Print the text to screen so we can see what's currently running */ 87 | _print_check_text(szMsg); 88 | 89 | /* Call our check */ 90 | int result = callback(); 91 | 92 | /* Print / Log the result */ 93 | if (szMsg) 94 | _print_check_result(result, szMsg); 95 | } 96 | 97 | VOID resize_console_window() 98 | { 99 | // Change the window title: 100 | SetConsoleTitle(_T("Al-Khaser - by Lord Noteworthy")); 101 | 102 | // Get console window handle 103 | HWND wh = GetConsoleWindow(); 104 | 105 | // Move window to required position 106 | MoveWindow(wh, 100, 100, 900, 900, TRUE); 107 | } 108 | 109 | 110 | VOID print_os() 111 | { 112 | TCHAR szOS[MAX_PATH] = _T(""); 113 | if (GetOSDisplayString(szOS)) 114 | { 115 | //_tcscpy_s(szOS, MAX_PATH, szOS); 116 | _tprintf(_T("\n[*] You are running: %s\n"), szOS); 117 | } 118 | } 119 | 120 | VOID print_last_error(LPCTSTR lpszFunction) 121 | { 122 | // Retrieve the system error message for the last-error code 123 | 124 | LPVOID lpMsgBuf; 125 | LPVOID lpDisplayBuf; 126 | DWORD dw = GetLastError(); 127 | 128 | if (FormatMessage( 129 | FORMAT_MESSAGE_ALLOCATE_BUFFER | 130 | FORMAT_MESSAGE_FROM_SYSTEM | 131 | FORMAT_MESSAGE_IGNORE_INSERTS, 132 | NULL, 133 | dw, 134 | MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), 135 | (LPTSTR)&lpMsgBuf, 136 | 0, NULL) == 0) 137 | { 138 | //FormatMessage failed, return 139 | return; 140 | } 141 | 142 | // Display the error message and exit the process 143 | 144 | lpDisplayBuf = (LPVOID)LocalAlloc(LMEM_ZEROINIT, 145 | (lstrlen((LPCTSTR)lpMsgBuf) + lstrlen((LPCTSTR)lpszFunction) + 40) * sizeof(TCHAR)); 146 | 147 | if (lpDisplayBuf) { 148 | 149 | StringCchPrintf((LPTSTR)lpDisplayBuf, 150 | LocalSize(lpDisplayBuf) / sizeof(TCHAR), 151 | TEXT("%s failed with error %u: %s"), 152 | lpszFunction, dw, lpMsgBuf); 153 | 154 | _tprintf((LPCTSTR)lpDisplayBuf); 155 | 156 | LocalFree(lpDisplayBuf); 157 | } 158 | LocalFree(lpMsgBuf); 159 | } 160 | 161 | WCHAR* ascii_to_wide_str(CHAR* lpMultiByteStr) 162 | { 163 | 164 | /* Get the required size */ 165 | INT iNumChars = MultiByteToWideChar(CP_ACP, 0, lpMultiByteStr, -1, NULL, 0); 166 | 167 | /* Allocate new wide string */ 168 | 169 | SIZE_T Size = (1 + iNumChars) * sizeof(WCHAR); 170 | 171 | WCHAR *lpWideCharStr = reinterpret_cast(malloc(Size)); 172 | 173 | if (lpWideCharStr) { 174 | SecureZeroMemory(lpWideCharStr, Size); 175 | /* Do the conversion */ 176 | iNumChars = MultiByteToWideChar(CP_ACP, 0, lpMultiByteStr, -1, lpWideCharStr, iNumChars); 177 | } 178 | return lpWideCharStr; 179 | } 180 | 181 | CHAR* wide_str_to_multibyte (TCHAR* lpWideStr) 182 | { 183 | errno_t status; 184 | int *pRetValue = NULL; 185 | CHAR *mbchar = NULL; 186 | size_t sizeInBytes = 0; 187 | 188 | status = wctomb_s(pRetValue, mbchar, sizeInBytes, *lpWideStr); 189 | return mbchar; 190 | } 191 | 192 | BOOL IsHexString(WCHAR* szStr) { 193 | std::wstring s(szStr); 194 | 195 | if (std::find_if(s.begin(), s.end(), [](wchar_t c) {return !std::isxdigit(static_cast(c)); }) == s.end()) 196 | return TRUE; 197 | else 198 | return FALSE; 199 | } 200 | -------------------------------------------------------------------------------- /al-khaser/Shared/Common.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | VOID print_detected() ; 4 | VOID print_not_detected() ; 5 | VOID print_category(const TCHAR* text); 6 | VOID print_last_error(LPCTSTR lpszFunction); 7 | VOID print_os(); 8 | WCHAR* ascii_to_wide_str(CHAR* lpMultiByteStr); 9 | CHAR* wide_str_to_multibyte(TCHAR* lpWideStr); 10 | BOOL IsHexString(WCHAR* szStr); 11 | VOID resize_console_window(); 12 | VOID print_results(int result, TCHAR* szMsg); 13 | VOID _print_check_text(const TCHAR* szMsg); 14 | VOID _print_check_result(int result, const TCHAR* szMsg); 15 | 16 | VOID exec_check(int(*callback)(), const TCHAR* szMsg); 17 | 18 | // this must be defined in this header file 19 | // see: https://stackoverflow.com/questions/495021/why-can-templates-only-be-implemented-in-the-header-file 20 | template 21 | VOID exec_check(int(*callback)(T param), T param, const TCHAR* szMsg) 22 | { 23 | /* Print the text to screen so we can see what's currently running */ 24 | _print_check_text(szMsg); 25 | 26 | /* Call our check */ 27 | int result = callback(param); 28 | 29 | /* Print / Log the result */ 30 | if (szMsg) 31 | _print_check_result(result, szMsg); 32 | } -------------------------------------------------------------------------------- /al-khaser/Shared/Utils.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | BOOL IsWoW64(); 4 | PVOID64 GetPeb64(); 5 | BOOL Is_RegKeyValueExists(HKEY hKey, const TCHAR* lpSubKey, const TCHAR* lpValueName, const TCHAR* search_str); 6 | BOOL Is_RegKeyExists(HKEY hKey, const TCHAR* lpSubKey); 7 | BOOL is_FileExists(TCHAR* szPath); 8 | BOOL is_DirectoryExists(TCHAR* szPath); 9 | BOOL check_mac_addr(const TCHAR* szMac); 10 | BOOL check_adapter_name(const TCHAR* szName); 11 | BOOL GetOSDisplayString(LPTSTR pszOS); 12 | BOOL IsWindowsVista(); 13 | BOOL IsWindows7(); 14 | BOOL IsWindows8or8PointOne(); 15 | DWORD GetProccessIDByName(TCHAR* szProcessNameTarget); 16 | DWORD GetProcessIdFromName(LPCTSTR ProcessName); 17 | BOOL SetPrivilege(HANDLE, LPCTSTR, BOOL); 18 | BOOL SetDebugPrivileges(VOID); 19 | DWORD GetMainThreadId(DWORD pid); 20 | BOOL InitWMI(IWbemServices **pSvc, IWbemLocator **pLoc, const TCHAR* szNetworkResource); 21 | BOOL ExecWMIQuery(IWbemServices **pSvc, IWbemLocator **pLoc, IEnumWbemClassObject **pEnumerator, const TCHAR* szQuery); 22 | ULONG get_idt_base(); 23 | ULONG get_ldt_base(); 24 | ULONG get_gdt_base(); 25 | BOOL IsElevated(); 26 | BOOL find_str_in_data(PBYTE needle, size_t needleLen, PBYTE haystack, size_t haystackLen); 27 | UINT enum_system_firmware_tables(_In_ DWORD FirmwareTableProviderSignature, _Out_ PVOID pFirmwareTableBuffer, _In_ DWORD BufferSize); 28 | PBYTE get_system_firmware(_In_ DWORD signature, _In_ DWORD table, _Out_ PDWORD pBufferSize); 29 | bool attempt_to_read_memory(void* addr, void* buf, int size); 30 | bool attempt_to_read_memory_wow64(PVOID buffer, DWORD size, PVOID64 address); 31 | bool attempt_to_read_memory_wow64(PVOID buffer, DWORD size, ULONGLONG address); 32 | std::vector* enumerate_memory(); 33 | std::vector* enumerate_memory_wow64(); 34 | std::vector* enumerate_object_directory(const wchar_t* path); 35 | 36 | #define MALLOC(x) HeapAlloc(GetProcessHeap(), 0, x) 37 | #define FREE(x) HeapFree(GetProcessHeap(), 0, x) 38 | 39 | #if _WIN32 || _WIN64 40 | #if _WIN64 41 | #define ENV64BIT 42 | #else 43 | #define ENV32BIT 44 | #endif 45 | #endif -------------------------------------------------------------------------------- /al-khaser/Shared/VersionHelpers.h: -------------------------------------------------------------------------------- 1 | /****************************************************************** 2 | * * 3 | * VersionHelpers.h -- This module defines helper functions to * 4 | * promote version check with proper * 5 | * comparisons. * 6 | * * 7 | * Copyright (c) Microsoft Corp. All rights reserved. * 8 | * * 9 | ******************************************************************/ 10 | #pragma once 11 | 12 | #include "winapifamily.h" 13 | 14 | #ifdef _MSC_VER 15 | #pragma once 16 | #endif // _MSC_VER 17 | 18 | #pragma region Application Family 19 | #if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP) 20 | 21 | #include // for _In_, etc. 22 | 23 | #if !defined(__midl) && !defined(SORTPP_PASS) 24 | 25 | #if (NTDDI_VERSION >= NTDDI_WINXP) 26 | 27 | #ifdef __cplusplus 28 | 29 | #define VERSIONHELPERAPI inline bool 30 | 31 | #else // __cplusplus 32 | 33 | #define VERSIONHELPERAPI FORCEINLINE BOOL 34 | 35 | #endif // __cplusplus 36 | 37 | VERSIONHELPERAPI 38 | IsWindowsVersionOrGreater(WORD wMajorVersion, WORD wMinorVersion, WORD wServicePackMajor) 39 | { 40 | OSVERSIONINFOEXW osvi = { sizeof(osvi), 0, 0, 0, 0, {0}, 0, 0 }; 41 | DWORDLONG const dwlConditionMask = VerSetConditionMask( 42 | VerSetConditionMask( 43 | VerSetConditionMask( 44 | 0, VER_MAJORVERSION, VER_GREATER_EQUAL), 45 | VER_MINORVERSION, VER_GREATER_EQUAL), 46 | VER_SERVICEPACKMAJOR, VER_GREATER_EQUAL); 47 | 48 | osvi.dwMajorVersion = wMajorVersion; 49 | osvi.dwMinorVersion = wMinorVersion; 50 | osvi.wServicePackMajor = wServicePackMajor; 51 | 52 | return VerifyVersionInfoW(&osvi, VER_MAJORVERSION | VER_MINORVERSION | VER_SERVICEPACKMAJOR, dwlConditionMask) != FALSE; 53 | } 54 | 55 | VERSIONHELPERAPI 56 | IsWindowsVersionOrLesser(WORD wMajorVersion, WORD wMinorVersion, WORD wServicePackMajor) 57 | { 58 | OSVERSIONINFOEXW osvi = { sizeof(osvi), 0, 0, 0, 0, { 0 }, 0, 0 }; 59 | DWORDLONG const dwlConditionMask = VerSetConditionMask( 60 | VerSetConditionMask( 61 | 0, VER_MAJORVERSION, VER_EQUAL), 62 | VER_MINORVERSION, VER_LESS_EQUAL); 63 | 64 | osvi.dwMajorVersion = wMajorVersion; 65 | osvi.dwMinorVersion = wMinorVersion; 66 | osvi.wServicePackMajor = wServicePackMajor; 67 | 68 | return VerifyVersionInfoW(&osvi, VER_MAJORVERSION | VER_MINORVERSION, dwlConditionMask) != FALSE; 69 | } 70 | 71 | VERSIONHELPERAPI 72 | IsWindowsXPOrGreater() 73 | { 74 | return IsWindowsVersionOrGreater(HIBYTE(_WIN32_WINNT_WINXP), LOBYTE(_WIN32_WINNT_WINXP), 0); 75 | } 76 | 77 | VERSIONHELPERAPI 78 | IsWindowsXPSP1OrGreater() 79 | { 80 | return IsWindowsVersionOrGreater(HIBYTE(_WIN32_WINNT_WINXP), LOBYTE(_WIN32_WINNT_WINXP), 1); 81 | } 82 | 83 | VERSIONHELPERAPI 84 | IsWindowsXPSP2OrGreater() 85 | { 86 | return IsWindowsVersionOrGreater(HIBYTE(_WIN32_WINNT_WINXP), LOBYTE(_WIN32_WINNT_WINXP), 2); 87 | } 88 | 89 | VERSIONHELPERAPI 90 | IsWindowsXPSP3OrGreater() 91 | { 92 | return IsWindowsVersionOrGreater(HIBYTE(_WIN32_WINNT_WINXP), LOBYTE(_WIN32_WINNT_WINXP), 3); 93 | } 94 | 95 | VERSIONHELPERAPI 96 | IsWindowsVistaOrGreater() 97 | { 98 | return IsWindowsVersionOrGreater(HIBYTE(_WIN32_WINNT_VISTA), LOBYTE(_WIN32_WINNT_VISTA), 0); 99 | } 100 | 101 | VERSIONHELPERAPI 102 | IsWindowsVistaSP1OrGreater() 103 | { 104 | return IsWindowsVersionOrGreater(HIBYTE(_WIN32_WINNT_VISTA), LOBYTE(_WIN32_WINNT_VISTA), 1); 105 | } 106 | 107 | VERSIONHELPERAPI 108 | IsWindowsVistaSP2OrGreater() 109 | { 110 | return IsWindowsVersionOrGreater(HIBYTE(_WIN32_WINNT_VISTA), LOBYTE(_WIN32_WINNT_VISTA), 2); 111 | } 112 | 113 | VERSIONHELPERAPI 114 | IsWindows7OrGreater() 115 | { 116 | return IsWindowsVersionOrGreater(HIBYTE(_WIN32_WINNT_WIN7), LOBYTE(_WIN32_WINNT_WIN7), 0); 117 | } 118 | 119 | VERSIONHELPERAPI 120 | IsWindows7SP1OrGreater() 121 | { 122 | return IsWindowsVersionOrGreater(HIBYTE(_WIN32_WINNT_WIN7), LOBYTE(_WIN32_WINNT_WIN7), 1); 123 | } 124 | 125 | VERSIONHELPERAPI 126 | IsWindows8OrGreater() 127 | { 128 | return IsWindowsVersionOrGreater(HIBYTE(_WIN32_WINNT_WIN8), LOBYTE(_WIN32_WINNT_WIN8), 0); 129 | } 130 | 131 | VERSIONHELPERAPI 132 | IsWindows8Point1OrGreater() 133 | { 134 | return IsWindowsVersionOrGreater(HIBYTE(_WIN32_WINNT_WINBLUE), LOBYTE(_WIN32_WINNT_WINBLUE), 0); 135 | } 136 | 137 | VERSIONHELPERAPI 138 | IsWindows10OrGreater() 139 | { 140 | return IsWindowsVersionOrGreater(10, 0, 0); 141 | } 142 | 143 | VERSIONHELPERAPI 144 | IsWindowsServer() 145 | { 146 | OSVERSIONINFOEXW osvi = { sizeof(osvi), 0, 0, 0, 0, {0}, 0, 0, 0, VER_NT_WORKSTATION }; 147 | DWORDLONG const dwlConditionMask = VerSetConditionMask( 0, VER_PRODUCT_TYPE, VER_EQUAL ); 148 | 149 | return !VerifyVersionInfoW(&osvi, VER_PRODUCT_TYPE, dwlConditionMask); 150 | } 151 | 152 | 153 | 154 | VERSIONHELPERAPI 155 | IsWindowsXPOr2k() 156 | { 157 | return IsWindowsVersionOrLesser(HIBYTE(_WIN32_WINNT_WINXP), LOBYTE(_WIN32_WINNT_WINXP), 0); 158 | } 159 | 160 | 161 | #endif // NTDDI_VERSION 162 | 163 | #endif // defined(__midl) 164 | 165 | #endif /* WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP) */ 166 | #pragma endregion 167 | -------------------------------------------------------------------------------- /al-khaser/Shared/WinStructs.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | typedef struct _LDR_MODULE { 4 | LIST_ENTRY InLoadOrderModuleList; 5 | LIST_ENTRY InMemoryOrderModuleList; 6 | LIST_ENTRY InInitializationOrderModuleList; 7 | PVOID BaseAddress; 8 | PVOID EntryPoint; 9 | ULONG SizeOfImage; 10 | UNICODE_STRING FullDllName; 11 | UNICODE_STRING BaseDllName; 12 | ULONG Flags; 13 | SHORT LoadCount; 14 | SHORT TlsIndex; 15 | LIST_ENTRY HashTableEntry; 16 | ULONG TimeDateStamp; 17 | } LDR_MODULE, *PLDR_MODULE; 18 | 19 | typedef LONG KPRIORITY; 20 | 21 | typedef struct _THREAD_BASIC_INFORMATION { 22 | NTSTATUS ExitStatus; 23 | PVOID TebBaseAddress; 24 | CLIENT_ID ClientId; 25 | KAFFINITY AffinityMask; 26 | KPRIORITY Priority; 27 | KPRIORITY BasePriority; 28 | } THREAD_BASIC_INFORMATION, *PTHREAD_BASIC_INFORMATION; 29 | 30 | typedef struct _PROCESS_BASIC_INFORMATION_WOW64 { 31 | PVOID Reserved1[2]; 32 | PVOID64 PebBaseAddress; 33 | PVOID Reserved2[4]; 34 | ULONG_PTR UniqueProcessId[2]; 35 | PVOID Reserved3[2]; 36 | } PROCESS_BASIC_INFORMATION_WOW64; 37 | 38 | typedef struct _PEB64 { 39 | BYTE Reserved1[2]; 40 | BYTE BeingDebugged; 41 | BYTE Reserved2[1]; 42 | PVOID64 Reserved3[2]; 43 | PVOID64 Ldr; 44 | PVOID64 ProcessParameters; 45 | BYTE Reserved4[104]; 46 | PVOID64 Reserved5[52]; 47 | PVOID64 PostProcessInitRoutine; 48 | BYTE Reserved6[128]; 49 | PVOID64 Reserved7[1]; 50 | ULONG SessionId; 51 | } PEB64, *PPEB64; 52 | 53 | typedef struct _PEB_LDR_DATA64 { 54 | BYTE Reserved1[8]; 55 | PVOID64 Reserved2[3]; 56 | LIST_ENTRY64 InMemoryOrderModuleList; 57 | } PEB_LDR_DATA64, *PPEB_LDR_DATA64; 58 | 59 | typedef struct _UNICODE_STRING64 { 60 | USHORT Length; 61 | USHORT MaximumLength; 62 | PVOID64 Buffer; 63 | } UNICODE_STRING64; 64 | 65 | typedef struct _LDR_DATA_TABLE_ENTRY64 { 66 | PVOID64 Reserved1[2]; 67 | LIST_ENTRY64 InMemoryOrderLinks; 68 | PVOID64 Reserved2[2]; 69 | PVOID64 DllBase; 70 | PVOID64 Reserved3[2]; 71 | UNICODE_STRING64 FullDllName; 72 | BYTE Reserved4[8]; 73 | PVOID64 Reserved5[3]; 74 | union { 75 | ULONG CheckSum; 76 | PVOID64 Reserved6; 77 | } DUMMYUNIONNAME; 78 | ULONG TimeDateStamp; 79 | } LDR_DATA_TABLE_ENTRY64, *PLDR_DATA_TABLE_ENTRY64; 80 | 81 | /*++ NtCreateThreadEx specific */ 82 | 83 | typedef struct _PS_ATTRIBUTE { 84 | ULONG Attribute; 85 | SIZE_T Size; 86 | union 87 | { 88 | ULONG Value; 89 | PVOID ValuePtr; 90 | } u1; 91 | PSIZE_T ReturnLength; 92 | } PS_ATTRIBUTE, *PPS_ATTRIBUTE; 93 | 94 | typedef struct _PS_ATTRIBUTE_LIST { 95 | SIZE_T TotalLength; 96 | PS_ATTRIBUTE Attributes[1]; 97 | } PS_ATTRIBUTE_LIST, *PPS_ATTRIBUTE_LIST; 98 | 99 | #define PS_ATTRIBUTE_NUMBER_MASK 0x0000ffff 100 | #define PS_ATTRIBUTE_THREAD 0x00010000 101 | #define PS_ATTRIBUTE_INPUT 0x00020000 102 | #define PS_ATTRIBUTE_ADDITIVE 0x00040000 103 | 104 | #define PsAttributeValue(Number, Thread, Input, Additive) \ 105 | (((Number) & PS_ATTRIBUTE_NUMBER_MASK) | \ 106 | ((Thread) ? PS_ATTRIBUTE_THREAD : 0) | \ 107 | ((Input) ? PS_ATTRIBUTE_INPUT : 0) | \ 108 | ((Additive) ? PS_ATTRIBUTE_ADDITIVE : 0)) 109 | 110 | typedef enum _PS_ATTRIBUTE_NUM { 111 | PsAttributeClientId = 3, 112 | } PS_ATTRIBUTE_NUM; 113 | 114 | #define PS_ATTRIBUTE_CLIENT_ID \ 115 | PsAttributeValue(PsAttributeClientId, TRUE, FALSE, FALSE) 116 | 117 | /* NtCreateThreadEx specific --*/ 118 | 119 | typedef struct _SYSTEM_HYPERVISOR_PROCESSOR_COUNT_INFORMATION 120 | { 121 | ULONG NumberOfLogicalProcessors; 122 | ULONG NumberOfCores; 123 | } SYSTEM_HYPERVISOR_PROCESSOR_COUNT_INFORMATION, *PSYSTEM_HYPERVISOR_PROCESSOR_COUNT_INFORMATION; 124 | 125 | 126 | typedef struct _OBJECT_DIRECTORY_INFORMATION 127 | { 128 | UNICODE_STRING Name; 129 | UNICODE_STRING TypeName; 130 | } OBJECT_DIRECTORY_INFORMATION, *POBJECT_DIRECTORY_INFORMATION; 131 | 132 | typedef VOID(NTAPI LDR_ENUM_CALLBACK)(_In_ PLDR_DATA_TABLE_ENTRY ModuleInformation, _In_ PVOID Parameter, _Out_ BOOLEAN *Stop); 133 | typedef LDR_ENUM_CALLBACK *PLDR_ENUM_CALLBACK; 134 | -------------------------------------------------------------------------------- /al-khaser/Shared/log.cpp: -------------------------------------------------------------------------------- 1 | #include "pch.h" 2 | #include "log.h" 3 | 4 | static int SESSION_TRACKER; //Keeps track of session 5 | 6 | TCHAR* print_time() 7 | { 8 | size_t size = 0; 9 | TCHAR *buf; 10 | errno_t err; 11 | TCHAR timestr[32]; 12 | 13 | /* get current calendar time */ 14 | time_t const sourceTime = time(NULL); 15 | tm tmDest = { 0 }; 16 | err = localtime_s(&tmDest, &sourceTime); 17 | if (err) 18 | { 19 | print_last_error(_T("localtime_s")); 20 | exit(1); 21 | } 22 | 23 | // Converts a time_t time value to a tm structure, and corrects for the local time zone. 24 | err = _tasctime_s(timestr, 32, &tmDest); 25 | if (err) 26 | { 27 | print_last_error(_T("_tasctime_s")); 28 | exit(1); 29 | } 30 | 31 | //Getting rid of \n 32 | timestr[_tcsclen(timestr) - 1] = 0; 33 | 34 | //Additional +2 for square braces 35 | size = (_tcsclen(timestr) + 1 + 2) * sizeof(TCHAR); 36 | buf = (TCHAR*)malloc(size); 37 | if (buf) { 38 | memset(buf, 0x0, size); 39 | _stprintf_s(buf, size / sizeof(TCHAR), _T("[%s]"), timestr); 40 | } 41 | return buf; 42 | } 43 | void log_print(const TCHAR* filename, const TCHAR *fmt, ...) 44 | { 45 | va_list list; 46 | const TCHAR *p, *r; 47 | int e; 48 | 49 | FILE *fp = NULL; 50 | errno_t error; 51 | 52 | TCHAR *pszTime; 53 | 54 | if (SESSION_TRACKER > 0) 55 | error = _tfopen_s(&fp, _T("log.txt"), _T("a+")); 56 | else 57 | error = _tfopen_s(&fp, _T("log.txt"), _T("w")); 58 | 59 | // file create/open failed 60 | if ((error != 0) || (fp == NULL)) 61 | return; 62 | 63 | pszTime = print_time(); 64 | if (pszTime) { 65 | _ftprintf(fp, _T("%s "), pszTime); 66 | free(pszTime); 67 | } 68 | va_start(list, fmt); 69 | 70 | for (p = fmt; *p; ++p) 71 | { 72 | if (*p != '%')//If simple string 73 | fputc(*p, fp); 74 | 75 | else 76 | { 77 | switch (*++p) 78 | { 79 | /* string */ 80 | case 's': 81 | { 82 | r = va_arg(list, TCHAR *); 83 | _ftprintf(fp, _T("%s"), r); 84 | continue; 85 | } 86 | 87 | /* integer */ 88 | case 'd': 89 | { 90 | e = va_arg(list, int); 91 | _ftprintf(fp, _T("%d"), e); 92 | continue; 93 | } 94 | 95 | default: 96 | fputc(*p, fp); 97 | } 98 | } 99 | } 100 | va_end(list); 101 | fputc('\n', fp); 102 | SESSION_TRACKER++; 103 | fclose(fp); 104 | } 105 | -------------------------------------------------------------------------------- /al-khaser/Shared/log.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #define WIDEN2(x) L##x 4 | #define WIDEN(x) WIDEN2(x) 5 | #define __WFILE__ WIDEN(__FILE__) 6 | 7 | #ifdef UNICODE 8 | #define __TFILE__ __WFILE__ 9 | #else 10 | #define __TFILE__ __FILE__ 11 | #endif 12 | 13 | void log_print(const TCHAR* filename, const TCHAR *fmt, ...); 14 | 15 | #define LOG_PRINT(...) log_print(__TFILE__, __VA_ARGS__ ) 16 | 17 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /al-khaser/Shared/pch.h: -------------------------------------------------------------------------------- 1 | #include "../pch.h" -------------------------------------------------------------------------------- /al-khaser/TimingAttacks/pch.h: -------------------------------------------------------------------------------- 1 | #include "../pch.h" -------------------------------------------------------------------------------- /al-khaser/TimingAttacks/timing.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | BOOL timing_SetTimer(UINT delayInMillis); 4 | BOOL timing_NtDelayexecution(UINT delayInMillis); 5 | BOOL timing_timeSetEvent(UINT delayInMillis); 6 | BOOL timing_WaitForSingleObject(UINT delayInMillis); 7 | BOOL timing_WaitForMultipleObjects(UINT delayInMillis); 8 | BOOL timing_sleep_loop(UINT delayInMillis); 9 | BOOL rdtsc_diff_locky(); 10 | BOOL rdtsc_diff_vmexit(); 11 | BOOL timing_IcmpSendEcho(UINT delayInMillis); 12 | BOOL timing_CreateWaitableTimer(UINT delayInMillis); 13 | BOOL timing_CreateTimerQueueTimer(UINT delayInMillis); 14 | VOID CALLBACK CallbackCTQT(PVOID lParam, BOOLEAN TimerOrWaitFired); 15 | -------------------------------------------------------------------------------- /al-khaser/al-khaser.manifest: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /al-khaser/packages.config: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /al-khaser/pch.cpp: -------------------------------------------------------------------------------- 1 | // pch.cpp: source file corresponding to pre-compiled header; necessary for compilation to succeed 2 | 3 | #include "pch.h" 4 | 5 | // In general, ignore this file, but keep it around if you are using pre-compiled headers. 6 | -------------------------------------------------------------------------------- /al-khaser/pch.h: -------------------------------------------------------------------------------- 1 | // Tips for Getting Started: 2 | // 1. Use the Solution Explorer window to add/manage files 3 | // 2. Use the Team Explorer window to connect to source control 4 | // 3. Use the Output window to see build output and other messages 5 | // 4. Use the Error List window to view errors 6 | // 5. Go to Project > Add New Item to create new code files, or Project > Add Existing Item to add existing code files to the project 7 | // 6. In the future, to open this project again, go to File > Open > Project and select the .sln file 8 | 9 | #ifndef PCH_H 10 | #define PCH_H 11 | 12 | // add headers that you want to pre-compile here 13 | 14 | 15 | 16 | #include 17 | #include 18 | #include 19 | 20 | #include 21 | #include 22 | #include 23 | #include 24 | #include 25 | #include 26 | #include 27 | #include 28 | #include 29 | #include 30 | #include 31 | #include 32 | #include 33 | #include 34 | #include 35 | #include 36 | #include 37 | #include 38 | #include 39 | #include 40 | #include // Device guids 41 | #include // IOCTL 42 | #include // cpuid() 43 | #include // 64-bit wchar atoi 44 | #include // check_power_modes() 45 | #include 46 | #include 47 | #include 48 | #include // SLIsGenuineLocal 49 | #include 50 | 51 | #pragma comment(lib, "Ws2_32.lib") 52 | #pragma comment(lib, "wbemuuid.lib") 53 | #pragma comment(lib, "Shlwapi.lib") 54 | #pragma comment(lib, "Mpr.lib") 55 | #pragma comment(lib, "Iphlpapi.lib") 56 | #pragma comment(lib, "Shlwapi.lib") 57 | #pragma comment(lib, "Psapi.lib") 58 | #pragma comment(lib, "wbemuuid.lib") 59 | #pragma comment(lib, "Winmm.lib") 60 | #pragma comment(lib, "setupapi.lib") 61 | #pragma comment(lib, "powrprof.lib") 62 | #pragma comment(lib, "Slwga.lib") 63 | 64 | #include "Shared/Common.h" 65 | #include "Shared/VersionHelpers.h" 66 | #include "Shared/log.h" 67 | #include "Shared/Utils.h" 68 | #include "Shared/WinStructs.h" 69 | #include "Shared/ApiTypeDefs.h" 70 | #include "Shared/APIs.h" 71 | #include "Shared/winapifamily.h" 72 | 73 | /* AntiDebugs headers */ 74 | #include "AntiDebug/CheckRemoteDebuggerPresent.h" 75 | #include "AntiDebug/IsDebuggerPresent.h" 76 | #include "AntiDebug/BeingDebugged.h" 77 | #include "AntiDebug/ProcessHeap_Flags.h" 78 | #include "AntiDebug/ProcessHeap_ForceFlags.h" 79 | #include "AntiDebug/NtGlobalFlag.h" 80 | #include "AntiDebug/NtQueryInformationProcess_ProcessDebugPort.h" 81 | #include "AntiDebug/NtQueryInformationProcess_ProcessDebugFlags.h" 82 | #include "AntiDebug/NtQueryInformationProcess_ProcessDebugObject.h" 83 | #include "AntiDebug/NtSetInformationThread_ThreadHideFromDebugger.h" 84 | #include "AntiDebug/CloseHandle_InvalidHandle.h" 85 | #include "AntiDebug/NtSystemDebugControl.h" 86 | #include "AntiDebug/UnhandledExceptionFilter_Handler.h" 87 | #include "AntiDebug/OutputDebugStringAPI.h" 88 | #include "AntiDebug/HardwareBreakpoints.h" 89 | #include "AntiDebug/SoftwareBreakpoints.h" 90 | #include "AntiDebug/Interrupt_0x2d.h" 91 | #include "AntiDebug/Interrupt_3.h" 92 | #include "AntiDebug/TrapFlag.h" 93 | #include "AntiDebug/MemoryBreakpoints_PageGuard.h" 94 | #include "AntiDebug/ParentProcess.h" 95 | #include "AntiDebug/SeDebugPrivilege.h" 96 | #include "AntiDebug/NtQueryObject_ObjectInformation.h" 97 | #include "AntiDebug/NtYieldExecution.h" 98 | #include "AntiDebug/SetHandleInformation_API.h" 99 | #include "AntiDebug/TLS_callbacks.h" 100 | #include "AntiDebug/NtQuerySystemInformation_SystemKernelDebuggerInformation.h" 101 | #include "AntiDebug/SharedUserData_KernelDebugger.h" 102 | #include "AntiDebug/ProcessJob.h" 103 | #include "AntiDebug/WriteWatch.h" 104 | #include "AntiDebug/PageExceptionBreakpointCheck.h" 105 | #include "AntiDebug/ModuleBoundsHookCheck.h" 106 | #include "AntiDebug/ScanForModules.h" 107 | #include "AntiDebug/WUDF_IsDebuggerPresent.h" 108 | #include "AntiDebug/LowFragmentationHeap.h" 109 | 110 | 111 | /* Anti dumping headers */ 112 | #include "AntiDump/ErasePEHeaderFromMemory.h" 113 | #include "AntiDump/SizeOfImage.h" 114 | 115 | /* Anti VM headers */ 116 | #include "AntiVM/VirtualBox.h" 117 | #include "AntiVM/VMware.h" 118 | #include "AntiVM/Wine.h" 119 | #include "AntiVM/Generic.h" 120 | #include "AntiVM/VirtualPC.h" 121 | #include "AntiVM/QEMU.h" 122 | #include "AntiVM/Xen.h" 123 | #include "AntiVM/KVM.h" 124 | #include "AntiVM/Parallels.h" 125 | #include "AntiVM/Services.h" 126 | #include "AntiVM/HyperV.h" 127 | 128 | /* Code Injections Headers */ 129 | #include "CodeInjection/CreateRemoteThread.h" 130 | #include "CodeInjection/SetWindowsHooksEx.h" 131 | #include "CodeInjection/NtCreateThreadEx.h" 132 | #include "CodeInjection/RtlCreateUserThread.h" 133 | #include "CodeInjection/QueueUserAPC.h" 134 | #include "CodeInjection/GetSetThreadContext.h" 135 | 136 | /* Delay Execution */ 137 | #include "TimingAttacks/timing.h" 138 | 139 | /* Anti-Analysis */ 140 | #include "AntiAnalysis/process.h" 141 | 142 | /* Anti-Disassembly */ 143 | #include "AntiDisassm/AntiDisassm.h" 144 | 145 | 146 | #endif //PCH_H 147 | --------------------------------------------------------------------------------