我正在测试公司编写的一个应用程序。其中一个场景是,看看如果该应用程序崩溃会发生什么系统状态。是否有一种应用程序可以强制崩溃我的应用程序?我不想在代码本身中编写崩溃(例如空指针引用)。使用任务管理器来结束进程并不能产生相同的结果。
我正在测试公司编写的一个应用程序。其中一个场景是,看看如果该应用程序崩溃会发生什么系统状态。是否有一种应用程序可以强制崩溃我的应用程序?我不想在代码本身中编写崩溃(例如空指针引用)。使用任务管理器来结束进程并不能产生相同的结果。
在Windows上,您可以将WinDbg附加到进程,损坏某些寄存器或内存并分离。例如,您可以将指令指针设置为某个活动应用程序线程的0。
windbg -pn notepad.exe
附加后,当前线程被设置为调试线程,所以您需要切换到应用程序线程以更新RIP寄存器并使其崩溃。
0:008> ~0s
0:000> rip=0
0:000> qd
winapiexec
工具来实现这个功能:
winapiexec64.exe CreateRemoteThread ( OpenProcess 0x1F0FFF 0 1234 ) 0 0 0xDEAD 0 0 0
1234
替换为进程ID,运行该命令,进程将崩溃。RaiseException(0x0000DEAD,0,0,0);
示例:
#include <windows.h>
#include <iostream>
using namespace std;
int main()
{
HINSTANCE h = LoadLibrary("ntoskrnl.exe");
cout<<h<<endl;
void* a;
a = (void*) GetProcAddress(h,"KeBugCheckEx");
int(*KeBugCheckEx)(ULONG,ULONG_PTR,ULONG_PTR,ULONG_PTR,ULONG_PTR);
KeBugCheckEx = (int(*)(ULONG,ULONG_PTR,ULONG_PTR,ULONG_PTR,ULONG_PTR))a;
cout << a;
KeBugCheckEx(0,0,0,0,0); //crash in module ntoskrnl.exe means that call success!
}
EXCEPTION_NONCONTINUABLE
而不是0。KeBugCheckEx会导致操作系统崩溃,这是过度杀伤力的,除非你从内核模式调用它并且崩溃系统是必要的以防止损坏。 - Adrian McCarthySTATUS_FAIL_FAST_EXCEPTION
(0xC0000409)。如果您想使用自己的自定义异常代码,请确保设置第29位(表示用户定义代码),并清除第28位(因为它被系统保留)。换句话说,您的异常代码应该以高四位中的0xE开头,例如0xE000DEAD。 - Adrian McCarthy您没有说明您正在运行哪个操作系统,但如果是Linux(或其他类UNIX系统),您可以直接使用kill -9
命令杀死进程。这个信号无法被捕获,会很快地终止您的进程。
如果您不在类UNIX系统上,我无法帮助您,抱歉,但您可能会在这里找到一些有用的信息(查找“taskkill”)。
如果系统运行在UNIX/Linux上,您可以向其发送一个信号:SIGQUIT应该会产生一个核心转储,您也可以发送SIGSEGV,如果您想测试它是否出现“分段错误”。它们分别是信号3和11。
如果系统是Windows,我不知道如何在不同的应用程序中引发信号,但如果您可以修改应用程序以处理特定的Windows消息编号,那么将调用raise(),您可以模拟这个过程。raise()会导致信号被引发,而无需编写执行非法操作的代码。然后,您可以向应用程序发布一条消息,该消息将具有引发此信号的处理程序。
“system state”在哪里定义?如果这是Unix,你可以向进程发送信号9...
如果真的需要,你可以将所有应用程序内存与另一个进程(或线程)共享,并让该线程随机写入一些不幸的内存位置的随机数据 - 我想NASA在其某些太空项目中就是这样做的,但我真的无法提供参考。
真正的问题是为什么你想这样做 - 你/真正/要测试什么?
例如,如果这是控制某些处方药医疗服务的程序...请对该服务进行单元测试,分析API并查找缺陷。
另一种方法是在良好的调试器中运行应用程序,将断点设置到特定的代码行,然后你的应用程序就会“崩溃”。这可能不会导致所有线程停止运行,这取决于所使用的调试器。或者,您可以在调试器中运行应用程序,并在一段时间后简单地“停止”应用程序。
这并不一定会导致内核杀死应用程序(可能会转储核心),但无论如何它都可能会达到您想要的效果。
编写一个缓冲区溢出攻击。
#include <string.h>
void doSomething(char *Overflow)
{
char Buffer[1];
strcpy(Buffer, Overflow);
}
int main()
{
doSomething("Muhaha");
}
而且你的程序会崩溃