wenmo8 发布的文章

当调用 StringBuilder.Insert 方法

尝试增加 StringBuilder 对象的长度超出其 StringBuilder.MaxCapacity 属性指定的大小。 下面的示例演示了在示例尝试插入将导致对象的 Length 属性超过其最大容量的字符串时,调用 StringBuilder.Insert(Int32, String, Int32) 方法所引发 OutOfMemoryException 异常。

usingSystem;usingSystem.Text;public classExample
{
public static voidMain()
{
StringBuilder sb
= new StringBuilder(15, 15);
sb.Append(
"Substring #1");try{
sb.Insert(
0, "Substring #2", 1);
}
catch(OutOfMemoryException e) {
Console.WriteLine(
"Out of Memory: {0}", e.Message);
}
}
}
//The example displays the following output://Out of Memory: Insufficient m

简介

RPC_NT_INVALID_STRING_BINDING即无效的字符串绑定,值为0xC0020001。其定义如下:

/
// MessageId: RPC_NT_INVALID_STRING_BINDING
//
// MessageText:
//
// The string binding is invalid.
//
#define RPC_NT_INVALID_STRING_BINDING    ((NTSTATUS)0xC0020001L)

说明

默认情况下,作为DLL创建的C++项目的托管扩展不链接到诸如C/C++运行库(CRT)库、ATL或MFC的本地C/C++库,不使用任何静态变量。此外,项目设置还指定应在启用/NOENTRY选项的情况下链接DLL。这样做是因为与入口点的链接会导致托管代码在DllMain期间运行,这是不安全的。没有入口点的DLL无法初始化静态变量,除非是非常简单的类型,例如整数。通常在/NOENTRY DLL中没有静态变量。ATL、MFC和CRT库都依赖于静态变量,因此如果不首先进行修改,也不能从这些DLL中使用这些库。如果混合模式DLL需要使用依赖于静态的静态或库(如ATL、MFC或CRT),则必须修改DLL,以便手动初始化静态。手动初始化的第一步是确保禁用自动初始化代码,这对于混合DLL是不安全的,并且可能导致死锁。要禁用初始化代码,请执行以下步骤。

某些DLL不与本机库链接,因此它们的DllMain不会初始化一些所需的本机子系统(如CRT或ATL)。一种推荐的解决方案是从托管DLL中删除入口点:
删除托管DLL的入口点

  1. 与/ NOENTRY联系。在解决方案资源管理器中,右键单击该项目
    单击节点,单击属性。在“属性页”对话框中,单击“确定”
    链接器,单击命令行,然后将此开关添加到
    附加选项字段。
  2. 链接msvcrt.lib。在“属性页”对话框中,单击“链接器”,
    单击输入。,然后将msvcrt.lib添加到其他依赖项
    属性。
  3. 删除nochkclr.obj。在“输入”页面(与上一步骤相同的页面)中,从“附加依赖项”属性中删除nochkclr.obj。
  4. CRT中的链接。在“输入”页面(与上一步骤相同的页面)中,将__DllMainCRTStartup @ 12添加到“强制符号引用”属性中。

异常结构信息

ExceptionAddress: 775d4402 (KERNELBASE!RaiseException+0x00000062)
   ExceptionCode: c0020001
  ExceptionFlags: 00000001
NumberParameters: 1
   Parameter[0]: 8007042b//真实错误码或进程退出码

 

简介

STATUS_PRIVILEGED_INSTRUCTION---应用程序执行了特权指令,值为0xC0000096。其定义如下:

//
// MessageId: STATUS_PRIVILEGED_INSTRUCTION
//
// MessageText:
//
// {EXCEPTION}
// Privileged instruction.
//
#define STATUS_PRIVILEGED_INSTRUCTION    ((NTSTATUS)0xC0000096L)    // winnt

说明

特权指令是一种处理器操作码(汇编指令),它只能在0环模式下执行。这些类型的指令通常用于从windows内核访问I/O设备和受保护的数据结构。常规程序以“用户模式”(环3)执行,这不允许直接访问I/O设备等。原因可能是堆栈损坏或函数指针调用混乱。当使用指向无效数据的函数指针时,通常会发生这种情况。如果您的代码破坏了返回堆栈,也可能发生这种情况。有时追踪这类bug可能相当棘手,因为它们通常很难复制。

异常结构信息

ExceptionAddress: 7bf90000
   ExceptionCode: c0000096
  ExceptionFlags: 00000000
NumberParameters: 0

了解如何调试是每个应用程序开发生命周期的一个关键方面。通过调试,开发人员不仅可以识别出发生了异常,还可以系统地遍历应用程序的执行,直到找到并修复罪魁祸首代码。无论解决方案是否需要修复一个小的错误,甚至需要重写系统中的大量组件,只要有足够的时间和人力,简单的调试操作就可以(最终)解决几乎所有问题。
然而,尽管调试功能强大,但它也有点难以承受。由于在几十个代码编辑器和集成开发环境(ide)中使用了数百种活动编程语言和框架,在开始调试自己的项目时,确切地知道如何开始可能有些令人吃惊。
我们去调试吧!

单步操作

调试过程和正常应用程序执行之间的第一个重要区别是,调试允许作为开发人员的您进行某种形式的附加交互。当您通常执行应用程式时,它会根据程式码库中提供的逻辑和指令,自行执行所有程式码,通常不需要使用者互动。

因为要频繁地使用windbg分析堆栈、参数、以及内存状态,但是windbg的界面跟OD、IDA差距是很大的,
对于漏洞分析或者其它用途来说,用它来分析堆栈、内存是很不方便的,需要多次手工输入命令。
为了简化分析工作,自己闲着蛋疼的时候写了两个脚本来增强windbg的这些功能。

准备:下载以下脚本krnldbg.rar,放置在windbg的安装目录。

首先说函数调用栈及参数dump脚本,当windbg命中断点后,用快捷键”ctrl+n”增加一个命令窗口,
输入命令 $$>a<advstk ,即可将栈、及调用栈中的函数参数列出来,蓝色带链接的证明这个内存地址是可访问的,
所以他极有可能是一个指针,所以做了一个内存“链接”,点击后可直接使用另一个脚本查看该处的内存。

 

 

注: 如果advstk执行出错,请换用脚本advstk1,因为我使用的方法很笨,一些细节没处理好.

接上,跳转到内存查看脚本后,会把这个内存地址进行不同的方式解析,
如db,dd,du,da,目的是减少命令的输入次数,并且还会进一步解析这块内存中储存的是否为指针,
如果内存可访问,会进一步再给其加上链接,以便于分析时进一步跟踪。

 

 

 

当然也可以直接在命令窗口中输入命令 $$>a<advmem 0x06FAEF80 查看0x06FAEF80处内存情况

接着下来的问题是怎样让这个命令窗口像真正像windbg的view“窗口”那样即时刷新呢?
答案是在命令窗口上右键,勾选“Auto refresh”,如果不出意外,他就带上了自动刷新的功能了,如下图:

 转自https://bbs.pediy.com/thread-139816.htm