[原]PInvoke导致栈破坏
项目中遇到一个诡异的问题,程序在升级到.net4.6.1后会崩溃,提示访问只读内存区。大概现象如下:
- debug版不崩溃,release版稳定崩溃。
- 只有x64位的程序崩溃,32位及anycpu编译出来的程序运行不会崩溃。
- 出问题的代码范围很小
以上信息,各位有什么想法呢?
由于release版可以稳定重现,而且范围不大,故通过二分排除法很快定位到了导致问题的代码。
最后发现并不是由于升级.net版本导致的,而是程序本身的问题: x64下MemoryStatus结构体中的成员有些不是4字节大小,而是8字节大小了。而我们的代码依然按4字节定义的。
我写了一个模拟程序来模拟出问题的代码。 参见后面的代码。
总结: 如果不是那么稳定的崩溃,恐怕解决这个问题还会花些时间的吧,how lucky I am!!!
BTW: 启用托管调试助手(MDA)有时候会对调试问题有极大的帮助,虽然我这次调试没有借助MDA,但我第一个想到的就是MDA。
完整的测试代码如下(如想重现问题,请编译x64版本)
- using System.Runtime.InteropServices;
- namespace ConsoleApplication1
- {
- class Program
- {
- [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance", "CA1815:OverrideEqualsAndOperatorEqualsOnValueTypes"),StructLayout(LayoutKind.Sequential)]
- public struct MemoryStatus
- {
- /// ---
- [MarshalAs(UnmanagedType.U4)]
- public uint dwLength;
- /// ---
- [MarshalAs(UnmanagedType.U4)]
- public uint dwMemoryLoad;
- /// ---
- [MarshalAs(UnmanagedType.U4)]
- public uint dwTotalPhys;
- /// ---
- [MarshalAs(UnmanagedType.U4)]
- public uint dwAvailPhys;
- /// ---
- [MarshalAs(UnmanagedType.U4)]
- public uint dwTotalPageFile;
- /// ---
- [MarshalAs(UnmanagedType.U4)]
- public uint dwAvailPageFile;
- /// ---
- [MarshalAs(UnmanagedType.U4)]
- public uint dwTotalVirtual;
- /// ---
- [MarshalAs(UnmanagedType.U4)]
- public uint dwAvailVirtual;
- }
- [DllImport("kernel32.dll")]
- public static extern void GlobalMemoryStatus(ref MemoryStatus memoryStatus);
- class CMyClass
- {
- public int n1 = 0;
- }
- struct CMyStruct
- {
- public CMyClass data;
- }
- static void Main(string[] args)
- {
- CMyStruct myObj = new CMyStruct(); myObj.data = new CMyClass();
- MemoryStatus memoryStatus = new MemoryStatus();
- // this line will corrupt the stack if we run in x64, because memoryStatus is defined on the stack
- GlobalMemoryStatus(ref memoryStatus);
- // myObj.data is corrupted
- System.Console.WriteLine("{0}", myObj.data);
- }
- }
- }
[原]PInvoke导致栈破坏的更多相关文章
- 转:C 函数调用栈
第一篇: 转自:http://kingj.iteye.com/blog/1555017 本文转自 http://blog.csdn.net/eno_rez/article/details/21586 ...
- 对抗栈帧地址随机化/ASLR的两种思路和一些技巧
栈帧地址随机化是地址空间布局随机化(Address space layout randomization,ASLR)的一种,它实现了栈帧起始地址一定程度上的随机化,令攻击者难以猜测需要攻击位置的地址. ...
- 深入理解golang 的栈
线程栈(thread stacks)介绍 先回顾下linux的内存空间布局 简书_stack02.png 当启动一个C实现的thread时,C标准库会负责分配一块内存作为这个线程的栈.标准库分配这 ...
- cve-2010-3333 Microsoft Office Open XML文件格式转换器栈缓冲区溢出漏洞 分析
用的是泉哥的POC来调的这个漏洞 0x0 漏洞调试 Microsoft Office Open XML文件格式转换器栈缓冲区溢出漏洞 Microsoft Office 是微软发布的非常流行的办公 ...
- CSAPP阅读笔记-变长栈帧,缓冲区溢出攻击-来自第三章3.10的笔记-P192-P204
一.几个关于指针的小知识点: 1. malloc是在堆上动态分配内存,返回的是void *,使用时会配合显式/隐式类型转换,用完后需要用free手动释放. alloca是标准库函数,可以在栈上分配任 ...
- Go语言是如何处理栈的
转自:http://tonybai.com/2014/11/05/how-stacks-are-handled-in-go/ Go 1.4Beta1刚刚发布,在Go 1.4Beta1中,Go语言的st ...
- java栈和队列
栈 可变长数组实现 链表实现 数组与链表的对比队列 链表实现 栈 下压栈(简称栈)是一种基于后进后出(LIFO)策略的集合类型.这里学习分别用数组和链表这两种基础数据结构来实现 ...
- 更改Linux默认栈空间的大小
有时候在Linux写C++程序处理大量的数据,程序内部需要分配很大的数组来存放一些数据,但有时候分配的数组太大的话运行时会出现段错误.这种情况可能是分配的数组大小超过了Linux系统的默认栈空间的大小 ...
- C语言数据结构----栈与递归
本节主要说程序中的栈函数栈的关系以及栈和递归算法的关系. 一.函数调用时的栈 1.程序调用时的栈是也就是平时所说的函数栈是数据结构的一种应用,函数调用栈一般是从搞地质向低地址增长的,栈顶为内存的低地址 ...
随机推荐
- 面试官,不要再问我“Java虚拟机类加载机制”了(转载)
关于Java虚拟机类加载机制往往有两方面的 面试题:根据程序判断输出结果和讲讲虚拟机类加载机制的流程.其实这两类题本质上都是考察面试者对Java虚拟机类加载机制的了解. 面试题试水 现在有这样一道判断 ...
- (2) JVM内存管理:垃圾回收
回顾上期 1)JVM中引用存在哪里? 答:虚拟机栈,该内存空间线程独有 2)该引用的对象存在哪里? 答:堆,所有通过new方法分配的对象都存在堆中 3)String s1="abc" ...
- 【新年呈献】高性能网络通信框架 HP-Socket v5.7.1
项目主页 : http://www.oschina.net/p/hp-socket 开发文档 : https://www.docin.com/p-2287339564.html 下载地址 : http ...
- (7)opencv图片内部的基本处理
就是,给定我们一张图片,我们可以对图片的每一个像素的色彩进行处理 比如,我们的原图是这个样子 然后我首先将他变成灰度图(灰度图的行道是1,就是chanaual是1) 然后,我又将灰色图片的黑白进行颠倒 ...
- jdk8安装
==安装jdk1.8== [root@ycj ~]# mkdir -p /usr/local/src/jdk //创建目录 [root@ycj jdk]# cd /usr/local/src/jdk ...
- Codeforces 1296D - Fight with Monsters
题目大意: n 只怪兽,每只的血量为 h[i] ,你的攻击力为 a ,你的对手攻击力为 b 打每只怪兽时,都是你先出手,然后你的对手出手,这样轮流攻击 如果是你给予了怪兽最后一击,你就能得到一分 你还 ...
- C++ CreateInstance("ADODB.Connection");创建接口失败的解决方法
数据库对象mssql2005sp3专业版: 一般数据引用该路径文件#import "c:\\program files\\common files\\system\\ado\\msado15 ...
- form——验证器Validators
form表单最大的作用就是验证功能了,通过cleaned_data清洗,我们可以获取传来的值,通过参数.验证器.自定义验证方法,我们可以做到很多的验证. 验证器可用于在不同类型的字段之间重用验证逻辑. ...
- CTF -bugku-web-web基础$_GET和$_POST
---恢复内容开始--- GET那题 就算没有学过php也会看懂if条件语句 于是我们在url后面直接加 ?what = flag 这样echo输出flag POST那题 直接火狐 要装hackbar ...
- dp--树形dp P1352 没有上司的舞会
题目描述 某大学有N个职员,编号为1~N.他们之间有从属关系,也就是说他们的关系就像一棵以校长为根的树,父结点就是子结点的直接上司.现在有个周年庆宴会,宴会每邀请来一个职员都会增加一定的快乐指数Ri, ...