// // возвращает размер зан¤той списком файлов пам¤ти в байтах // BOOLEAN GetFileListSizeByBytes(PULONG pdwSize) { BOOLEAN bRes = FALSE; KDLinkedListItem* pNode; PFILEINFO pFileInfo; if ( KeGetCurrentIrql() == PASSIVE_LEVEL && _MmIsAddressValid(pdwSize) && _MmIsAddressValid(pSaveList) ) { *pdwSize = 0; MUTEX_WAIT(LockMutexToFileSaveList); pNode = pSaveList->GetHead(); while (_MmIsAddressValid(pNode)) { pFileInfo = (PFILEINFO)pNode->GetObject(); if (_MmIsAddressValid(pFileInfo)) { *pdwSize += pFileInfo->dwSizeAllNamesArea + SIZEOF_FILEINFO_REAL; } pNode = pNode->GetNext(); } MUTEX_RELEASE(LockMutexToFileSaveList); bRes = TRUE; } return bRes; }
void mutex_release(mutex_t mutex) { proc_t notify = NULL; if (!MUTEX_HOLD(mutex)) return; int irq = __irq_save(); spinlock_acquire(&mutex->lock); if (MUTEX_WAIT(mutex)) { ips_node_t node = MUTEX_PTR(mutex); IPS_NODE_WAIT_CLEAR(node); notify = IPS_NODE_PTR(node); node->next->prev = node->prev; node->prev->next = node->next; if (node->next == node) MUTEX_WAIT_CLEAR(mutex); else MUTEX_PTR_SET(mutex, node->next); } else MUTEX_HOLD_CLEAR(mutex); spinlock_release(&mutex->lock); __irq_restore(irq); if (notify != NULL) proc_notify(notify); }
int mutex_acquire(mutex_t mutex, ips_node_t node) { if (node == NULL) { ips_node_s node; if (!mutex_acquire(mutex, &node)) { ips_wait(&node); return 0; } else return 1; } else { int irq = __irq_save(); spinlock_acquire(&mutex->lock); if (!MUTEX_HOLD(mutex)) { MUTEX_HOLD_SET(mutex); MUTEX_WAIT_CLEAR(mutex); spinlock_release(&mutex->lock); __irq_restore(irq); IPS_NODE_WAIT_CLEAR(node); return 1; } else { ips_wait_init(node, current); if (MUTEX_WAIT(mutex)) { node->next = MUTEX_PTR(mutex); node->prev = node->next->prev; node->next->prev = node; node->prev->next = node; } else { MUTEX_WAIT_SET(mutex); node->next = node->prev = node; MUTEX_PTR_SET(mutex, node); } spinlock_release(&mutex->lock); __irq_restore(irq); return 0; } } }
static void meet( void) { MUTEX_LOCK(&mutex); while (!(waita && waitb)) { DEBUG_PRINT1("C Waiting"); MUTEX_WAIT(&waitc, &mutex); } DEBUG_PRINT1("C Continuing"); MUTEX_UNLOCK(&mutex); }
BOOLEAN GetFileSaveList(PFILEINFOSET pFileInfoSet) { BOOLEAN bRes = FALSE; KDLinkedListItem* pNode; PFILEINFO pFileInfo, pFileInfoDest; ULONG dwSize; if ( KeGetCurrentIrql() == PASSIVE_LEVEL && _MmIsAddressValid(pSaveList) && _MmIsAddressValid(pFileInfoSet) && pFileInfoSet->dwSize >= SIZEOF_FILEINFOSET ) { dwSize = pFileInfoSet->dwSize; memset(pFileInfoSet, 0, dwSize); dwSize -= sizeof(ULONG); pFileInfoDest = &pFileInfoSet->FileInfo[0]; MUTEX_WAIT(LockMutexToFileSaveList); pNode = pSaveList->GetHead(); while (_MmIsAddressValid(pNode)) { pFileInfo = (PFILEINFO)pNode->GetObject(); if (_MmIsAddressValid(pFileInfo)) { if (dwSize >= (pFileInfo->dwSizeAllNamesArea + SIZEOF_FILEINFO_REAL)) { memcpy(pFileInfoDest, pFileInfo, (pFileInfo->dwSizeAllNamesArea + SIZEOF_FILEINFO_REAL)); // if (dwSize >= (pFileInfo->dwSizeAllNamesArea + SIZEOF_FILEINFO_REAL)) dwSize -= (pFileInfo->dwSizeAllNamesArea + SIZEOF_FILEINFO_REAL); // else // dwSize = 0; pFileInfoDest = (PFILEINFO)((CHAR*)pFileInfoDest + (pFileInfo->dwSizeAllNamesArea + SIZEOF_FILEINFO_REAL)); pFileInfoSet->dwSize += (pFileInfo->dwSizeAllNamesArea + SIZEOF_FILEINFO_REAL); } } pNode = pNode->GetNext(); } MUTEX_RELEASE(LockMutexToFileSaveList); if (pFileInfoSet->dwSize != 0) pFileInfoSet->dwSize += sizeof(ULONG); bRes = TRUE; } return bRes; }
static void holdb( void) { MUTEX_LOCK(&mutex); waitb = 1; DEBUG_PRINT1("B Broadcast C"); MUTEX_BROADCAST(&waitc); while (waitb) { DEBUG_PRINT1("B Waiting"); MUTEX_WAIT(&condb, &mutex); } DEBUG_PRINT1("B Continuing"); MUTEX_UNLOCK(&mutex); }
static void holda( void) { MUTEX_LOCK(&mutex); waita = 1; DEBUG_PRINT1("A Broadcast C"); MUTEX_BROADCAST(&waitc); while (waita) { DEBUG_PRINT1("A Waiting"); MUTEX_WAIT(&conda, &mutex); } DEBUG_PRINT1("A Continuing"); MUTEX_UNLOCK(&mutex); }
//******************************************************************// //********************* List destroy functions *********************// //******************************************************************// void ClearSaveFileList(void) { PFILEINFO lpFileInfo; KDLinkedListItem* lpNode; __try { MUTEX_WAIT(LockMutexToFileSaveList); if (_MmIsAddressValid(pDirTree)) delete pDirTree; pDirTree = NULL; if (_MmIsAddressValid(pSaveList)) { lpNode = pSaveList->GetHead(); while (_MmIsAddressValid(lpNode)) { lpFileInfo = (PFILEINFO)pSaveList->RemoveHead(); if (_MmIsAddressValid(lpFileInfo)) { FreePoolToKHeap(hKHeapSOFileList, lpFileInfo); } lpNode = pSaveList->GetHead(); } delete pSaveList; pSaveList = NULL; } MUTEX_RELEASE(LockMutexToFileSaveList); } __except(EXCEPTION_EXECUTE_HANDLER) { MUTEX_RELEASE(LockMutexToFileSaveList); DbgPrintSO(("He4HookInv: ClearSaveFileList: EXCEPTION\n")); } }
/* run procthread */ void procthread_run(void *arg) { PROCTHREAD *pth = (PROCTHREAD *)arg; int i = 0, usec = 0, sec = 0; struct timeval tv = {0,0}; struct timespec ts = {0, 0}; int k = 0, n = 0, policy = 0; if(pth) { struct sched_param param; pthread_getschedparam(pthread_self(), &policy, ¶m); ACCESS_LOGGER(pth->logger, "Ready for running thread[%p] policy:%d SCHED_FIFO:%d SCHED_RR:%d SCHED_OTHER:%d", (void*)((long)(pth->threadid)), policy, SCHED_FIFO, SCHED_RR, SCHED_OTHER); pth->running_status = 1; if(pth->usec_sleep > 1000000) sec = pth->usec_sleep/1000000; usec = pth->usec_sleep % 1000000; tv.tv_sec = sec; tv.tv_usec = usec; ts.tv_sec = sec; ts.tv_nsec = (long)usec * 1000l; if(pth->have_evbase) { if(pth->cond > 0) { event_set(&(pth->event), pth->cond, E_READ|E_PERSIST, (void *)pth, (void *)&procthread_event_handler); pth->evbase->add(pth->evbase, &(pth->event)); if(pth->service->flag & SB_LOG_THREAD) { char line[256]; if(pth == pth->service->outdaemon) { sprintf(line, "/tmp/%s_outdaemon.log", pth->service->service_name); evbase_set_logfile(pth->evbase, line); } else { sprintf(line, "/tmp/%s_indaemon.log", pth->service->service_name); evbase_set_logfile(pth->evbase, line); } } } do { i = pth->evbase->loop(pth->evbase, 0, NULL); if(pth->service->flag & SB_LOG_THREAD) { if(pth == pth->service->outdaemon) { ACCESS_LOGGER(pth->logger, "outdaemon_loop(%d/%d) q[%p]{total:%d left:%d}", i, k, pth->message_queue, QMTOTAL(pth->message_queue), QNLEFT(pth->message_queue)); } else { ACCESS_LOGGER(pth->logger, "iodaemon_loop(%d/%d) q[%p]{total:%d left:%d}", i, k, pth->message_queue, QMTOTAL(pth->message_queue), QNLEFT(pth->message_queue)); } } if(pth->message_queue && (k = QMTOTAL(pth->message_queue)) > 0) { qmessage_handler(pth->message_queue, pth->logger); } if((pth->service->flag & (SB_IO_NANOSLEEP|SB_IO_USLEEP|SB_IO_SELECT)) && n++ > pth->service->nworking_tosleep) { if(pth->service->flag & SB_IO_NANOSLEEP) nanosleep(&ts, NULL); else if(pth->service->flag & SB_IO_USLEEP) usleep(pth->usec_sleep); else if(pth->service->flag & SB_IO_SELECT) select(0, NULL, NULL, NULL, &tv); n = 0; } }while(pth->running_status); if(pth == pth->service->outdaemon) { ACCESS_LOGGER(pth->logger, "Ready for stop outdaemons[%p]", pth); } else { ACCESS_LOGGER(pth->logger, "Ready for stop iodaemons[%p]", pth); } } else if(pth->listenfd > 0) { do { service_accept_handler(pth->service); }while(pth->running_status); ACCESS_LOGGER(pth->logger, "Ready for stop threads[acceptor]"); } else { if(pth->use_cond_wait) { do { //DEBUG_LOGGER(pth->logger, "starting cond-wait() threads[%p]->qmessage[%p]_handler(%d)", (void *)pth->threadid,pth->message_queue, QMTOTAL(pth->message_queue)); if(pth->message_queue && (k = QMTOTAL(pth->message_queue)) > 0) { qmessage_handler(pth->message_queue, pth->logger); i = 1; } if(QMTOTAL(pth->message_queue) < 1) { if(pth->service->flag & SB_USE_EVSIG) evsig_wait(&(pth->evsig)); else if(pth->service->flag & SB_USE_COND) { MUTEX_WAIT(pth->mutex); } else nanosleep(&ts, NULL); } }while(pth->running_status); ACCESS_LOGGER(pth->logger, "ready to exit threads/daemons[%d]", pth->index); } else { do { //DEBUG_LOGGER(pth->logger, "starting threads[%p]->qmessage[%p]_handler(%d)", (void *)(pth->threadid),pth->message_queue, QMTOTAL(pth->message_queue)); if(pth->evtimer){EVTIMER_CHECK(pth->evtimer);} if(pth->message_queue && QMTOTAL(pth->message_queue) > 0) { qmessage_handler(pth->message_queue, pth->logger); } nanosleep(&ts, NULL); //WARN_LOGGER(pth->logger, "over threads[%p]->qmessage[%p]_handler(%d)", (void *)(pth->threadid),pth->message_queue, QMTOTAL(pth->message_queue)); }while(pth->running_status); ACCESS_LOGGER(pth->logger, "ready to exit threads/daemons[%d]", pth->index); } } if(pth->message_queue && QMTOTAL(pth->message_queue) > 0) qmessage_handler(pth->message_queue, pth->logger); ACCESS_LOGGER(pth->logger, "terminate threads[%d][%p] evbase[%p] qmessage[%p] ioqmessage[%p] qtotal:%d", pth->index, (void *)(pth->threadid), pth->evbase, pth->message_queue, pth->inqmessage, QMTOTAL(pth->message_queue)); } #ifdef HAVE_PTHREAD pthread_exit(NULL); #endif return ; }
BOOLEAN DelFileSaveList(PFILEINFOSET lpFileInfoSet) { ULONG dwSize, dwSizeOfItem; CHAR *lpszStr; KDLinkedListItem* lpNode; PFILEINFO lpFileInfo, lpFileInfoIn; if (!_MmIsAddressValid(pSaveList)) return FALSE; if (!_MmIsAddressValid(pDirTree)) return FALSE; if (!_MmIsAddressValid(lpFileInfoSet)) return FALSE; if (lpFileInfoSet->dwSize < SIZEOF_FILEINFOSET) return FALSE; MUTEX_WAIT(LockMutexToFileSaveList); dwSize = lpFileInfoSet->dwSize - (SIZEOF_FILEINFOSET - SIZEOF_FILEINFO); lpFileInfoIn = &lpFileInfoSet->FileInfo[0]; while (dwSize > SIZEOF_FILEINFO) { if (!CheckFileInfo(lpFileInfoIn)) break; dwSizeOfItem = ((SIZEOF_FILEINFO-sizeof(CHAR)) + lpFileInfoIn->dwSizeAllNamesArea); if (lpFileInfoIn->dwSizeAnsiName > sizeof(CHAR)) { lpNode = pSaveList->GetHead(); while (_MmIsAddressValid(lpNode)) { lpFileInfo = (PFILEINFO)lpNode->GetObject(); if (!_MmIsAddressValid(lpFileInfo)) { lpNode = lpNode->GetNext(); continue; } lpszStr = lpFileInfoIn->szNames+lpFileInfoIn->dwOffsetToAnsiName; if (!CompareString(lpFileInfo->szNames+lpFileInfo->dwOffsetToAnsiName, lpszStr, TRUE)) { DbgPrintSO(("He4HookInv: DelFileSaveList: Start delete - %s\n", lpszStr)); pDirTree->Remove((PWSTR)(lpFileInfo->szNames+lpFileInfo->dwOffsetToUniName), NULL); pSaveList->Remove(lpNode); lpNode = pSaveList->GetHead(); DbgPrintSO(("He4HookInv: DelFileSaveList: End delete - %s\n", lpszStr)); FreePoolToKHeap(hKHeapSOFileList, lpFileInfo); continue; } lpNode = lpNode->GetNext(); } } dwSize -= dwSizeOfItem; lpFileInfoIn = (PFILEINFO)((PCHAR)lpFileInfoIn + dwSizeOfItem); } MUTEX_RELEASE(LockMutexToFileSaveList); return TRUE; }
BOOLEAN AddFileSaveList(PFILEINFOSET lpFileInfoSet) { PFILEINFO lpFileInfo, lpFileInfoIn; ULONG dwSize, dwSizeOfItem, dwSizeOfItemNew; PWSTR pwszNtFileName; ULONG dwSizeOfNtFileName; ANSI_STRING FileNameAnsi; UNICODE_STRING FileNameUni; if (!_MmIsAddressValid(lpFileInfoSet)) return FALSE; if (lpFileInfoSet->dwSize < SIZEOF_FILEINFOSET) return FALSE; MUTEX_WAIT(LockMutexToFileSaveList); DbgPrintSO(("He4HookInv: AddFileSaveList: Start!!!\n")); if (!_MmIsAddressValid(pSaveList)) { pSaveList = new KDLinkedList(NULL); if (pSaveList == NULL) { DbgPrintSO(("He4HookInv: AddFileSaveList: File list create ERROR!!!\n")); MUTEX_RELEASE(LockMutexToFileSaveList); return FALSE; } } if (!_MmIsAddressValid(pDirTree)) { pDirTree = new KShieldDirectoryTree(); if (pDirTree == NULL) { DbgPrintSO(("He4HookInv: AddFileSaveList: KShieldDirectoryTree create ERROR!!!\n")); MUTEX_RELEASE(LockMutexToFileSaveList); return FALSE; } } DbgPrintSO(("He4HookInv: AddFileSaveList: List created OK!!!\n")); dwSize = lpFileInfoSet->dwSize - (SIZEOF_FILEINFOSET - SIZEOF_FILEINFO); lpFileInfoIn = &lpFileInfoSet->FileInfo[0]; while(dwSize > SIZEOF_FILEINFO) { if (!CheckFileInfo(lpFileInfoIn)) break; dwSizeOfItem = ((SIZEOF_FILEINFO-sizeof(CHAR)) + lpFileInfoIn->dwSizeAllNamesArea); if (lpFileInfoIn->dwSizeAnsiName > sizeof(CHAR)) { pwszNtFileName = (PWSTR)_AllocatePoolFromKHeap(hKHeapSOFileList, sizeof(WCHAR)*lpFileInfoIn->dwSizeAnsiName+2048); if (pwszNtFileName) { RtlInitAnsiString(&FileNameAnsi, lpFileInfoIn->szNames+lpFileInfoIn->dwOffsetToAnsiName); RtlAnsiStringToUnicodeString(&FileNameUni, &FileNameAnsi, TRUE); dwSizeOfNtFileName = DosPathNameToNtPathName(FileNameUni.Buffer, pwszNtFileName, sizeof(WCHAR)*lpFileInfoIn->dwSizeAnsiName+2048, 255, NULL); RtlFreeUnicodeString(&FileNameUni); if (dwSizeOfNtFileName) { dwSizeOfNtFileName += sizeof(WCHAR); dwSizeOfItemNew = (SIZEOF_FILEINFO-sizeof(CHAR)) + lpFileInfoIn->dwSizeAnsiName + dwSizeOfNtFileName; #define ADD_NT_PATH L"\\??\\" //L"\\DosDevices\\" //L"\\??\\" if (lpFileInfoIn->dwAccessType & FILE_ACC_TYPE_EXCHANGE) { if (lpFileInfoIn->dwSizeAnsiChangedName > sizeof(CHAR)) { dwSizeOfItemNew += sizeof(WCHAR)*lpFileInfoIn->dwSizeAnsiChangedName + sizeof(ADD_NT_PATH)-sizeof(WCHAR); } else { if (lpFileInfoIn->dwSizeUniChangedName > sizeof(WCHAR)) dwSizeOfItemNew += lpFileInfoIn->dwSizeUniChangedName; } } lpFileInfo = (PFILEINFO)_AllocatePoolFromKHeap(hKHeapSOFileList, dwSizeOfItemNew+sizeof(WCHAR)); if (lpFileInfo) { memset(lpFileInfo, 0, dwSizeOfItemNew+sizeof(WCHAR)); lpFileInfo->dwAccessType = lpFileInfoIn->dwAccessType; lpFileInfo->dwSizeAllNamesArea = dwSizeOfItemNew - (SIZEOF_FILEINFO-sizeof(CHAR)); lpFileInfo->dwOffsetToAnsiName = 0; lpFileInfo->dwSizeAnsiName = lpFileInfoIn->dwSizeAnsiName; RtlCopyMemory(lpFileInfo->szNames+lpFileInfo->dwOffsetToAnsiName, lpFileInfoIn->szNames+lpFileInfoIn->dwOffsetToAnsiName, lpFileInfo->dwSizeAnsiName); lpFileInfo->dwOffsetToUniName = lpFileInfo->dwOffsetToAnsiName + lpFileInfo->dwSizeAnsiName; lpFileInfo->dwSizeUniName = dwSizeOfNtFileName; RtlCopyMemory(lpFileInfo->szNames+lpFileInfo->dwOffsetToUniName, pwszNtFileName, dwSizeOfNtFileName); if (lpFileInfoIn->dwAccessType & FILE_ACC_TYPE_EXCHANGE) { if (lpFileInfoIn->dwSizeAnsiChangedName > sizeof(CHAR)) { lpFileInfo->dwOffsetToUniChangedName = lpFileInfo->dwOffsetToUniName + lpFileInfo->dwSizeUniName; lpFileInfo->dwSizeUniChangedName = sizeof(WCHAR)*lpFileInfoIn->dwSizeAnsiChangedName+sizeof(ADD_NT_PATH)-sizeof(WCHAR); RtlInitAnsiString(&FileNameAnsi, lpFileInfoIn->szNames+lpFileInfoIn->dwOffsetToAnsiChangedName); RtlAnsiStringToUnicodeString(&FileNameUni, &FileNameAnsi, TRUE); RtlCopyMemory(lpFileInfo->szNames+lpFileInfo->dwOffsetToUniChangedName, ADD_NT_PATH, sizeof(ADD_NT_PATH)); RtlCopyMemory((lpFileInfo->szNames+lpFileInfo->dwOffsetToUniChangedName+sizeof(ADD_NT_PATH)-sizeof(WCHAR)), FileNameUni.Buffer, (sizeof(WCHAR)*lpFileInfoIn->dwSizeAnsiChangedName) < (FileNameUni.Length+sizeof(WCHAR)) ? (sizeof(WCHAR)*lpFileInfoIn->dwSizeAnsiChangedName) : (FileNameUni.Length+sizeof(WCHAR))); RtlFreeUnicodeString(&FileNameUni); } else { if (lpFileInfoIn->dwSizeUniChangedName > sizeof(WCHAR)) { lpFileInfo->dwOffsetToUniChangedName = lpFileInfo->dwOffsetToUniName + lpFileInfo->dwSizeUniName; lpFileInfo->dwSizeUniChangedName = lpFileInfoIn->dwSizeUniChangedName; RtlCopyMemory( lpFileInfo->szNames+lpFileInfo->dwOffsetToUniChangedName, lpFileInfoIn->szNames+lpFileInfoIn->dwOffsetToUniChangedName, lpFileInfo->dwSizeUniChangedName ); } else { lpFileInfo->dwAccessType &= ~FILE_ACC_TYPE_EXCHANGE; } } } PVOID pContext; if (pDirTree->Find((PWSTR)(lpFileInfo->szNames+lpFileInfo->dwOffsetToUniName), &pContext) == NULL) { DbgPrintSO(("He4HookInv: AddFileSaveList: %s, type = %x\n", lpFileInfo->szNames+lpFileInfo->dwOffsetToAnsiName, lpFileInfo->dwAccessType)); if (pDirTree->Add((PWSTR)(lpFileInfo->szNames+lpFileInfo->dwOffsetToUniName), (PVOID)lpFileInfo) == TRUE) { if (pSaveList->AddTailObject(lpFileInfo) == FALSE) { pDirTree->Remove((PWSTR)(lpFileInfo->szNames+lpFileInfo->dwOffsetToUniName), NULL); FreePoolToKHeap(hKHeapSOFileList, lpFileInfo); } } else { FreePoolToKHeap(hKHeapSOFileList, lpFileInfo); } } else { FreePoolToKHeap(hKHeapSOFileList, lpFileInfo); } } } FreePoolToKHeap(hKHeapSOFileList, pwszNtFileName); } } dwSize -= dwSizeOfItem; lpFileInfoIn = (PFILEINFO)((PCHAR)lpFileInfoIn + dwSizeOfItem); } MUTEX_RELEASE(LockMutexToFileSaveList); return TRUE; }