x64异常处理端口 [英] x64 Exception Handling Port

查看:333
本文介绍了x64异常处理端口的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试将一些动态dll调用移植到x64.  

I am attempting to port some dynamic dll calls to x64.  

以前,我使用以下类似的方法来捕获来自外部库的异常:

Previously I used something like the following to trap exceptions from external libraries:

__ try {

} __ except(){}

}__except(){}

以前,如果我成功捕获了异常,我想设置一个错误并返回给用户.

Previously, if I successfully caught an exception, I want to set an error and return to the user.

以下是我要测试的情况:

Here are the cases I like to test against:

 

 

 // C++ exception

抛出 std :: exception();

 

//本机类型

 

抛出 3.14;

 

 

 // divide by zero

x/= 0;

 

//取消引用NULL

x = *

reinterpret_cast < *>(x);

reinterpret_cast<unsigned long*>(x);

 

 

 // access violation

x = 4;

(*

reinterpret_cast < *>(x))= 0xDEADBEEF;

reinterpret_cast<unsigned long*>(x)) = 0xDEADBEEF;

 

 

 // custom exception type

 

抛出 myExceptionType();

在为x64编译了我的旧代码之后,__try/__ except 结构不再正常工作.我只能捕获本机类型测试用例.

After compiling my old code for x64, the __try/__except structure no longer works properly. I can only catch the native type test case.

我注意到x64的一些文档,我开始使用RtlInstallFunctionTableCallback玩弄,因为实际的dll调用是在动态生成的代码中进行的.

I noticed some documentation for x64 and I started toying with using RtlInstallFunctionTableCallback as the actual dll calls are in dynamically generated code.

使用新的x64 API使我感到困惑.例如,以下代码似乎能够捕获来自外部x64 dll的任何异常引发,但是我能从中得出含义的唯一参数是回调指针.改变 标识符,baseAddress和length似乎对使其成为我的回调函数没有任何影响.在我相信自己的应用程序中之前,我想更详细地了解安装过程.

I was puzzled by many things using the new x64 API. For instance, the following code seems to be capable of catching any exception throw from external x64 dlls, but the only parameter I can derive significance from is the call back pointer. Changing the identifier, baseAddress, and length seemed to have no effect on making it into my callback function. I would like to understand the install process in greater detail before I trust this in my application.

   RtlInstallFunctionTableCallback(
    baseAddress | 0x3,//标识符
    baseAddress,       //由回调管理的内存
              nbsp; b  //长度
   & Win64ExceptionCallback,
    NULL,
    NULL
   );

   RtlInstallFunctionTableCallback(
    baseAddress|0x3, //identifier
    baseAddress,       //of memory managed by callback
    0x1,                    //length
    &Win64ExceptionCallback,
    NULL,
    NULL
   );

在回调中,我不知道如何构建PRUNTIME_FUNCTION.我能够找到PGET_RUNTIME_FUNCTION_CALLBACK的定义,但是在winnt.h或SDK的其他地方找不到UNWIND_INFO的定义.这些结构在哪里 在磁盘上定义?最后,我暂时使用了非本地跳转,但是我想了解展开过程.

Once in the callback, I have no idea how to build a PRUNTIME_FUNCTION. I was able to find the definition for PGET_RUNTIME_FUNCTION_CALLBACK, but I could not find a definition for UNWIND_INFO in winnt.h or elsewhere in the SDK. Where are these structures defined on disk? In the end I resorted to doing a non-local jump for the time being, but I would like to understand the unwind process.

理想情况下,我想看到一个完整实现的PGET_RUNTIME_FUNCTION_CALLBACK示例,用于动态生成的代码.

Ideally, I would like to see a fully implemented example of a PGET_RUNTIME_FUNCTION_CALLBACK for dynamically generated code.

推荐答案

您是否一直在进行更改设置有什么用?对于没有更改编译器选项的基本程序,我可以让SEH捕获其中的几种类型(尽管我没有检查类的抛出).

Have you been changing settings in any way? For a basic program with no compiler options changed, I was able to get SEH to catch several of those types (I didn't check the throwing of classes though).

我使用的代码很简单.而且编译器设置没有任何更改.还在x64 Debug和x64 Release版本中进行了测试.

The code I used was simple. And there was no alterations to the compiler settings. This was also tested with x64 Debug and x64 Release builds.


#include <Windows.h>
#include <stdio.h>
#include <wchar.h>

int main()
{
	DWORD_PTR x = 0;
	DWORD_PTR y;

	__try
	{
		throw 1;
	}
	__except(1)
	{
		wprintf(L"Exception caught\n");
	}

	__try
	{
		x /= 0;
	}
	__except(1)
	{
		wprintf(L"Exception caught\n");
	}

	__try
	{
		*(char*)x = 'a';
	}
	__except(1)
	{
		wprintf(L"Exception caught\n");
	}

	__try
	{
		*(char*)y = 'a';
	}
	__except(1)
	{
		wprintf(L"Exception caught\n");
	}

	return 0;
}


这篇关于x64异常处理端口的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