2014-04-06 18:31:53 +00:00
/* Benjamin DELPY `gentilkiwi`
2020-09-17 01:17:11 +00:00
https : //blog.gentilkiwi.com
2014-04-06 18:31:53 +00:00
benjamin @ gentilkiwi . com
2015-08-25 09:19:01 +00:00
Licence : https : //creativecommons.org/licenses/by/4.0/
2014-04-06 18:31:53 +00:00
*/
# include "kull_m_patch.h"
BOOL kull_m_patch ( PKULL_M_MEMORY_SEARCH sMemory , PKULL_M_MEMORY_ADDRESS pPattern , SIZE_T szPattern , PKULL_M_MEMORY_ADDRESS pPatch , SIZE_T szPatch , LONG offsetOfPatch , PKULL_M_PATCH_CALLBACK pCallBackBeforeRestore , int argc , wchar_t * args [ ] , NTSTATUS * pRetCallBack )
{
BOOL result = FALSE , resultBackup = ! pCallBackBeforeRestore , resultProtect = TRUE ;
KULL_M_MEMORY_ADDRESS destination = { NULL , sMemory - > kull_m_memoryRange . kull_m_memoryAdress . hMemory } ;
2016-03-27 17:22:36 +00:00
KULL_M_MEMORY_ADDRESS backup = { NULL , & KULL_M_MEMORY_GLOBAL_OWN_HANDLE } ;
2014-04-06 18:31:53 +00:00
MEMORY_BASIC_INFORMATION readInfos ;
NTSTATUS status ;
DWORD flags , oldProtect = 0 , tempProtect = 0 ;
if ( kull_m_memory_search ( pPattern , szPattern , sMemory , TRUE ) )
{
destination . address = ( LPBYTE ) sMemory - > result + offsetOfPatch ;
if ( ! resultBackup )
if ( backup . address = LocalAlloc ( LPTR , szPatch ) )
resultBackup = kull_m_memory_copy ( & backup , & destination , szPatch ) ;
if ( resultBackup )
{
if ( kull_m_memory_query ( & destination , & readInfos ) )
{
flags = readInfos . Protect & ~ 0xff ;
if ( ( readInfos . Protect & 0x0f ) & & ( ( readInfos . Protect & 0x0f ) < PAGE_READWRITE ) )
tempProtect = PAGE_READWRITE ;
else if ( ( readInfos . Protect & 0xf0 ) & & ( ( readInfos . Protect & 0xf0 ) < PAGE_EXECUTE_READWRITE ) )
tempProtect = PAGE_EXECUTE_READWRITE ;
if ( tempProtect )
resultProtect = kull_m_memory_protect ( & destination , szPatch , tempProtect | flags , & oldProtect ) ;
if ( resultProtect )
{
if ( result = kull_m_memory_copy ( & destination , pPatch , szPatch ) )
{
if ( pCallBackBeforeRestore )
{
status = pCallBackBeforeRestore ( argc , args ) ;
if ( pRetCallBack )
* pRetCallBack = status ;
result = kull_m_memory_copy ( & destination , & backup , szPatch ) ;
}
}
if ( oldProtect )
kull_m_memory_protect ( & destination , szPatch , oldProtect , NULL ) ;
}
}
if ( backup . address )
LocalFree ( backup . address ) ;
}
}
return result ;
}
PKULL_M_PATCH_GENERIC kull_m_patch_getGenericFromBuild ( PKULL_M_PATCH_GENERIC generics , SIZE_T cbGenerics , DWORD BuildNumber )
{
SIZE_T i ;
PKULL_M_PATCH_GENERIC current = NULL ;
for ( i = 0 ; i < cbGenerics ; i + + )
{
if ( generics [ i ] . MinBuildNumber < = BuildNumber )
current = & generics [ i ] ;
else break ;
}
return current ;
}
2014-04-30 21:01:08 +00:00
BOOL kull_m_patch_genericProcessOrServiceFromBuild ( PKULL_M_PATCH_GENERIC generics , SIZE_T cbGenerics , PCWSTR processOrService , PCWSTR moduleName , BOOL isService ) // to do for process // to do callback ! (vault & lsadump)
2014-04-06 18:31:53 +00:00
{
BOOL result = FALSE ;
SERVICE_STATUS_PROCESS ServiceStatusProcess ;
PKULL_M_MEMORY_HANDLE hMemory ;
KULL_M_PROCESS_VERY_BASIC_MODULE_INFORMATION iModule ;
HANDLE hProcess ;
KULL_M_MEMORY_ADDRESS
2016-03-27 17:22:36 +00:00
aPatternMemory = { NULL , & KULL_M_MEMORY_GLOBAL_OWN_HANDLE } ,
aPatchMemory = { NULL , & KULL_M_MEMORY_GLOBAL_OWN_HANDLE } ;
2014-04-06 18:31:53 +00:00
KULL_M_MEMORY_SEARCH sMemory ;
PKULL_M_PATCH_GENERIC currenReferences ;
if ( currenReferences = kull_m_patch_getGenericFromBuild ( generics , cbGenerics , MIMIKATZ_NT_BUILD_NUMBER ) )
{
aPatternMemory . address = currenReferences - > Search . Pattern ;
aPatchMemory . address = currenReferences - > Patch . Pattern ;
if ( kull_m_service_getUniqueForName ( processOrService , & ServiceStatusProcess ) )
{
if ( ServiceStatusProcess . dwCurrentState > = SERVICE_RUNNING )
{
if ( hProcess = OpenProcess ( PROCESS_VM_READ | PROCESS_VM_WRITE | PROCESS_VM_OPERATION | PROCESS_QUERY_INFORMATION , FALSE , ServiceStatusProcess . dwProcessId ) )
{
if ( kull_m_memory_open ( KULL_M_MEMORY_TYPE_PROCESS , hProcess , & hMemory ) )
{
if ( kull_m_process_getVeryBasicModuleInformationsForName ( hMemory , moduleName , & iModule ) )
{
sMemory . kull_m_memoryRange . kull_m_memoryAdress = iModule . DllBase ;
sMemory . kull_m_memoryRange . size = iModule . SizeOfImage ;
if ( result = kull_m_patch ( & sMemory , & aPatternMemory , currenReferences - > Search . Length , & aPatchMemory , currenReferences - > Patch . Length , currenReferences - > Offsets . off0 , NULL , 0 , NULL , NULL ) )
kprintf ( L " \" %s \" service patched \n " , processOrService ) ;
else
PRINT_ERROR_AUTO ( L " kull_m_patch " ) ;
} else PRINT_ERROR_AUTO ( L " kull_m_process_getVeryBasicModuleInformationsForName " ) ;
kull_m_memory_close ( hMemory ) ;
}
} else PRINT_ERROR_AUTO ( L " OpenProcess " ) ;
} else PRINT_ERROR ( L " Service is not running \n " ) ;
} else PRINT_ERROR_AUTO ( L " kull_m_service_getUniqueForName " ) ;
} else PRINT_ERROR ( L " Incorrect version in references \n " ) ;
return result ;
}