信息
This commit is contained in:
@@ -266,7 +266,7 @@ void WalkProcessMoudle(DWORD pID,HANDLE pHandle,WCHAR* pMoudleName) {
|
||||
FoundNum++;
|
||||
}
|
||||
if (FoundNum > 1) {
|
||||
printf("\t => [<5B><><EFBFBD>̼<EFBFBD><CCBC><EFBFBD>] <20><><EFBFBD><EFBFBD><E2B5BD><EFBFBD><EFBFBD><EFBFBD>Ŀ<EFBFBD>ִ<EFBFBD><D6B4><EFBFBD><EFBFBD><EFBFBD><EFBFBD>(.rdata<74><61>ɱ or <20>ӿdz<D3BF><C7B3><EFBFBD>) <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> %ws <EFBFBD><EFBFBD><EFBFBD><EFBFBD>id %d ģ<><C4A3><EFBFBD><EFBFBD> %ws <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> %s \n", pMoudleName, moduleEntry.szExePath, pID, SectionHeader[i].Name);
|
||||
printf("\t => [<5B><><EFBFBD>̼<EFBFBD><CCBC><EFBFBD>] <20><><EFBFBD><EFBFBD><E2B5BD><EFBFBD><EFBFBD><EFBFBD>Ŀ<EFBFBD>ִ<EFBFBD><D6B4><EFBFBD><EFBFBD><EFBFBD><EFBFBD>(.rdata<74><61>ɱ or <20>ӿdz<D3BF><C7B3><EFBFBD>) <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> %ws ·<EFBFBD><EFBFBD> %ws <20><><EFBFBD><EFBFBD>id %d\n", pMoudleName, moduleEntry.szExePath, pID);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
26
README.md
Normal file
26
README.md
Normal file
@@ -0,0 +1,26 @@
|
||||
# DuckMemoryScan
|
||||
一个简单寻找无文件落地后门的工具,由huoji花了1天编写,编写时间2021-02-24
|
||||
|
||||
# 功能列表
|
||||
1. HWBP hook检测 检测线程中所有疑似被hwb挂钩
|
||||
2. 内存免杀shellcode检测(metasploit,Cobaltstrike完全检测)
|
||||
3. 可疑进程检测(主要针对有逃避性质的进程[如过期签名与多各可执行区段])
|
||||
4. 无文件落地木马检测(检测所有已知内存加载木马)
|
||||
5. 简易rootkit检测(检测证书过期/拦截读取/证书无效的驱动)
|
||||
|
||||
# 免杀木马检测原理:
|
||||
所有所谓的内存免杀后门大部分基于"VirtualAlloc"函数申请内存 之后通过各种莫名其妙的xor甚至是aes加密去混淆shellcode达到"免杀"效果.
|
||||
本工具通过线程堆栈回溯方法(StackWalkEx函数)遍历线程,寻找系统中在VirtualAlloc区域执行代码的区域,从而揪出"免杀木马"
|
||||
当然也会存在误报,多常见于加壳程序也会申请VirtualAlloc分配内存.
|
||||
|
||||
# 无文件落地木马检测原理:
|
||||
所有无文件落地木马都是一个标准PE文件被映射到内存中,主要特征如下:
|
||||
1. 内存区段有M.Z标志
|
||||
2. 线程指向一个NOIMAGE内存
|
||||
本工具将会通过第一种特征检测出所有"无文件落地木马"
|
||||
|
||||
# 使用方式
|
||||
编译 运行 得到信息列表
|
||||
|
||||
# 追踪这个项目
|
||||
https://key08.com
|
||||
@@ -1,380 +0,0 @@
|
||||
#include <iostream>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <windows.h>
|
||||
#include <psapi.h>
|
||||
#include <shlwapi.h>
|
||||
#include <string.h>
|
||||
#include <wchar.h>
|
||||
#include <dbghelp.h>
|
||||
#pragma comment(lib,"dbghelp.lib")
|
||||
#include "tlhelp32.h"
|
||||
#include "CdigitalSig.h"
|
||||
BOOL Is64BitPorcess(HANDLE hProcess)
|
||||
{
|
||||
BOOL bIsWow64 = false;
|
||||
IsWow64Process(hProcess, &bIsWow64);
|
||||
return bIsWow64 == false;
|
||||
}
|
||||
BOOL EnableDebugPrivilege(BOOL bEnable)
|
||||
{
|
||||
//Enabling the debug privilege allows the application to see
|
||||
//information about service application
|
||||
BOOL fOK = FALSE; //Assume function fails
|
||||
HANDLE hToken;
|
||||
//Try to open this process's acess token
|
||||
if (OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES, &hToken))
|
||||
{
|
||||
//Attempt to modify the "Debug" privilege
|
||||
TOKEN_PRIVILEGES tp;
|
||||
tp.PrivilegeCount = 1;
|
||||
LookupPrivilegeValue(NULL, SE_DEBUG_NAME, &tp.Privileges[0].Luid);
|
||||
tp.Privileges[0].Attributes = bEnable ? SE_PRIVILEGE_ENABLED : 0;
|
||||
AdjustTokenPrivileges(hToken, FALSE, &tp, sizeof(tp), NULL, NULL);
|
||||
fOK = (GetLastError() == ERROR_SUCCESS);
|
||||
CloseHandle(hToken);
|
||||
}
|
||||
return fOK;
|
||||
}
|
||||
|
||||
void WCharToChar(const WCHAR* tchar, char* _char)
|
||||
{
|
||||
int iLength;
|
||||
iLength = WideCharToMultiByte(CP_ACP, 0, tchar, -1, NULL, 0, NULL, NULL);
|
||||
WideCharToMultiByte(CP_ACP, 0, tchar, -1, _char, iLength, NULL, NULL);
|
||||
}
|
||||
void CharToWchar(const char* _char, WCHAR* tchar)
|
||||
{
|
||||
int iLength;
|
||||
iLength = MultiByteToWideChar(CP_ACP, 0, _char, strlen(_char) + 1, NULL, 0);
|
||||
MultiByteToWideChar(CP_ACP, 0, _char, strlen(_char) + 1, tchar, iLength);
|
||||
}
|
||||
BOOL DosPathToNtPath(WCHAR* pszDosPath, LPTSTR pszNtPath)
|
||||
{
|
||||
TCHAR szDriveStr[500];
|
||||
TCHAR szDrive[3];
|
||||
TCHAR szDevName[100];
|
||||
INT cchDevName;
|
||||
INT i;
|
||||
|
||||
//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
if (!pszDosPath || !pszNtPath)
|
||||
return FALSE;
|
||||
|
||||
//<2F><>ȡ<EFBFBD><C8A1><EFBFBD>ش<EFBFBD><D8B4><EFBFBD><EFBFBD>ַ<EFBFBD><D6B7><EFBFBD>
|
||||
if (GetLogicalDriveStrings(sizeof(szDriveStr), szDriveStr))
|
||||
{
|
||||
for (i = 0; szDriveStr[i]; i += 4)
|
||||
{
|
||||
if (!lstrcmpi(&(szDriveStr[i]), L"A:\\") || !lstrcmpi(&(szDriveStr[i]), L"B:\\"))
|
||||
continue;
|
||||
|
||||
szDrive[0] = szDriveStr[i];
|
||||
szDrive[1] = szDriveStr[i + 1];
|
||||
szDrive[2] = '\0';
|
||||
if (!QueryDosDevice(szDrive, szDevName, 100))//<2F><>ѯ Dos <20>豸<EFBFBD><E8B1B8>
|
||||
return FALSE;
|
||||
|
||||
cchDevName = lstrlen(szDevName);
|
||||
if (_wcsnicmp(pszDosPath, szDevName, cchDevName) == 0)//<2F><><EFBFBD><EFBFBD>
|
||||
{
|
||||
lstrcpy(pszNtPath, szDrive);//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
lstrcat(pszNtPath, pszDosPath + cchDevName);//<2F><><EFBFBD><EFBFBD>·<EFBFBD><C2B7>
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
lstrcpy(pszNtPath, pszDosPath);
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
DWORD64 GetProcessMoudleHandle(DWORD pid) {
|
||||
MODULEENTRY32 moduleEntry;
|
||||
HANDLE handle = NULL;
|
||||
handle = ::CreateToolhelp32Snapshot(0x00000008, pid);
|
||||
ZeroMemory(&moduleEntry, sizeof(MODULEENTRY32));
|
||||
moduleEntry.dwSize = sizeof(MODULEENTRY32);
|
||||
if (!Module32First(handle, &moduleEntry)) {
|
||||
CloseHandle(handle);
|
||||
return NULL;
|
||||
}
|
||||
do {
|
||||
CloseHandle(handle);
|
||||
return (DWORD64)moduleEntry.hModule;
|
||||
} while (Module32Next(handle, &moduleEntry));
|
||||
return 0;
|
||||
}
|
||||
bool CheckThreadAddressIsExcute(DWORD64 pAddress,HANDLE pHandle, HANDLE pID, HANDLE Tid) {
|
||||
|
||||
DWORD64 ReadNum = 0;
|
||||
MEMORY_BASIC_INFORMATION mbi = { 0 };
|
||||
|
||||
if (VirtualQueryEx(pHandle, (LPCVOID)pAddress, &mbi, sizeof(mbi)))
|
||||
{
|
||||
if (mbi.AllocationBase) {
|
||||
if (mbi.Type != MEM_IMAGE) {
|
||||
if (mbi.AllocationProtect & PAGE_EXECUTE ||
|
||||
mbi.AllocationProtect & PAGE_EXECUTE_READ ||
|
||||
mbi.AllocationProtect & PAGE_EXECUTE_READWRITE ||
|
||||
mbi.AllocationProtect & PAGE_EXECUTE_WRITECOPY)
|
||||
{
|
||||
printf("\t => [<5B>̶߳<DFB3>ջ<EFBFBD><D5BB><EFBFBD><EFBFBD>] <20><><EFBFBD>δ֪<CEB4>ڴ<EFBFBD><DAB4><EFBFBD><EFBFBD><EFBFBD>[VirtualAlloc<6F><63>ɱ?] <20><>ַ %p PID %d TID %d \n", pAddress, pID, Tid);
|
||||
char PEStack[0x2];
|
||||
if (ReadProcessMemory(pHandle, mbi.BaseAddress, PEStack, sizeof(PEStack), &ReadNum)) {
|
||||
if (PEStack[0] == 'M' && PEStack[1] == 'Z') {
|
||||
printf("\t => [!!!<21>̶߳<DFB3>ջ<EFBFBD><D5BB><EFBFBD><EFBFBD>!!!] <20><><EFBFBD><EFBFBD>ڴ<EFBFBD><DAB4><EFBFBD><EFBFBD>س<EFBFBD><D8B3><EFBFBD> <20>̵߳<DFB3>ַ %p PID %d TID %d <20>ڴ<EFBFBD><DAB4><EFBFBD><EFBFBD><EFBFBD>ģ<EFBFBD><C4A3><EFBFBD><EFBFBD>ַ: %p\n", pAddress, pID, Tid, mbi.BaseAddress);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
void ThreadStackWalk() {
|
||||
HANDLE hThreadSnap = INVALID_HANDLE_VALUE;
|
||||
THREADENTRY32 te32;
|
||||
DWORD ExitCode = 0;
|
||||
hThreadSnap = CreateToolhelp32Snapshot(0x00000004, GetCurrentProcessId());
|
||||
if (hThreadSnap)
|
||||
{
|
||||
te32.dwSize = sizeof(THREADENTRY32);
|
||||
if (!Thread32First(hThreadSnap, &te32))
|
||||
{
|
||||
CloseHandle(hThreadSnap);
|
||||
return;
|
||||
}
|
||||
do
|
||||
{
|
||||
if (te32.th32OwnerProcessID != GetCurrentProcessId() && te32.th32ThreadID != GetCurrentThreadId())
|
||||
{
|
||||
HANDLE hThread = OpenThread(THREAD_ALL_ACCESS, 0, te32.th32ThreadID);
|
||||
if (hThread && hThread != (HANDLE)-1)
|
||||
{
|
||||
HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS, false, te32.th32OwnerProcessID);
|
||||
if (hProcess) {
|
||||
STACKFRAME_EX StackFarmeEx;
|
||||
memset(&StackFarmeEx, 0, sizeof(STACKFRAME_EX));
|
||||
if (Is64BitPorcess(hProcess)) {
|
||||
CONTEXT context = { 0 };
|
||||
context.ContextFlags = CONTEXT_ALL;
|
||||
if (GetThreadContext(hThread, &context))
|
||||
{
|
||||
if (context.Dr0 != 0 || context.Dr1 != 0 || context.Dr2 != 0 || context.Dr3 != 0)
|
||||
{
|
||||
//hwbp hook
|
||||
printf("\t => [<5B>̶߳<DFB3>ջ<EFBFBD><D5BB><EFBFBD><EFBFBD>] <20><><EFBFBD>HWBP Hook PID %d TID %d \n", te32.th32OwnerProcessID, te32.th32ThreadID);
|
||||
}
|
||||
CheckThreadAddressIsExcute(context.Rip, hProcess, (HANDLE)te32.th32OwnerProcessID, (HANDLE)te32.th32ThreadID);
|
||||
StackFarmeEx.AddrPC.Offset = context.Rip;
|
||||
StackFarmeEx.AddrPC.Mode = AddrModeFlat;
|
||||
StackFarmeEx.AddrStack.Offset = context.Rsp;
|
||||
StackFarmeEx.AddrStack.Mode = AddrModeFlat;
|
||||
StackFarmeEx.AddrFrame.Offset = context.Rsp;
|
||||
StackFarmeEx.AddrFrame.Mode = AddrModeFlat;
|
||||
DWORD machineType = IMAGE_FILE_MACHINE_AMD64;
|
||||
while (true)
|
||||
{
|
||||
if (!StackWalkEx(machineType, hProcess, hThread, &StackFarmeEx, &context, NULL, NULL, NULL, NULL, NULL))
|
||||
break;
|
||||
if (StackFarmeEx.AddrFrame.Offset == 0)
|
||||
break;
|
||||
CheckThreadAddressIsExcute(StackFarmeEx.AddrPC.Offset, hProcess, (HANDLE)te32.th32OwnerProcessID, (HANDLE)te32.th32ThreadID);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
WOW64_CONTEXT context = { 0 };
|
||||
context.ContextFlags = CONTEXT_ALL;
|
||||
if (Wow64GetThreadContext(hThread, &context))
|
||||
{
|
||||
if (context.Dr0 != 0 || context.Dr1 != 0 || context.Dr2 != 0 || context.Dr3 != 0)
|
||||
{
|
||||
//hwbp hook
|
||||
printf("\t => [<5B>̶߳<DFB3>ջ<EFBFBD><D5BB><EFBFBD><EFBFBD>] <20><><EFBFBD>HWBP Hook PID %d TID %d \n", te32.th32OwnerProcessID, te32.th32ThreadID);
|
||||
}
|
||||
|
||||
CheckThreadAddressIsExcute(context.Eip, hProcess, (HANDLE)te32.th32OwnerProcessID, (HANDLE)te32.th32ThreadID);
|
||||
StackFarmeEx.AddrPC.Offset = context.Eip;
|
||||
StackFarmeEx.AddrPC.Mode = AddrModeFlat;
|
||||
StackFarmeEx.AddrStack.Offset = context.Esp;
|
||||
StackFarmeEx.AddrStack.Mode = AddrModeFlat;
|
||||
StackFarmeEx.AddrFrame.Offset = context.Ebp;
|
||||
StackFarmeEx.AddrFrame.Mode = AddrModeFlat;
|
||||
DWORD machineType = IMAGE_FILE_MACHINE_I386;//IMAGE_FILE_MACHINE_I386; IMAGE_FILE_MACHINE_AMD64;
|
||||
while (true)
|
||||
{
|
||||
if (!StackWalkEx(machineType, hProcess, hThread, &StackFarmeEx, NULL, NULL, NULL, NULL, NULL, NULL))
|
||||
break;
|
||||
if (StackFarmeEx.AddrFrame.Offset == 0)
|
||||
break;
|
||||
CheckThreadAddressIsExcute(StackFarmeEx.AddrPC.Offset, hProcess, (HANDLE)te32.th32OwnerProcessID, (HANDLE)te32.th32ThreadID);
|
||||
}
|
||||
}
|
||||
}
|
||||
CloseHandle(hProcess);
|
||||
}
|
||||
CloseHandle(hThread);
|
||||
}
|
||||
}
|
||||
|
||||
} while (Thread32Next(hThreadSnap, &te32));
|
||||
CloseHandle(hThreadSnap);
|
||||
}
|
||||
}
|
||||
void WalkProcessMoudle(DWORD pID,HANDLE pHandle,WCHAR* pMoudleName) {
|
||||
|
||||
MODULEENTRY32 moduleEntry;
|
||||
HANDLE handle = NULL;
|
||||
handle = ::CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, pID);
|
||||
ZeroMemory(&moduleEntry, sizeof(MODULEENTRY32));
|
||||
moduleEntry.dwSize = sizeof(MODULEENTRY32);
|
||||
char* AllocBuff = (char*)VirtualAlloc(NULL, 0x200, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE);
|
||||
if (AllocBuff) {
|
||||
if (!Module32First(handle, &moduleEntry)) {
|
||||
CloseHandle(handle);
|
||||
return;
|
||||
}
|
||||
do {
|
||||
DWORD64 ReadNum = 0;
|
||||
if (ReadProcessMemory(pHandle, moduleEntry.modBaseAddr, AllocBuff, 0x200, &ReadNum)) {
|
||||
if (AllocBuff[0] == 'M' && AllocBuff[1] == 'Z') {
|
||||
PIMAGE_DOS_HEADER CopyDosHead = (PIMAGE_DOS_HEADER)AllocBuff;
|
||||
PIMAGE_NT_HEADERS CopyNthead = (PIMAGE_NT_HEADERS)((LPBYTE)AllocBuff + CopyDosHead->e_lfanew);
|
||||
/*
|
||||
DWORD64 BaseOfCode = 0;
|
||||
DWORD64 SizeOfCode = 0;
|
||||
if (CopyNthead->FileHeader.Machine == IMAGE_FILE_MACHINE_AMD64) {
|
||||
PIMAGE_NT_HEADERS64 CopyNthead64 = (PIMAGE_NT_HEADERS64)CopyNthead;
|
||||
BaseOfCode = CopyNthead64->OptionalHeader.BaseOfCode;
|
||||
SizeOfCode = CopyNthead64->OptionalHeader.SizeOfCode;
|
||||
}
|
||||
else {
|
||||
PIMAGE_NT_HEADERS32 CopyNthead32 = (PIMAGE_NT_HEADERS32)CopyNthead;
|
||||
BaseOfCode = CopyNthead32->OptionalHeader.BaseOfCode;
|
||||
SizeOfCode = CopyNthead32->OptionalHeader.SizeOfCode;
|
||||
}
|
||||
*/
|
||||
PIMAGE_SECTION_HEADER SectionHeader = (PIMAGE_SECTION_HEADER)((PUCHAR)CopyNthead + sizeof(CopyNthead->Signature) + sizeof(CopyNthead->FileHeader) + CopyNthead->FileHeader.SizeOfOptionalHeader);
|
||||
int FoundNum = 0;
|
||||
for (WORD i = 0; i < CopyNthead->FileHeader.NumberOfSections; i++)
|
||||
{
|
||||
if (SectionHeader[i].Characteristics & IMAGE_SCN_MEM_EXECUTE) {
|
||||
FoundNum++;
|
||||
}
|
||||
if (FoundNum > 1) {
|
||||
printf("\t => [<5B><><EFBFBD>̼<EFBFBD><CCBC><EFBFBD>] <20><><EFBFBD><EFBFBD><E2B5BD><EFBFBD><EFBFBD><EFBFBD>Ŀ<EFBFBD>ִ<EFBFBD><D6B4><EFBFBD><EFBFBD><EFBFBD><EFBFBD>(.rdata<74><61>ɱ or <20>ӿdz<D3BF><C7B3><EFBFBD>) <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> %ws ģ<><C4A3><EFBFBD><EFBFBD> %ws <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> %s \n", pMoudleName, moduleEntry.szExePath, SectionHeader[i].Name);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} while (Module32Next(handle, &moduleEntry));
|
||||
VirtualFree(AllocBuff, 0, MEM_RELEASE);
|
||||
}
|
||||
CloseHandle(handle);
|
||||
}
|
||||
void ProcessStackWalk() {
|
||||
PROCESSENTRY32 pe32;
|
||||
pe32.dwSize = sizeof(pe32);
|
||||
HANDLE hProcessSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
|
||||
if (hProcessSnap == INVALID_HANDLE_VALUE)
|
||||
{
|
||||
printf("CreateToolhelp32Snapshot error.\n");
|
||||
return;
|
||||
}
|
||||
BOOL bProcess = Process32First(hProcessSnap, &pe32);
|
||||
while (bProcess)
|
||||
{
|
||||
//<2F><>ӡ<EFBFBD><D3A1><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ͽ<EFBFBD><CDBD><EFBFBD>ID
|
||||
HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS, false, pe32.th32ProcessID);
|
||||
if (hProcess) {
|
||||
WalkProcessMoudle(pe32.th32ProcessID, hProcess, pe32.szExeFile);
|
||||
WCHAR szImagePath[MAX_PATH];
|
||||
WCHAR pszFullPath[MAX_PATH];
|
||||
if (GetProcessImageFileName(hProcess, szImagePath, MAX_PATH))
|
||||
{
|
||||
if (DosPathToNtPath(szImagePath, pszFullPath))
|
||||
{
|
||||
CdigitalSig DigitalSig(pszFullPath);
|
||||
DWORD dDigitalState = DigitalSig.GetDigitalState();
|
||||
if (dDigitalState == DIGITAL_SIGSTATE_REVOKED || dDigitalState == DIGITAL_SIGSTATE_EXPIRE) {
|
||||
printf("\t => [<5B><><EFBFBD><EFBFBD>ɨ<EFBFBD><C9A8>] <20><><EFBFBD><EFBFBD><E2B5BD><EFBFBD><EFBFBD>ǩ<EFBFBD><C7A9><EFBFBD><EFBFBD><EFBFBD><EFBFBD> ·<><C2B7> %ws static %d \n", pszFullPath, dDigitalState);
|
||||
}
|
||||
}
|
||||
}
|
||||
CloseHandle(hProcess);
|
||||
}
|
||||
bProcess = Process32Next(hProcessSnap, &pe32);
|
||||
}
|
||||
CloseHandle(hProcessSnap);
|
||||
return;
|
||||
|
||||
}
|
||||
void ScanSystemDrivers() {
|
||||
DWORD cbNeeded = 0; // drivers[] <20><><EFBFBD>ص<EFBFBD><D8B5>ֽ<EFBFBD><D6BD><EFBFBD>
|
||||
LPVOID drivers[MAX_PATH] = { 0 }; // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ַ<EFBFBD>б<EFBFBD><D0B1><EFBFBD><EFBFBD><EFBFBD>
|
||||
int cDrivers = 0; // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
Wow64EnableWow64FsRedirection(0);
|
||||
if (EnumDeviceDrivers(drivers, sizeof(drivers), &cbNeeded) && cbNeeded < sizeof(drivers)) // EnumDeviceDrivers <20><><EFBFBD><EFBFBD>ÿ<EFBFBD><C3BF><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ļ<EFBFBD><C4BC>ļ<EFBFBD><C4BC>ص<EFBFBD>ַ
|
||||
{
|
||||
char szDriver[MAX_PATH] = { 0 }; // <20><><EFBFBD><EFBFBD><EFBFBD>ļ<EFBFBD><C4BC><EFBFBD>
|
||||
char szPath[MAX_PATH] = { 0 }; // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ļ<EFBFBD>ȫ·<C8AB><C2B7>
|
||||
char szNtPath[MAX_PATH] = { 0 };
|
||||
char szSystemPath[MAX_PATH] = { 0 }; // <20><><EFBFBD><EFBFBD> system32 <20>ļ<EFBFBD><C4BC><EFBFBD>·<EFBFBD><C2B7>
|
||||
cDrivers = cbNeeded / sizeof(LPVOID); // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
|
||||
for (int i = 0; i < cDrivers; i++)
|
||||
{
|
||||
if (drivers[i]) {
|
||||
if (GetDeviceDriverBaseNameA(drivers[i], szDriver, sizeof(szDriver) / sizeof(LPVOID)))
|
||||
{
|
||||
if (GetDeviceDriverFileNameA(drivers[i], szPath, sizeof(szPath))) {
|
||||
bool isSystemDriver = true;
|
||||
//ֻ<>жϷ<D0B6>ϵͳ<CFB5><CDB3><EFBFBD><EFBFBD>
|
||||
if (szPath[1] == '?')
|
||||
{
|
||||
isSystemDriver = false;
|
||||
int len = strlen(szPath);
|
||||
szPath[len + 1] = '\0';
|
||||
for (int j = 0; j < len; j++)
|
||||
{
|
||||
szPath[j] = szPath[j + 4];
|
||||
}
|
||||
WCHAR UnicodeFilePath[MAX_PATH << 1] = { 0 };
|
||||
CharToWchar(szPath, UnicodeFilePath);
|
||||
CdigitalSig DigitalSig(UnicodeFilePath);
|
||||
DWORD dDigitalState = DigitalSig.GetDigitalState();
|
||||
if (dDigitalState != DIGITAL_SIGSTATE_VALID) {
|
||||
printf("\t => [<5B><><EFBFBD><EFBFBD>ɨ<EFBFBD><C9A8>] <20><><EFBFBD>δ֪<CEB4><D6AA><EFBFBD><EFBFBD> ·<><C2B7> %ws \n", UnicodeFilePath);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Wow64EnableWow64FsRedirection(1);
|
||||
}
|
||||
int main()
|
||||
{
|
||||
printf("DuckMemoryScan By huoji 2021-02-23 \n");
|
||||
if (EnableDebugPrivilege(true) == false) {
|
||||
printf("Ȩ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʧ<EFBFBD><EFBFBD>,<2C><><EFBFBD>Թ<EFBFBD><D4B9><EFBFBD>Ա<EFBFBD><D4B1><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> \n");
|
||||
system("pause");
|
||||
return 0;
|
||||
}
|
||||
printf("<EFBFBD>̶߳<EFBFBD>ջ<EFBFBD><EFBFBD><EFBFBD>ݼ<EFBFBD><EFBFBD><EFBFBD> ... \n");
|
||||
ThreadStackWalk();
|
||||
printf("<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>... \n");
|
||||
ScanSystemDrivers();
|
||||
printf("<EFBFBD><EFBFBD><EFBFBD>̼<EFBFBD><EFBFBD><EFBFBD>... \n");
|
||||
ProcessStackWalk();
|
||||
printf("<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> ... \n");
|
||||
system("pause");
|
||||
return 0;
|
||||
}
|
||||
Reference in New Issue
Block a user