fatal error lnk1561: 必须定义入口点_数组通过下标运算取出程序入口点位置

通过下标运算取任何地址

    取 p[2] 的地址

    定义 int *p = NULL,求 p[2] 的地址,编写程序。

#include #include int main(){  int *p = NULL;  printf("%08x\r\n", &p[2]);  system("pause");  return 0;}

    由公众号数组这篇文章的计算公式:ary[n] 的地址是(int)ary + sizeof(type)*n。运用公式必须有两个操作数,一个操作数必须是某类型的地址,另一个操作数必须为整形类。取出某类型的地址代入到公式 ary 部分,取出整形代入到上述公式中 n 部分,取出数组元素的类型代入到上述公式中 type 部分。

    因为 p 是 int 类型的地址,p 的值是 0 。2 是整形,数组元素的类型是 int,所以 &p[2] =  (int)p + sizeof(int)*2 = 0 + 4*2 = 8,所以打印出来的值为 00000008。

465727fa5f4ddf52b01ffa4a4374e696.png

    取地址 0x00400000 处的四个字节内容

    由公式,ary[n] 的地址是(int)ary + sizeof(type)*n,所以可以推出 

    0x00400000 = (int)ary + sizeof(type) * n

    n = (0x00400000 - (int)ary) / sizeof(int)

    0x00400000 的内容就是 ary[(0x00400000 - (int)ary) / sizeof(int)] 

#include #include int main(){  int ary[5] = {1, 2, 3, 4, 5};  printf("%08x\r\n", ary[(0x00400000 - (int)ary) / sizeof(int)]);  system("pause");  return 0;}

    按 F10 进行单步调试,在搜索框中搜索 0x00400000,可以看到里面的内容是 4d5a9000 ,按照小尾方式排列就是 00905a4d。

4886142c283c17373a10e4e339603996.png

    编译执行,打印的值就是 00905a4d

1894d7b1d843812434acb7476d64260d.png

    也就是说,当学会数组的下标运算法则以后,内存中任何一个点,都可以访问,这时如果对内存结构又很熟悉。例如打游戏时,如果知道哪个地方放血量,哪个地方放防御力,哪个地方放攻击力,可以对其进行读写,那在游戏中就是逆天的存在。

edea522cd61299d28ce2bd5a33c8723c.png

通过调试找到程序入口点地址

    编写程序

#include #include int main(){  int n = 0;  int ary[5] = {1, 2, 3, 4, 5};  system("pause");  return 0;}

    按 F10 进入单步调试模式,双击栈窗口的  mainCRTStartup()

0aca6fd4ac574b97cc9047e3dd5efac9.png

    找到 void mainCRTStartup() 第一个左括号的位置

void mainCRTStartup(#endif  /* WPRFLAG */#endif  /* _WINMAIN_ */        void){

    按 F9 下断点

89577a629dc0bed8828bd789d6a87ab0.png

    按 alt + 8 进入反汇编模式,可以看到程序的入口点地址是 00401410

f46100583ea3eabacc8f15b30037c4cb.png

0ecf4d44b4ecefda3904e8bdadaf3300.png

通过计算方法找到程序入口点地址

    进入调试状态找到 0x00400000 的地址,在往后数 3c 个位置,并取出里面的值,也就是 0x000000d8。

e9b1ea1c3068f697f2d23b032517b75f.png

    将取出来的 0x000000d8 加上 0x00400000,得出 0x004000d8,可以看到 PE 两个字。

4540ed5395b1130e853cc315edb0d298.png

    在 0x004000d8 之后,在往后数两行半,也就是再往后数 40(十六进制 28)个,0x004000d8 + 0x28 = 0x00400100 。里面的值是 0x00001410。

91d65a00d949bfd7d5260f2400f26f40.png

    将 0x00001410 加上 0x00400000 ,得出的结果 0x00401410 就是程序的入口点地址。

f46100583ea3eabacc8f15b30037c4cb.png

0ecf4d44b4ecefda3904e8bdadaf3300.png

通过程序找到程序入口点地址

    将上一内容进行简化,用程序实现找到程序入口点的位置。

    取出 0x0040003c 的值

#include #include int main(){  int n = 0;  int ary[5] = {1, 2, 3, 4, 5};  n = ary[(0x0040003c - (int)ary) / sizeof(int)];    printf("%08x\r\n", n);  system("pause");  return 0;}

57e2729e8b4157fa86b42da764751b37.png

    将取出来的值加上 0x00400000 ,再加上 0x28。

#include #include int main(){  int n = 0;  int ary[5] = {1, 2, 3, 4, 5};  n = ary[(0x0040003c - (int)ary) / sizeof(int)];  n = n + 0x00400000 + 0x28;  printf("%08x\r\n", n);  system("pause");  return 0;}

b1ca516aaeb11b89e85f397f002ee430.png

    以上一步得出的结果为地址,取出里面的值

#include #include int main(){  int n = 0;  int ary[5] = {1, 2, 3, 4, 5};  n = ary[(0x0040003c - (int)ary) / sizeof(int)];  n = n + 0x00400000 + 0x28;  n = ary[(n - (int)ary) / sizeof(int)];  printf("%08x\r\n", n);  system("pause");  return 0;}

d41c381b2dcd5d12fa181ee20cfbdea4.png

    将上一步取得的值,加上 0x00400000 ,就是程序的入口点位置。

#include #include int main(){  int n = 0;  int ary[5] = {1, 2, 3, 4, 5};  n = ary[(0x0040003c - (int)ary) / sizeof(int)];  n = n + 0x00400000 + 0x28;  n = ary[(n - (int)ary) / sizeof(int)];  printf("%08x\r\n", n + 0x00400000);  system("pause");  return 0;}

4a69b06251db4e729ced8b8e1d223e34.png

END

dd01f9cab6e2c51cd54b7ae74873fef5.png 38d4d6c1a3bdd12d8961b57de5f8f78b.png

扫码关注

更多精彩

6bf3cde8858b858d8ba545630fe6a0e2.gif

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值