吾爱破解 - 52pojie.cn

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 6355|回复: 59
收起左侧

[原创] 就是你,进来看看如何优雅地使用内存暴力搜索!

  [复制链接]
Panel 发表于 2023-4-2 13:39
本帖最后由 Panel 于 2023-4-2 20:03 编辑

就是你,进来看看如何优雅地使用内存暴力搜索!

0x1:什么是内存暴力搜索?

答:查找指定内存区段是否存在指定的值。

0x2:内存暴力搜索原理是啥?

答:从目标内存区段起始地址到内存区段结束位置去判断其中是否有满足我们条件的值,有则搜索到了目标地址。

0x3:用途

答:
1.恶意程序特征提取;
2.特殊变量获取;
3.获取未公开函数地址;
4.and so on.

0x4:例子

获取Windows 7 x86的PspCidTable值:
通过windbg我们可以使用 dd PspCidTable命令获取到全局句柄表相关结构HANDLE_TABLE的地址,但是我们写 代码的过程中却没办法通过这个命令拿到PspCidTable的值,所以我们有一个方法就是通过字节特征码去查找到这个值,通过实验发现在PsLookupProcessByProcessId这个函数通过进程id查找进程的eprocess时使用到了这个PspCidTable,那我们就可以通过在驱动加载的时候去查找这个函数地址引用那块数据,从而便可以找到我们的PspCidTable了。
咱们先看看PsLookupProcessByProcessId函数的特征:
PAGE:006696E9                                                 var_C= dword ptr -0Ch
PAGE:006696E9                                                 var_8= dword ptr -8
PAGE:006696E9                                                 var_4= dword ptr -4
PAGE:006696E9                                                 ProcessId= dword ptr  8
PAGE:006696E9                                                 Process= dword ptr  0Ch
PAGE:006696E9
PAGE:006696E9 8B FF                                           mov     edi, edi
PAGE:006696EB 55                                              push    ebp
PAGE:006696EC 8B EC                                           mov     ebp, esp
PAGE:006696EE 83 EC 0C                                        sub     esp, 0Ch
PAGE:006696F1 53                                              push    ebx
PAGE:006696F2 56                                              push    esi
PAGE:006696F3 64 8B 35 24 01 00 00                            mov     esi, large fs:124h
PAGE:006696FA 33 DB                                           xor     ebx, ebx
PAGE:006696FC 66 FF 8E 84 00 00 00                            dec     word ptr [esi+84h]
PAGE:00669703 57                                              push    edi
PAGE:00669704 FF 75 08                                        push    [ebp+ProcessId]
PAGE:00669707 8B 3D 94 DD 54 00                               mov     edi, _PspCidTable
PAGE:0066970D E8 21 52 FE FF                                  call    _ExMapHandleToPointer@8         ; ExMapHandleToPointer(x,x)
从上面可以看到 mov edi, _PspCidTable这个指令使用到了PspCidTable的值,但是这个值不是固定的,是运行时才能得到值的,所以咱们需要用相邻的字节特征来找到这个PspCidTable的值,那咱们就用call  _ExMapHandleToPointer特征查找:

E8 21 52 FE FF           call    _ExMapHandleToPointer@8

当然我选用上面这段指令的特征没去确定有没有其他地方也调用了这段指令,但是我就是头铁我就要选它,你们也可以选则push edi上面那条指令,特征性相对来说比我选的这个强,好了,我以这个例子来说一下代码思路,也是暴力搜索思路:
1.获取PsLookupProcessByProcessId所在模块地址和模块大小,模块名为“ntkrnlpa.exe”,模块地址便是内存搜索起始地址,模块地址+模块大小便是搜索结束地址;
2.从搜索起始地址不停判断是否存在一块连续内存是符合我们特征的是的话就找到了,返回这个地址;
3.PspCidTable地址占4个字节,所以我们通过特征拿到的地址减去4个字节就得到了PspCidTable的地址了;
奉上代码:
#include <ntifs.h>

