1

我想从程序中强制执行核心转储(或以其他方式在特定时间查看其内存)。但是有几个问题:

  • 我在 wine 下运行它(不能通过 winedbg 运行,因为应用程序检测到它)
  • 应用程序使用异常/SEH/其他处理程序,它们捕获非标准事件
  • 即使附加 strace 也会阻止程序工作
  • 我想四处看看,所以没有可以打印的特定区域
  • 嗯...我没有来源

我尝试将代码更改为:

xor eax, eax
call eax

以及一些不是真正指令的随机内容——SEH 介入并拯救了应用程序。

如何获取信息?我需要特定时间的内存映像,并且可以修补它发生的确切位置。

4

2 回答 2

3

由于您可以访问 wine 的源代码,我建议只更改 wine SEH 代码和/或IsDebuggerPresent()函数的实现。

另一种选择是通过发出 SIGSTOP 信号来修改应用程序以暂停自身。Wine 中的 Windows 应用程序仍然可以通过调用来访问 linux API int $0x80,因此您可以注入如下代码:

mov %eax, $20  ;; sys_getpid
int $0x80
mov %ebx, %eax ;; load pid parameter
mov %eax, $37  ;; sys_kill
mov %ecx, $19  ;; sig = SIGSTOP
int $0x80      ;; after executing this instruction, execution will halt

然后你可以mmap/proc/(pid)/mem读取进程的内存,甚至附加gdb并使用它的generate-core-file命令。或者,您可以将其更改为简单地引发SIGQUIT或立即触发核心转储(假设 wine 尚未安装SIGQUIT处理程序 - 但也可以克服正确的系统调用)。

于 2010-08-29T04:27:43.503 回答
0

尝试像 MSVC 那样做。他们直接调用 UnhandledExceptionFilter 绕过应用程序的异常处理程序。来自 gs_report.c(跳过了一些 #ifdefs):

/* Make sure any filter already in place is deleted. */
SetUnhandledExceptionFilter(NULL);
UnhandledExceptionFilter((EXCEPTION_POINTERS *)&GS_ExceptionPointers);
TerminateProcess(GetCurrentProcess(), STATUS_STACK_BUFFER_OVERRUN);

另一种可能性是将空处理程序放在列表的开头。像这样的东西:

#include <stdio.h>
#include <excpt.h>
#include <intrin.h>
int main()
{
  __try
  {
    __writefsdword(0, -1); // put chain end marker (-1) in fs:0
    *(int*)9 = 0;          // trigger the exception
  }
  __except( EXCEPTION_EXECUTE_HANDLER )
  {
    printf("Exception!\n");  // this does not appear
  }
}

编辑:抱歉,直到现在我才注意到“没有来源”。但是,如果您可以修补代码,您可能可以在其中添加“mov fs:[0], -1”。

于 2010-08-30T09:35:55.000 回答