Advanced Windows Debug - Memory Corruption - Stacks

 

Memory Corruption - Stacks

Condition

1.       The executing thread writes to a block of memory that it does not own

2.       The executing thread writes to a block of memory that it does own, but corrupts the state of that memory block.

The best-case scenario for writing to memory that an application does not own is crash.

However, consider the scenario in which the invalid pointer points to a block of memory in use by other parts of application.

1.       Application Crash

2.       Non-crashing and Unpredictable behavior

 

Memory Corruption Analysis

First step is to check whether the issue is caused by memory corruption.

Crash case: checks state of the memory, if there are code path can lead to the state, it may not a memory corruption; if no code path allow for the memory to get into that state, then the memory is corrupted by someone else, it is memory corruption.

Non-Crashing case: break in when strange behaviors observed, identify which memory was the potentially corrupted one, checks whether there are valid code path lead to the state to find out whether it is a real memory corruption or just exception.

How to analyze memory contents

1.       Use dc command to dump out the memory contents of the pointer. (Double-words & ASCII)

2.       Use the !address extension to get info about the memory (R/W, Commit/Reserved, Stack/Heap)

a.       2: kd> !address

unable to resolve nt!MiSessionViewStart

3.       Use dds command to dump out the memory as double words and symbols.

4.       Use dpp command to dereference the specified pointer and dump out the double-word contents of the memory.

5.       Use dpa/dpu to display the memory pointed to in ASCII and Unicode formats

6.       If the memory content is a small number (in a multiple of 4), it might be a handle; use !handle extension to dump out the information about the handle.

7.       If nothing found, try to search the entire address space for references to the address of the memory block

 

Memory Corruption Detection tools

Common: Trap common memory related programming mistakes immediately, as the memory corruption occurs, rather than later when the more troublesome side effects might appear.

Stack Corruption – Compiler

Heap Corruption – Application Verifier

 

Instrument Source Code

Collect all the info gathered and theorize about the possibilities, then instrument your code to prove them right or wrong.

 

Define Avoidance Strategies

Avoidance strategies can come in the form of utilizing tools throughout the development to help catch common memory corruption problems, as well as making sure the code you are writing takes explicit steps to minimize the risk of potential memory corruptions.

 

Frame Pointer Omission

An optimization technique in which the base frame pointer register (EBP) can be used as a general-purpose register rather than a reserved based frame pointer.

 

This command is used to enable hot patching. The basic principle is that these commands can be replaced by a jmp instruction that can execute whatever new code is required. This command is a 2-byte instruction, which enables a short jmp available. We can check the instructions adjacent ahead of this one to patch a long jmp for hot patch.

 

Common Scenarios

1.       Stack Overrun

Overwrite the return address for a particular frame, entire frames, or exhaust the stack completely; the net effect of stack overruns ranges from crashes to unpredictable behavior or even security holes.

PREFast Analysis Tool

http://msdn.microsoft.com/en-us/windows/hardware/gg487345

http://msdn.microsoft.com/en-us/library/ms933794.aspx

http://www.cppblog.com/sandy/archive/2006/03/28/4689.html

 

2.       Asynchronous Operations and Stack Pointers

The lifetime of a local variable declared in a function is directly tied to the scope of that function. A very common programming mistake is to make wrongful assumptions about the lifetime of the local variables and cause unpredictable behavior during execution.

 

3.       Calling Convention Mismatch

Calling convention is a contract between the caller of a function and the function itself. The main difference between these calling conventions lies in how parameters are passed to the calling function and how they are cleaned up from the stack.

__ cedel: caller is responsible for stack cleaning-up, the parameter is pushed from right to left

__ stdcall: called function is responsible for stack cleaning-up, the parameter is pushed from right to left

Generally, stdcall is preferred for its reduction size of the code generated; however in order to support Variable Argument list, cedel must be used, because the called function have no iffo about how many parameters were passed in, which makes it impossible for it to properly clean up the stack.

 

NX-Enabled System

On systems running with NX-enabled hardware and a Windows version that supports NX, the result of executing code from data-only memory is an access violation.

 

Compiler Option

Some compiler options are available to trap stack corruptions early in the development process.

/GS: stack buffer overruns is an attacker is able to overwrite the return address of a frame and resume execution at a location of his own choosing. This flag push a cookie onto the stack before the return address, and when the function returns, checks to see if the cookie is intact. If it is, the return address has not been tampered with and execution continues; if it is not the same, this means that there is a possibility that the return address has been corrupted and the application terminate.

/RTC (Run Time Checks) – it has following Sub-options, pls note that this option is designed to work with debug builds and have no impact on release builds.

/RTCs: each time a function is called, it initializes all local variables to nonzero values to prevent them from retaining old values from prior function calls; verify stack pointer (ESP register) to avoid stack corruption caused by calling convention mismatches; protect against buffer overruns and underruns of local variables

/RTCc: Data loss protection, this compiler option displays an error dialog anytime a cast results in a data loss.

/RTCu: Uninitialized variable protection, display an error whenever a variable is accessed that has yet to be initialized.

 

Other tools:

Rational’s Purify, NuMega’s Bounds Checker, PREFast

 

 

 

 

 

WinDbg Cmd & Extension

da - Display ASCII Character

du – Display Unicode Character

dd – Display Double-word values

dc – Display Double-word values, as well as ASCII equivalent

dds, dps, dqs – Display words and symbols, display the contents of memory in the given range, the memory is assumed to be a series of addresses in the symbol table, the corresponding symbols are displayed as well

dda, ddp, ddu, dpa, dpp, dpu, dqa, dqp, dqu – Display referenced memory, display the pointer at the specified location, dereference the pointer and then display the memory at the resulting location, dereference that pointer at the resulting in a variety of format

!address – display info about the memory (Stack/Heap/…, Image/Mapped/Privated, Commit/Reserved/Free)

!handle – display info about a handle or handles that one or all processes

Uf – unassembled the entire function

Lm – display the address range of the modules loaded into you process

Ln Add – display the symbols at or near the given address

P – execute a single instruction or source line and display the resulting values of all registers and flags.

 

 

 

 

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值