typedef struct _RTL_PROCESS_MODULE_INFORMATION {
        HANDLE Section;                 // Not filled in
        PVOID MappedBase;
        PVOID ImageBase;
        ULONG ImageSize;
        ULONG Flags;
        USHORT LoadOrderIndex;
        USHORT InitOrderIndex;
        USHORT LoadCount;
        USHORT OffsetToFileName;
        UCHAR  FullPathName[256];
} RTL_PROCESS_MODULE_INFORMATION, *PRTL_PROCESS_MODULE_INFORMATION;
typedef struct _RTL_PROCESS_MODULES {
        ULONG NumberOfModules;
        RTL_PROCESS_MODULE_INFORMATION Modules[1];
} RTL_PROCESS_MODULES, *PRTL_PROCESS_MODULES;
typedef enum _SYSTEM_INFORMATION_CLASS {
        SystemBasicInformation,
        SystemProcessorInformation,             // obsolete...delete
        SystemPerformanceInformation,
        SystemTimeOfDayInformation,
        SystemPathInformation,
        SystemProcessInformation,
        SystemCallCountInformation,
        SystemDeviceInformation,
        SystemProcessorPerformanceInformation,
        SystemFlagsInformation,
        SystemCallTimeInformation,
        SystemModuleInformation,
        SystemLocksInformation,
        SystemStackTraceInformation,
        SystemPagedPoolInformation,
        SystemNonPagedPoolInformation,
        SystemHandleInformation,
        SystemObjectInformation,
        SystemPageFileInformation,
        SystemVdmInstemulInformation,
        SystemVdmBopInformation,
        SystemFileCacheInformation,
        SystemPoolTagInformation,
        SystemInterruptInformation,
        SystemDpcBehaviorInformation,
        SystemFullMemoryInformation,
        SystemLoadGdiDriverInformation,
        SystemUnloadGdiDriverInformation,
        SystemTimeAdjustmentInformation,
        SystemSummaryMemoryInformation,
        SystemMirrorMemoryInformation,
        SystemPerformanceTraceInformation,
        SystemObsolete0,
        SystemExceptionInformation,
        SystemCrashDumpStateInformation,
        SystemKernelDebuggerInformation,
        SystemContextSwitchInformation,
        SystemRegistryQuotaInformation,
        SystemExtendServiceTableInformation,
        SystemPrioritySeperation,
        SystemVerifierAddDriverInformation,
        SystemVerifierRemoveDriverInformation,
        SystemProcessorIdleInformation,
        SystemLegacyDriverInformation,
        SystemCurrentTimeZoneInformation,
        SystemLookasideInformation,
        SystemTimeSlipNotification,
        SystemSessionCreate,
        SystemSessionDetach,
        SystemSessionInformation,
        SystemRangeStartInformation,
        SystemVerifierInformation,
        SystemVerifierThunkExtend,
        SystemSessionProcessInformation,
        SystemLoadGdiDriverInSystemSpace,
        SystemNumaProcessorMap,
        SystemPrefetcherInformation,
        SystemExtendedProcessInformation,
        SystemRecommendedSharedDataAlignment,
        SystemComPlusPackage,
        SystemNumaAvailableMemory,
        SystemProcessorPowerInformation,
        SystemEmulationBasicInformation,
        SystemEmulationProcessorInformation,
        SystemExtendedHandleInformation,
        SystemLostDelayedWriteInformation,
        SystemBigPoolInformation,
        SystemSessionPoolTagInformation,
        SystemSessionMappedViewInformation,
        SystemHotpatchInformation,
        SystemObjectSecurityMode,
        SystemWatchdogTimerHandler,
        SystemWatchdogTimerInformation,
        SystemLogicalProcessorInformation,
        SystemWow64SharedInformation,
        SystemRegisterFirmwareTableInformationHandler,
        SystemFirmwareTableInformation,
        SystemModuleInformationEx,
        SystemVerifierTriageInformation,
        SystemSuperfetchInformation,
        SystemMemoryListInformation,
        SystemFileCacheInformationEx,
        MaxSystemInfoClass  // MaxSystemInfoClass should always be the last enum
} SYSTEM_INFORMATION_CLASS;

