取0x00400000 往下数4⾏最后4字节的内容,加上0x00400000,检查对应的ASCII码是否是PE,再往数下2⾏半,取里面的内容加上0x00400000,判断这个地址是否是程序⼊⼝点位置?

image.png
0x00400000 + 0x0000000D=0x004000D0
内存编号0x004000D0处对应的内容是PE
image.png

从PE处再往下数两行半
image.png
0x00400000 + 0x00001130 = 0x00401130

0x00401130 此地址为程序入口地址

编写程序寻找

#include <stdio.h>
#include <stdlib.h>

int main(){

    int ary[5] = {0};

    int nMZoffset = (0x00400000 - (int)ary) / sizeof(int);
    int nMZ = ary[nMZoffset];

    int nPEoffset = ary[nMZoffset + 15] + 0x00400000;
    int nPE = *(int*)nPEoffset;

    if(*(char*)nPEoffset == 'P' && *(char*)(nPEoffset + 1) == 'E'){
        printf("%08x\r\n",*((int*)nPEoffset + 10) + 0x00400000);
    }
    system("pause");
    return 0;

}

image.png

指针

#include <stdio.h>
#include <stdlib.h>

int main(){

    int ary[5] = {0};
    int a = 0;
    int* pa = &a;
    printf("%08x\r\n",pa);

//     int nMZoffset = (0x00400000 - (int)ary) / sizeof(int);
//     int nMZ = ary[nMZoffset];
//     
//     int nPEoffset = ary[nMZoffset + 15] + 0x00400000;
//     int nPE = *(int*)nPEoffset;
//     
//     if(*(char*)nPEoffset == 'P' && *(char*)(nPEoffset + 1) == 'E'){
//         printf("%08x\r\n",*((int*)nPEoffset + 10) + 0x00400000);
//     }
    int* pValue = NULL;
    int nMZoffset = (0x00400000 - (int)&pValue) / sizeof(int*);
    int nMZ = *(int*)((int*)&pValue+nMZoffset);

    int nPEoffset = *(int*)((int*)&pValue + nMZoffset + 15) + 0x00400000;
    int nPE = *(int*)nPEoffset;

    if (*(char*)nPEoffset == 'P' && *(char*)(nPEoffset + 1) == 'E') {
        printf("%08x\r\n", *((int*)nPEoffset + 10) + 0x00400000);
    }

    system("pause");
    return 0;

}

验证

image.png

  • 下断点
  • F11跟进去 (或者在堆栈窗口双击mainCRTStartup()

image.png

  • ALT + 8显示汇编窗口

image.png

与控制台窗口的地址相对比
image.png

最后修改:2022 年 01 月 17 日 02 : 10 AM
如果觉得我的文章对你有用,那就请作者喝杯奶茶吧~