• 查找进程加载到内存中的EntryPoint


    工作中遇到了这样的问题:

    创建了一个子进程并将其挂起后,想获取该子进程的EntryPoint,已知通过GetModuleInformation(HANDLE hProcess, HMODULE hModule)(HModule就是模块的基地址)可以获取到Module的EntryPoint,但尝试通过CreateToolhelp32Snapshot 或者 EnumProcessModules 来遍历进程的module,进而获取HMODULE时总会失败,GetLastError返回299(仅完成部分的 ReadProcessMemory 或 WriteProcessMemory 请求),这与进程被挂起有关。但这里又必须在创建进程后将其挂起(需要修改进程入口点的指令以注入DLL),这种情况下该怎么办呢?

    这里补充一下:虽然在Xp系统下,进程加载到内存中后的虚基址总是0x410000,但在Win7中却是变化的。

    下面就是我用的办法:

    先通过 NtQueryInformationProcess API来获取到进程的PROCESS_BASIC_INFORMATION,然后再获取到PEB结构的地址,再 ReadProcessMemory 获取到 ImageBaseAddress,再用 ImageLoad 获取到 EntryPoint 的地址!

    代码如下:

    #include <imagehlp.h>
    
    #pragma comment(lib,"Imagehlp.lib")
    
    typedef struct {
        DWORD ExitStatus;
        DWORD PebBaseAddress;
        DWORD AffinityMask;
        DWORD BasePriority;
        ULONG UniqueProcessId;
        ULONG InheritedFromUniqueProcessId;
    } PROCESS_BASIC_INFORMATION;
    typedef LONG (WINAPI *PROCNTQSIP)(HANDLE,UINT,PVOID,ULONG,PULONG);
    
    LPBYTE GetExeEntryPoint(HANDLE procHdl, const char* ansiExeFilePath) {
        LPBYTE entryPoint = NULL;
    
        PROCNTQSIP NtQueryInformationProcess = (PROCNTQSIP)GetProcAddress(GetModuleHandleA("ntdll"), "NtQueryInformationProcess");
    
        if (!NtQueryInformationProcess)
            return entryPoint;
    
        LONG status;
        DWORD dwParentPID = (DWORD)-1;
        PROCESS_BASIC_INFORMATION pbi;
    
        // Retrieve information
        status = NtQueryInformationProcess(procHdl,
            0,
            (PVOID)&pbi,
            sizeof(PROCESS_BASIC_INFORMATION),
            NULL
            );
    
        DWORD bytesRead = 0;
        HINSTANCE baseAddr = NULL;
        ReadProcessMemory(procHdl,
            (PVOID)(pbi.PebBaseAddress + 8),    // 这个8就是 ImageBaseAddress 在 PEB 结构中的偏移
            &baseAddr,
            sizeof(baseAddr),
            &bytesRead);
    
        PLOADED_IMAGE pImage = ImageLoad(ansiExeFilePath, NULL);    // ImageLoad 只支持ANSI编码。。。
        if(pImage == NULL)
            return entryPoint;
        PIMAGE_NT_HEADERS pNTHeader = pImage->FileHeader;
        entryPoint = (LPBYTE)baseAddr + pNTHeader->OptionalHeader.AddressOfEntryPoint;
        ImageUnload(pImage);
    
         return entryPoint;
    }
  • 相关阅读:
    Android中传感器的基本概念
    Android攻城狮 multi-touch多点触摸
    Android攻城狮SurfaceView
    Android攻城狮Tab类型
    Android攻城狮使用SubMenu创建子菜单
    Android攻城狮认识ContextMenu
    Android攻城狮OptionsMenu
    Android攻城狮Notification实现状态通知栏
    虹软人脸识别SDK(java+linux/window)
    人脸识别ArcFace C#DEMO 开发应用全过程
  • 原文地址:https://www.cnblogs.com/jeJee/p/2950345.html
Copyright © 2020-2023  润新知