NTSYSAPI NTSTATUS NTAPI ZwQuerySystemInformation(
        __in SYSTEM_INFORMATION_CLASS SystemInformationClass,
        __out_bcount_opt(SystemInformationLength) PVOID SystemInformation,
        __in ULONG SystemInformationLength,
        __out_opt PULONG ReturnLength
        );

ULONG_PTR GetKernelModuleBase(PUCHAR moduleName, PULONG pModuleSize) {
        RTL_PROCESS_MODULES SysModules = { 0 };
        PRTL_PROCESS_MODULES pModules = &SysModules;
        ULONG SystemInformationLength = 0;
        //查询系统中所有内核模块,底层也是遍历链表
        NTSTATUS status = ZwQuerySystemInformation(SystemModuleInformation, pModules, sizeof(RTL_PROCESS_MODULES), &SystemInformationLength);
        if (status == STATUS_INFO_LENGTH_MISMATCH) {
                pModules = ExAllocatePool(NonPagedPool, SystemInformationLength + sizeof(RTL_PROCESS_MODULES));
                RtlZeroMemory(pModules, SystemInformationLength + sizeof(RTL_PROCESS_MODULES));
                status = ZwQuerySystemInformation(SystemModuleInformation, pModules, SystemInformationLength + sizeof(RTL_PROCESS_MODULES), &SystemInformationLength);
                if (!NT_SUCCESS(status)) {
                        ExFreePool(pModules);
                        return 0;
                }
        }
        if (!strcmp("ntkrnlpa.exe", moduleName)) {
                ULONG_PTR ret = pModules->Modules[0].ImageBase;
                *pModuleSize = pModules->Modules[0].ImageSize;
                if (SystemInformationLength) {
                        ExFreePool(pModules);
                }
                return ret;
        }
        for (ULONG i = 0; i < pModules->NumberOfModules; i++) {
                if (strstr(pModules->Modules[i].FullPathName, moduleName)) {
                        ULONG_PTR ret = pModules->Modules[i].ImageBase;
                        *pModuleSize = pModules->Modules[0].ImageSize;
                        if (SystemInformationLength) {
                                ExFreePool(pModules);
                        }
                        //返回模块地址
                        return ret;
                }
        }
        if (SystemInformationLength) {
                ExFreePool(pModules);
        }
        return 0;
}

PVOID SearchSpecialCode(PVOID pSearchBeginAddr, ULONG ulSearchLength, PUCHAR pSpecialCode, ULONG ulSpecialCodeLength)
{
        PVOID pDestAddr = NULL;
        PUCHAR pBeginAddr = (PUCHAR)pSearchBeginAddr;
        PUCHAR pEndAddr = pBeginAddr + ulSearchLength;
        PUCHAR i = NULL;
        ULONG j = 0;

        for (i = pBeginAddr; i <= pEndAddr; i++)
        {
                // 遍历特征码
                for (j = 0; j < ulSpecialCodeLength; j++)
                {
                        // 判断地址是否有效
                        if (FALSE == MmIsAddressValid((PVOID)(i + j)))
                        {
                                break;
                        }
                        // 匹配特征码
                        if (*(PUCHAR)(i + j) != pSpecialCode[j])
                        {
                                break;
                        }
                }

                // 匹配成功
                if (j >= ulSpecialCodeLength)
                {
                        pDestAddr = (PVOID)i;
                        break;
                }
        }
        return pDestAddr;
}

VOID UnloadDriver(PDRIVER_OBJECT pDriver)
{

}

