首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >理解hook_finder

理解hook_finder
EN

Stack Overflow用户
提问于 2022-01-05 08:23:36
回答 1查看 96关注 0票数 0

我试图理解PE格式&这里的"hook_finder“的源代码"https://github.com/Mr-Un1k0d3r/EDRs/blob/main/hook_finder64.c

在这个片段中,我现在尝试计算Export_Table偏移量:

代码语言:javascript
复制
VOID DumpListOfExport(VOID *lib, BOOL bNt) {
    DWORD dwIter = 0;
    CHAR* base = (CHAR*)lib;
    CHAR* PE = base + (unsigned char)*(base + 0x3c); 
    DWORD ExportDirectoryOffset = *((DWORD*)PE + (0x8a / 4));
    CHAR* ExportDirectory = base + ExportDirectoryOffset;
    DWORD dwFunctionsCount = *((DWORD*)ExportDirectory + (0x14 / 4));
    DWORD OffsetNamesTableOffset = *((DWORD*)ExportDirectory + (0x20 / 4));
    CHAR* OffsetNamesTable = base + OffsetNamesTableOffset;

    printf("------------------------------------------\nBASE\t\t\t0x%p\t%s\nPE\t\t\t0x%p\t%s\nExportTableOffset\t0x%p\nOffsetNameTable\t\t0x%p\nFunctions Count\t\t0x%x (%d)\n------------------------------------------\n",
    base, base, PE, PE, ExportDirectory, OffsetNamesTable, dwFunctionsCount, dwFunctionsCount);

    for(dwIter; dwIter < dwFunctionsCount - 1; dwIter++) {
        DWORD64 offset = *((DWORD*)OffsetNamesTable + dwIter);
        CHAR* current = base + offset;
        GetBytesByName((HANDLE)lib, current, bNt);
    }
}

ox3c是e_lfnew偏移量。但是,无法理解其他十六进制值是什么,以及为什么它被4字节除以?

此外,

代码语言:javascript
复制
VOID GetBytesByName(HANDLE hDll, CHAR *name, BOOL bNt) {
    FARPROC ptr = GetProcAddress((HMODULE)hDll, name);
    DWORD* opcode = (DWORD*)*ptr;

    if(bNt) {
        if(name[0] != 'N' && name[1] != 't') {
            return;
        }
    }
    
    if((*opcode << 24) >> 24 == 0xe9) {
        if(!IsFalsePositive(name)) {
            printf("%s is hooked\n", name);
        }
    }
}

究竟是什么在左&右移动,为什么特别是24?根据我对EDR的理解,它在函数的开头添加了一个JMP指令,这就是为什么条件试图检查它是否是(0xe9),但是它是如何跟随并确定函数流的呢?

这是否只适用于ntdll.dll?

对不起,我开始研究体育的行为,并试图把事情弄清楚。

提前谢谢你

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2022-01-07 08:20:45

函数DumpListOfExport假设NtHeaders从基座的偏移量0x3c开始,但并不总是这样,这取决于DOS存根的大小。可能,这段代码为ntdll.dll做出了这样的假设。

在函数GetBytesByName中,如果过程的第一个字节以JMP开始(在这种情况下,它是相对的jmp,其操作代码以“E9”开头)指令,并且过程名称不在假阳性列表中,则该函数将决定函数是否挂起。

设为opcode 0xca0e4be9指向的4字节的值,左移24将导致0xe9000000,然后右移24,结果为0x000000e9,即ptr第一个字节的值。

该程序可简化如下。

代码语言:javascript
复制
VOID GetBytesByName(HANDLE hDll, CHAR *name, BOOL bNt) {
    FARPROC ptr = GetProcAddress((HMODULE)hDll, name);
    BYTE* opcode = (BYTE*)ptr;

    if(bNt) {
        if(name[0] != 'N' && name[1] != 't') {
            return;
        }
    }
    
    if(!IsFalsePositive(name) && *opcode == 0xe9) {
        printf("%s is hooked\n", name);
    }
}

作为一个注释,:我可以说代码写得不好,并且没有遵循任何好的编码风格。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/70589742

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档