开发者

Forcing a coredump via Wine ignoring SEH

开发者 https://www.devze.com 2023-01-13 06:53 出处:网络
I\'d like to force a coredump from a program (or see its memory at a specific time in some other way). There are a couple of problems though:

I'd like to force a coredump from a program (or see its memory at a specific time in some other way). There are a couple of problems though:

  • I'm running it under wine (cannot run via winedbg, because开发者_运维问答 the application detects it)
  • The application uses exceptions / SEH / other handlers, which capture non-standard events
  • Even attaching strace stops the program from working
  • I'd like to poke around, so there are no specific areas that I could print
  • Well... I don't have the source

I've tried changing the code to both:

xor eax, eax
call eax

and some random stuff which wasn't a real instruction - both time SEH kicked in and rescued the application.

How can I get the information? I need the memory image from a specific time and can patch the exact place where it occurs.


Since you have access to the source code of wine, I'd suggest just altering the wine SEH code, and/or the implementation of the IsDebuggerPresent() function.

Another option would be to modify the application to suspend itself by raising a SIGSTOP signal. Windows applications in Wine can still access linux APIs by invoking int $0x80, so you could inject some code like the following:

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

Then you can mmap ranges from /proc/(pid)/mem to read out the process's memory, or even attach gdb and use its generate-core-file command. Alternately, you could change this to simply raise SIGQUIT or something to trigger a core dump right then and there (assuming wine hasn't installed a SIGQUIT handler - but with the right syscalls that can be overcome as well).


Try doing it like MSVC. They call UnhandledExceptionFilter directly which bypasses application's exception handlers. From gs_report.c (some #ifdefs skipped):

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

Another possibility is to put an empty handler at the head of the list. Something like this:

#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
  }
}

Edit: sorry, I didn't notice "don't have the source" until now. But if you can patch the code, you can probably add "mov fs:[0], -1" to it.

0

精彩评论

暂无评论...
验证码 换一张
取 消