NTSTATUS DriverEntry(PDRIVER_OBJECT pDriver, PUNICODE_STRING pRegPath)
{
        ULONG sizeofcode = 0;
        ULONG_PTR baseaddr = GetKernelModuleBase("ntkrnlpa.exe", &sizeofcode);
        DbgPrintEx(77, 0, "[db]:base地址为:%p\n", baseaddr);
        DbgPrintEx(77, 0, "[db]:base长度为:%p\n", sizeofcode);
        UCHAR specode[4] = { 0xE8, 0x21, 0x52, 0xFE,0xFF };
        ULONG_PTR codeaddr = SearchSpecialCode(baseaddr, sizeofcode, specode,5);
        DbgPrintEx(77, 0, "[db]:找到的代码地址为:%p\n", codeaddr);
        ULONG_PTR uGetPspGet = (*(PULONG)((PUCHAR)codeaddr - 6 + 2));
        DbgPrintEx(77, 0, "[db]:全局句柄表的地址为:%p\n", uGetPspGet);
        pDriver->DriverUnload = UnloadDriver;
        return STATUS_SUCCESS;
}
效果:

image-20230402133539413.png

image-20230402133603083.png

Tip:以上打印的把PspCidTable说成全局句柄表地址了,但是实际上不是哈,严谨点说是全局句柄表相关结构地址

免费评分

参与人数 15吾爱币 +17 热心值 +14 收起 理由
笙若 + 1 + 1 谢谢@Thanks!
Hmily + 7 + 1 欢迎分析讨论交流,吾爱破解论坛有你更精彩!
Brunello + 1 + 1 热心回复!
13783867676 + 1 谢谢@Thanks!
莫奇 + 1 + 1 谢谢@Thanks!
cloudy520 + 1 + 1 用心讨论,共获提升!
杨辣子 + 1 + 1 热心回复!
zhaosongquanlol + 1 我很赞同!
leommm + 1 我很赞同!
allspark + 1 + 1 用心讨论,共获提升!
wanjingbo + 1 谢谢@Thanks!
Firecrack + 1 + 1 我很赞同!
SPT + 1 + 1 热心回复!
husu1012 + 1 谢谢@Thanks!
QQ11 + 1 + 1 我很赞同!

查看全部评分

本帖被以下淘专辑推荐:

发帖前要善用论坛搜索功能,那里可能会有你要找的答案或者已经有人发布过相同内容了,请勿重复发帖。

 楼主| Panel 发表于 2023-4-2 16:59
侃遍天下无二人 发表于 2023-4-2 15:09
这样的程序鲁棒性非常差,要是哪天想迁移到wine里会很麻烦

怎么说呢,这样的写法如果要普遍给大众用大话需要采集多个不同系统版本的特征数据来进行不同的处理
 楼主| Panel 发表于 2023-4-2 21:32
叶隽 发表于 2023-4-2 21:23
不需要考虑端序吗

他是什么端序你就直接用类型去取值就行了,cpu会帮你处理的,除非你是做字节分割之类的需要自己处理
huangjiloqw 发表于 2023-4-2 14:03
侃遍天下无二人 发表于 2023-4-2 15:09
这样的程序鲁棒性非常差,要是哪天想迁移到wine里会很麻烦
PPPANY 发表于 2023-4-2 16:46
太牛逼了
yu520 发表于 2023-4-2 17:13
不是很明白,博主可以介绍的清楚一点吗
 楼主| Panel 发表于 2023-4-2 17:14
yu520 发表于 2023-4-2 17:13
不是很明白,博主可以介绍的清楚一点吗

什么地方不懂吗
无用户名 发表于 2023-4-2 17:15
跟着大佬学习
dspgl 发表于 2023-4-2 17:21
学习了,虽然不懂
cxclj520 发表于 2023-4-2 18:37
我也不是很懂但我想学习学习
您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则

返回列表

RSS订阅|小黑屋|处罚记录|联系我们|吾爱破解 - LCG - LSG ( 京ICP备16042023号 | 京公网安备 11010502030087号 )

GMT+8, 2024-12-23 15:57

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表