/*============================================ * FuncName : MemoryLog::ClearLogByName * Description : * @key : * Author : * Time : 2017-06-05 ============================================*/ void MemoryLog::ClearLogByName(const char *key, bool tips = true, bool lock = true) { if(lock) MUTEX_P (mutex); if(tips) fprintf(stdout, "clear mlog key[%s], ", key); MLOG_MAP_IT it = mlog.find(string(key)); if(it != mlog.end()) { MLOG_VEC &vec = it->second; for(MLOG_VEC_IT vit = vec.begin(); vit != vec.end(); ++vit) { T_MLOG tlog = (*vit); free(tlog.msgaddr); } vec.clear(); mlog.erase(it); if(tips) fprintf(stdout, "\nclear mlog key[%s] done!!\n", key); } else { if(tips) fprintf(stdout, "no data!!\n"); } if(lock) MUTEX_V (mutex); }
/*============================================ * FuncName : MemoryLog::ClearLogAll * Description : * @ : * Author : * Time : 2017-06-05 ============================================*/ void MemoryLog::ClearLogAll() { MUTEX_P (mutex); if(!mlog.size() ) { fprintf(stdout, "no data!!\n"); MUTEX_V (mutex); return; } fprintf(stdout, "clear all mlog, size:%u\n", mlog.size()); vector<string> keys; vector<string>::iterator it; keys.clear(); for(MLOG_MAP_IT it = mlog.begin(); it != mlog.end(); ++it) { keys.push_back(it->first); } for(it = keys.begin(); it != keys.end(); it++) ClearLogByName((*it).c_str(),false, false); mlog.clear(); keys.clear(); fprintf(stdout, "clear all mlog, size:%u, done!!\n", mlog.size()); MUTEX_V (mutex); }
/*============================================ * FuncName : MemoryLog::ShowLogLastItemByName * Description : show key's memory log last item(one) * @key : * @index : show tips or not * Author : * Time : 2017-06-05 ============================================*/ void MemoryLog::ShowLogLastItemByName(const char *key, bool index = true) { MUTEX_P (mutex); if(index) fprintf(stdout, "show mlog key[%-10s], ", key); MLOG_MAP_IT it = mlog.find(string(key)); if(it != mlog.end()) { MLOG_VEC &vec = it->second; fprintf(stdout, "key[%s] size:%u\n", key, vec.size()); for(MLOG_VEC_RIT rvit = vec.rbegin(); rvit != vec.rend(); ++rvit) { ParseMsgBody(*rvit,stdout); break; } if(index) fprintf(stdout, "show mlog key[%s] size:%u done!!\n\n", key, vec.size()); } else { if(index) fprintf(stdout, "no data!!\n\n"); } MUTEX_V (mutex); }
/*============================================ * FuncName : MemoryLog::ShowLogByNameLastCnt * Description : show key's memory log from last print count's info * @key : * @index : show tips or not * Author : * Time : 2017-06-05 ============================================*/ void MemoryLog::ShowLogByNameLastCnt(const char *key, unsigned int count) { MUTEX_P (mutex); MLOG_MAP_IT it = mlog.find(string(key)); if(it != mlog.end()) { unsigned int loopnum = 0; unsigned int curnum = 0; MLOG_VEC &vec = it->second; fprintf(stdout, "[%s] size:%u, last cnt:%u\n", key, vec.size(), count); loopnum = count >= vec.size() ? 0 : (vec.size() - count); for(MLOG_VEC_IT vit = vec.begin(); vit != vec.end(); ++vit) { if(curnum++ < loopnum ) { // fprintf(stdout, "curnum:%u, loopnum:%u\n",curnum, loopnum); continue; } // fprintf(stdout, "else curnum:%u, loopnum:%u\n",curnum, loopnum); ParseMsgBody(*vit,stdout); } } else { if(count) fprintf(stdout, "no data!!\n\n"); } MUTEX_V (mutex); }
/*============================================ * FuncName : MemoryLog::CheckPushLog * Description : * @key : * Author : * Time : 2017-06-07 ============================================*/ bool MemoryLog::CheckPushLog(const char *key) { MUTEX_P(mutex); MLOG_MAP_IT it = mlog.find(string(key)); if(it != mlog.end()) { MLOG_VEC &vec = it->second; if(get_mlogformat() && vec.size() >= get_mlogmaxsize()) { T_MLOG tlog = *(vec.begin()); free(tlog.msgaddr); vec.erase(vec.begin() + 0, vec.begin() + 1);//erase the first data MUTEX_V(mutex); return true; } if(vec.size() >= get_mlogmaxsize()) { MUTEX_V(mutex); return false; } else { MUTEX_V(mutex); return true; } } MUTEX_V(mutex); return true; }
//当用户程序不读数据时,重新设置LOG //---------------------------------------------------------------------- VOID ResetLog( VOID ) { PLOG_BUF current, next; MUTEX_P( LogMutex ); // // Traverse the list of output buffers // current = Log->Next; while( current ) { // // Free the buffer // next = current->Next; ExFreePool( current ); current = next; } // // Move the output pointer in the buffer that's being kept // the start of the buffer. // NumLog = 1; Log->Length = 0; Log->Next = NULL; MUTEX_V( LogMutex ); }
/*============================================ * FuncName : MemoryLog::SaveLog2FileByName * Description : * @key : * @tips : * Author : * Time : 2017-06-05 ============================================*/ void MemoryLog::SaveLog2FileByName(const char *key, const char *filewithpath = "/tmp/aaa.mlog", bool tips = true, FILE *fother = NULL) { string name(filewithpath); FILE *fp = NULL; if(NULL == fother) { fp = fopen(name.c_str(), "w"); if(!fp) { fprintf(stderr, "open file err![%-10s] %s\n", name.c_str(), strerror(errno)); return; } } else { fp = fother; } timeval now; gettimeofday(&now, NULL); MUTEX_P (mutex); if(tips && name != ""){ // fprintf(fp, "time:s-us: %u-%u\n", now.tv_sec, now.tv_usec); fprintf(stdout, "save mlog to file[%-10s], ", name.c_str()); fprintf(fp, "save mlog to file[%-10s], ", name.c_str()); } else if(tips) { // fprintf(fp, "time:s-us: %u-%u\n", now.tv_sec, now.tv_usec); fprintf(stdout, "save mlog key[%-10s], ", key); fprintf(fp, "save mlog key[%-10s], ", key); } MLOG_MAP_IT it = mlog.find(string(key)); if(it != mlog.end()) { MLOG_VEC &vec = it->second; fprintf(fp, "[%s] size:%u\n", key, vec.size()); for(MLOG_VEC_IT vit = vec.begin(); vit != vec.end(); ++vit) { ParseMsgBody(*vit,fp); } if(tips){ fprintf(stdout, "save mlog key[%-10s], done!!\n\n", key); fprintf(fp, "save mlog key[%-10s], done!!\n\n", key); } } else { if(tips) fprintf(fp, "no data!!\n\n"); } fflush(fp); if(NULL == fother) { fclose(fp); } MUTEX_V (mutex); }
/*============================================ * FuncName : MemoryLog::PushLog * Description : 推入数据流到内存 * @key : 索引字 * @fmt : 字符串格式 * @-- : 变长 * Author : * Time : 2017-06-05 ============================================*/ void MemoryLog::PushLog(const char *key, T_MLOG &tlog) { MUTEX_P (mutex); MLOG_MAP_IT it = mlog.find(string(key)); if(it != mlog.end()) { MLOG_VEC &vec = it->second; if(vec.size() >= get_mlogmaxsize()) { MUTEX_V(mutex); return; } try { vec.push_back(tlog); PrintPushLog(key, tlog); } catch (exception& e) { // cout << e.what() << endl; printf("get mem failed!!!\n"); } } else { try { MLOG_VEC vec; vec.push_back(tlog); mlog.insert(MLOG_MAP_PAIR(string(key), vec)); PrintPushLog(key, tlog); } catch (exception& e) { // cout << e.what() << endl; printf("get mem failed!!!\n"); } } MUTEX_V(mutex); // if(mlogswitch) // { // ShowLogLastItemByName(key, false); // } }
//把程序行为放到LOG里 VOID UpdateLog(PTSTR pData) { PMESSAGE pTempM; ULONG TempLength = 0; MUTEX_P(LogMutex); if(Log->Length > MAX_MESSAGE - 500) { NewLog(); } // /*typedef struct _log { ULONG Length; struct _log * Next; TCHAR Message[MAX_MESSAGE]; }LOG_BUF,*PLOG_BUF; typedef struct { ULONG Sequence; TCHAR Message[0]; }MESSAGE,*PMESSAGE;*/ pTempM = (PMESSAGE)(Log->Message + Log->Length);//Log->Message+Log->Length后指针指向之前存的字符串的末尾 //然后再装入数据知道指定长度 if(pTempM == NULL) { DbgPrint("pTempM == NULL\n"); } else { TempLength = sprintf(pTempM->Message,"%s",pData); Log->Length +=TempLength + 1; } MUTEX_V(LogMutex); return ; }
NTSTATUS SSDTDeviceIoCtl( PDEVICE_OBJECT pDeviceObject, PIRP Irp ) { // ULONG pbuf; PLOG_BUF old; NTSTATUS s; PIO_STACK_LOCATION IrpStack; PVOID InputBuffer; PVOID OutputBuffer; ULONG InputBufferLength; ULONG OutputBufferLength; ULONG IoControlCode; s = Irp->IoStatus.Status = STATUS_SUCCESS; Irp->IoStatus.Information = 0; IrpStack = IoGetCurrentIrpStackLocation( Irp ); InputBuffer = IrpStack->Parameters.DeviceIoControl.Type3InputBuffer; InputBufferLength = IrpStack->Parameters.DeviceIoControl.InputBufferLength; OutputBuffer = Irp->UserBuffer; OutputBufferLength = IrpStack->Parameters.DeviceIoControl.OutputBufferLength; IoControlCode = IrpStack->Parameters.DeviceIoControl.IoControlCode; /////////////////////////////////////////////// //这里处理分发例程 switch( IoControlCode ) { case IOCTL_REG_PROTECTION://开启注册表保护 CmRegisterCallback(RegistryCallback, NULL, &Cookie ); Prot=TRUE; break; case IOCTL_STOP_PROTECTION://停止注册表保护 CmUnRegisterCallback(Cookie); Prot=FALSE; break; case IOCTL_SAVE_EVENT://把事件传到驱动 { EVENT_INFORMATION EvntInfo; __try { ProbeForRead( InputBuffer, sizeof(EvntInfo), sizeof( ULONG ) ); memcpy(&EvntInfo,InputBuffer,8); } __except(EXCEPTION_EXECUTE_HANDLER) { ; } if (!NT_SUCCESS(ObReferenceObjectByHandle(EvntInfo.hKernelSetEvent,0,*ExEventObjectType,UserMode,&EventKernelSet,NULL))) { EventKernelSet=NULL; } if (!NT_SUCCESS(ObReferenceObjectByHandle(EvntInfo.hKernelWaitEvent,0,*ExEventObjectType,UserMode,&EventKernelWait,NULL))) { EventKernelWait=NULL; } DbgPrint("[Kernel_Driver] EventKernelSet = 0x%X, EventKernelWait=0x%X.\n",EventKernelSet,EventKernelWait); s = STATUS_SUCCESS; break; } case IOCTL_REGISTRY_INFO://获得注册表信息 { DbgPrint("[Kernel_Driver] IOCTL_GET_CREATE_PROC_INFO.\n"); __try { REGISTRY_INFORMATION RegInfo={0}; memcpy(RegInfo.ProcessName,aProcessName,256); memcpy(RegInfo.KeyPath,astr.Buffer,256); DbgPrint("%s %s.\n",RegInfo.ProcessName,RegInfo.KeyPath); ProbeForWrite( OutputBuffer, sizeof(RegInfo), sizeof( ULONG ) ); RtlCopyMemory(OutputBuffer,&RegInfo,sizeof(RegInfo)); // it's strange. } __except(EXCEPTION_EXECUTE_HANDLER) { DbgPrint("[Kernel_Driver] IOCTL_GET_CREATE_PROC_INFO raised exception.\n"); ; } break; } case IOCTL_ALLOW_MODIFY://允许修改 { __try { ProbeForRead( InputBuffer, sizeof(CreateAllowed), sizeof( ULONG ) ); memcpy(&CreateAllowed,InputBuffer,sizeof(CreateAllowed)); } __except(EXCEPTION_EXECUTE_HANDLER) { ; } break; } //************************************************* case IOCTL_GETSSDT: //得到SSDT __try { ProbeForWrite( OutputBuffer, sizeof( MYSSDT ), sizeof( ULONG ) ); RtlCopyMemory( OutputBuffer, KeServiceDescriptorTable, sizeof( MYSSDT ) ); } __except( EXCEPTION_EXECUTE_HANDLER ) { s = GetExceptionCode(); break; } DbgPrint( "SSDT: GetSSDT Completeled!" ); break; case IOCTL_KILL: { __try { ProbeForRead( InputBuffer, sizeof( ULONG ), sizeof( ULONG ) ); memcpy(&processID,InputBuffer,sizeof(processID)); s=PsLookupProcessByProcessId(processID,&eProcess); if(NT_SUCCESS(s)) { ObDereferenceObject(eProcess); } s=TerminateProcess(eProcess); if(NT_SUCCESS(s)) { DbgPrint("TerminateProcess Ok!\n"); } } __except( EXCEPTION_EXECUTE_HANDLER ) { s = GetExceptionCode(); break; } // status = STATUS_SUCCESS; break; } case IOCTL_ENUMTCP://枚举TCP连接 { PVOID pOut=NULL; ULONG OutLen=0; if(OutputBufferLength<sizeof(CONNINFO102)) { KdPrint(("输出缓冲区长度无效\n")); s=STATUS_BUFFER_OVERFLOW; break; } pOut=EnumPortInformation(&OutLen,TCPPORT); if(!pOut) { KdPrint(("获取TCP端口信息失败!\n")); s=STATUS_UNSUCCESSFUL; break; } if(OutputBufferLength<OutLen) { KdPrint(("输出缓冲区太小,应为%ld\n",OutLen)); ExFreePool(pOut); s=STATUS_BUFFER_OVERFLOW; break; } RtlCopyMemory(OutputBuffer,pOut,OutLen); ExFreePool(pOut); Irp->IoStatus.Information = OutLen; break; } case IOCTL_ENUMUDP://枚举UDP连接 { PVOID pOut=NULL; ULONG OutLen=0; if(OutputBufferLength<sizeof(UDPCONNINFO)) { KdPrint(("输出缓冲区长度无效\n")); s=STATUS_BUFFER_OVERFLOW; break; } pOut=EnumPortInformation(&OutLen,UDPPORT); if(!pOut) { KdPrint(("获取UDP端口信息失败!\n")); s=STATUS_UNSUCCESSFUL; break; } if(OutputBufferLength<OutLen) { KdPrint(("输出缓冲区太小,应为%ld\n",OutLen)); ExFreePool(pOut); s=STATUS_BUFFER_OVERFLOW; break; } RtlCopyMemory(OutputBuffer,pOut,OutLen); ExFreePool(pOut); Irp->IoStatus.Information = OutLen; break; } case IOCTL_QSIADDR: EnumProcess(); __try { ProbeForWrite( OutputBuffer, OutputBufferLength, sizeof( UCHAR )); } __except( EXCEPTION_EXECUTE_HANDLER ) { Irp->IoStatus.Information = STATUS_INVALID_PARAMETER; return FALSE; } if(MAX_MESSAGE > OutputBufferLength) { return FALSE; } else if(Log->Length != 0 || Log->Next != NULL) { //pReturnLog = Log; MUTEX_P(LogMutex); // NewLog(); old=OldestLog(); if(old!=Log) { MUTEX_V(LogMutex); DbgPrint("Old log\n"); } memcpy(OutputBuffer,old->Message,old->Length); Irp->IoStatus.Information = old->Length; if(old!=Log) { ExFreePool(old); } else { DbgPrint("Current log\n"); Log->Length=0; MUTEX_V(LogMutex); } } else { // MUTEX_V(LogMutex); Irp->IoStatus.Information = 0; } DbgPrint("SSDT: Set QuerySystemInformation Address Completed!"); break; case IOCTL_SETSSDT: //设置 SSDT __try { ProbeForRead( InputBuffer, sizeof( MYSSDT ), sizeof( ULONG ) ); //去掉内存保护 __asm { cli ;//关中断 mov eax, cr0 and eax, ~0x10000 mov cr0, eax } RtlCopyMemory( KeServiceDescriptorTable, InputBuffer, sizeof( MYSSDT ) ); //开中断,把内存保护加上 __asm { mov eax, cr0 or eax, 0x10000 mov cr0, eax sti ;//开中断 } } __except( EXCEPTION_EXECUTE_HANDLER ) { s = GetExceptionCode(); break; } DbgPrint( "SSDT: SetSSDT Completeled!" ); break; //************************************************* case IOCTL_GETHOOK: //查询SSDT指定地址 __try { ProbeForRead( InputBuffer, sizeof( ULONG ), sizeof( ULONG ) ); ProbeForWrite( OutputBuffer, sizeof( ULONG ), sizeof( ULONG ) ); } __except( EXCEPTION_EXECUTE_HANDLER ) { s = GetExceptionCode(); break; } //测试传入的参数是否正确 if( KeServiceDescriptorTable->ulNumberOfServices <= *(PULONG)InputBuffer ) { s = STATUS_INVALID_PARAMETER; break; } //将结果传到用户输出位置 *((PULONG)OutputBuffer) = *( (PULONG)(KeServiceDescriptorTable->pvSSDTBase) + *(PULONG)InputBuffer ); DbgPrint( "SSDT: GetHookedAddress Completeled!" ); break; //************************************************* case IOCTL_SETHOOK: //设置SSDT指定地址 __try { ProbeForRead( InputBuffer, sizeof( ULONG ), sizeof( ULONG ) ); ProbeForRead( OutputBuffer, sizeof( ULONG ), sizeof( ULONG ) ); } __except( EXCEPTION_EXECUTE_HANDLER ) { s = GetExceptionCode(); break; } //测试传入的参数是否正确 if( KeServiceDescriptorTable->ulNumberOfServices <= *(PULONG)InputBuffer ) { s = STATUS_INVALID_PARAMETER; break; } //在此将输出缓冲区当作输入缓冲区来用,输入指定SSDT HOOK的地址值 //去掉内存保护 __asm { cli ;//关中断 mov eax, cr0 and eax, ~0x10000 mov cr0, eax } *( (PULONG)(KeServiceDescriptorTable->pvSSDTBase) + *(PULONG)InputBuffer ) = *((PULONG)OutputBuffer); //开中断,把内存保护加上 __asm { mov eax, cr0 or eax, 0x10000 mov cr0, eax sti ;//开中断 } DbgPrint( "SSDT: SetHookedAddress Completeled!" ); break; //************************************************* default: s = STATUS_INVALID_DEVICE_REQUEST; DbgPrint( "SSDT: Invalid Parameter Completeled!" ); break; } /////////////////////////////////////////////// IoCompleteRequest( Irp, IO_NO_INCREMENT ); return s; }