Protecting Your Code with Visual C++ Defenses

delphi之多线程编程(一) <br />本文的内容取自网络,并重新加以整理,在此留存仅仅是方便自己学习和查阅。所有代码均亲自测试 delphi7下测试有效。图片均为自己制作。<br /><br />多线程应该是编程工作者的基础技能, 但这个基础我从来没学过,所以仅仅是看上去会一些,明白了2+2的时候,其实我还不知道1+1。<br /><br />开始本应该是一篇洋洋洒洒的文字, 不过我还是提倡先做起来, 在尝试中去理解.<br />先试试这个:<br /> <br />procedure TForm1.Button1Click(Sen 阅读详情

Michael Howard

Contents

Stack-Based Buffer Overrun Detection (/GS)
Safe Exception Handling (/SafeSEH)
DEP Compatibility (/NXCompat)
Image Randomization (/DynamicBase)
Safer Function Calls
C++ Operator::new
What if It Fails?

A lot of code is written in C and C++ and unfortunately a lot of this code has security vulnerabilities that many developers do not know about. Programs written in any language can have vulnerabilities that leave their users open to attack, but it's the C and C++ languages that have a special place in Internet history because so many security vulnerabilities are due to the very thing that makes these two programming languages so popular: the unbridled access to computer hardware and the performance that comes with it. When you read about security and C or C++ crops up, the words "buffer" and "overrun" are usually pretty close by because buffers are typically an example of direct access to memory. This kind of direct access is very powerful--and very, very dangerous.

There are a number of reasons for the many buffer overruns in production C and C++ code. The first I have already mentioned: the languages provide direct access to vulnerable memory. Second, developers make mistakes. And third, there are normally no defenses offered by compilers. It is feasible to provide remedies for the first issue, but then C and C++ start to become different languages.

The reason for developers making mistakes could be partially addressed through education, but I really don't see the educational institutions stepping up. Sure there is a place in industry for security education, too, but we are all part of the solution or part of the problem, and I would love to see colleges doing more to educate students about software security. You're probably asking, "Why are educational institutions not attempting to teach this critically important subject?" To be honest, I have absolutely no idea. It's kind of depressing, actually.

Finally, even with an excellent education, some security issues are complex enough that even well-educated engineers won't catch everything. We humans are not perfect.

The issue about needing to build more defenses into compilers is something the Microsoft Visual C++ team has been working on and slowly improving over the years, with help from our security team. This column outlines some of the buffer overrun defenses available in Visual C++® 2005 and beyond. Note that some other compilers do offer defenses, but Visual C++ has two major advantages over the likes of gcc. First, all these defenses are in the toolset by default; there is no need to download some funky add-in. Second, the options are easy to use.

In no particular order, the defenses offered by the Visual C++ toolset are:

  • Stack-based Buffer Overrun Detection (/GS)
  • Safe Exception Handling (/SafeSEH)
  • Data Execution Prevention (DEP) Compatibility (/NXCompat)
  • Image Randomization (/DynamicBase)
  • Automatic use of safer function calls
  • C++ operator::new

Before I discuss each of these in detail I want to point out that these defenses do not compensate for insecure code. You should always strive to create the most secure code possible, and if you don't know how to do that, then run right out and read some of the very good books available on the subject.

Typical Stack Compared to One Compiled with /GS (Click the image for a larger view)

I also want to point out that these are all Security Development Lifecycle (SDL) requirements at Microsoft, which means that C and C++ code must use these options in order to ship. There are occasional exceptions, but they are relatively rare, so I won't be going into detail about them here.

Finally, you must keep in mind this important point: it is possible, depending on the code in question, to circumvent these elaborate defenses. The more defenses used by the code, the harder they are to work around, but no defense is perfect. They are all speed bumps to reduce the chance an exploit will succeed. You have been warned! The only variant is the use of safer function calls, which are real defenses and can remove vulnerabilities. Let's look at each defense in detail.

Stack-Based Buffer Overrun Detection (/GS)

Stack-based buffer overrun detection is the oldest and most well-known defense available in Visual C++. The goal of the /GS compiler flag is simple: reduce the chance that malicious code will execute correctly. The /GS option is on by default in Visual C++ 2003 and later, and it detects certain kinds of stack smash at run time. It goes about doing this by including a random number in a function's stack just before the return address on the stack, and when the function returns, function epilogue code checks this value to make sure it has not changed. If the cookie, as it's called, has changed, execution is halted.

The function prologue code that sets the cookie looks like this:

Copy Code

sub    esp, 8
mov    eax, DWORD PTR ___security_cookie
xor    eax, esp
mov    DWORD PTR __$ArrayPad$[esp+8], eax
mov    eax, DWORD PTR _input$[esp+4]

And shown here is the function epilogue code that checks the cookie:

Copy Code

mov    ecx, DWORD PTR __$ArrayPad$[esp+12]
add    esp, 4
xor    ecx, esp
call    @__security_check_cookie@4
add    esp, 8

Visual C++ 2005 also moves data around on the stack to make it harder to corrupt that data. Examples include moving buffers to higher memory than non-buffers. This step can help protect function pointers that reside on the stack, for example. Alternately, moving pointer and buffer arguments to lower memory at run time mitigates various buffer overrun attacks. See the diagram to compare a typical stack with a /GS stack.

The /GS compiler option is not applied in any of the following situations:

  • Functions do not contain a buffer.
  • Optimizations are not enabled.
  • Functions are defined to have a variable argument list.
  • Functions are marked with the naked keyword (C++).
  • Functions contain inline assembly code in the first statement.
  • The buffer isn't an 8-byte type and is less than 4 bytes in size.

An option was added to Visual C++ 2005 SP1 to make the /GS heuristics much more aggressive so that more functions would be protected. Microsoft added this because a small number of security bulletins were issued in code that had stack-based buffer overruns and the code, even though it was compiled with /GS, was not protected by a cookie. This new option increases the number of protected by functions substantially.

Use this option by placing the following line in modules where you want added protection, such as code that handles data from the Internet:

Copy Code

#pragma strict_gs_check(on)

This pragma is just one example of how Microsoft is constantly evolving the /GS capability. The original version in Visual C++ 2003 was pretty simple, and then it was updated in Visual C++ 2005 SP1 and again in Visual C++ 2008 as we learned about new attacks as well as new ways to circumvent existing attacks. In our analysis, we have found that /GS causes no real compatibility or performance problems.

Safe Exception Handling (/SafeSEH)

The CodeRed worm that affected Internet Information Server (IIS) 4.0 was caused by a stack-based buffer overrun. Interestingly, /GS would not have caught the problem exploited by the worm because the code did not overrun the affected function's return address; rather, it corrupted an exception handler on the stack. This is a great example of why you must constantly focus on writing secure code and not rely solely on these types of compiler-based defenses.

An exception handler is code executed when an exceptional condition occurs, such as division by zero. The address of the handler is held on the stack frame of the function and is therefore subject to corruption. The linker included with Visual Studio® 2003 and later includes an option to store the list of valid exception handlers in the image's PE header at compile time. When an exception is raised at run time, the operating system checks the image header to determine whether the exception handler address is correct; if it is not, the application is terminated. This would have prevented CodeRed if the technology existed at the time the code was linked. There is no performance hit whatsoever from the /SafeSEH option, other than when an exception is raised, so you should always link with this option.

DEP Compatibility (/NXCompat)

Just about every CPU produced today supports a no execute (NX) capability, which means the CPU will not execute non-code pages. Think about the implications of this for a moment: just about every buffer overrun vulnerability is a data bug; the attacker then injects data into the process by way of the buffer overrun and then continues execution within the malicious data buffer. Why on earth is the CPU running data?

Linking with the /NXCompat option means your executable will be protected by the CPU's no execute capability. In our experience, the security team at Microsoft has seen very few compatibility issues because of this option, and there is no performance degradation whatsoever.

Windows Vista® SP1 also adds a new API that will enabled DEP for your running process and once it is set, it cannot be unset:

Copy Code

SetProcessDEPPolicy(PROCESS_DEP_ENABLE);

Image Randomization (/DynamicBase)

Windows Vista and Windows Server® 2008 support image randomization, which means, when the system boots, it shuffles operating system images around in memory. The purpose of this feature is to simply remove some of the predictability from attackers. This is also known as Address Space Layout Randomization (ASLR). Note that for ASLR to be of any use whatsoever, you must also have DEP enabled.

By default, Windows® will only juggle system components around. If you want your image to be moved around by the operating system (highly recommended), then you should link with the /DynamicBase option. (This option is available in the Visual Studio 2005 SP1 and later toolset.) There is an interesting side effect of linking with /DynamicBase--the operating system will also randomize your stack, which helps reduce predictability and makes it much harder for attackers to successfully compromise a system. Note also that the heap is also randomized in Windows Vista and Windows Server 2008, but this is there by default, you do not need to compile or link with any special options.

Safer Function Calls

Take a look at the following lines of code:

Copy Code

void func(char *p) {
    char d[20];
    strcpy(d,p);
    // etc
}

Assuming *p contains untrusted data, this code represents a security vulnerability. The perverse thing about this code is that the compiler could potentially have promoted the call to strcpy to a safer function call that bounded the copy operation to the size of the destination buffer. Why? Because the buffer size is static and known at compile time!

With Visual C++ you can add the following line to your stdafx.h header file:

Copy Code

#define _CRT_SECURE_COPP_OVERLOAD_STANDARD_NAMES 1

The compiler will then go ahead and emit the following code from the initial, unsafe function:

Copy Code

void func(char *p) {
    char d[20];
    strcpy_s(d,__countof(d), p);
    // etc
}

As you can see, the code is now secure, and yet the developer did nothing other than add a #define. This is one of my favorite additions to Visual C++ because about 50 percent of unsafe function calls can be promoted to safer calls automatically.

C++ Operator::new

Finally, Visual C++ 2005 and later adds a defense that detects integer overflow when calling operator::new. You can start with code like this:

Copy Code

CFoo *p = new CFoo[count];

Visual C++ compiles it to this:

Copy Code

00004    33 c9           xor    ecx, ecx
00006    8b c6           mov    eax, esi
00008    ba 04 00 00 00  mov    edx, 4
0000d    f7 e2           mul    edx
0000f    0f 90 c1       seto    cl
00012    f7 d9           neg    ecx
00014    0b c8            or    ecx, eax
00016    51             push    ecx
00017    e8 00 00 00 00 call    ??2@YAPAXI@Z    ; operator new

After the amount of memory to allocate is calculated (mul edx), the CL register is set or not set depending on the value of the overflow flag after the multiplication, so, ECX will be 0x00000000 or 0xFFFFFFFF. Because of the next operation (or ecx) the ECX register will either be 0xFFFFFFFF or the value held in EAX, which is result of the initial multiply. This is then passed to operator::new, which will fail in the face of the 2^N-1 allocation.

This defense is free. There is no compiler switch; this is simply what the compiler does.

What if It Fails?

Ah! This thorny question! If any of the defenses listed above are triggered, there is a pretty nasty result: the application quits. That's hardly optimal, but it is a heck of a lot better than running the attacker's malicious code.

The SDL mandates that new code use all these defensive options simply because there are so many attacks out there and you can never verify that your code is 100 percent free of vulnerabilities. One of the catch phrases of the SDL is "assume your code will fail; now what?" In the real world "now what" means put up a fight! Don't let the attacker's code have an easy time; make it hard for the attacker to get exploits to work. Don't give up!

So compile with the latest version of the C++ compiler to get a better /GS, and link with the latest linker to get the benefit of CPU and operating systems defenses.

Send your questions and comments to briefs@microsoft.com.

Michael Howard is a Principal Security Program Manager at Microsoft focusing on secure process improvement and best practices. He is the coauthor of five security books including Writing Secure Code for Windows Vista, The Security Development Lifecycle, Writing Secure Code, and 19 Deadly Sins of Software Security. View his blog at blogs.msdn.com/michael_howard.

 
delphi Process进程控制 unit Process; interface uses Windows, SysUtils,Generics.Collections; type IProcess = interface ['{6F9391CA-3C18-40CE-BA91-BEDA3B405F45}'] function GetProcessHandle(): ... 阅读详情

相关推荐

多目标跟踪(MOT)中的卡尔曼滤波(Kalman filter)和匈牙利(Hungarian)算法详解

多目标跟踪(MOT)中的卡尔曼滤波(Kalman filter)和匈牙利(Hungarian)算法详解 1. 概览 在开始具体讨论卡尔曼滤波和匈牙利算法之前,首先我们来看一下基于检测的目标跟踪算法的大致流程。 2. 卡尔曼滤波(Kalman filter) 目标跟踪中使用的就是最基础的 Kalman filter 算法。这里也仅仅讨论最基础的 Kalman filter 算法。 卡尔曼滤波算法的过程很简单,如下图所示。最核心的两个步骤就是预测和更新(下图的 correct)。 在目标跟踪任务中,目标的

生命在于折腾! 2万+

delphi 中关闭进程

delphi 中关闭进程。代码如下 function KillTask(ExeFileName: string): boolean; const   PROCESS_TERMINATE = $0001; var   ContinueLoop: BOOLean;   FSnapshotHandle: THandle;   FProcessEntry32: TProcessEntry

lenovo455的专栏 1336

【GPT】Coze使用开放平台接口-【7】Dify 比较篇

coze 用于社交,dify 用来内部构建。抛开工作流,机器人,工具,coze 最大的区别在于可以直接发布到社交媒体上。所以,coze 对操作体验上也花了不少功夫,而 dify 就专注在帮助使用者打磨工作流。coze 各个大模块之前可以联动的机制也比较多,所以侧重点各不相同。

非晓为骁的博客 7615

[zz]DEP bypass with SetProcessDEPPolicy()

/* This is a proof of concept of buffer overflow exploitation with DEP bypass on Windows XP Professional SP3 english updated on December 9, 2009 with DEP manually set to OptOut so e...

weixin_34067049的博客 281

【算法设计与分析】期末复习题(超详细)

刚刚整理了一下电脑的文件,发现了这份上学期的算法设计与分析期末复习题,有需要的文后自取。

a1234567822的博客 6616

S7-200SMART PLC在线监视时梯形图是灰色的,无法正常监控的解决办法

S7-200SMART PLC在线监视时梯形图是灰色的,无法正常监控的解决办法

Robot_PLC_HMI_Automation 1万+

Delphi 提升进程权限到SeDebugPrivilege

众所周知,当我们要结束一个进程时,可以调用WINDOWS API函数TerminateProcess函数。但是,有很多进程依然还是无法结束的,这是因为进程权限不够,这时我们可以给进程提升权限再K掉K不掉的进程。一般进程获取了SeDebugPrivilege权限后都可以杀掉大部分进程了。  //提升进程令牌函数 function AdjustProcessPrivilege(ProcessHand

编程小战 3167

Multisim14.0仿真(五十九)基于74LS161的24进制计数器应用设计

它具有同步预置、异步清零功能,支持并行数据加载,并可在计数使能控制下进行二进制计数。:低电平时,在下一个时钟上升沿加载输入数据(A, B, C, D)。(多个 74LS161D 串联构成 8 位、12 位等更长计数器)。低电平时,下一个时钟上升沿加载输入数据(A, B, C, D)。:低电平有效,立即清零计数器(不受时钟控制)。均为高电平时,每个时钟上升沿计数。:两者均为高电平时,计数器才能递增。:立即清零计数器(不受时钟控制)。(通过预置初始值控制计数范围)。(计数范围:0 ~ 15,即。

corlin6688的博客 4766

Delphi 关闭 DEP (2008/xp sp3?)

DEP有时会保护了某些操作, 当进行某些类hack操作的代码时会报错!-_- 用 SetProcessDEPPolicy 可以覆盖系统的DEP设置, but似乎只限2008, xp sp3似乎也支持(待测) hk := GetModuleHandle('Kernel32.dll'); if hk INVALID_HANDLE_VALUE then begin ...

goingchan的专栏 659

CQE和SQE 以及 PQA和DQA的区别

‌:PQA聚焦产品全生命周期流程管理,DQA专注于设计阶段的质量控制。

a1809032425的博客 1907

delphi fmx android 自动更新(一)

所以,如果是http 则,manifest.xml application 下,https无需添加。增加android:usesCleartextTraffic="true",不然无法使用http下载东西。1,REQUEST_INSTALL_PACKAGES 权限。4,WRITE_EXTERNAL_STORAGE 权限。3,READ_EXTERNAL_STORAGE 权限。一般是从http下载安装包 apk。2,INTERNET 权限。sFile为apk包路径。

全粘工程师 553

小程序提示:downloadFile:fail 发生了 SSL 错误,无法建立与该服务器的安全连接

今天在写一个“文案助手”主要用于一些公司企业,发布一些公司宣传,下面的经销商可以快速找到公司最新方案,并且在手机上一键下载。但在开发过程中遇到个问题,微信在安卓手机上下载视频图片可以正常在方案助手下载,到了苹果微信小程序里却提示“downloadFile:fail 发生了 SSL 错误,无法建立与该服务器的安全连接” 然后找了很多资料,发现是因为 WinDows sever 的IIS默认...

junword的博客 2万+

【路径规划】Theta_star算法机器人栅格地图最短路径规划【含Matlab源码 2618期】

Theta_star算法机器人栅格地图最短路径规划 完整的代码,方可运行;可提供运行操作视频!适合小白!

订阅付费专栏Matlab(奶茶价版),可赠送奶茶价版付费专栏指定代码1份; 365

cocos creator 热更新报错 ERROR_DOWNLOAD_MANIFEST: not permitted by network security policy

由于android 限制了明文流量的网络请求,非加密的请求都会被禁止。 可以使用以下的方式进行解决: network-security-config.xml <?xml version="1.0" encoding="utf-8"?> <network-security-config> <base-config cleartextTrafficPermitted="true" /> </network-security-config>

erweimac的博客 1730

蓝牙模块HM-10手册

蓝牙模块HM-10手册,该手册对蓝牙模块HM-10进行了详细的介绍和使用方法以及一些AT指令。

WINCC7.3破解文件

WINCC7.3硬件够破解文件,有需要的下载!WINCC7.3硬件够破解文件,有需要的下载!

win10系统出现蓝屏KERNEL-SECURITY-CHECK-FAILURE的修复方法

写在前面 作为一个运维工程师,关于windows 操作系统出现蓝屏问题是最常见的,假如你是一个桌面运维工程师,对于排查系统蓝屏故障,一定要掌握的一项技能,首先遇到客户问题,应该如何快速的找到问题所在,给客户一个合理的说法。 排查过程 针对win10蓝屏问题,首先需要记录出现蓝屏时的错误信息及错误码,排查过程思路有: 如果记录了当前蓝屏的错误信息,我们首先待操作系统重...

任飞 10万+

OV9734 DATASHEET,完整规格书

OV9734完整规格书,包括电气参数,尺寸规格,寄存器配置表等

深挖C++:类和对象(中)

(先进后出)

xys_678的博客 255

精雕软件(JDpaint) 5.5 绿色版

精雕软件(JDpaint) 5.5 绿色版精雕软件(JDpaint) 5.5 绿色版精雕软件(JDpaint) 5.5 绿色版

跟我学c++中级篇—类型定义的方式

本文系统阐述了编程中类型定义的重要性及c++中的实现方式。重点对比了宏定义、typedef与modern using三种机制,指出using在可读性、灵活性和模板支持上的优势,推荐优先使用。同时提醒开发者注意别名滥用、类型歧义、错误信息冗长等问题,强调统一规范与合理设计。最终结论:在现代c++开发中,应以using为主,兼顾简洁性与可维护性,避免陷入命名混乱与编译困境。

fpcc的专栏 396

【C++——类和对象(上)】筑基篇:以封装奠定面向对象之基

本文系统梳理C++类与对象的核心知识点,涵盖类的定义、访问限定符(public/private)、类作用域、对象实例化及内存布局。重点解析封装思想、this指针机制、空类大小为1字节的原因,以及类与对象在内存中的存储差异。通过对比C语言结构体与C++类,揭示面向对象设计的优势:数据保护、接口统一、命名隔离与代码可维护性提升。内容由浅入深,适合作为学习笔记与复习参考。

2602_95684935的博客 635

【C++】C++17的主要特性

C++17引入多项重要特性:结构化绑定简化多值返回与遍历;inline变量解决头文件中变量定义的ODR问题,支持类内初始化;if/switch初始化语句允许在条件中声明变量,提升代码简洁性;属性语法(如[[nodiscard]]、[[deprecated]])增强代码可读性与安全性;求值顺序明确化,提高程序可预测性。这些改进显著提升了代码的简洁性、安全性和可维护性。

记录我一步步的学习历程,期待无限进步,向星举目! 342

【C++碎片化知识补充】C++ 里 int 也算对象?聊聊对象和变量的边界

盯着sessionId不就是个变量吗?变量凭什么能调用函数?后来才反应过来——它当然是对象。是我把对象这个词理解窄了。

2501_93351213的博客 319

【C++ 基础入门】C++11新特性(下):可变参数模板、lambda 表达式与包装器

C++11高阶特性(可变参数模板与参数包展开、emplace_back、lambda表达式与捕获列表、仿函数、std::function包装器)

2601_96587588的博客 254

#SQLite 数据库笔记一:(概念 / 终端指令 / SQL 语句 / C 编程 / 回调函数)

数据库 = 数据的仓库,假设数据是海量。能力说明存储数据持久化保存,程序退出数据还在统计数据、分组、排序数据管理增、删、改、查(CRUD)嵌入式设备上也会用数据库(单片机网关、路由器、工业 HMI 都常见),因为 sqlite 体积小、无需服务进程、单文件即可。数据库 = 库 > 表 > 记录(行) > 字段(列)sqlite3 = 开源、C 写的、单文件、免安装、最多 2T 的嵌入式关系型数据库。

lwq20051110的博客 259

1-10 PostgreSQL中多表连接全解:inner/left/right/full/cross join

本文基于 PostgreSQL 15+ 完整拆解 5 种主流连接:内连接、左连接、右连接、全连接、笛卡尔连接。结合可落地的测试数据,演示每种连接的执行逻辑、返回结果,重点剖析 NULL 值对 JOIN 匹配的核心影响,彻底解决多表连接数据丢失、匹配异常、结果错乱的问题。

zhangjw34的专栏 139
上一篇: 找到原始的SSDT表的内容
下一篇: 获取LoadLibrary函数的代码
iiprogram
博客等级 码龄25年 1068粉丝 1515原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值